import logging from fastapi import HTTPException from ..clients.jellyfin import JellyfinClient from ..db import create_user_if_missing, set_user_jellyseerr_id from ..runtime import get_runtime_settings from .user_cache import ( build_jellyseerr_candidate_map, get_cached_jellyseerr_users, match_jellyseerr_user_id, save_jellyfin_users_cache, ) logger = logging.getLogger(__name__) async def sync_jellyfin_users() -> int: runtime = get_runtime_settings() client = JellyfinClient(runtime.jellyfin_base_url, runtime.jellyfin_api_key) if not client.configured(): raise HTTPException(status_code=400, detail="Jellyfin not configured") users = await client.get_users() if not isinstance(users, list): return 0 save_jellyfin_users_cache(users) jellyseerr_users = get_cached_jellyseerr_users() candidate_map = build_jellyseerr_candidate_map(jellyseerr_users or []) imported = 0 for user in users: if not isinstance(user, dict): continue name = user.get("Name") if not name: continue matched_id = match_jellyseerr_user_id(name, candidate_map) if candidate_map else None created = create_user_if_missing( name, "jellyfin-user", role="user", auth_provider="jellyfin", jellyseerr_user_id=matched_id, ) if created: imported += 1 elif matched_id is not None: set_user_jellyseerr_id(name, matched_id) return imported async def run_daily_jellyfin_sync() -> None: while True: delay = _seconds_until_midnight() await _sleep_seconds(delay) try: imported = await sync_jellyfin_users() logger.info("Jellyfin daily sync complete: imported=%s", imported) except HTTPException as exc: logger.warning("Jellyfin daily sync skipped: %s", exc.detail) except Exception: logger.exception("Jellyfin daily sync failed") def _seconds_until_midnight() -> float: from datetime import datetime, timedelta now = datetime.now() next_midnight = (now + timedelta(days=1)).replace( hour=0, minute=0, second=0, microsecond=0 ) return max((next_midnight - now).total_seconds(), 0.0) async def _sleep_seconds(delay: float) -> None: import asyncio await asyncio.sleep(delay)