import asyncio import os import uuid from datetime import datetime, timezone from pathlib import Path from motor.motor_asyncio import AsyncIOMotorClient from transcode import classify_source async def main(): client = AsyncIOMotorClient(os.environ["MONGO_URL"]) db = client[os.environ.get("DB_NAME", "kino")] videos_dir = Path(os.environ.get("MEDIA_ROOT", "/media")) / "videos" cancel_res = await db.transcode_queue.update_many( {"status": "pending"}, {"$set": {"status": "cancelled", "finished_at": datetime.now(timezone.utc).isoformat()}}, ) print(f"cancelled stale pending jobs: {cancel_res.modified_count}") stats = {"native": 0, "audio": 0, "abr": 0, "no_source": 0} for coll_name, content_type in (("movies", "movie"), ("episodes", "episode")): coll = db[coll_name] async for doc in coll.find({"hls_status": {"$ne": "done"}}, {"_id": 0}): storage_type = doc.get("storage_type") storage_path = doc.get("storage_path") if storage_type not in ("local", "radarr", "sonarr", "scan") or not storage_path: stats["no_source"] += 1 continue source = Path(storage_path) if storage_type in ("radarr", "sonarr", "scan") else videos_dir / storage_path classification = await classify_source(source) if classification == "native": await coll.update_one({"id": doc["id"]}, {"$set": {"hls_status": "not_needed"}}) stats["native"] += 1 continue quality = "abr" if classification == "abr" else "audio" stats[quality] += 1 job = { "id": str(uuid.uuid4()), "movie_id": doc["id"], "movie_title": doc.get("title", ""), "content_type": content_type, "quality": quality, "status": "pending", "error": "", "triggered_by": "backfill", "progress": 0.0, "superseded_by": None, "created_at": datetime.now(timezone.utc).isoformat(), "started_at": None, "finished_at": None, } await db.transcode_queue.insert_one(job) await coll.update_one({"id": doc["id"]}, {"$set": {"hls_status": "pending"}}) print(stats) asyncio.run(main())