2018-02-17 05:28:36 +00:00
|
|
|
'''
|
|
|
|
This file provides data and objects that do not change throughout the runtime.
|
|
|
|
'''
|
2016-12-17 04:02:08 +00:00
|
|
|
import converter
|
2016-11-06 04:24:43 +00:00
|
|
|
import string
|
2016-12-17 04:02:08 +00:00
|
|
|
import traceback
|
2018-03-19 00:03:11 +00:00
|
|
|
import warnings
|
2016-12-17 04:02:08 +00:00
|
|
|
|
2020-02-07 23:15:49 +00:00
|
|
|
from voussoirkit import sqlhelpers
|
2020-01-22 07:50:11 +00:00
|
|
|
from voussoirkit import winwhich
|
|
|
|
|
2018-07-14 02:22:05 +00:00
|
|
|
# FFmpeg ###########################################################################################
|
|
|
|
|
2018-03-19 00:03:11 +00:00
|
|
|
FFMPEG_NOT_FOUND = '''
|
|
|
|
ffmpeg or ffprobe not found.
|
|
|
|
Add them to your PATH or use symlinks such that they appear in:
|
|
|
|
Linux: which ffmpeg & which ffprobe
|
|
|
|
Windows: where ffmpeg & where ffprobe
|
|
|
|
'''
|
|
|
|
|
|
|
|
def _load_ffmpeg():
|
2020-01-22 07:50:11 +00:00
|
|
|
ffmpeg_path = winwhich.which('ffmpeg')
|
|
|
|
ffprobe_path = winwhich.which('ffprobe')
|
2018-03-19 00:03:11 +00:00
|
|
|
|
|
|
|
if (not ffmpeg_path) or (not ffprobe_path):
|
|
|
|
warnings.warn(FFMPEG_NOT_FOUND)
|
|
|
|
return None
|
|
|
|
|
|
|
|
try:
|
|
|
|
ffmpeg = converter.Converter(
|
|
|
|
ffmpeg_path=ffmpeg_path,
|
|
|
|
ffprobe_path=ffprobe_path,
|
|
|
|
)
|
|
|
|
except converter.ffmpeg.FFMpegError:
|
|
|
|
traceback.print_exc()
|
2020-02-19 22:06:53 +00:00
|
|
|
return None
|
2018-03-19 00:03:11 +00:00
|
|
|
|
|
|
|
return ffmpeg
|
|
|
|
|
|
|
|
ffmpeg = _load_ffmpeg()
|
2016-11-06 04:24:43 +00:00
|
|
|
|
2018-07-14 02:22:05 +00:00
|
|
|
# Database #########################################################################################
|
2018-06-30 19:55:30 +00:00
|
|
|
|
2021-02-03 20:12:47 +00:00
|
|
|
DATABASE_VERSION = 19
|
2020-01-28 04:46:32 +00:00
|
|
|
DB_VERSION_PRAGMA = f'''
|
|
|
|
PRAGMA user_version = {DATABASE_VERSION};
|
|
|
|
'''
|
|
|
|
|
2018-05-04 02:02:53 +00:00
|
|
|
DB_PRAGMAS = f'''
|
2018-01-14 00:48:48 +00:00
|
|
|
PRAGMA cache_size = 10000;
|
2018-03-18 00:54:15 +00:00
|
|
|
PRAGMA count_changes = OFF;
|
|
|
|
PRAGMA foreign_keys = ON;
|
2018-05-04 02:02:53 +00:00
|
|
|
'''
|
2018-06-30 19:55:30 +00:00
|
|
|
|
2018-05-04 02:02:53 +00:00
|
|
|
DB_INIT = f'''
|
2020-02-05 02:43:30 +00:00
|
|
|
BEGIN;
|
2018-05-04 02:02:53 +00:00
|
|
|
{DB_PRAGMAS}
|
2020-01-28 04:46:32 +00:00
|
|
|
{DB_VERSION_PRAGMA}
|
2018-01-14 00:48:48 +00:00
|
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
CREATE TABLE IF NOT EXISTS albums(
|
2018-03-18 07:09:08 +00:00
|
|
|
id TEXT PRIMARY KEY NOT NULL,
|
2018-01-14 00:48:48 +00:00
|
|
|
title TEXT,
|
2018-03-18 22:28:26 +00:00
|
|
|
description TEXT,
|
2021-01-08 07:05:43 +00:00
|
|
|
created INT,
|
2021-01-19 18:35:58 +00:00
|
|
|
thumbnail_photo TEXT,
|
2018-03-18 22:28:26 +00:00
|
|
|
author_id TEXT,
|
2021-01-19 18:35:58 +00:00
|
|
|
FOREIGN KEY(author_id) REFERENCES users(id),
|
|
|
|
FOREIGN KEY(thumbnail_photo) REFERENCES photos(id)
|
2018-01-14 00:48:48 +00:00
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_albums_id on albums(id);
|
2018-03-18 22:28:26 +00:00
|
|
|
CREATE INDEX IF NOT EXISTS index_albums_author_id on albums(author_id);
|
2018-01-14 00:48:48 +00:00
|
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
CREATE TABLE IF NOT EXISTS bookmarks(
|
2018-03-18 07:09:08 +00:00
|
|
|
id TEXT PRIMARY KEY NOT NULL,
|
2018-01-14 00:48:48 +00:00
|
|
|
title TEXT,
|
|
|
|
url TEXT,
|
2021-01-08 07:05:43 +00:00
|
|
|
created INT,
|
2018-03-18 07:09:08 +00:00
|
|
|
author_id TEXT,
|
|
|
|
FOREIGN KEY(author_id) REFERENCES users(id)
|
2018-01-14 00:48:48 +00:00
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_bookmarks_id on bookmarks(id);
|
2018-03-18 22:28:26 +00:00
|
|
|
CREATE INDEX IF NOT EXISTS index_bookmarks_author_id on bookmarks(author_id);
|
2018-01-14 00:48:48 +00:00
|
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
CREATE TABLE IF NOT EXISTS photos(
|
2018-03-18 07:09:08 +00:00
|
|
|
id TEXT PRIMARY KEY NOT NULL,
|
2018-01-14 00:48:48 +00:00
|
|
|
filepath TEXT COLLATE NOCASE,
|
2020-12-30 23:28:52 +00:00
|
|
|
basename TEXT COLLATE NOCASE,
|
2018-01-14 00:48:48 +00:00
|
|
|
override_filename TEXT COLLATE NOCASE,
|
2020-12-30 23:28:52 +00:00
|
|
|
extension TEXT COLLATE NOCASE,
|
2021-02-03 20:12:47 +00:00
|
|
|
mtime INT,
|
|
|
|
sha256 TEXT,
|
2018-01-14 00:48:48 +00:00
|
|
|
width INT,
|
|
|
|
height INT,
|
|
|
|
ratio REAL,
|
|
|
|
area INT,
|
|
|
|
duration INT,
|
|
|
|
bytes INT,
|
|
|
|
created INT,
|
|
|
|
thumbnail TEXT,
|
|
|
|
tagged_at INT,
|
2018-03-10 01:10:27 +00:00
|
|
|
author_id TEXT,
|
2018-03-18 07:09:08 +00:00
|
|
|
searchhidden INT,
|
|
|
|
FOREIGN KEY(author_id) REFERENCES users(id)
|
2018-01-14 00:48:48 +00:00
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_photos_id on photos(id);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_photos_filepath on photos(filepath COLLATE NOCASE);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_photos_override_filename on
|
|
|
|
photos(override_filename COLLATE NOCASE);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_photos_created on photos(created);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_photos_extension on photos(extension);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_photos_author_id on photos(author_id);
|
2018-03-10 01:10:27 +00:00
|
|
|
CREATE INDEX IF NOT EXISTS index_photos_searchhidden on photos(searchhidden);
|
2018-01-14 00:48:48 +00:00
|
|
|
----------------------------------------------------------------------------------------------------
|
2018-03-18 00:54:15 +00:00
|
|
|
CREATE TABLE IF NOT EXISTS tags(
|
2018-03-18 07:09:08 +00:00
|
|
|
id TEXT PRIMARY KEY NOT NULL,
|
|
|
|
name TEXT NOT NULL,
|
2018-03-18 22:28:26 +00:00
|
|
|
description TEXT,
|
2021-01-08 07:05:43 +00:00
|
|
|
created INT,
|
2018-03-18 22:28:26 +00:00
|
|
|
author_id TEXT,
|
|
|
|
FOREIGN KEY(author_id) REFERENCES users(id)
|
2018-03-18 00:54:15 +00:00
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_tags_id on tags(id);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_tags_name on tags(name);
|
2018-03-18 22:28:26 +00:00
|
|
|
CREATE INDEX IF NOT EXISTS index_tags_author_id on tags(author_id);
|
2018-03-18 00:54:15 +00:00
|
|
|
----------------------------------------------------------------------------------------------------
|
2021-01-19 17:42:51 +00:00
|
|
|
CREATE TABLE IF NOT EXISTS users(
|
|
|
|
id TEXT PRIMARY KEY NOT NULL,
|
|
|
|
username TEXT NOT NULL COLLATE NOCASE,
|
|
|
|
password BLOB NOT NULL,
|
|
|
|
display_name TEXT,
|
|
|
|
created INT
|
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_users_id on users(id);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_users_username on users(username COLLATE NOCASE);
|
|
|
|
----------------------------------------------------------------------------------------------------
|
2018-03-18 00:54:15 +00:00
|
|
|
|
|
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
CREATE TABLE IF NOT EXISTS album_associated_directories(
|
2018-03-18 07:09:08 +00:00
|
|
|
albumid TEXT NOT NULL,
|
|
|
|
directory TEXT NOT NULL COLLATE NOCASE,
|
|
|
|
FOREIGN KEY(albumid) REFERENCES albums(id)
|
2018-03-18 00:54:15 +00:00
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_album_associated_directories_albumid on
|
|
|
|
album_associated_directories(albumid);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_album_associated_directories_directory on
|
|
|
|
album_associated_directories(directory);
|
|
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
CREATE TABLE IF NOT EXISTS album_group_rel(
|
2018-03-18 07:09:08 +00:00
|
|
|
parentid TEXT NOT NULL,
|
|
|
|
memberid TEXT NOT NULL,
|
|
|
|
FOREIGN KEY(parentid) REFERENCES albums(id),
|
|
|
|
FOREIGN KEY(memberid) REFERENCES albums(id)
|
2018-03-18 00:54:15 +00:00
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_album_group_rel_parentid on album_group_rel(parentid);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_album_group_rel_memberid on album_group_rel(memberid);
|
|
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
CREATE TABLE IF NOT EXISTS album_photo_rel(
|
2018-03-18 07:09:08 +00:00
|
|
|
albumid TEXT NOT NULL,
|
|
|
|
photoid TEXT NOT NULL,
|
|
|
|
FOREIGN KEY(albumid) REFERENCES albums(id),
|
|
|
|
FOREIGN KEY(photoid) REFERENCES photos(id)
|
2018-03-18 00:54:15 +00:00
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_album_photo_rel_albumid on album_photo_rel(albumid);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_album_photo_rel_photoid on album_photo_rel(photoid);
|
|
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
CREATE TABLE IF NOT EXISTS id_numbers(
|
2018-03-18 07:09:08 +00:00
|
|
|
tab TEXT NOT NULL,
|
|
|
|
last_id TEXT NOT NULL
|
2018-03-18 00:54:15 +00:00
|
|
|
);
|
|
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
CREATE TABLE IF NOT EXISTS photo_tag_rel(
|
2018-03-18 07:09:08 +00:00
|
|
|
photoid TEXT NOT NULL,
|
|
|
|
tagid TEXT NOT NULL,
|
|
|
|
FOREIGN KEY(photoid) REFERENCES photos(id),
|
|
|
|
FOREIGN KEY(tagid) REFERENCES tags(id)
|
2018-03-18 00:54:15 +00:00
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_photo_tag_rel_photoid on photo_tag_rel(photoid);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_photo_tag_rel_tagid on photo_tag_rel(tagid);
|
2018-03-22 02:00:13 +00:00
|
|
|
CREATE INDEX IF NOT EXISTS index_photo_tag_rel_photoid_tagid on photo_tag_rel(photoid, tagid);
|
2018-03-18 07:09:08 +00:00
|
|
|
----------------------------------------------------------------------------------------------------
|
2018-01-14 00:48:48 +00:00
|
|
|
CREATE TABLE IF NOT EXISTS tag_group_rel(
|
2018-03-18 07:09:08 +00:00
|
|
|
parentid TEXT NOT NULL,
|
|
|
|
memberid TEXT NOT NULL,
|
|
|
|
FOREIGN KEY(parentid) REFERENCES tags(id),
|
|
|
|
FOREIGN KEY(memberid) REFERENCES tags(id)
|
2018-01-14 00:48:48 +00:00
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_tag_group_rel_parentid on tag_group_rel(parentid);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_tag_group_rel_memberid on tag_group_rel(memberid);
|
|
|
|
----------------------------------------------------------------------------------------------------
|
|
|
|
CREATE TABLE IF NOT EXISTS tag_synonyms(
|
2018-03-18 07:09:08 +00:00
|
|
|
name TEXT NOT NULL,
|
|
|
|
mastername TEXT NOT NULL
|
2018-01-14 00:48:48 +00:00
|
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS index_tag_synonyms_name on tag_synonyms(name);
|
|
|
|
----------------------------------------------------------------------------------------------------
|
2020-02-05 02:43:30 +00:00
|
|
|
COMMIT;
|
2018-04-15 08:13:02 +00:00
|
|
|
'''
|
2018-01-14 00:48:48 +00:00
|
|
|
|
2020-02-07 23:15:49 +00:00
|
|
|
SQL_COLUMNS = sqlhelpers.extract_table_column_map(DB_INIT)
|
|
|
|
SQL_INDEX = sqlhelpers.reverse_table_column_map(SQL_COLUMNS)
|
2016-12-17 04:02:08 +00:00
|
|
|
|
2020-12-30 00:06:43 +00:00
|
|
|
ALLOWED_ORDERBY_COLUMNS = {
|
2018-01-14 00:48:48 +00:00
|
|
|
'area',
|
2020-12-30 23:28:52 +00:00
|
|
|
'basename',
|
2020-12-30 00:06:43 +00:00
|
|
|
'bitrate',
|
2018-01-14 00:48:48 +00:00
|
|
|
'bytes',
|
|
|
|
'created',
|
2020-12-30 00:06:43 +00:00
|
|
|
'duration',
|
|
|
|
'extension',
|
|
|
|
'height',
|
2018-01-14 00:48:48 +00:00
|
|
|
'random',
|
2020-12-30 00:06:43 +00:00
|
|
|
'ratio',
|
|
|
|
'tagged_at',
|
|
|
|
'width',
|
|
|
|
}
|
2018-01-14 00:48:48 +00:00
|
|
|
|
2018-07-14 02:22:05 +00:00
|
|
|
# Errors and warnings ##############################################################################
|
2016-12-17 04:02:08 +00:00
|
|
|
|
2016-11-06 04:24:43 +00:00
|
|
|
WARNING_MINMAX_INVALID = 'Field "{field}": "{value}" is not a valid request. Ignored.'
|
2016-12-25 01:13:45 +00:00
|
|
|
WARNING_ORDERBY_INVALID = 'Invalid orderby request "{request}". Ignored.'
|
2016-11-06 04:24:43 +00:00
|
|
|
WARNING_ORDERBY_BADCOL = '"{column}" is not a sorting option. Ignored.'
|
2017-03-15 04:18:42 +00:00
|
|
|
WARNING_ORDERBY_BADDIRECTION = '''
|
|
|
|
You can\'t order "{column}" by "{direction}". Defaulting to descending.
|
|
|
|
'''
|
2016-11-06 04:24:43 +00:00
|
|
|
|
2018-07-14 02:22:05 +00:00
|
|
|
# Janitorial stuff #################################################################################
|
|
|
|
|
|
|
|
FILENAME_BADCHARS = '\\/:*?<>|"'
|
2017-03-10 23:01:12 +00:00
|
|
|
TRUTHYSTRING_TRUE = {s.lower() for s in ('1', 'true', 't', 'yes', 'y', 'on')}
|
2021-01-29 01:21:30 +00:00
|
|
|
TRUTHYSTRING_FALSE = {s.lower() for s in ('0', 'false', 'f', 'no', 'n', 'off')}
|
2017-03-10 23:01:12 +00:00
|
|
|
TRUTHYSTRING_NONE = {s.lower() for s in ('null', 'none')}
|
|
|
|
|
2020-09-19 10:51:55 +00:00
|
|
|
USER_ID_CHARACTERS = string.digits + string.ascii_uppercase
|
|
|
|
|
2016-12-17 02:53:12 +00:00
|
|
|
ADDITIONAL_MIMETYPES = {
|
2017-02-28 07:05:43 +00:00
|
|
|
'7z': 'archive',
|
|
|
|
'gz': 'archive',
|
|
|
|
'rar': 'archive',
|
2017-02-28 07:39:06 +00:00
|
|
|
|
|
|
|
'aac': 'audio/aac',
|
|
|
|
'ac3': 'audio/ac3',
|
|
|
|
'dts': 'audio/dts',
|
|
|
|
'm4a': 'audio/mp4',
|
2017-10-04 23:54:28 +00:00
|
|
|
'opus': 'audio/ogg',
|
2017-02-28 07:39:06 +00:00
|
|
|
|
|
|
|
'mkv': 'video/x-matroska',
|
|
|
|
|
2017-03-04 06:50:36 +00:00
|
|
|
'ass': 'text/plain',
|
2018-03-10 21:27:21 +00:00
|
|
|
'md': 'text/plain',
|
2018-01-10 02:46:32 +00:00
|
|
|
'nfo': 'text/plain',
|
2018-03-10 21:27:21 +00:00
|
|
|
'rst': 'text/plain',
|
2017-02-28 07:39:06 +00:00
|
|
|
'srt': 'text/plain',
|
2016-12-17 02:53:12 +00:00
|
|
|
}
|
2016-11-06 04:24:43 +00:00
|
|
|
|
2018-07-14 02:22:05 +00:00
|
|
|
# Photodb ##########################################################################################
|
|
|
|
|
2021-01-09 23:41:52 +00:00
|
|
|
DEFAULT_DATADIR = '_etiquette'
|
2017-04-21 01:26:15 +00:00
|
|
|
DEFAULT_DBNAME = 'phototagger.db'
|
|
|
|
DEFAULT_CONFIGNAME = 'config.json'
|
|
|
|
DEFAULT_THUMBDIR = 'site_thumbnails'
|
2016-12-16 09:53:51 +00:00
|
|
|
|
2016-12-17 02:53:12 +00:00
|
|
|
DEFAULT_CONFIGURATION = {
|
2017-07-29 23:23:15 +00:00
|
|
|
'cache_size': {
|
|
|
|
'album': 1000,
|
2017-12-21 04:10:58 +00:00
|
|
|
'bookmark': 100,
|
2017-07-29 23:23:15 +00:00
|
|
|
'photo': 100000,
|
2018-07-19 01:27:18 +00:00
|
|
|
'tag': 10000,
|
2017-07-29 23:23:15 +00:00
|
|
|
'user': 200,
|
|
|
|
},
|
|
|
|
|
|
|
|
'enable_feature': {
|
|
|
|
'album': {
|
|
|
|
'edit': True,
|
|
|
|
'new': True,
|
|
|
|
},
|
|
|
|
'bookmark': {
|
|
|
|
'edit': True,
|
|
|
|
'new': True,
|
|
|
|
},
|
|
|
|
'photo': {
|
|
|
|
'add_remove_tag': True,
|
|
|
|
'new': True,
|
|
|
|
'edit': True,
|
|
|
|
'generate_thumbnail': True,
|
|
|
|
'reload_metadata': True,
|
|
|
|
},
|
|
|
|
'tag': {
|
|
|
|
'edit': True,
|
|
|
|
'new': True,
|
|
|
|
},
|
|
|
|
'user': {
|
2018-04-15 21:23:24 +00:00
|
|
|
'edit': True,
|
2017-07-29 23:23:15 +00:00
|
|
|
'login': True,
|
|
|
|
'new': True,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
'tag': {
|
|
|
|
'min_length': 1,
|
|
|
|
'max_length': 32,
|
2020-09-18 01:52:00 +00:00
|
|
|
# 'valid_chars': string.ascii_lowercase + string.digits + '_()',
|
2017-07-29 23:23:15 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
'user': {
|
2018-04-15 21:32:18 +00:00
|
|
|
'min_username_length': 2,
|
2017-07-29 23:23:15 +00:00
|
|
|
'min_password_length': 6,
|
2018-04-15 21:23:24 +00:00
|
|
|
'max_display_name_length': 24,
|
2018-04-15 21:32:18 +00:00
|
|
|
'max_username_length': 24,
|
2018-04-15 21:23:24 +00:00
|
|
|
'valid_chars': string.ascii_letters + string.digits + '_-',
|
2017-07-29 23:23:15 +00:00
|
|
|
},
|
2016-11-06 04:24:43 +00:00
|
|
|
|
2016-12-17 02:53:12 +00:00
|
|
|
'digest_exclude_files': [
|
|
|
|
'phototagger.db',
|
|
|
|
'desktop.ini',
|
|
|
|
'thumbs.db',
|
|
|
|
],
|
|
|
|
'digest_exclude_dirs': [
|
2018-03-13 09:50:54 +00:00
|
|
|
'_etiquette',
|
2016-12-17 02:53:12 +00:00
|
|
|
'_site_thumbnails',
|
2018-03-13 09:50:54 +00:00
|
|
|
'site_thumbnails',
|
2016-12-17 02:53:12 +00:00
|
|
|
],
|
|
|
|
|
2017-11-26 10:37:33 +00:00
|
|
|
'file_read_chunk': 2 ** 20,
|
2017-07-29 23:23:15 +00:00
|
|
|
'id_length': 12,
|
2016-12-17 02:53:12 +00:00
|
|
|
'thumbnail_width': 400,
|
|
|
|
'thumbnail_height': 400,
|
2017-07-29 23:23:15 +00:00
|
|
|
|
2020-02-27 22:18:46 +00:00
|
|
|
'recycle_instead_of_delete': True,
|
|
|
|
|
2016-12-17 02:53:12 +00:00
|
|
|
'motd_strings': [
|
|
|
|
'Good morning, Paul. What will your first sequence of the day be?',
|
|
|
|
],
|
2016-11-06 04:24:43 +00:00
|
|
|
}
|