OverviewFilesCommitsIssuesDocsReleasesPeers

kodi-jacktook commits / f255bf5

Reuse cached subtitles without asking, now that there always are some (1.16.4)
The "use existing subtitles?" dialog was nearly unreachable until this week: the OpenSubtitles path needed an imdb id and shipped disabled, so the cache was almost always empty and the prompt almost never fired. Wyzie writes ~32 files on the FIRST play of every title. So the prompt went from theoretical to landing on every subsequent play of everything -- a modal yes/no between the user and the film they just pressed play on. That is a regression this feature caused, not a pre-existing quirk it happened to reveal. Reusing the cache is also right on the merits: wyzie returns every language it has, so "download them again" cannot produce anything the cache does not already hold. There is no choice to offer. The dialog stays for the OpenSubtitles path, where a re-download genuinely can return a different and better subtitle, so the choice still means something. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
f255bf52438a84d9a054d0efbad44e9be91c688e
by plankatron <fleeky@gmail.com> · 2026-09-05T01:23:09.000Z

Changed files (3) +66 -3

plugin.video.jacktook/addon.xml +1 -1
……@@ -1,5 +1,5 @@
11<?xml version="1.0" encoding="utf-8"?>
2 <addon id="plugin.video.jacktook" name="Jacktook" version="1.16.3" provider-name="Sam-Max">
2 <addon id="plugin.video.jacktook" name="Jacktook" version="1.16.4" provider-name="Sam-Max">
33 <requires>
44 <import addon="xbmc.python" version="3.00.0"/>
55 <import addon="script.module.requests" version="2.25.1"/>
plugin.video.jacktook/lib/clients/subtitle/submanager.py +10 -2
……@@ -145,8 +145,16 @@ class SubtitleManager(KodiJsonRpcClient):
145145
146146 subtitle_files = self.get_downloaded_subtitle_paths(folder_path)
147147 if subtitle_files:
148 # Skip "use existing?" dialog when auto-download or auto-select is enabled
149 if auto_select or get_setting("auto_subtitle_download"):
148 # Skip "use existing?" dialog when auto-download or auto-select is
149 # enabled -- and when Wyzie is, because it already fetched every
150 # language it has. Re-downloading cannot produce anything the cache
151 # does not hold, so the dialog would be a modal box on every replay
152 # of every title in exchange for nothing. (It stays for the
153 # OpenSubtitles path, where a re-download genuinely can return a
154 # different and better subtitle.)
155 if (auto_select
156 or get_setting("auto_subtitle_download")
157 or get_setting("wyzie_subtitle_enabled")):
150158 return subtitle_files
151159
152160 dialog = xbmcgui.Dialog()
plugin.video.jacktook/tests/unit/test_wyzie_subtitles.py +55 -0
……@@ -429,3 +429,58 @@ class TestIdentFromOriginalId:
429429 with patch("lib.clients.subtitle.submanager.get_setting", _settings()):
430430 m.fetch_subtitles(folder_path=str(tmp_path))
431431 assert m.wyzie_client.get_subtitles.call_args[0][1] == "kitsu:anime-42"
432
433
434class TestCachedSubtitlesAreReusedSilently:
435 """A populated cache must not turn every replay into a modal prompt.
436
437 The "use existing subtitles?" dialog was nearly unreachable before: the
438 OpenSubtitles path needed an imdb id and shipped disabled, so the cache was
439 usually empty. Wyzie writes ~32 files on the FIRST play of every title, so
440 without this every subsequent play of anything stops on a yes/no box.
441
442 Reusing them is also the right answer on the merits: wyzie returns every
443 language it has, so "download them again" cannot produce anything the cache
444 does not already hold.
445 """
446
447 def _cache(self, tmp_path, n=3):
448 for name in ("English", "French", "German")[:n]:
449 (tmp_path / (name + ".srt")).write_text("1\n00:00:01,000 --> 00:00:02,000\nx\n")
450 return sorted(str(p) for p in tmp_path.glob("*.srt"))
451
452 def test_cached_files_are_returned_without_a_dialog(self, tmp_path):
453 cached = self._cache(tmp_path)
454 m = _manager()
455 m.wyzie_client.get_subtitles = MagicMock()
456 with patch("lib.clients.subtitle.submanager.get_setting", _settings()), \
457 patch("lib.clients.subtitle.submanager.xbmcgui") as gui:
458 got = m.fetch_subtitles(folder_path=str(tmp_path))
459 assert sorted(got) == cached
460 gui.Dialog.assert_not_called()
461 m.wyzie_client.get_subtitles.assert_not_called()
462
463 def test_the_dialog_still_appears_when_wyzie_is_off(self, tmp_path):
464 """Without wyzie the cache came from OpenSubtitles, where re-downloading
465 genuinely can produce a different (better) subtitle -- so the choice
466 still belongs to the user there."""
467 self._cache(tmp_path)
468 m = _manager()
469 m.opensub_client.get_subtitles = MagicMock(return_value=None)
470 with patch("lib.clients.subtitle.submanager.get_setting",
471 _settings(wyzie_subtitle_enabled=False,
472 stremio_subtitle_enabled=True)), \
473 patch("lib.clients.subtitle.submanager.xbmcgui") as gui:
474 gui.Dialog.return_value.yesno.return_value = False
475 m.fetch_subtitles(folder_path=str(tmp_path))
476 gui.Dialog.assert_called()
477
478 def test_an_empty_cache_still_goes_to_wyzie(self, tmp_path):
479 m = _manager()
480 m.wyzie_client.get_subtitles = MagicMock(return_value=TRACKS)
481 m.wyzie_client.download_subtitles_batch = MagicMock(return_value=["/a.srt"])
482 with patch("lib.clients.subtitle.submanager.get_setting", _settings()), \
483 patch("lib.clients.subtitle.submanager.xbmcgui") as gui:
484 got = m.fetch_subtitles(folder_path=str(tmp_path))
485 assert got == ["/a.srt"]
486 gui.Dialog.assert_not_called()