diff --git a/core/repair_jobs/missing_lyrics.py b/core/repair_jobs/missing_lyrics.py index 4cf02a93..1cf9d95d 100644 --- a/core/repair_jobs/missing_lyrics.py +++ b/core/repair_jobs/missing_lyrics.py @@ -114,8 +114,13 @@ class MissingLyricsJob(RepairJob): # Option A: only flag tracks LRClib actually has lyrics for. An # instrumental returns nothing here and is silently skipped (never # re-flagged on future scans). + # tracks.duration is stored in MILLISECONDS (schema) — LRClib's + # exact-match wants SECONDS, so convert (else exact-match never + # hits and it silently falls back to a fuzzier search). try: - duration_s = int(duration) if duration else None + duration_s = int(int(duration) / 1000) if duration else None + if duration_s is not None and duration_s <= 0: + duration_s = None except (TypeError, ValueError): duration_s = None try: diff --git a/tests/test_missing_lyrics_job.py b/tests/test_missing_lyrics_job.py index fe7038e2..3adfbd9c 100644 --- a/tests/test_missing_lyrics_job.py +++ b/tests/test_missing_lyrics_job.py @@ -112,6 +112,23 @@ def test_scan_flags_only_tracks_with_available_lyrics(tmp_path, monkeypatch): assert findings[0]["details"]["track_title"] == "Song" # the instrumental was skipped +def test_scan_converts_duration_ms_to_seconds(tmp_path, monkeypatch): + # tracks.duration is milliseconds; LRClib wants seconds. The scan must + # convert before querying (215000ms → 215s) and store seconds in the finding. + t1 = tmp_path / "song.flac"; t1.write_bytes(b"x") + rows = [(1, "Song", "Artist", "Album", str(t1), 215000)] # 215000 ms = 215 s + seen = {} + fake_client = SimpleNamespace( + api=object(), + has_remote_lyrics=lambda title, artist, album, dur: seen.update(dur=dur) or True) + monkeypatch.setattr("core.lyrics_client.lyrics_client", fake_client) + + findings = [] + MissingLyricsJob().scan(_ctx(_DB(rows), findings)) + assert seen["dur"] == 215 # converted to seconds + assert findings[0]["details"]["duration"] == 215 + + def test_scan_skips_tracks_that_already_have_lrc(tmp_path, monkeypatch): t1 = tmp_path / "song.flac"; t1.write_bytes(b"x") (tmp_path / "song.lrc").write_text("[00:01]hi") # already has lyrics