from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from .database import engine from .tasks import task_organize_comics, task_update_metadata, task_sort_by_artist import logging logger = logging.getLogger(__name__) # Map readable names to Huey task functions TASK_MAP = { "organize_comics": task_organize_comics, "update_metadata": task_update_metadata, "sort_by_artist": task_sort_by_artist } jobstores = { 'default': SQLAlchemyJobStore(engine=engine) } scheduler = BackgroundScheduler(jobstores=jobstores) def start_scheduler(): try: scheduler.start() logger.info("Scheduler started.") except Exception as e: logger.error(f"Failed to start scheduler: {e}") def add_job(task_name, cron_str, args=None, kwargs=None): if task_name not in TASK_MAP: raise ValueError(f"Unknown task: {task_name}") func = TASK_MAP[task_name] # Parse cron string (e.g. "* * * * *") -> minute, hour, day, month, day_of_week # Simple implementation: expect "min hour day month day_of_week" try: parts = cron_str.split() if len(parts) != 5: raise ValueError("Invalid cron format. Expected 5 fields.") trigger_args = { 'minute': parts[0], 'hour': parts[1], 'day': parts[2], 'month': parts[3], 'day_of_week': parts[4] } job = scheduler.add_job(func, 'cron', args=args, kwargs=kwargs, **trigger_args) return job.id except Exception as e: logger.error(f"Failed to add job: {e}") raise e def get_jobs(): jobs = [] for job in scheduler.get_jobs(): jobs.append({ "id": job.id, "name": job.name, "next_run": str(job.next_run_time), "trigger": str(job.trigger) }) return jobs def remove_job(job_id): scheduler.remove_job(job_id)