mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-30 23:03:02 +00:00 
			
		
		
		
	Added background scheduler and scheduled thumbnail generation job
This commit is contained in:
		
							
								
								
									
										4
									
								
								cps.py
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								cps.py
									
									
									
									
									
								
							| @@ -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) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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() | ||||||
| @@ -95,7 +97,7 @@ def create_app(): | |||||||
|         app.instance_path = app.instance_path.decode('utf-8') |         app.instance_path = app.instance_path.decode('utf-8') | ||||||
|  |  | ||||||
|     if os.environ.get('FLASK_DEBUG'): |     if os.environ.get('FLASK_DEBUG'): | ||||||
|     	cache_buster.init_cache_busting(app) |         cache_buster.init_cache_busting(app) | ||||||
|  |  | ||||||
|     log.info('Starting Calibre Web...') |     log.info('Starting Calibre Web...') | ||||||
|     Principal(app) |     Principal(app) | ||||||
| @@ -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 | ||||||
|   | |||||||
							
								
								
									
										52
									
								
								cps/services/background_scheduler.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								cps/services/background_scheduler.py
									
									
									
									
									
										Normal 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) | ||||||
| @@ -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) | ||||||
|   | |||||||
| @@ -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()) |  | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 mmonkey
					mmonkey