lyrics: sort lrclib lyrics by synced field and query search first

I found that the `/get` endpoint often returns incorrect or unsynced
lyrics, while results returned by the `/search` more accurate options.

Thus I reversed the change in the previous commit to prioritize
searching first.
This commit is contained in:
Šarūnas Nejus 2024-12-15 00:17:07 +00:00
parent 33aafdd50b
commit bb5f3e0593
No known key found for this signature in database
GPG key ID: DD28F6704DBE3435
2 changed files with 26 additions and 8 deletions

View file

@ -332,7 +332,7 @@ class LRCLyrics:
)
@cached_property
def dist(self) -> tuple[float, bool]:
def dist(self) -> tuple[bool, float]:
"""Distance/score of the given lyrics item.
Return a tuple with the following values:
@ -342,7 +342,7 @@ class LRCLyrics:
Best lyrics match is the one that has the closest duration to
``target_duration`` and has synced lyrics available.
"""
return self.duration_dist, not self.synced
return not self.synced, self.duration_dist
def get_text(self, want_synced: bool) -> str:
if self.instrumental:
@ -381,8 +381,11 @@ class LRCLib(Backend):
) -> Iterator[list[LRCLibItem]]:
"""Yield lyrics candidates for the given song data.
Firstly, attempt to GET lyrics directly, and then search the API if
lyrics are not found or the duration does not match.
I found that the ``/get`` endpoint sometimes returns inaccurate or
unsynced lyrics, while ``search`` yields more suitable candidates.
Therefore, we prioritize the latter and rank the results using our own
algorithm. If the search does not give suitable lyrics, we fall back to
the ``/get`` endpoint.
Return an iterator over lists of candidates.
"""
@ -391,11 +394,11 @@ class LRCLib(Backend):
if album:
get_params["album_name"] = album
yield self.fetch_json(self.SEARCH_URL, params=base_params)
with suppress(NotFoundError):
yield [self.fetch_json(self.GET_URL, params=get_params)]
yield self.fetch_json(self.SEARCH_URL, params=base_params)
@classmethod
def pick_best_match(cls, lyrics: Iterable[LRCLyrics]) -> LRCLyrics | None:
"""Return best matching lyrics item from the given list."""

View file

@ -414,8 +414,23 @@ class TestLRCLibLyrics(LyricsBackendTest):
),
lyrics_match(syncedLyrics="synced", plainLyrics="plain 2"),
],
"plain with closer duration",
id="prefer closer duration",
"synced",
id="prefer synced lyrics even if plain duration is closer",
),
pytest.param(
[
lyrics_match(
duration=ITEM_DURATION,
syncedLyrics=None,
plainLyrics="valid plain",
),
lyrics_match(
duration=1,
syncedLyrics="synced with invalid duration",
),
],
"valid plain",
id="ignore synced with invalid duration",
),
pytest.param(
[lyrics_match(syncedLyrics=None), lyrics_match()],