rpi-media: приоритет русской дорожки и автозамена, ручные субтитры из Sub-раздачи

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gilfanovr
2026-10-11 16:39:35 +03:00
co-authored by Claude Opus 5.5
parent 716539def3
commit b8a31c7e54
2 changed files with 46 additions and 3 deletions
+44 -2
View File
@@ -3,7 +3,7 @@
ничего не ломает, уже сделанное пропускает.
Запуск на малине: python3 /opt/media/provision.py [шаг ...]
Шаги: qbit jellyfin arr prowlarr bazarr seerr connect homepage (без аргументов — все).
Шаги: qbit jellyfin arr langs prowlarr bazarr seerr connect homepage (без аргументов — все).
Пароль админа берётся из /opt/media/.admin-password, API-ключи — из config.xml.
"""
from http.cookiejar import CookieJar
@@ -187,6 +187,48 @@ def arr():
log(name, "ok")
# ---------------------------------------------------------------- языки в *arr
def langs():
"""Приоритет дорожек: русская+оригинал (150) > русская (100) > оригинал (50). Ничего не отклоняется,
а cutoffFormatScore=150 + upgradeAllowed — *arr сами перекачают, когда появится раздача с русской дорожкой
(у свежих фильмов дубляж выходит через недели после оригинала)."""
for name, a in ARR.items():
h = {"X-Api-Key": apikey(name)}
u = f"{a['url']}/api/{a['api']}"
st, ll = http("GET", u + "/language", headers=h)
lid = {l["name"]: l["id"] for l in ll}
spec = lambda n, impl, v: {"name": n, "implementation": impl, "negate": False, "required": False,
"fields": [{"name": "value", "value": v}]}
orig = ("Оригинальная дорожка", "Original") if name == "radarr" else ("Английская дорожка", "English")
defs = {
# RuTracker с опцией «добавить RUS»: язык может не распознаться, а тег в названии есть
"Русская дорожка": [spec("Russian", "LanguageSpecification", lid["Russian"]),
spec("RUS в названии", "ReleaseTitleSpecification", r"\b(RUS|Rus|MVO|DVO|Dub|Дубляж)\b")],
orig[0]: [spec(orig[1], "LanguageSpecification", lid[orig[1]])],
}
scores = {"Русская дорожка": 100, orig[0]: 50}
st, cfs = http("GET", u + "/customformat", headers=h)
ids = {c["name"]: c["id"] for c in cfs}
for cname, specs in defs.items():
if cname not in ids:
st, r = http("POST", u + "/customformat",
{"name": cname, "includeCustomFormatWhenRenaming": False, "specifications": specs}, h)
ids[cname] = r["id"]
st, profs = http("GET", u + "/qualityprofile", headers=h)
for p in profs:
items = {fi["format"]: fi for fi in p["formatItems"]}
for cname, sc in scores.items():
if ids[cname] in items:
items[ids[cname]]["score"] = sc
else:
p["formatItems"].append({"format": ids[cname], "name": cname, "score": sc})
p.update({"minFormatScore": 0, "cutoffFormatScore": 150, "upgradeAllowed": True})
if name == "radarr": # было Original — отклоняло раздачи только с дубляжом
p["language"] = {"id": lid["Any"], "name": "Any"}
http("PUT", u + "/qualityprofile/%d" % p["id"], p, h)
log(name, "langs ok")
# ---------------------------------------------------------------- Prowlarr
def prowlarr():
k = apikey("prowlarr")
@@ -385,7 +427,7 @@ def jellyseerr():
log("seerr ok")
STEPS = {"qbit": qbit, "jellyfin": jellyfin, "arr": arr, "prowlarr": prowlarr, "bazarr": bazarr, "connect": connect, "homepage": homepage, "seerr": jellyseerr}
STEPS = {"qbit": qbit, "jellyfin": jellyfin, "arr": arr, "langs": langs, "prowlarr": prowlarr, "bazarr": bazarr, "connect": connect, "homepage": homepage, "seerr": jellyseerr}
if __name__ == "__main__":
for s in sys.argv[1:] or list(STEPS):