Emby-kanalen som førsteklasses kilde: set/favorit virker uden YouTube-bibliotek
Biblioteket er nu valgfrit. Findes hverken kanal eller bibliotek, er svaret ok=False, og fejler opslaget for en bruger, kastes der, så cyklus-sletningen aldrig kører uden alle brugeres favoritter. Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
This commit is contained in:
@@ -54,7 +54,7 @@
|
|||||||
<div class="setgrid" style="margin-top:.8rem">
|
<div class="setgrid" style="margin-top:.8rem">
|
||||||
<label class="fld"><span>Karens efter set (dage)</span><input type="number" name="grace_days" min="0" max="365" value="{{ settings.grace_days }}"></label>
|
<label class="fld"><span>Karens efter set (dage)</span><input type="number" name="grace_days" min="0" max="365" value="{{ settings.grace_days }}"></label>
|
||||||
<label class="fld"><span>Undertekst-sprog</span><input name="sub_langs" value="{{ settings.sub_langs }}"></label>
|
<label class="fld"><span>Undertekst-sprog</span><input name="sub_langs" value="{{ settings.sub_langs }}"></label>
|
||||||
<label class="fld"><span>Emby-bibliotek</span><input name="library_name" value="{{ settings.library_name }}"></label>
|
<label class="fld"><span>Emby-kanal/bibliotek</span><input name="library_name" value="{{ settings.library_name }}"></label>
|
||||||
<label class="fld"><span>Kvalitet (yt-dlp -f)</span><input name="quality" value="{{ settings.quality }}"></label>
|
<label class="fld"><span>Kvalitet (yt-dlp -f)</span><input name="quality" value="{{ settings.quality }}"></label>
|
||||||
</div>
|
</div>
|
||||||
<p style="margin-top:1rem;display:flex;gap:.6rem;flex-wrap:wrap">
|
<p style="margin-top:1rem;display:flex;gap:.6rem;flex-wrap:wrap">
|
||||||
|
|||||||
@@ -1153,34 +1153,32 @@ def _marked_played(ud: dict) -> bool:
|
|||||||
return bool((ud or {}).get("Played"))
|
return bool((ud or {}).get("Played"))
|
||||||
|
|
||||||
|
|
||||||
async def _kanal_brugerdata(c, users: list, merged: dict) -> None:
|
async def _kanal_brugerdata(c, users: list, merged: dict, navn: str) -> bool:
|
||||||
"""Læg set/favorit fra Emby-kanalen "YouTube" (kanal-plugin'et) oven i
|
"""Læg set/favorit fra Emby-kanalen (kanal-plugin'et) ind i `merged`, nøglet på
|
||||||
biblioteket for samme fil, så slettereglen og fredningen virker uanset hvor
|
filens sti. Kanalens elementer bærer video-id'et i ProviderIds["youtube"]; stien
|
||||||
videoen blev set. Kanalens elementer bærer video-id'et i ProviderIds["youtube"];
|
findes via indekset. Samme video ligger i "Alle videoer" og i playlister, og
|
||||||
stien findes via indekset. Mangler kanalen eller indekset, sker der intet.
|
kopierne deler brugerdata, så det er ligegyldigt hvilken vi læser.
|
||||||
(Plugin'et synkroniserer selv kanal og bibliotek; det her er et sikkerhedsnet.)"""
|
|
||||||
|
False hvis kanalen eller indekset mangler. Fejler opslaget for en bruger, kastes
|
||||||
|
der: uden alle brugeres favoritter må slettereglen ikke køre."""
|
||||||
try:
|
try:
|
||||||
with open(indeks_sti(), encoding="utf-8") as f:
|
with open(indeks_sti(), encoding="utf-8") as f:
|
||||||
stier = {vid: os.path.realpath(v["path"]) for vid, v in json.load(f)["videos"].items()}
|
stier = {vid: os.path.realpath(v["path"]) for vid, v in json.load(f)["videos"].items()}
|
||||||
except (OSError, ValueError, KeyError):
|
except (OSError, ValueError, KeyError):
|
||||||
return
|
return False
|
||||||
try:
|
if not users:
|
||||||
kanaler = await _emby(c, "/Channels", UserId=users[0]) if users else {}
|
return False
|
||||||
except Exception: # noqa: BLE001
|
kanaler = await _emby(c, "/Channels", UserId=users[0])
|
||||||
return
|
|
||||||
kanal = next((k for k in (kanaler.get("Items") or [])
|
kanal = next((k for k in (kanaler.get("Items") or [])
|
||||||
if (k.get("Name") or "").lower() == "youtube"), None)
|
if (k.get("Name") or "").lower() == navn.lower()), None)
|
||||||
if not kanal:
|
if not kanal:
|
||||||
return
|
return False
|
||||||
for uid in users:
|
for uid in users:
|
||||||
try:
|
data = await _emby(c, f"/Users/{uid}/Items", ParentId=kanal["Id"],
|
||||||
data = await _emby(c, f"/Users/{uid}/Items", ParentId=kanal["Id"],
|
Recursive="true", IncludeItemTypes="Video", Fields="ProviderIds,UserData")
|
||||||
Recursive="true", Fields="ProviderIds,UserData")
|
|
||||||
except Exception: # noqa: BLE001
|
|
||||||
continue
|
|
||||||
for it in data.get("Items", []):
|
for it in data.get("Items", []):
|
||||||
pid = it.get("ProviderIds") or {}
|
pid = it.get("ProviderIds") or {}
|
||||||
vid = pid.get("YouTube") or pid.get("Youtube") or pid.get("youtube")
|
vid = pid.get("youtube") or pid.get("YouTube") or pid.get("Youtube")
|
||||||
sti = stier.get(vid or "")
|
sti = stier.get(vid or "")
|
||||||
if not sti:
|
if not sti:
|
||||||
continue
|
continue
|
||||||
@@ -1191,38 +1189,43 @@ async def _kanal_brugerdata(c, users: list, merged: dict) -> None:
|
|||||||
m["played"] = True
|
m["played"] = True
|
||||||
if ud.get("IsFavorite"):
|
if ud.get("IsFavorite"):
|
||||||
m["favorite"] = True
|
m["favorite"] = True
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def emby_yt_items() -> dict:
|
async def emby_yt_items() -> dict:
|
||||||
"""Alle videoer i YouTube-biblioteket med set/favorit aggregeret over ALLE brugere."""
|
"""Alle videoer i Emby med set/favorit aggregeret over ALLE brugere.
|
||||||
|
|
||||||
|
Kilden er kanalen fra kanal-plugin'et og/eller et bibliotek med samme navn
|
||||||
|
(standard "YouTube"). Findes ingen af dem, er svaret ok=False, så intet slettes."""
|
||||||
settings = get_settings()
|
settings = get_settings()
|
||||||
|
navn = settings.get("library_name") or "YouTube"
|
||||||
out = {"ok": False, "items": [], "error": ""}
|
out = {"ok": False, "items": [], "error": ""}
|
||||||
try:
|
try:
|
||||||
async with httpx.AsyncClient(timeout=45) as c:
|
async with httpx.AsyncClient(timeout=45) as c:
|
||||||
lib = await _library_id(c, settings.get("library_name") or "YouTube")
|
|
||||||
if not lib:
|
|
||||||
out["error"] = (f"Fandt ikke Emby-biblioteket "
|
|
||||||
f"'{settings.get('library_name')}'")
|
|
||||||
return out
|
|
||||||
users = [u["Id"] for u in await _emby(c, "/Users")]
|
users = [u["Id"] for u in await _emby(c, "/Users")]
|
||||||
merged = {}
|
merged = {}
|
||||||
for uid in users:
|
lib = await _library_id(c, navn)
|
||||||
data = await _emby(c, f"/Users/{uid}/Items", ParentId=lib,
|
if lib:
|
||||||
Recursive="true", Fields="Path,UserData")
|
for uid in users:
|
||||||
for it in data.get("Items", []):
|
data = await _emby(c, f"/Users/{uid}/Items", ParentId=lib,
|
||||||
path = it.get("Path") or ""
|
Recursive="true", Fields="Path,UserData")
|
||||||
if not path:
|
for it in data.get("Items", []):
|
||||||
continue
|
path = it.get("Path") or ""
|
||||||
key = os.path.realpath(path)
|
if not path:
|
||||||
m = merged.setdefault(key, {
|
continue
|
||||||
"id": it["Id"], "name": it.get("Name") or os.path.basename(path),
|
key = os.path.realpath(path)
|
||||||
"path": key, "played": False, "favorite": False})
|
m = merged.setdefault(key, {
|
||||||
ud = it.get("UserData") or {}
|
"id": it["Id"], "name": it.get("Name") or os.path.basename(path),
|
||||||
if _marked_played(ud):
|
"path": key, "played": False, "favorite": False})
|
||||||
m["played"] = True
|
ud = it.get("UserData") or {}
|
||||||
if ud.get("IsFavorite"):
|
if _marked_played(ud):
|
||||||
m["favorite"] = True
|
m["played"] = True
|
||||||
await _kanal_brugerdata(c, users, merged)
|
if ud.get("IsFavorite"):
|
||||||
|
m["favorite"] = True
|
||||||
|
kanal = await _kanal_brugerdata(c, users, merged, navn)
|
||||||
|
if not lib and not kanal:
|
||||||
|
out["error"] = f"Fandt hverken Emby-kanalen eller -biblioteket '{navn}'"
|
||||||
|
return out
|
||||||
out["items"] = list(merged.values())
|
out["items"] = list(merged.values())
|
||||||
out["ok"] = True
|
out["ok"] = True
|
||||||
except Exception as e: # noqa: BLE001
|
except Exception as e: # noqa: BLE001
|
||||||
|
|||||||
Reference in New Issue
Block a user