mirror of
https://github.com/myronblair/kino-app
synced 2026-07-31 13:02:29 -05:00
b28a49e8fa
- Requests approval now shows a Radarr/Sonarr candidate picker instead of grabbing the first search result (fixes wrong-title/wrong-year matches) - approve_request reuses an existing Radarr/Sonarr entry instead of erroring when content is already in the library - New codec-check queue (step 1) probes source codecs and skips transcoding entirely for already browser-native files; only non-native content reaches the transcode queue (step 2) - Fixes ffmpeg hard-failing on non-H.264 sources via the h264_mp4toannexb bitstream filter (root cause of the fix-audio-all failures) - Added Codec Check Worker / Transcode Worker to the services health panel with restart - Reorganized the admin page into Pipeline/Utilities dropdowns; added the missing Sonarr Import link - Bumped VERSION 1.0.0 -> 1.1.0
54 lines
2.2 KiB
Python
54 lines
2.2 KiB
Python
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())
|