Release v1.0.12: fetch English TheTVDB episode titles for matching.
Anime and other non-English shows returned Japanese default titles while filenames use English; add Episode titles language control defaulting to English. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
+40
-4
@@ -31,7 +31,7 @@ from engine.rules import (
|
||||
PrefixSuffixRule,
|
||||
CsvMappingRule,
|
||||
)
|
||||
from engine.tvdb_client import TvdbClient, TvdbError, TVDB_API_KEY, SEASON_TYPE_CHOICES
|
||||
from engine.tvdb_client import TvdbClient, TvdbError, TVDB_API_KEY, SEASON_TYPE_CHOICES, LANGUAGE_CHOICES
|
||||
from engine.episode_match import match_filenames_to_episodes
|
||||
|
||||
|
||||
@@ -340,6 +340,7 @@ class _TvdbMatchWorker(QThread):
|
||||
filenames: list[str],
|
||||
all_seasons: bool,
|
||||
multi_episode: bool,
|
||||
language: str,
|
||||
):
|
||||
super().__init__()
|
||||
self.series_id = series_id
|
||||
@@ -348,18 +349,23 @@ class _TvdbMatchWorker(QThread):
|
||||
self.filenames = filenames
|
||||
self.all_seasons = all_seasons
|
||||
self.multi_episode = multi_episode
|
||||
self.language = language
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
client = TvdbClient(TVDB_API_KEY)
|
||||
lang = self.language
|
||||
if self.all_seasons:
|
||||
official = client.get_all_episodes(self.series_id, season_type="official")
|
||||
official = client.get_all_episodes(
|
||||
self.series_id, season_type="official", language=lang,
|
||||
)
|
||||
season_filter = 0
|
||||
else:
|
||||
official = client.get_season_episodes(
|
||||
self.series_id,
|
||||
self.season,
|
||||
season_type="official",
|
||||
language=lang,
|
||||
)
|
||||
season_filter = self.season
|
||||
|
||||
@@ -367,12 +373,14 @@ class _TvdbMatchWorker(QThread):
|
||||
episodes = client.get_all_episodes(
|
||||
self.series_id,
|
||||
season_type=self.season_type,
|
||||
language=lang,
|
||||
)
|
||||
else:
|
||||
episodes = client.get_season_episodes(
|
||||
self.series_id,
|
||||
self.season,
|
||||
season_type=self.season_type,
|
||||
language=lang,
|
||||
)
|
||||
|
||||
combined = None
|
||||
@@ -381,13 +389,25 @@ class _TvdbMatchWorker(QThread):
|
||||
combined = client.get_all_episodes(
|
||||
self.series_id,
|
||||
season_type="alternate",
|
||||
language=lang,
|
||||
)
|
||||
else:
|
||||
combined = client.get_season_episodes(
|
||||
self.series_id,
|
||||
self.season,
|
||||
season_type="alternate",
|
||||
language=lang,
|
||||
)
|
||||
if not combined and lang:
|
||||
# Combined order may lack translations; fall back to show language.
|
||||
if self.all_seasons:
|
||||
combined = client.get_all_episodes(
|
||||
self.series_id, season_type="alternate",
|
||||
)
|
||||
else:
|
||||
combined = client.get_season_episodes(
|
||||
self.series_id, self.season, season_type="alternate",
|
||||
)
|
||||
|
||||
if self.season_type == "alternate":
|
||||
episodes = official
|
||||
@@ -450,6 +470,13 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
self.order_type.currentIndexChanged.connect(self._emit)
|
||||
layout.addRow("Episode order:", self.order_type)
|
||||
|
||||
self.title_language = QComboBox()
|
||||
for label, value in LANGUAGE_CHOICES:
|
||||
self.title_language.addItem(label, value)
|
||||
self.title_language.setCurrentIndex(1) # English — most filenames use it
|
||||
self.title_language.currentIndexChanged.connect(self._emit)
|
||||
layout.addRow("Episode titles:", self.title_language)
|
||||
|
||||
self.season = QSpinBox()
|
||||
self.season.setMinimum(0)
|
||||
self.season.setMaximum(99)
|
||||
@@ -485,6 +512,7 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
info = QLabel(
|
||||
"Reads titles from S01E05 - Episode Title, S01E05-E06 (multi-episode), "
|
||||
"or Show 04x01 Episode Title filenames. "
|
||||
"For non-English shows, set Episode titles to English if your filenames use English. "
|
||||
"Use All seasons to match across every season and fix wrong season numbers too."
|
||||
)
|
||||
info.setWordWrap(True)
|
||||
@@ -500,6 +528,13 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
value = self.order_type.currentData()
|
||||
return value if value else "default"
|
||||
|
||||
def _language_value(self) -> str:
|
||||
value = self.title_language.currentData()
|
||||
return value if value else ""
|
||||
|
||||
def _language_label(self) -> str:
|
||||
return self.title_language.currentText()
|
||||
|
||||
def _emit(self):
|
||||
self.ruleChanged.emit()
|
||||
|
||||
@@ -551,7 +586,7 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
self.match_btn.setEnabled(False)
|
||||
all_seasons = self.season.value() == 0
|
||||
self.status.setText(
|
||||
f"Fetching episodes ({self._order_label()}, "
|
||||
f"Fetching episodes ({self._order_label()}, {self._language_label()}, "
|
||||
f"{'all seasons' if all_seasons else f'season {self.season.value()}'}…) and matching titles…"
|
||||
)
|
||||
self._match_worker = _TvdbMatchWorker(
|
||||
@@ -561,6 +596,7 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
self._file_names,
|
||||
all_seasons,
|
||||
self.multi_episode_cb.isChecked(),
|
||||
self._language_value(),
|
||||
)
|
||||
self._match_worker.finished.connect(self._on_match_finished)
|
||||
self._match_worker.failed.connect(self._on_match_failed)
|
||||
@@ -572,7 +608,7 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
matched = len(mapping)
|
||||
total = len(self._file_names)
|
||||
scope = "all seasons" if self.season.value() == 0 else f"season {self.season.value()}"
|
||||
msg = f"Matched {matched} of {total} file(s) ({scope}, {self._order_label()})."
|
||||
msg = f"Matched {matched} of {total} file(s) ({scope}, {self._order_label()}, {self._language_label()})."
|
||||
if unmatched:
|
||||
msg += f" {len(unmatched)} file(s) unmatched."
|
||||
self.status.setText(msg)
|
||||
|
||||
Reference in New Issue
Block a user