"""Natlig YouTube-kørsel (systemd-timer). Rækkefølgen er ikke tilfældig: 1. sync_subs — find nye videoer i playliste-/kanal-abonnementer 2. process_queue — hent alt i køen (også jobs der hang efter en genstart) 3. enforce_cycles — hold hver kanal på sine X nyeste (favoritter tæller ikke med) 4. run_cycle — slet videoer der er markeret som set, efter karensen Cyklussen håndhæves EFTER hentningen, ellers ville den se et halvt bibliotek. """ import asyncio import ytdl async def opdater_ytdlp(): """YouTube ændrer ofte noget, der giver 403, indtil yt-dlp er opdateret. Derfor opdateres den hver nat, før der hentes.""" try: proc = await asyncio.create_subprocess_exec( ytdl.config.YT_DLP_BIN, "-U", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT) out, _ = await asyncio.wait_for(proc.communicate(), timeout=180) sidste = (out.decode("utf-8", "replace").strip().splitlines() or [""])[-1] print(f"yt_job: yt-dlp -U: {sidste[:160]}") except Exception as e: # noqa: BLE001 print(f"yt_job: yt-dlp kunne ikke opdateres: {e}") async def main(): if not ytdl.configured(): print("yt_job: ikke konfigureret (mangler EMBY-env, yt-dlp eller download-mappe)") return await opdater_ytdlp() sub = await ytdl.sync_subs() if sub["checked"] or sub["errors"]: print(f"yt_job: abonnementer tjekket={sub['checked']} nye_i_koe={sub['queued']}") for e in sub["errors"]: print(" abonnement-fejl:", e) q = await ytdl.process_queue() if q["done"] or q["failed"]: print(f"yt_job: hentet={q['done']} fejlet={q['failed']}") cyc = await ytdl.enforce_cycles() if cyc["evicted"] or cyc["errors"]: print(f"yt_job: ude_af_cyklus={len(cyc['evicted'])} " f"frigjort={ytdl._human(cyc['freed'])}") for e in cyc["errors"]: print(" cyklus-fejl:", e) # Kanal-plugin'ets indeks: playlister (højst ugentligt pr. kanal) og så indekset. try: pl = await ytdl.opdater_playlister() print(f"yt_job: playlister opdateret for {pl['kanaler']} kanaler, {pl['playlister']} i alt") for e in pl["fejl"][:10]: print(" playliste-fejl:", e) except Exception as e: # noqa: BLE001 print(f"yt_job: playlister kunne ikke opdateres: {e}") try: ix = ytdl.skriv_indeks() print(f"yt_job: indeks: {ix['channels']} kanaler, {ix['videos']} videoer, {ix['playlists']} playlister") except Exception as e: # noqa: BLE001 print(f"yt_job: indekset kunne ikke skrives: {e}") res = await ytdl.run_cycle(dry_run=False) if res.get("error"): print("yt_job FEJL:", res["error"]) return print(f"yt_job: vores videoer={res['seen']} nye_paa_vej_ud={len(res['new'])} " f"fredet={len(res['spared'])} slettet={len(res['deleted'])} " f"frigjort={ytdl._human(res['freed'])} " f"sletning={'til' if res['enabled'] else 'fra'}") for e in res.get("errors", []): print(" fejl:", e) if __name__ == "__main__": asyncio.run(main())