Add watchlist episode offset naming

This commit is contained in:
Dymas
2026-05-25 17:57:42 +02:00
parent d10ae832b3
commit 75262d261d
8 changed files with 210 additions and 14 deletions
+32 -7
View File
@@ -54,6 +54,7 @@ from app_support import (
migrate_legacy_state_storage,
normalize_season,
normalize_config,
normalize_episode_offset,
normalize_media_type,
now_iso,
sanitize_path_component,
@@ -1217,6 +1218,7 @@ class WatchlistStore:
"auto_download_quality": str(config.get("auto_download_quality") or "best").strip().lower() or "best",
"auto_download_name": sanitize_path_component(title, "Anime"),
"auto_download_series": "1",
"auto_download_offset": None,
"media_type": "tv",
}
@@ -1296,6 +1298,7 @@ class WatchlistStore:
auto_download_quality TEXT,
auto_download_name TEXT,
auto_download_series TEXT,
auto_download_offset TEXT,
downloaded_sub_episodes_json TEXT,
downloaded_dub_episodes_json TEXT,
thumbnail_path TEXT,
@@ -1342,6 +1345,8 @@ class WatchlistStore:
conn.execute("ALTER TABLE watchlist ADD COLUMN auto_download_name TEXT")
if "auto_download_series" not in columns:
conn.execute("ALTER TABLE watchlist ADD COLUMN auto_download_series TEXT")
if "auto_download_offset" not in columns:
conn.execute("ALTER TABLE watchlist ADD COLUMN auto_download_offset TEXT")
if "downloaded_sub_episodes_json" not in columns:
conn.execute("ALTER TABLE watchlist ADD COLUMN downloaded_sub_episodes_json TEXT")
if "downloaded_dub_episodes_json" not in columns:
@@ -1388,6 +1393,7 @@ class WatchlistStore:
item["auto_download_quality"] = quality if quality in QUALITY_CHOICES else defaults["auto_download_quality"]
item["auto_download_name"] = sanitize_path_component(item.get("auto_download_name") or defaults["auto_download_name"], defaults["auto_download_name"])
item["auto_download_series"] = normalize_season(item.get("auto_download_series") or defaults["auto_download_series"])
item["auto_download_offset"] = normalize_episode_offset(item.get("auto_download_offset"))
item["downloaded_sub_episodes"] = decode_episode_values(item.get("downloaded_sub_episodes_json"))
item["downloaded_dub_episodes"] = decode_episode_values(item.get("downloaded_dub_episodes_json"))
if item.get("animeschedule_route"):
@@ -1412,10 +1418,10 @@ class WatchlistStore:
animeschedule_route, animeschedule_title,
anilist_id, anilist_title, anilist_site_url, alternative_titles_json,
anidb_aid, anidb_title, media_type,
auto_download_mode, auto_download_quality, auto_download_name, auto_download_series,
auto_download_mode, auto_download_quality, auto_download_name, auto_download_series, auto_download_offset,
downloaded_sub_episodes_json, downloaded_dub_episodes_json,
thumbnail_path, thumbnail_checked_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(show_id) DO UPDATE SET
title = excluded.title,
category = excluded.category,
@@ -1443,6 +1449,7 @@ class WatchlistStore:
auto_download_quality = excluded.auto_download_quality,
auto_download_name = excluded.auto_download_name,
auto_download_series = excluded.auto_download_series,
auto_download_offset = excluded.auto_download_offset,
downloaded_sub_episodes_json = excluded.downloaded_sub_episodes_json,
downloaded_dub_episodes_json = excluded.downloaded_dub_episodes_json,
thumbnail_path = excluded.thumbnail_path,
@@ -1477,6 +1484,7 @@ class WatchlistStore:
item.get("auto_download_quality"),
item.get("auto_download_name"),
item.get("auto_download_series"),
normalize_episode_offset(item.get("auto_download_offset")),
item.get("downloaded_sub_episodes_json"),
item.get("downloaded_dub_episodes_json"),
item.get("thumbnail_path"),
@@ -1533,6 +1541,7 @@ class WatchlistStore:
"auto_download_quality": None,
"auto_download_name": None,
"auto_download_series": None,
"auto_download_offset": None,
"downloaded_sub_episodes_json": None,
"downloaded_dub_episodes_json": None,
"thumbnail_path": None,
@@ -1684,6 +1693,7 @@ class WatchlistStore:
"downloaded_dub_episodes_json": None,
}
item["auto_download_series"] = normalize_season(payload.get("auto_download_series") or item.get("auto_download_series") or "1")
item["auto_download_offset"] = normalize_episode_offset(payload.get("auto_download_offset"))
self._upsert_conn(conn, item)
queued = self.schedule_refresh(show_id, source="initial")
@@ -2002,7 +2012,7 @@ class WatchlistStore:
self.schedule_refresh(normalized_show_id, source="sync")
return self.get(normalized_show_id)
def update_auto_download_settings(self, show_id, mode=None, quality=None, name=None, series=None):
def update_auto_download_settings(self, show_id, mode=None, quality=None, name=None, series=None, episode_offset=None):
existing = self.get(show_id)
defaults = self._auto_download_defaults(existing["title"])
normalized_mode = str(mode or defaults["auto_download_mode"]).strip().lower()
@@ -2013,14 +2023,19 @@ class WatchlistStore:
raise ValueError("Unknown auto-download quality.")
normalized_name = sanitize_path_component(name or defaults["auto_download_name"], defaults["auto_download_name"])
normalized_series = normalize_season(series or existing.get("auto_download_series") or defaults["auto_download_series"])
normalized_offset = (
normalize_episode_offset(existing.get("auto_download_offset"))
if episode_offset is None
else normalize_episode_offset(episode_offset)
)
with self.lock, self._connect() as conn:
conn.execute(
"""
UPDATE watchlist
SET auto_download_mode = ?, auto_download_quality = ?, auto_download_name = ?, auto_download_series = ?, updated_at = ?
SET auto_download_mode = ?, auto_download_quality = ?, auto_download_name = ?, auto_download_series = ?, auto_download_offset = ?, updated_at = ?
WHERE show_id = ?
""",
(normalized_mode, normalized_quality, normalized_name, normalized_series, now_iso(), existing["show_id"]),
(normalized_mode, normalized_quality, normalized_name, normalized_series, normalized_offset, now_iso(), existing["show_id"]),
)
return self.get(show_id)
@@ -2248,6 +2263,7 @@ def download_watchlist_item(show_id, mode):
"anime_name": item.get("auto_download_name") or item["title"],
"media_type": item.get("media_type") or "tv",
"season": item.get("auto_download_series") or "1",
"episode_offset": item.get("auto_download_offset"),
"index": match.get("index", 1),
"mode": normalized_mode,
"quality": runtime["config"]["quality"],
@@ -2305,6 +2321,7 @@ def queue_watchlist_auto_download(item, refresh_source="manual"):
sanitize_path_component(item.get("title") or match.get("title") or "Anime", "Anime"),
)
series = normalize_season(item.get("auto_download_series") or "1")
episode_offset = normalize_episode_offset(item.get("auto_download_offset"))
jobs = []
for episode_spec in specs:
job = runtime["download_queue"].add(
@@ -2315,6 +2332,7 @@ def queue_watchlist_auto_download(item, refresh_source="manual"):
"anime_name": anime_name,
"media_type": item.get("media_type") or "tv",
"season": series,
"episode_offset": episode_offset,
"index": match.get("index", 1),
"mode": mode,
"quality": quality,
@@ -2393,9 +2411,16 @@ def update_watchlist_media_type(show_id, media_type):
return {"message": f"Saved {item['title']} as {item['media_type_label']}.", "item": item}
def update_watchlist_auto_download(show_id, mode=None, quality=None, name=None, series=None):
def update_watchlist_auto_download(show_id, mode=None, quality=None, name=None, series=None, episode_offset=None):
ensure_runtime()
item = WATCHLIST.update_auto_download_settings(show_id, mode=mode, quality=quality, name=name, series=series)
item = WATCHLIST.update_auto_download_settings(
show_id,
mode=mode,
quality=quality,
name=name,
series=series,
episode_offset=episode_offset,
)
return {"message": f"Saved auto-download settings for {item['title']}.", "item": item}