mirror of
https://github.com/janeczku/calibre-web
synced 2024-11-18 07:44:54 +00:00
ebe7cd7ba4
Cookies are saved in database for better Invalidation Cookies expiry date is saved in database for further deletion (missing) Database conversion is missing
217 lines
7.4 KiB
Python
Executable File
217 lines
7.4 KiB
Python
Executable File
# -*- coding: utf-8 -*-
|
|
|
|
# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
|
|
# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11,
|
|
# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh,
|
|
# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe,
|
|
# ruben-herold, marblepebble, JackED42, SiphonSquirrel,
|
|
# apetresc, nanu-c, mutschler
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
__package__ = "cps"
|
|
|
|
import sys
|
|
import os
|
|
import mimetypes
|
|
|
|
from flask import Flask
|
|
from .MyLoginManager import MyLoginManager
|
|
from flask_principal import Principal
|
|
|
|
from . import logger
|
|
from .cli import CliParameter
|
|
from .constants import CONFIG_DIR
|
|
from .reverseproxy import ReverseProxied
|
|
from .server import WebServer
|
|
from .dep_check import dependency_check
|
|
from .updater import Updater
|
|
from .babel import babel, get_locale
|
|
from . import config_sql
|
|
from . import cache_buster
|
|
from . import ub, db
|
|
|
|
try:
|
|
from flask_limiter import Limiter
|
|
limiter_present = True
|
|
except ImportError:
|
|
limiter_present = False
|
|
try:
|
|
from flask_wtf.csrf import CSRFProtect
|
|
wtf_present = True
|
|
except ImportError:
|
|
wtf_present = False
|
|
|
|
|
|
mimetypes.init()
|
|
mimetypes.add_type('application/xhtml+xml', '.xhtml')
|
|
mimetypes.add_type('application/epub+zip', '.epub')
|
|
mimetypes.add_type('application/epub+zip', '.kepub')
|
|
mimetypes.add_type('text/xml', '.fb2')
|
|
mimetypes.add_type('application/octet-stream', '.mobi')
|
|
mimetypes.add_type('application/octet-stream', '.prc')
|
|
mimetypes.add_type('application/vnd.amazon.ebook', '.azw')
|
|
mimetypes.add_type('application/x-mobi8-ebook', '.azw3')
|
|
mimetypes.add_type('application/x-rar', '.cbr')
|
|
mimetypes.add_type('application/zip', '.cbz')
|
|
mimetypes.add_type('application/x-tar', '.cbt')
|
|
mimetypes.add_type('application/x-7z-compressed', '.cb7')
|
|
mimetypes.add_type('image/vnd.djv', '.djv')
|
|
mimetypes.add_type('image/vnd.djv', '.djvu')
|
|
mimetypes.add_type('application/mpeg', '.mpeg')
|
|
mimetypes.add_type('audio/mpeg', '.mp3')
|
|
mimetypes.add_type('application/mp4', '.m4a')
|
|
mimetypes.add_type('application/mp4', '.m4b')
|
|
mimetypes.add_type('audio/ogg', '.ogg')
|
|
mimetypes.add_type('application/ogg', '.oga')
|
|
mimetypes.add_type('text/css', '.css')
|
|
mimetypes.add_type('application/x-ms-reader', '.lit')
|
|
mimetypes.add_type('text/javascript; charset=UTF-8', '.js')
|
|
|
|
log = logger.create()
|
|
|
|
app = Flask(__name__)
|
|
app.config.update(
|
|
SESSION_COOKIE_HTTPONLY=True,
|
|
SESSION_COOKIE_SAMESITE='Strict',
|
|
REMEMBER_COOKIE_SAMESITE='Strict', # will be available in flask-login 0.5.1 earliest
|
|
WTF_CSRF_SSL_STRICT=False
|
|
)
|
|
|
|
lm = MyLoginManager()
|
|
|
|
cli_param = CliParameter()
|
|
|
|
config = config_sql.ConfigSQL()
|
|
|
|
if wtf_present:
|
|
csrf = CSRFProtect()
|
|
else:
|
|
csrf = None
|
|
|
|
calibre_db = db.CalibreDB()
|
|
|
|
web_server = WebServer()
|
|
|
|
updater_thread = Updater()
|
|
|
|
if limiter_present:
|
|
limiter = Limiter(key_func=True, headers_enabled=True, auto_check=False, swallow_errors=False)
|
|
else:
|
|
limiter = None
|
|
|
|
|
|
def create_app():
|
|
if csrf:
|
|
csrf.init_app(app)
|
|
|
|
cli_param.init()
|
|
|
|
ub.init_db(cli_param.settings_path)
|
|
# pylint: disable=no-member
|
|
encrypt_key, error = config_sql.get_encryption_key(os.path.dirname(cli_param.settings_path))
|
|
|
|
config_sql.load_configuration(ub.session, encrypt_key)
|
|
config.init_config(ub.session, encrypt_key, cli_param)
|
|
|
|
if error:
|
|
log.error(error)
|
|
|
|
ub.password_change(cli_param.user_credentials)
|
|
|
|
if sys.version_info < (3, 0):
|
|
log.info(
|
|
'*** Python2 is EOL since end of 2019, this version of Calibre-Web is no longer supporting Python2, '
|
|
'please update your installation to Python3 ***')
|
|
print(
|
|
'*** Python2 is EOL since end of 2019, this version of Calibre-Web is no longer supporting Python2, '
|
|
'please update your installation to Python3 ***')
|
|
web_server.stop(True)
|
|
sys.exit(5)
|
|
|
|
lm.login_view = 'web.login'
|
|
lm.anonymous_user = ub.Anonymous
|
|
lm.session_protection = 'strong' if config.config_session == 1 else "basic"
|
|
|
|
db.CalibreDB.update_config(config)
|
|
db.CalibreDB.setup_db(config.config_calibre_dir, cli_param.settings_path)
|
|
calibre_db.init_db()
|
|
|
|
updater_thread.init_updater(config, web_server)
|
|
# Perform dry run of updater and exit afterward
|
|
if cli_param.dry_run:
|
|
updater_thread.dry_run()
|
|
sys.exit(0)
|
|
updater_thread.start()
|
|
requirements = dependency_check()
|
|
for res in requirements:
|
|
if res['found'] == "not installed":
|
|
message = ('Cannot import {name} module, it is needed to run calibre-web, '
|
|
'please install it using "pip install {name}"').format(name=res["name"])
|
|
log.info(message)
|
|
print("*** " + message + " ***")
|
|
web_server.stop(True)
|
|
sys.exit(8)
|
|
for res in requirements + dependency_check(True):
|
|
log.info('*** "{}" version does not meet the requirements. '
|
|
'Should: {}, Found: {}, please consider installing required version ***'
|
|
.format(res['name'],
|
|
res['target'],
|
|
res['found']))
|
|
app.wsgi_app = ReverseProxied(app.wsgi_app)
|
|
|
|
if os.environ.get('FLASK_DEBUG'):
|
|
cache_buster.init_cache_busting(app)
|
|
log.info('Starting Calibre Web...')
|
|
Principal(app)
|
|
lm.init_app(app)
|
|
app.secret_key = os.getenv('SECRET_KEY', config_sql.get_flask_session_key(ub.session))
|
|
|
|
web_server.init_app(app, config)
|
|
if hasattr(babel, "localeselector"):
|
|
babel.init_app(app)
|
|
babel.localeselector(get_locale)
|
|
else:
|
|
babel.init_app(app, locale_selector=get_locale)
|
|
|
|
from . import services
|
|
|
|
if services.ldap:
|
|
services.ldap.init_app(app, config)
|
|
if services.goodreads_support:
|
|
services.goodreads_support.connect(config.config_goodreads_api_key,
|
|
config.config_use_goodreads)
|
|
config.store_calibre_uuid(calibre_db, db.Library_Id)
|
|
# Configure rate limiter
|
|
# https://limits.readthedocs.io/en/stable/storage.html
|
|
app.config.update(RATELIMIT_ENABLED=config.config_ratelimiter)
|
|
if config.config_limiter_uri != "" and not cli_param.memory_backend:
|
|
app.config.update(RATELIMIT_STORAGE_URI=config.config_limiter_uri)
|
|
if config.config_limiter_options != "":
|
|
app.config.update(RATELIMIT_STORAGE_OPTIONS=config.config_limiter_options)
|
|
try:
|
|
limiter.init_app(app)
|
|
except Exception as e:
|
|
log.error('Wrong Flask Limiter configuration, falling back to default: {}'.format(e))
|
|
app.config.update(RATELIMIT_STORAGE_URI=None)
|
|
limiter.init_app(app)
|
|
|
|
# Register scheduled tasks
|
|
from .schedule import register_scheduled_tasks, register_startup_tasks
|
|
register_scheduled_tasks(config.schedule_reconnect)
|
|
register_startup_tasks()
|
|
|
|
return app
|
|
|
|
|