diff --git a/cps/constants.py b/cps/constants.py index 1e44796a..6a6b8f2b 100644 --- a/cps/constants.py +++ b/cps/constants.py @@ -40,7 +40,10 @@ else: 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 = os.path.join(BASE_DIR, 'cps', 'cache') + +# 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) if HOME_CONFIG: home_dir = os.path.join(os.path.expanduser("~"),".calibre-web") diff --git a/cps/fs.py b/cps/fs.py index 699d5991..8528e39c 100644 --- a/cps/fs.py +++ b/cps/fs.py @@ -50,6 +50,14 @@ class FileSystem: path = self.get_cache_dir(cache_type) return [file for file in listdir(path) if isfile(join(path, file))] + def list_existing_cache_files(self, filenames, cache_type=None): + path = self.get_cache_dir(cache_type) + return [file for file in listdir(path) if isfile(join(path, file)) and file in filenames] + + def list_missing_cache_files(self, filenames, cache_type=None): + path = self.get_cache_dir(cache_type) + return [file for file in listdir(path) if isfile(join(path, file)) and file not in filenames] + def delete_cache_dir(self, cache_type=None): if not cache_type and isdir(self._cache_dir): rmtree(self._cache_dir) diff --git a/cps/helper.py b/cps/helper.py index 6f22a701..688bc615 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -405,6 +405,7 @@ def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepa src=new_path, dest=new_name, error=str(ex)) return False + def update_dir_structure_gdrive(book_id, first_author): error = False book = calibre_db.get_book(book_id) @@ -505,6 +506,7 @@ def uniq(inpt): output.append(x) return output + def check_email(email): email = valid_email(email) if ub.session.query(ub.User).filter(func.lower(ub.User.email) == email.lower()).first(): diff --git a/cps/schedule.py b/cps/schedule.py index 8ab9c732..649b65a3 100644 --- a/cps/schedule.py +++ b/cps/schedule.py @@ -27,13 +27,12 @@ from .tasks.thumbnail import TaskSyncCoverThumbnailCache, TaskGenerateCoverThumb def register_jobs(): scheduler = BackgroundScheduler() - # Generate up to 1000 book covers daily - generate_thumbnails_task = scheduler.add_task(user=None, task=lambda: TaskGenerateCoverThumbnails(limit=1000), - trigger='interval', days=1) - generate_thumbnails_task.modify(next_run_time=datetime.now()) + if scheduler: + # Reconnect metadata.db once every 12 hours + scheduler.add_task(user=None, task=lambda: TaskReconnectDatabase(), trigger='interval', hours=12) - # Cleanup book cover cache every 6 hours - scheduler.add_task(user=None, task=lambda: TaskSyncCoverThumbnailCache(), trigger='cron', minute='15', hour='*/6') + # Cleanup book cover cache once every 24 hours + scheduler.add_task(user=None, task=lambda: TaskSyncCoverThumbnailCache(), trigger='interval', days=1) - # Reconnect metadata.db every 4 hours - scheduler.add_task(user=None, task=lambda: TaskReconnectDatabase(), trigger='cron', minute='5', hour='*/4') + # Generate all missing book cover thumbnails once every 24 hours + scheduler.add_task(user=None, task=lambda: TaskGenerateCoverThumbnails(), trigger='interval', days=1) diff --git a/cps/services/background_scheduler.py b/cps/services/background_scheduler.py index 122168e8..f2688b7f 100644 --- a/cps/services/background_scheduler.py +++ b/cps/services/background_scheduler.py @@ -21,13 +21,23 @@ import atexit from .. import logger from .worker import WorkerThread -from apscheduler.schedulers.background import BackgroundScheduler as BScheduler + +try: + from apscheduler.schedulers.background import BackgroundScheduler as BScheduler + use_APScheduler = True +except (ImportError, RuntimeError) as e: + use_APScheduler = False + log = logger.create() + log.info(f'APScheduler not found. Unable to schedule tasks.') class BackgroundScheduler: _instance = None def __new__(cls): + if not use_APScheduler: + return False + if cls._instance is None: cls._instance = super(BackgroundScheduler, cls).__new__(cls) @@ -41,12 +51,14 @@ class BackgroundScheduler: return cls._instance def add(self, func, trigger, **trigger_args): - return self.scheduler.add_job(func=func, trigger=trigger, **trigger_args) + if use_APScheduler: + return 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) + if use_APScheduler: + 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) - return self.add(func=scheduled_task, trigger=trigger, **trigger_args) + return self.add(func=scheduled_task, trigger=trigger, **trigger_args)