61 lines
2.3 KiB
Python
61 lines
2.3 KiB
Python
"""Explicit original-language requests without changing shared quality defaults."""
|
|
import asyncio
|
|
import copy
|
|
import hashlib
|
|
import json
|
|
import re
|
|
|
|
import httpx
|
|
|
|
from fastapi import HTTPException
|
|
|
|
_profile_lock = asyncio.Lock()
|
|
_prefix = "Magent Original "
|
|
|
|
|
|
def language_info(details):
|
|
code = str(details.get("originalLanguage") or details.get("original_language") or "").lower()
|
|
if not re.fullmatch(r"[a-z]{2}", code) or code in {"en", "xx", "zz"}:
|
|
return None
|
|
return {"code": code}
|
|
|
|
|
|
def profile_body(profile):
|
|
return {key: copy.deepcopy(value) for key, value in profile.items() if key not in {"id", "name"}}
|
|
|
|
|
|
def profile_name(body):
|
|
return _prefix + hashlib.sha256(json.dumps(body, sort_keys=True).encode()).hexdigest()[:16]
|
|
|
|
|
|
def is_original_profile(profile):
|
|
return ((profile.get("language") or {}).get("id") == -2
|
|
and profile.get("name") == profile_name(profile_body(profile)))
|
|
|
|
|
|
async def original_profile(client, default_id):
|
|
# Reuse immutable copies; never edit a profile already used by other titles.
|
|
async with _profile_lock:
|
|
try:
|
|
profiles = await client.get_quality_profiles()
|
|
except httpx.HTTPError as exc:
|
|
raise HTTPException(502, "Radarr could not load the language profile. Try again.") from exc
|
|
if not isinstance(profiles, list):
|
|
raise HTTPException(502, "Radarr returned invalid quality profiles.")
|
|
default = next((p for p in profiles if p.get("id") == default_id), None)
|
|
if not default:
|
|
raise HTTPException(409, "The default quality profile changed. Reload the request.")
|
|
body = profile_body(default)
|
|
body["language"] = {"id": -2, "name": "Original"}
|
|
name = profile_name(body)
|
|
match = next((p for p in profiles if p.get("name") == name and profile_body(p) == body), None)
|
|
if match:
|
|
return match["id"]
|
|
try:
|
|
result = await client.post("/api/v3/qualityprofile", payload={**body, "name": name})
|
|
except httpx.HTTPError as exc:
|
|
raise HTTPException(502, "Radarr could not prepare the original-language profile. Try again.") from exc
|
|
if not isinstance(result, dict) or not isinstance(result.get("id"), int):
|
|
raise HTTPException(502, "Radarr could not prepare the original-language profile. Try again.")
|
|
return result["id"]
|