from apscheduler.schedulers.asyncio import AsyncIOScheduler from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from apscheduler.triggers.cron import CronTrigger from apscheduler.triggers.interval import IntervalTrigger from .jobs import update_daily_tasks, update_weather, refresh_meme, update_current_weather, update_daily_surprise, update_dressing_advice, update_morning_briefing_transcript, update_news, get_relevant_news_titles, update_quick_insight import asyncio import atexit from datetime import datetime from .cache import cache scheduler = AsyncIOScheduler() def get_jobs_info(): jobs_info = [] for job in scheduler.get_jobs(): job_data = cache.get(job.id, {}) jobs_info.append({ "id": job.id, "status": job_data.get("status", "unknown"), "last_run": job_data.get("last_run"), "next_run": job.next_run_time.isoformat() if job.next_run_time else None, "error": job_data.get("error"), "data": job_data.get("data"), }) return jobs_info def my_job(): job_id = "test_job" try: # Mark job as running cache[job_id] = {"status": "running", "started_at": datetime.now().isoformat()} # Simulate work print(f"Job ran at {datetime.now().isoformat()}") # Store success result cache[job_id] = { "status": "completed", "last_run": datetime.now().isoformat(), "data": {"note": "Test job executed successfully."} } except Exception as e: # Store failure result cache[job_id] = { "status": "failed", "last_run": datetime.now().isoformat(), "error": str(e) } def start_scheduler(): scheduler.configure( jobstores={ 'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite') }, job_defaults={ 'coalesce': False, 'misfire_grace_time': 300 # 5 min grace period for missed jobs } ) scheduler.start() # Only add jobs if they don't already exist if not scheduler.get_job("daily_quick_insight"): scheduler.add_job( update_quick_insight, trigger=CronTrigger(hour=11, minute=5), id="daily_quick_insight", ) if not scheduler.get_job("select_relevant_news"): scheduler.add_job( get_relevant_news_titles, trigger=CronTrigger(hour=11, minute=5), id="select_relevant_news", ) if not scheduler.get_job("top_news"): scheduler.add_job( update_news, trigger=CronTrigger(hour=11, minute=0), id="top_news", ) if not scheduler.get_job("morning_briefing_transcript"): scheduler.add_job( update_morning_briefing_transcript, trigger=CronTrigger(hour=6, minute=10), id="morning_briefing_transcript", ) if not scheduler.get_job("daily_tasks"): scheduler.add_job( update_daily_tasks, trigger=CronTrigger(hour=6, minute=0), id="daily_tasks", ) if not scheduler.get_job("daily_weather"): scheduler.add_job( update_weather, trigger=CronTrigger(hour=6, minute=0), id="daily_weather", ) if not scheduler.get_job("current_weather"): scheduler.add_job( update_current_weather, trigger=IntervalTrigger(hours=1), id="current_weather", ) if not scheduler.get_job("daily_dressing_advice"): scheduler.add_job( update_dressing_advice, trigger=CronTrigger(hour=6, minute=5), id="daily_dressing_advice", ) if not scheduler.get_job("daily_surprise"): scheduler.add_job( update_daily_surprise, trigger=CronTrigger(hour=6, minute=0), id="daily_surprise", ) if not scheduler.get_job("daily_meme"): scheduler.add_job( refresh_meme, trigger=CronTrigger(hour=6, minute=0), id="daily_meme", ) if not scheduler.get_job("test_job"): scheduler.add_job( my_job, trigger=IntervalTrigger(seconds=30), id="test_job", ) atexit.register(lambda: scheduler.shutdown(wait=False))