Added background scheduler and scheduled thumbnail generation job

This commit is contained in:
mmonkey 2020-12-19 02:58:40 -06:00
parent 774b9ae12d
commit 21fce9a5b5
6 changed files with 66 additions and 16 deletions

4
cps.py
View File

@ -43,7 +43,6 @@ from cps.gdrive import gdrive
from cps.editbooks import editbook from cps.editbooks import editbook
from cps.remotelogin import remotelogin from cps.remotelogin import remotelogin
from cps.error_handler import init_errorhandler from cps.error_handler import init_errorhandler
from cps.thumbnails import generate_thumbnails
try: try:
from cps.kobo import kobo, get_kobo_activated from cps.kobo import kobo, get_kobo_activated
@ -79,9 +78,6 @@ def main():
app.register_blueprint(kobo_auth) app.register_blueprint(kobo_auth)
if oauth_available: if oauth_available:
app.register_blueprint(oauth) app.register_blueprint(oauth)
generate_thumbnails()
success = web_server.start() success = web_server.start()
sys.exit(0 if success else 1) sys.exit(0 if success else 1)

View File

@ -36,6 +36,8 @@ from flask_principal import Principal
from . import config_sql, logger, cache_buster, cli, ub, db from . import config_sql, logger, cache_buster, cli, ub, db
from .reverseproxy import ReverseProxied from .reverseproxy import ReverseProxied
from .server import WebServer from .server import WebServer
from .services.background_scheduler import BackgroundScheduler
from .tasks.thumbnail import TaskThumbnail
mimetypes.init() mimetypes.init()
@ -115,8 +117,13 @@ def create_app():
config.config_goodreads_api_secret, config.config_goodreads_api_secret,
config.config_use_goodreads) config.config_use_goodreads)
scheduler = BackgroundScheduler()
# Generate 100 book cover thumbnails every 5 minutes
scheduler.add_task(user=None, task=lambda: TaskThumbnail(config=config, limit=100), trigger='interval', minutes=5)
return app return app
@babel.localeselector @babel.localeselector
def get_locale(): def get_locale():
# if a user is logged in, use the locale from the user settings # if a user is logged in, use the locale from the user settings

View File

@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
# Copyright (C) 2020 mmonkey
#
# 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/>.
from __future__ import division, print_function, unicode_literals
import atexit
from .. import logger
from .worker import WorkerThread
from apscheduler.schedulers.background import BackgroundScheduler as BScheduler
class BackgroundScheduler:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(BackgroundScheduler, cls).__new__(cls)
scheduler = BScheduler()
atexit.register(lambda: scheduler.shutdown())
cls.log = logger.create()
cls.scheduler = scheduler
cls.scheduler.start()
return cls._instance
def add(self, func, trigger, **trigger_args):
self.scheduler.add_job(func=func, trigger=trigger, **trigger_args)
def add_task(self, user, task, trigger, **trigger_args):
def scheduled_task():
worker_task = task()
self.log.info('Running scheduled task in background: ' + worker_task.name + ': ' + worker_task.message)
WorkerThread.add(user, worker_task)
self.add(func=scheduled_task, trigger=trigger, **trigger_args)

View File

@ -19,7 +19,7 @@
from __future__ import division, print_function, unicode_literals from __future__ import division, print_function, unicode_literals
import os import os
from cps import config, db, gdriveutils, logger, ub from cps import db, logger, ub
from cps.constants import CACHE_DIR as _CACHE_DIR from cps.constants import CACHE_DIR as _CACHE_DIR
from cps.services.worker import CalibreTask from cps.services.worker import CalibreTask
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -36,8 +36,9 @@ THUMBNAIL_RESOLUTION_2X = 2.0
class TaskThumbnail(CalibreTask): class TaskThumbnail(CalibreTask):
def __init__(self, limit=100, task_message=u'Generating cover thumbnails'): def __init__(self, config, limit=100, task_message=u'Generating cover thumbnails'):
super(TaskThumbnail, self).__init__(task_message) super(TaskThumbnail, self).__init__(task_message)
self.config = config
self.limit = limit self.limit = limit
self.log = logger.create() self.log = logger.create()
self.app_db_session = ub.get_new_session_instance() self.app_db_session = ub.get_new_session_instance()
@ -47,9 +48,6 @@ class TaskThumbnail(CalibreTask):
if self.worker_db.session and use_IM: if self.worker_db.session and use_IM:
thumbnails = self.get_thumbnail_book_ids() thumbnails = self.get_thumbnail_book_ids()
thumbnail_book_ids = list(map(lambda t: t.book_id, thumbnails)) thumbnail_book_ids = list(map(lambda t: t.book_id, thumbnails))
self.log.info(','.join([str(elem) for elem in thumbnail_book_ids]))
self.log.info(len(thumbnail_book_ids))
books_without_thumbnails = self.get_books_without_thumbnails(thumbnail_book_ids) books_without_thumbnails = self.get_books_without_thumbnails(thumbnail_book_ids)
count = len(books_without_thumbnails) count = len(books_without_thumbnails)
@ -116,10 +114,10 @@ class TaskThumbnail(CalibreTask):
def generate_book_thumbnail(self, book, thumbnail): def generate_book_thumbnail(self, book, thumbnail):
if book and thumbnail: if book and thumbnail:
if config.config_use_google_drive: if self.config.config_use_google_drive:
self.log.info('google drive thumbnail') self.log.info('google drive thumbnail')
else: else:
book_cover_filepath = os.path.join(config.config_calibre_dir, book.path, 'cover.jpg') book_cover_filepath = os.path.join(self.config.config_calibre_dir, book.path, 'cover.jpg')
if os.path.isfile(book_cover_filepath): if os.path.isfile(book_cover_filepath):
with Image(filename=book_cover_filepath) as img: with Image(filename=book_cover_filepath) as img:
height = self.get_thumbnail_height(thumbnail) height = self.get_thumbnail_height(thumbnail)

View File

@ -57,7 +57,3 @@ def cover_thumbnail_exists_for_book(book):
return thumbnail_path and os.path.isfile(thumbnail_path) return thumbnail_path and os.path.isfile(thumbnail_path)
return False return False
def generate_thumbnails():
WorkerThread.add(None, TaskThumbnail())

View File

@ -1,3 +1,4 @@
APScheduler==3.6.3
Babel>=1.3, <2.9 Babel>=1.3, <2.9
Flask-Babel>=0.11.1,<2.1.0 Flask-Babel>=0.11.1,<2.1.0
Flask-Login>=0.3.2,<0.5.1 Flask-Login>=0.3.2,<0.5.1