import asyncio import logging from datetime import datetime, timezone, timedelta from apscheduler.schedulers.asyncio import AsyncIOScheduler from sqlalchemy.orm import Session from models import SessionLocal, User, AzureGroupConfig from sync_engine import sync_user_contacts from group_sync import sync_group_members logger = logging.getLogger(__name__) scheduler = AsyncIOScheduler(timezone="UTC") async def run_due_syncs(): """Prüft welche Benutzer synchronisiert werden sollen und startet den Sync""" db: Session = SessionLocal() try: users = db.query(User).filter(User.sync_enabled == True).all() now = datetime.now(timezone.utc) for user in users: interval = user.sync_interval_minutes or 60 last = user.last_sync_at if last: if last.tzinfo is None: last = last.replace(tzinfo=timezone.utc) next_sync = last + timedelta(minutes=interval) if now < next_sync: continue logger.info(f"Starte Sync für {user.email}") await sync_user_contacts(user.id, db) except Exception as e: logger.error(f"Scheduler run_due_syncs error: {e}") finally: db.close() async def run_due_group_sync(): """Prüft ob Azure AD Gruppenmitgliedschaft erneut synchronisiert werden soll""" db: Session = SessionLocal() try: config = db.query(AzureGroupConfig).first() if not config or not config.auto_sync_members: return now = datetime.now(timezone.utc) interval = config.member_sync_interval_hours or 6 last = config.last_member_sync_at if last: if last.tzinfo is None: last = last.replace(tzinfo=timezone.utc) if now < last + timedelta(hours=interval): return logger.info(f"Starte Azure AD Gruppen-Sync (alle {interval}h)") await sync_group_members(db) except Exception as e: logger.error(f"Scheduler group sync error: {e}") finally: db.close() def start_scheduler(): scheduler.add_job(run_due_syncs, "interval", minutes=1, id="sync_job", replace_existing=True) scheduler.add_job(run_due_group_sync, "interval", minutes=10, id="group_sync_job", replace_existing=True) scheduler.start() logger.info("Sync-Scheduler gestartet (Kontakte: 1 Min., Gruppen: 10 Min.)") def stop_scheduler(): if scheduler.running: scheduler.shutdown()