Fix TheTVDB matching for 04x01 filenames and add all-seasons mode.
Parse NxNN and SxxExx layouts, match across every season when season is 0, and rewrite season plus episode numbers. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
+39
-17
@@ -338,24 +338,39 @@ class _TvdbMatchWorker(QThread):
|
||||
season: int,
|
||||
season_type: str,
|
||||
filenames: list[str],
|
||||
all_seasons: bool,
|
||||
):
|
||||
super().__init__()
|
||||
self.series_id = series_id
|
||||
self.season = season
|
||||
self.season_type = season_type
|
||||
self.filenames = filenames
|
||||
self.all_seasons = all_seasons
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
client = TvdbClient(TVDB_API_KEY)
|
||||
episodes = client.get_season_episodes(
|
||||
self.series_id,
|
||||
self.season,
|
||||
season_type=self.season_type,
|
||||
)
|
||||
if self.all_seasons:
|
||||
episodes = client.get_all_episodes(
|
||||
self.series_id,
|
||||
season_type=self.season_type,
|
||||
)
|
||||
season_filter = 0
|
||||
else:
|
||||
episodes = client.get_season_episodes(
|
||||
self.series_id,
|
||||
self.season,
|
||||
season_type=self.season_type,
|
||||
)
|
||||
season_filter = self.season
|
||||
if not episodes:
|
||||
raise TvdbError(f"No episodes found for season {self.season}")
|
||||
mapping, unmatched, notes = match_filenames_to_episodes(self.filenames, episodes)
|
||||
label = "all seasons" if self.all_seasons else f"season {self.season}"
|
||||
raise TvdbError(f"No episodes found for {label}")
|
||||
mapping, unmatched, notes = match_filenames_to_episodes(
|
||||
self.filenames,
|
||||
episodes,
|
||||
season_filter=season_filter,
|
||||
)
|
||||
self.finished.emit(mapping, unmatched, notes)
|
||||
except TvdbError as e:
|
||||
self.failed.emit(str(e))
|
||||
@@ -407,7 +422,8 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
self.season = QSpinBox()
|
||||
self.season.setMinimum(0)
|
||||
self.season.setMaximum(99)
|
||||
self.season.setValue(1)
|
||||
self.season.setValue(0)
|
||||
self.season.setSpecialValueText("All seasons")
|
||||
self.season.valueChanged.connect(self._emit)
|
||||
layout.addRow("Season:", self.season)
|
||||
|
||||
@@ -422,13 +438,13 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
self.match_btn.clicked.connect(self._match_titles)
|
||||
layout.addRow(self.match_btn)
|
||||
|
||||
self.status = QLabel("Search for a show, choose episode order and season, then match titles.")
|
||||
self.status = QLabel("Search for a show, choose episode order, then match titles (0 = all seasons).")
|
||||
self.status.setWordWrap(True)
|
||||
layout.addRow(self.status)
|
||||
|
||||
info = QLabel(
|
||||
"Reads episode titles from filenames like S01E05 - Episode Title. "
|
||||
"Fetches the chosen TheTVDB episode order for that season and rewrites SxxExx numbers to match."
|
||||
"Reads titles from S01E05 - Episode Title or Show 04x01 Episode Title filenames. "
|
||||
"Use All seasons to match across every season and fix wrong season numbers too."
|
||||
)
|
||||
info.setWordWrap(True)
|
||||
layout.addRow(info)
|
||||
@@ -492,12 +508,17 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
if series_id is None:
|
||||
return
|
||||
self.match_btn.setEnabled(False)
|
||||
self.status.setText(f"Fetching episodes ({self._order_label()}) and matching titles…")
|
||||
all_seasons = self.season.value() == 0
|
||||
self.status.setText(
|
||||
f"Fetching episodes ({self._order_label()}, "
|
||||
f"{'all seasons' if all_seasons else f'season {self.season.value()}'}…) and matching titles…"
|
||||
)
|
||||
self._match_worker = _TvdbMatchWorker(
|
||||
int(series_id),
|
||||
self.season.value(),
|
||||
self._order_value(),
|
||||
self._file_names,
|
||||
all_seasons,
|
||||
)
|
||||
self._match_worker.finished.connect(self._on_match_finished)
|
||||
self._match_worker.failed.connect(self._on_match_failed)
|
||||
@@ -508,10 +529,8 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
self.match_btn.setEnabled(True)
|
||||
matched = len(mapping)
|
||||
total = len(self._file_names)
|
||||
msg = (
|
||||
f"Matched {matched} of {total} file(s) for season {self.season.value()} "
|
||||
f"({self._order_label()})."
|
||||
)
|
||||
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()})."
|
||||
if unmatched:
|
||||
msg += f" {len(unmatched)} file(s) unmatched."
|
||||
self.status.setText(msg)
|
||||
@@ -524,7 +543,10 @@ class TvdbEpisodeRenumberRuleWidget(QWidget):
|
||||
|
||||
def getRule(self) -> TvdbEpisodeRenumberRule:
|
||||
r = TvdbEpisodeRenumberRule(
|
||||
episode_mapping=dict(self._episode_mapping),
|
||||
episode_mapping={
|
||||
k: (v.season, v.episode) if hasattr(v, "season") else v
|
||||
for k, v in self._episode_mapping.items()
|
||||
},
|
||||
padding=self.padding.value(),
|
||||
)
|
||||
r.enabled = self.enabled_cb.isChecked()
|
||||
|
||||
Reference in New Issue
Block a user