Files
ani-cli-web/watchlist_identity.py
T

69 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""Helpers for resolving watchlist identities from queued download jobs."""
import re
def _resolution_result(show_id, title, reason, return_reason):
if return_reason:
return show_id, title, reason
return show_id, title
def _normalized_variants(title, normalize_title_key_fn, base_title_variants_fn):
del base_title_variants_fn
variants = set()
normalized_title = normalize_title_key_fn(title)
if normalized_title:
variants.add(normalized_title)
stripped = re.sub(r"\b(19|20)\d{2}\b", " ", normalized_title)
stripped = re.sub(r"\s+", " ", stripped).strip()
if stripped:
variants.add(stripped)
return variants
def titles_confidently_match(expected_title, candidate_title, normalize_title_key_fn, base_title_variants_fn):
expected_variants = _normalized_variants(expected_title, normalize_title_key_fn, base_title_variants_fn)
candidate_variants = _normalized_variants(candidate_title, normalize_title_key_fn, base_title_variants_fn)
if not expected_variants or not candidate_variants:
return False
return bool(expected_variants & candidate_variants)
def resolve_job_watchlist_identity(
job,
*,
search_fn,
normalize_title_key_fn,
base_title_variants_fn,
default_mode,
return_reason=False,
):
show_id = str(job.get("show_id") or "").strip()
title = str(job.get("title") or job.get("anime_name") or "").strip()
if show_id:
return _resolution_result(show_id, title, "", return_reason)
try:
index = max(1, int(job.get("result_index") or 1))
except (TypeError, ValueError):
return _resolution_result("", title, "invalid queued result index", return_reason)
query = str(job.get("query") or title).strip()
if not query or not title:
return _resolution_result("", title, "missing queued search query or title", return_reason)
try:
results = search_fn(query, job.get("mode") or default_mode)
except Exception as exc:
return _resolution_result("", title, f"search fallback failed: {exc}", return_reason)
if index > len(results):
return _resolution_result("", title, "queued result index no longer exists in search results", return_reason)
result = results[index - 1]
candidate_title = str(result.get("title") or "").strip()
if not titles_confidently_match(title, candidate_title, normalize_title_key_fn, base_title_variants_fn):
return _resolution_result("", title, f"title mismatch with fallback search result: {candidate_title or 'unknown'}", return_reason)
resolved_show_id = str(result.get("id") or "").strip()
if not resolved_show_id:
return _resolution_result("", title, "fallback search result did not include a show_id", return_reason)
return _resolution_result(resolved_show_id, candidate_title or title, "", return_reason)