1 Commits
Author SHA1 Message Date
Bulk RenamerandCursor 0d7c16372c Release v1.0.15: fix nxnn preview crash and improve truncated title matching.
Co-authored-by: Cursor <[email protected]>
2026-07-03 22:34:29 -05:00
4 changed files with 38 additions and 4 deletions
+1 -1
View File
@@ -1 +1 @@
1.0.14
1.0.15
+32 -2
View File
@@ -170,6 +170,7 @@ def rewrite_episode_stem(
span = target.episode_end - target.episode + 1
else:
span = parsed["span"]
title = parsed.get("title") or ""
if parsed["format"] == "nxnn":
s_pad = max(parsed["season_pad"], len(str(new_season)))
@@ -218,6 +219,33 @@ def _similarity(a: str, b: str) -> float:
return SequenceMatcher(None, a, b).ratio()
def _title_match_score(fnorm: str, enorm: str) -> float:
"""Fuzzy title match; handles filenames that use a shortened episode title."""
if not fnorm or not enorm:
return 0.0
if fnorm == enorm:
return 1.0
score = _similarity(fnorm, enorm)
if len(fnorm) >= 4 and (fnorm in enorm or enorm.startswith(fnorm)):
score = max(score, 0.78)
ftokens = [t for t in fnorm.split() if len(t) > 2]
if ftokens:
etokens = set(enorm.split())
overlap = sum(1 for t in ftokens if t in etokens) / len(ftokens)
if overlap >= 0.75:
score = max(score, 0.66 + overlap * 0.3)
return score
def _episode_number_boost(parsed: dict, season: int, ep_num: int, title_score: float) -> float:
"""Nudge score up when NxNN/SxxExx in the filename agrees with this episode."""
if title_score < 0.45:
return 0.0
if parsed.get("season") == season and parsed.get("old_first") == ep_num:
return 0.12
return 0.0
def _coerce_target(
value: EpisodeTarget | tuple[int, ...] | int,
parsed: dict,
@@ -278,7 +306,7 @@ def _combined_title_variants(name: str) -> list[str]:
def _combined_match_score(fnorm: str, combined_name: str, file_title: str = "") -> float:
variants = _combined_title_variants(combined_name)
best = max((_similarity(fnorm, v) for v in variants), default=0.0)
best = max((_title_match_score(fnorm, v) for v in variants), default=0.0)
if file_title and _dual_title_matches_combined(file_title, combined_name):
best = max(best, 0.96)
return best
@@ -417,8 +445,10 @@ def match_filenames_to_episodes(
for season, ep_num, enorm, ep_name in season_eps:
if not fnorm:
continue
title_score = _title_match_score(fnorm, enorm)
score = title_score + _episode_number_boost(parsed, season, ep_num, title_score)
score = _apply_season_hint(
_similarity(fnorm, enorm),
score,
EpisodeTarget(season=season, episode=ep_num),
parsed,
)
+3
View File
@@ -0,0 +1,3 @@
HSRename 1.0.15
- Fix nxnn preview crash (undefined title in rewrite_episode_stem)
- Improve matching for shortened episode titles (prefix/token overlap scoring)
+2 -1
View File
@@ -76,7 +76,8 @@ API="${GITEA_HOST}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases"
NOTES="$(cat <<EOF
## HSRename ${TAG}
- Fix botched v1.0.4 AppImage (restores TheTVDB episode match + search fix)
- Fix nxnn preview crash (\`name 'title' is not defined\`)
- Improve TheTVDB matching for shortened episode titles (prefix and token overlap)
- Always verify/update via Gear Lever Forgejo: \`https://git.hisora.dev/Dawnsorrow/HS-Rename\`
Download: