Release v1.0.15: fix nxnn preview crash and improve truncated title matching.
Co-authored-by: Cursor <[email protected]>
This commit is contained in:
+32
-2
@@ -170,6 +170,7 @@ def rewrite_episode_stem(
|
|||||||
span = target.episode_end - target.episode + 1
|
span = target.episode_end - target.episode + 1
|
||||||
else:
|
else:
|
||||||
span = parsed["span"]
|
span = parsed["span"]
|
||||||
|
title = parsed.get("title") or ""
|
||||||
|
|
||||||
if parsed["format"] == "nxnn":
|
if parsed["format"] == "nxnn":
|
||||||
s_pad = max(parsed["season_pad"], len(str(new_season)))
|
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()
|
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(
|
def _coerce_target(
|
||||||
value: EpisodeTarget | tuple[int, ...] | int,
|
value: EpisodeTarget | tuple[int, ...] | int,
|
||||||
parsed: dict,
|
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:
|
def _combined_match_score(fnorm: str, combined_name: str, file_title: str = "") -> float:
|
||||||
variants = _combined_title_variants(combined_name)
|
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):
|
if file_title and _dual_title_matches_combined(file_title, combined_name):
|
||||||
best = max(best, 0.96)
|
best = max(best, 0.96)
|
||||||
return best
|
return best
|
||||||
@@ -417,8 +445,10 @@ def match_filenames_to_episodes(
|
|||||||
for season, ep_num, enorm, ep_name in season_eps:
|
for season, ep_num, enorm, ep_name in season_eps:
|
||||||
if not fnorm:
|
if not fnorm:
|
||||||
continue
|
continue
|
||||||
|
title_score = _title_match_score(fnorm, enorm)
|
||||||
|
score = title_score + _episode_number_boost(parsed, season, ep_num, title_score)
|
||||||
score = _apply_season_hint(
|
score = _apply_season_hint(
|
||||||
_similarity(fnorm, enorm),
|
score,
|
||||||
EpisodeTarget(season=season, episode=ep_num),
|
EpisodeTarget(season=season, episode=ep_num),
|
||||||
parsed,
|
parsed,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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
@@ -76,7 +76,8 @@ API="${GITEA_HOST}/api/v1/repos/${GITEA_OWNER}/${GITEA_REPO}/releases"
|
|||||||
NOTES="$(cat <<EOF
|
NOTES="$(cat <<EOF
|
||||||
## HSRename ${TAG}
|
## 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\`
|
- Always verify/update via Gear Lever Forgejo: \`https://git.hisora.dev/Dawnsorrow/HS-Rename\`
|
||||||
|
|
||||||
Download:
|
Download:
|
||||||
|
|||||||
Reference in New Issue
Block a user