Skip to content

Commit 5ec1cf8

Browse files
committed
translations: make sure we do not re-translate
1 parent 36f0b3c commit 5ec1cf8

File tree

2 files changed

+26
-10
lines changed

2 files changed

+26
-10
lines changed

beetsplug/lyrics.py

+15-7
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,7 @@ def scrape(cls, html: str) -> str | None:
733733
class Translator(RequestHandler):
734734
TRANSLATE_URL = "https://api.cognitive.microsofttranslator.com/translate"
735735
LINE_PARTS_RE = re.compile(r"^(\[\d\d:\d\d.\d\d\]|) *(.*)$")
736+
remove_translations = partial(re.compile(r" / [^\n]+").sub, "")
736737

737738
_log: beets.logging.Logger
738739
api_key: str
@@ -802,21 +803,33 @@ def append_translations(self, lines: Iterable[str]) -> list[str]:
802803
def translate(self, new_lyrics: str, old_lyrics: str) -> str:
803804
"""Translate the given lyrics to the target language.
804805
806+
Check old lyrics for existing translations and return them if their
807+
original text matches the new lyrics. This is to avoid translating
808+
the same lyrics multiple times.
809+
805810
If the lyrics are already in the target language or not in any of
806811
of the source languages (if configured), they are returned as is.
807812
808813
The footer with the source URL is preserved, if present.
809814
"""
815+
if (
816+
" / " in old_lyrics
817+
and self.remove_translations(old_lyrics) == new_lyrics
818+
):
819+
self.info("🔵 Translations already exist")
820+
return old_lyrics
821+
810822
lyrics_language = langdetect.detect(new_lyrics)
811823
if lyrics_language != self.to_lang and (
812824
not self.from_langs or lyrics_language in self.from_langs
813825
):
814826
lyrics, *url = new_lyrics.split("\n\nSource: ")
815827
with self.handle_request():
816828
translated_lines = self.append_translations(lyrics.splitlines())
829+
self.info("🟢 Translated lyrics to {}", self.to_lang.upper())
817830
return "\n\nSource: ".join(["\n".join(translated_lines), *url])
818831

819-
return lyrics
832+
return new_lyrics
820833

821834

822835
@dataclass
@@ -1052,12 +1065,7 @@ def add_item_lyrics(self, item: Item, write: bool) -> None:
10521065
if lyrics := self.find_lyrics(item):
10531066
self.info("🟢 Found lyrics: {0}", item)
10541067
if translator := self.translator:
1055-
initial_lyrics = lyrics
1056-
if (lyrics := translator.translate(lyrics)) != initial_lyrics:
1057-
self.info(
1058-
"🟢 Added translation to {}",
1059-
self.config["translate_to"].get().upper(),
1060-
)
1068+
lyrics = translator.translate(lyrics, item.lyrics)
10611069
else:
10621070
self.info("🔴 Lyrics not found: {}", item)
10631071
lyrics = self.config["fallback"].get()

test/plugins/test_lyrics.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ def callback(request, _):
560560
requests_mock.post(lyrics.Translator.TRANSLATE_URL, json=callback)
561561

562562
@pytest.mark.parametrize(
563-
"initial_lyrics, expected",
563+
"new_lyrics, old_lyrics, expected",
564564
[
565565
pytest.param(
566566
"""
@@ -569,6 +569,7 @@ def callback(request, _):
569569
My body wouldn't let me hide it (Hide it)
570570
No matter what, I wouldn't fold (Wouldn't fold, wouldn't fold)
571571
Ridin' through the thunder, lightnin'""",
572+
"",
572573
"""
573574
[Refrain: Doja Cat] / [Refrain : Doja Cat]
574575
Hard for me to let you go (Let you go, let you go) / Difficile pour moi de te laisser partir (Te laisser partir, te laisser partir)
@@ -584,6 +585,7 @@ def callback(request, _):
584585
[00:01.00] Some more synced lyrics
585586
586587
Source: https://lrclib.net/api/123""",
588+
"",
587589
"""
588590
[00:00.00] Some synced lyrics / Quelques paroles synchronisées
589591
[00:00:50]
@@ -592,14 +594,20 @@ def callback(request, _):
592594
Source: https://lrclib.net/api/123""", # noqa: E501
593595
id="synced",
594596
),
597+
pytest.param(
598+
"Some lyrics",
599+
"Some lyrics / Some translation",
600+
"Some lyrics / Some translation",
601+
id="already translated",
602+
),
595603
],
596604
)
597-
def test_translate(self, initial_lyrics, expected):
605+
def test_translate(self, new_lyrics, old_lyrics, expected):
598606
plugin = lyrics.LyricsPlugin()
599607
bing = lyrics.Translator(plugin._log, "123", ["en"], "fr")
600608

601609
assert bing.translate(
602-
textwrap.dedent(initial_lyrics)
610+
textwrap.dedent(new_lyrics), old_lyrics
603611
) == textwrap.dedent(expected)
604612

605613

0 commit comments

Comments
 (0)