import time from pathlib import Path from apscheduler.schedulers.asyncio import AsyncIOScheduler _scheduler: AsyncIOScheduler | None = None def _cleanup_old_files(upload_dir: Path, output_dir: Path, max_age_seconds: int = 3600) -> None: """Delete MP3 files older than max_age_seconds. Runs in a thread pool.""" now = time.time() for f in upload_dir.glob("*.mp3"): try: if now - f.stat().st_mtime > max_age_seconds: f.unlink(missing_ok=True) except OSError: pass for f in output_dir.rglob("*.mp3"): try: if now - f.stat().st_mtime > max_age_seconds: f.unlink(missing_ok=True) except OSError: pass # Remove empty per-job output directories left after file cleanup. for d in sorted(output_dir.rglob("*"), reverse=True): if not d.is_dir(): continue try: next(d.iterdir()) except StopIteration: d.rmdir() except OSError: pass def start_cleanup_scheduler(upload_dir: Path, output_dir: Path) -> None: global _scheduler _scheduler = AsyncIOScheduler() _scheduler.add_job( _cleanup_old_files, "interval", minutes=15, args=[upload_dir, output_dir], executor="default", ) _scheduler.start() def stop_cleanup_scheduler() -> None: global _scheduler if _scheduler is not None: _scheduler.shutdown(wait=False) _scheduler = None