Skip to content

Comments

fix: batch song renamer and prepare for centralised song editing#783

Open
safepay wants to merge 8 commits intovicwomg:masterfrom
safepay:fix-batch-song-renamer-and-prepare-for-centralised-song-editing
Open

fix: batch song renamer and prepare for centralised song editing#783
safepay wants to merge 8 commits intovicwomg:masterfrom
safepay:fix-batch-song-renamer-and-prepare-for-centralised-song-editing

Conversation

@safepay
Copy link
Collaborator

@safepay safepay commented Feb 22, 2026

Batch song renamer fixes and metadata extraction groundwork

Preparatory work for the metadata extraction plan outlined in #779. Cleans up and correctly structures batch_song_renamer.py so that its logic can be extracted into pikaraoke/lib/metadata_parser.py in a follow-up PR.

What changed

Format detection: artist-title and title-artist both handled correctly

The renamer now detects whether a filename uses Artist - Title or Title - Artist ordering and preserves that format in the suggested rename. Previous tests had the assertions backwards — this branch corrects both the logic and the tests.

Functions decomposed for testability

score_result was split into _score_query_match and _score_penalties. Helpers for accent removal, format detection, artist deduplication, and name comparison were extracted as named functions. This makes the scoring and format-detection logic independently testable and directly extractable into metadata_parser.py without refactoring.

Last.fm resilience

  • Proactive rate limiting at 5 req/sec via _last_api_request_time
  • Reactive retry with exponential backoff on HTTP 429 / API error 29
  • _RATE_LIMITED sentinel distinguishes transient failures (don't cache) from genuine no-results (cache). Previously, timeouts and network errors were cached permanently as None.
  • Plain dict cache replaces lru_cache to enforce this distinction

Case-only rename support

Two-step rename via a temp file handles case-insensitive filesystems (Windows, macOS) — e.g. renaming abba to ABBA no longer silently fails.

Route cleanup

  • browse simplified to GET-only
  • get_songs_to_rename query param song-index renamed to song_index (consistent with Python/schema conventions)

Test coverage added

  • 9 tests for _detect_artist_first covering format detection edge cases
  • 6 tests for rate limiting: retry behaviour, backoff timing, cache-vs-no-cache semantics
  • Existing assertions corrected

Prepares for #779

The decomposed functions and plain-dict cache in this branch are the direct prerequisite for extracting them into pikaraoke/lib/metadata_parser.py. The follow-up will add regex_tidy() (lightweight cleanup for YouTube-sourced files), has_youtube_id() (provenance detection), and server-side endpoints to replace the client-side Last.fm calls in edit.html.

@safepay safepay force-pushed the fix-batch-song-renamer-and-prepare-for-centralised-song-editing branch from dc27c6c to f1480e0 Compare February 22, 2026 21:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant