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
+123 -1
View File
@@ -365,6 +365,42 @@ class QueueApiTests(unittest.TestCase):
self.assertFalse(source.exists())
self.assertTrue(Path(moved[0]).exists())
def test_tv_finalizer_applies_episode_offset_to_named_files(self):
with tempfile.TemporaryDirectory() as temp_root:
job = APP.app_support.build_job(
{
"query": "Split Season Show",
"title": "Split Season Show",
"anime_name": "Split Season Show",
"media_type": "tv",
"mode": "sub",
"quality": "best",
"episodes": "1-2",
"download_dir": temp_root,
"season": "2",
"episode_offset": "13",
},
{"mode": "sub", "quality": "best", "download_dir": temp_root},
)
staging_dir = APP.app_support.job_staging_dir(job)
staging_dir.mkdir(parents=True, exist_ok=True)
first = staging_dir / "Split Season Show Episode 1.mp4"
second = staging_dir / "Split Season Show Episode 2.mp4"
first.write_bytes(b"ep1")
second.write_bytes(b"ep2")
moved = APP.app_support.finalize_library_files(job)
self.assertEqual(
moved,
[
f"{temp_root}/tv/Split Season Show/Season 02/Split Season Show - S02E13.mp4",
f"{temp_root}/tv/Split Season Show/Season 02/Split Season Show - S02E14.mp4",
],
)
self.assertTrue(Path(moved[0]).exists())
self.assertTrue(Path(moved[1]).exists())
def test_shutdown_wait_cancels_active_process_for_deterministic_teardown(self):
queue = object.__new__(APP.DownloadQueue)
queue.lock = threading.RLock()
@@ -1113,6 +1149,14 @@ class WatchlistCompletionTests(unittest.TestCase):
self.assertEqual(result["item"]["auto_download_series"], "4")
def test_add_uses_requested_auto_download_offset(self):
with mock.patch.object(APP.WATCHLIST, "schedule_refresh", side_effect=lambda show_id, source="manual": APP.WATCHLIST.get(show_id)):
result = APP.WATCHLIST.add(
{"show_id": "show-23b", "title": "Queued Show", "category": "watching", "auto_download_offset": "13"}
)
self.assertEqual(result["item"]["auto_download_offset"], "13")
def test_add_uses_requested_media_type(self):
with mock.patch.object(APP.WATCHLIST, "schedule_refresh", side_effect=lambda show_id, source="manual": APP.WATCHLIST.get(show_id)):
result = APP.WATCHLIST.add(
@@ -1202,6 +1246,7 @@ class WatchlistCompletionTests(unittest.TestCase):
"anime_name": "Queue Show Library",
"media_type": "movie",
"season": "4",
"episode_offset": None,
"index": 3,
"mode": "dub",
"quality": "best",
@@ -1699,6 +1744,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
"auto_download_quality": "best",
"auto_download_name": 'Queue Show: Alt/Name',
"auto_download_series": "3",
"auto_download_offset": "13",
"downloaded_dub_episodes": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
"downloaded_sub_episodes": [],
}
@@ -1733,6 +1779,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
"anime_name": "Queue Show- Alt-Name",
"media_type": "tv",
"season": "3",
"episode_offset": "13",
"index": 2,
"mode": "dub",
"quality": "best",
@@ -1754,6 +1801,7 @@ class AutoDownloadQueueTests(unittest.TestCase):
"auto_download_quality": "best",
"auto_download_name": "Backlog Show",
"auto_download_series": "1",
"auto_download_offset": None,
"downloaded_dub_episodes": [],
"downloaded_sub_episodes": [],
}
@@ -1778,6 +1826,76 @@ class AutoDownloadQueueTests(unittest.TestCase):
self.assertTrue(result["queued"])
self.assertEqual(result["episodes"], ["1-3"])
download_queue.add.assert_called_once_with(
{
"show_id": "show-99",
"query": "Backlog Show",
"title": "Backlog Show",
"anime_name": "Backlog Show",
"media_type": "tv",
"season": "1",
"episode_offset": None,
"index": 1,
"mode": "dub",
"quality": "best",
"episodes": "1-3",
"download_dir": "/tmp/downloads",
}
)
def test_queue_watchlist_auto_download_passes_episode_offset_to_jobs(self):
item = {
"show_id": "show-77",
"title": "Split Season Show",
"category": "watching",
"previous_last_checked": "2026-05-25T10:00:00+00:00",
"had_new_episodes": False,
"dub_episode_values": ["1", "2"],
"sub_episode_values": [],
"auto_download_mode": "dub",
"auto_download_quality": "best",
"auto_download_name": "Split Season Show",
"auto_download_series": "2",
"auto_download_offset": "13",
"downloaded_dub_episodes": [],
"downloaded_sub_episodes": [],
}
download_queue = mock.Mock()
download_queue.covered_episodes.return_value = set()
download_queue.add.return_value = {"id": "job-split", "episodes": "1-2"}
runtime = {
"config": {
"auto_download_enabled": True,
"auto_download_mode": "dub",
"auto_download_quality": "best",
"download_dir": "/tmp/downloads",
},
"download_queue": download_queue,
}
with mock.patch.object(APP, "ensure_runtime", return_value=runtime), mock.patch.object(
APP,
"search_anime",
return_value=[{"id": "show-77", "title": "Split Season Show", "query": "Split Season Show", "index": 1}],
):
result = APP.queue_watchlist_auto_download(item, refresh_source="manual")
self.assertTrue(result["queued"])
download_queue.add.assert_called_once_with(
{
"show_id": "show-77",
"query": "Split Season Show",
"title": "Split Season Show",
"anime_name": "Split Season Show",
"media_type": "tv",
"season": "2",
"episode_offset": "13",
"index": 1,
"mode": "dub",
"quality": "best",
"episodes": "1-2",
"download_dir": "/tmp/downloads",
}
)
class StartupBehaviorTests(unittest.TestCase):
@@ -2119,13 +2237,16 @@ class HandlerRouteTests(unittest.TestCase):
self.assertEqual(handler.json_status, HTTPStatus.CREATED)
def test_watchlist_auto_download_settings_post_returns_updated_item(self):
body = b'{"show_id":"show-1","mode":"dub","quality":"best","name":"Example Name","series":"2"}'
body = b'{"show_id":"show-1","mode":"dub","quality":"best","name":"Example Name","series":"2","episode_offset":"13"}'
handler = DummyHandler("/api/watchlist/update-auto-download", body=body, content_length=len(body))
payload = {"message": "Saved auto-download settings for Show 1.", "item": {"show_id": "show-1"}}
handler.handler_context = mock.Mock(update_watchlist_auto_download=mock.Mock(return_value=payload))
APP.Handler.do_POST(handler)
self.assertEqual(handler.json_payload, payload)
self.assertEqual(handler.json_status, HTTPStatus.OK)
handler.handler_context.update_watchlist_auto_download.assert_called_once_with(
"show-1", "dub", "best", "Example Name", "2", "13"
)
def test_watchlist_media_type_post_returns_updated_item(self):
body = b'{"show_id":"show-1","media_type":"movie"}'
@@ -2273,6 +2394,7 @@ class TemplateHelperTests(unittest.TestCase):
self.assertIn('class="wide-half">Name', APP.WATCHLIST_HTML)
self.assertIn("Custom", APP.WATCHLIST_HTML)
self.assertIn("Series", APP.WATCHLIST_HTML)
self.assertIn("Episode offset", APP.WATCHLIST_HTML)
def test_watchlist_thumbnail_warmup_skips_repeated_attempts(self):
self.assertIn("thumbnailWarmupPending: new Set()", APP.WATCHLIST_HTML)