Files
Calibre-Web-Automated/cps/constants.py
T
2025-09-02 15:32:04 +02:00

234 lines
8.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
# Calibre-Web Automated fork of Calibre-Web
# Copyright (C) 2018-2025 Calibre-Web contributors
# Copyright (C) 2024-2025 Calibre-Web Automated contributors
# SPDX-License-Identifier: GPL-3.0-or-later
# See CONTRIBUTORS for full list of authors.
import sys
import os
from collections import namedtuple
from flask_babel import gettext as _
# APP_MODE - production, development, or test
APP_MODE = os.environ.get('APP_MODE', 'production')
# if installed via pip this variable is set to true (empty file with name .HOMEDIR present)
HOME_CONFIG = os.path.isfile(os.path.join(os.path.dirname(os.path.abspath(__file__)), '.HOMEDIR'))
# In executables updater is not available, so variable is set to False there
UPDATER_AVAILABLE = False
# Base dir is parent of current file, necessary if called from different folder
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir))
# if executable file the files should be placed in the parent dir (parallel to the exe file)
STATIC_DIR = os.path.join(BASE_DIR, 'cps', 'static')
TEMPLATES_DIR = os.path.join(BASE_DIR, 'cps', 'templates')
TRANSLATIONS_DIR = os.path.join(BASE_DIR, 'cps', 'translations')
# Cache dir - use CACHE_DIR environment variable, otherwise use the default directory: cps/cache
DEFAULT_CACHE_DIR = os.path.join(BASE_DIR, 'cps', 'cache')
CACHE_DIR = os.environ.get('CACHE_DIR', DEFAULT_CACHE_DIR)
OAUTH_SSL_STRICT = os.environ.get('OAUTH_SSL_STRICT', "1").lower() in ("true", "1")
if HOME_CONFIG:
home_dir = os.path.join(os.path.expanduser("~"), ".calibre-web-automated")
if not os.path.exists(home_dir):
os.makedirs(home_dir)
CONFIG_DIR = os.environ.get('CALIBRE_DBPATH', home_dir)
else:
CONFIG_DIR = os.environ.get('CALIBRE_DBPATH', BASE_DIR)
if getattr(sys, 'frozen', False):
CONFIG_DIR = os.path.abspath(os.path.join(CONFIG_DIR, os.pardir))
DEFAULT_SETTINGS_FILE = "app.db"
DEFAULT_GDRIVE_FILE = "gdrive.db"
ROLE_USER = 0 << 0
ROLE_ADMIN = 1 << 0
ROLE_DOWNLOAD = 1 << 1
ROLE_UPLOAD = 1 << 2
ROLE_EDIT = 1 << 3
ROLE_PASSWD = 1 << 4
ROLE_ANONYMOUS = 1 << 5
ROLE_EDIT_SHELFS = 1 << 6
ROLE_DELETE_BOOKS = 1 << 7
ROLE_VIEWER = 1 << 8
ALL_ROLES = {
"admin_role": ROLE_ADMIN,
"download_role": ROLE_DOWNLOAD,
"upload_role": ROLE_UPLOAD,
"edit_role": ROLE_EDIT,
"passwd_role": ROLE_PASSWD,
"edit_shelf_role": ROLE_EDIT_SHELFS,
"delete_role": ROLE_DELETE_BOOKS,
"viewer_role": ROLE_VIEWER,
}
DETAIL_RANDOM = 1 << 0
SIDEBAR_LANGUAGE = 1 << 1
SIDEBAR_SERIES = 1 << 2
SIDEBAR_CATEGORY = 1 << 3
SIDEBAR_HOT = 1 << 4
SIDEBAR_RANDOM = 1 << 5
SIDEBAR_AUTHOR = 1 << 6
SIDEBAR_BEST_RATED = 1 << 7
SIDEBAR_READ_AND_UNREAD = 1 << 8
SIDEBAR_RECENT = 1 << 9
SIDEBAR_SORTED = 1 << 10
MATURE_CONTENT = 1 << 11
SIDEBAR_PUBLISHER = 1 << 12
SIDEBAR_RATING = 1 << 13
SIDEBAR_FORMAT = 1 << 14
SIDEBAR_ARCHIVED = 1 << 15
SIDEBAR_DOWNLOAD = 1 << 16
SIDEBAR_LIST = 1 << 17
SIDEBAR_DUPLICATES = 1 << 18
sidebar_settings = {
"detail_random": DETAIL_RANDOM,
"sidebar_language": SIDEBAR_LANGUAGE,
"sidebar_series": SIDEBAR_SERIES,
"sidebar_category": SIDEBAR_CATEGORY,
"sidebar_random": SIDEBAR_RANDOM,
"sidebar_author": SIDEBAR_AUTHOR,
"sidebar_best_rated": SIDEBAR_BEST_RATED,
"sidebar_read_and_unread": SIDEBAR_READ_AND_UNREAD,
"sidebar_recent": SIDEBAR_RECENT,
"sidebar_sorted": SIDEBAR_SORTED,
"sidebar_publisher": SIDEBAR_PUBLISHER,
"sidebar_rating": SIDEBAR_RATING,
"sidebar_format": SIDEBAR_FORMAT,
"sidebar_archived": SIDEBAR_ARCHIVED,
"sidebar_download": SIDEBAR_DOWNLOAD,
"sidebar_list": SIDEBAR_LIST,
"sidebar_duplicates": SIDEBAR_DUPLICATES,
}
ADMIN_USER_ROLES = sum(r for r in ALL_ROLES.values()) & ~ROLE_ANONYMOUS
ADMIN_USER_SIDEBAR = (SIDEBAR_DUPLICATES << 1) - 1
UPDATE_STABLE = 0 << 0
AUTO_UPDATE_STABLE = 1 << 0
UPDATE_NIGHTLY = 1 << 1
AUTO_UPDATE_NIGHTLY = 1 << 2
LOGIN_STANDARD = 0
LOGIN_LDAP = 1
LOGIN_OAUTH = 2
LDAP_AUTH_ANONYMOUS = 0
LDAP_AUTH_UNAUTHENTICATE = 1
LDAP_AUTH_SIMPLE = 0
DEFAULT_MAIL_SERVER = "mail.example.org"
DEFAULT_PASSWORD = "admin123" # nosec
DEFAULT_PORT = 8083
env_CWA_PORT_OVERRIDE = os.environ.get("CWA_PORT_OVERRIDE")
if env_CWA_PORT_OVERRIDE:
try:
DEFAULT_PORT = int(env_CWA_PORT_OVERRIDE)
except (ValueError, TypeError):
print(f"Environment variable CWA_PORT_OVERRIDE has invalid value ('{env_CWA_PORT_OVERRIDE}'), falling back to default (8083)")
DEFAULT_PORT = 8083
EXTENSIONS_AUDIO = {'mp3', 'mp4', 'ogg', 'opus', 'wav', 'flac', 'm4a', 'm4b'}
EXTENSIONS_CONVERT_FROM = ['pdf', 'epub', 'mobi', 'azw3', 'docx', 'rtf', 'fb2', 'lit', 'lrf',
'txt', 'htmlz', 'rtf', 'odt', 'cbz', 'cbr', 'prc', 'acsm']
EXTENSIONS_CONVERT_TO = ['pdf', 'epub', 'mobi', 'azw3', 'docx', 'rtf', 'fb2',
'lit', 'lrf', 'txt', 'htmlz', 'rtf', 'odt']
EXTENSIONS_UPLOAD = {'txt', 'pdf', 'epub', 'kepub', 'mobi', 'azw', 'azw3', 'cbr', 'cbz', 'cbt', 'cb7', 'djvu', 'djv',
'prc', 'doc', 'docx', 'fb2', 'html', 'rtf', 'lit', 'odt', 'mp3', 'mp4', 'ogg',
'opus', 'wav', 'flac', 'm4a', 'm4b', 'acsm'}
_extension = ""
if sys.platform == "win32":
_extension = ".exe"
SUPPORTED_CALIBRE_BINARIES = {binary: binary + _extension for binary in ["ebook-convert", "calibredb"]}
def has_flag(value, bit_flag):
return bit_flag == (bit_flag & (value or 0))
def selected_roles(dictionary):
return sum(v for k, v in ALL_ROLES.items() if k in dictionary)
# :rtype: BookMeta
BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, description, tags, series, '
'series_id, languages, publisher, pubdate, identifiers')
def _read_text(path: str, default: str = "") -> str:
try:
with open(path, 'r') as f:
return f.read().strip()
except Exception:
return default
# Versions are resolved at container startup by cwa-init and provided via env and persisted files.
# Avoid any network or slow I/O during module import.
INSTALLED_VERSION = os.environ.get("CWA_INSTALLED_VERSION") or _read_text("/app/CWA_RELEASE", "V0.0.0")
STABLE_VERSION = os.environ.get("CWA_STABLE_VERSION") or _read_text("/app/CWA_STABLE_RELEASE", "V0.0.0")
USER_AGENT = f"Calibre-Web-Automated/{INSTALLED_VERSION}"
NIGHTLY_VERSION = dict()
NIGHTLY_VERSION[0] = '0af52f205358b0147ee3430f9e6c8fe007c0ea77'
NIGHTLY_VERSION[1] = '2024-11-16T07:21:28+01:00'
# CACHE
CACHE_TYPE_THUMBNAILS = 'thumbnails'
# Thumbnail Types
THUMBNAIL_TYPE_COVER = 1
THUMBNAIL_TYPE_SERIES = 2
THUMBNAIL_TYPE_AUTHOR = 3
# Thumbnails Sizes
COVER_THUMBNAIL_ORIGINAL = 0
COVER_THUMBNAIL_SMALL = 1
COVER_THUMBNAIL_MEDIUM = 2
COVER_THUMBNAIL_LARGE = 4
# clean-up the module namespace
del sys, os, namedtuple
# Mapping of language codes to full language names
LANGUAGE_NAMES = {
"cs": _("Czech"),
"de": _("German"),
"el": _("Greek"),
"es": _("Spanish"),
"fi": _("Finnish"),
"fr": _("French"),
"gl": _("Galician"),
"hu": _("Hungarian"),
"id": _("Indonesian"),
"it": _("Italian"),
"ja": _("Japanese"),
"km": _("Khmer"),
"ko": _("Korean"),
"nl": _("Dutch"),
"no": _("Norwegian"),
"pl": _("Polish"),
"pt": _("Portuguese"),
"pt_BR": _("Portuguese (Brazil)"),
"ru": _("Russian"),
"sk": _("Slovak"),
"sl": _("Slovenian"),
"sv": _("Swedish"),
"tr": _("Turkish"),
"uk": _("Ukrainian"),
"vi": _("Vietnamese"),
"zh_Hans_CN": _("Chinese (Simplified, China)"),
"zh_Hant_TW": _("Chinese (Traditional, Taiwan)"),
}