69 lines
2.0 KiB
Python
69 lines
2.0 KiB
Python
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)
|