feat: add "Nur Ohne Deutsch" scan option to rescan only current missing-German entries without clearing cache

Add "missing" job state to jobs dict with idle/total/done/error tracking. Update start_scan() to handle "missing" source by filtering radarr_rows() and sonarr_groups() for is_german_review_candidate() entries without has_german_track(). Skip cache deletion for missing-German scan in api_rescan() with comment explaining cache preservation. Add "Nur Ohne Deutsch" option to scanSource select
This commit is contained in:
nessi committed 2026-08-21 15:36:27 +02:00
1 parent 58c8ad3bcc
commit dfbeec4dc0
3 files changed
+14 -6

No files matched your search

+10 -2
View File
@@ -75,7 +75,7 @@ def service_worker():
return response
executor = ThreadPoolExecutor(max_workers=int(os.environ.get("SCAN_WORKERS", "2")))
scan_executor = ThreadPoolExecutor(max_workers=int(os.environ.get("SCAN_WORKERS", "4")))
jobs = {"radarr": {"state": "idle", "total": 0, "done": 0, "error": None}, "sonarr": {"state": "idle", "total": 0, "done": 0, "error": None}}
jobs = {"radarr": {"state": "idle", "total": 0, "done": 0, "error": None}, "sonarr": {"state": "idle", "total": 0, "done": 0, "error": None}, "missing": {"state": "idle", "total": 0, "done": 0, "error": None}}
job_lock = threading.Lock()
system_lock = threading.Lock()
previous_cpu = None
@@ -828,9 +828,15 @@ def start_scan(source, force=False):
if source == "radarr":
for row in radarr_rows():
if row["local_path"] != "—" and row["pending"]: paths.append(row["local_path"])
else:
elif source == "sonarr":
for group in sonarr_groups():
paths.extend(r["local_path"] for r in group["episodes"] if r["local_path"] != "—" and r["pending"])
else:
for row in radarr_rows():
if row["local_path"] != "—" and is_german_review_candidate(row) and not has_german_track(row): paths.append(row["local_path"])
if SONARR_URL and SONARR_API_KEY:
for group in sonarr_groups():
paths.extend(r["local_path"] for r in group["episodes"] if r["local_path"] != "—" and is_german_review_candidate(r) and not has_german_track(r))
with job_lock: jobs[source]["total"] = len(paths)
futures = [scan_executor.submit(scan_one, path) for path in paths]
for future in as_completed(futures):
@@ -888,6 +894,8 @@ def api_rescan():
con = db()
if source in ("radarr", "all"): con.execute("DELETE FROM media_cache WHERE path NOT LIKE ?", (LOCAL_SERIES_PATH.rstrip("/") + "/%",))
if source in ("sonarr", "all"): con.execute("DELETE FROM media_cache WHERE path LIKE ?", (LOCAL_SERIES_PATH.rstrip("/") + "/%",))
# The missing-German scan deliberately keeps the cache: it re-processes
# only current candidates and leaves the rest of the library untouched.
con.commit(); con.close()
if source == "all":
start_scan("radarr", force=True)