mirror of
https://github.com/Horizontal42/Sort_YM.git
synced 2026-11-10 19:11:59 +03:00
lyrics --all-languages flag to opt out of the ru filter
This commit is contained in:
parent
2344889418
commit
1c0f6928bf
4 changed files with 62 additions and 18 deletions
|
|
@ -71,16 +71,19 @@ def cmd_lyrics(args: argparse.Namespace) -> None:
|
||||||
if not tracks_cache:
|
if not tracks_cache:
|
||||||
raise SystemExit("Кэш треков пуст. Сначала запустите: python -m sort_ym fetch")
|
raise SystemExit("Кэш треков пуст. Сначала запустите: python -m sort_ym fetch")
|
||||||
|
|
||||||
# Тот же вызов, что в cmd_report: инкрементальный, на заполненном кэше почти no-op,
|
lang_cache: dict[str, str | None] = {}
|
||||||
# но без него RU-гейт опирался бы только на алфавитную эвристику.
|
if not args.all_languages:
|
||||||
ids_needing_lang = [str(t["id"]) for t in tracks_cache.values() if t["lyrics_available"]]
|
# Тот же вызов, что в cmd_report: инкрементальный, на заполненном кэше почти no-op,
|
||||||
lang_cache = language.fetch_api_languages(client, ids_needing_lang, cfg.cache_dir, cfg.lyrics_request_delay)
|
# но без него RU-гейт опирался бы только на алфавитную эвристику.
|
||||||
|
ids_needing_lang = [str(t["id"]) for t in tracks_cache.values() if t["lyrics_available"]]
|
||||||
|
lang_cache = language.fetch_api_languages(client, ids_needing_lang, cfg.cache_dir, cfg.lyrics_request_delay)
|
||||||
|
|
||||||
ids = lyrics.ru_lyric_track_ids(tracks_cache, lang_cache)
|
ids = lyrics.ru_lyric_track_ids(tracks_cache, lang_cache, all_languages=args.all_languages)
|
||||||
if args.limit is not None:
|
if args.limit is not None:
|
||||||
ids = ids[: args.limit]
|
ids = ids[: args.limit]
|
||||||
|
|
||||||
print(f"RU-треков с текстом: {len(ids)}")
|
label = "треков" if args.all_languages else "RU-треков"
|
||||||
|
print(f"{label} с текстом: {len(ids)}")
|
||||||
lyrics.fetch_lyrics_text(client, ids, cfg.cache_dir, cfg.lyrics_request_delay)
|
lyrics.fetch_lyrics_text(client, ids, cfg.cache_dir, cfg.lyrics_request_delay)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -263,6 +266,11 @@ def main(argv: list[str] | None = None) -> None:
|
||||||
|
|
||||||
p_lyrics = sub.add_parser("lyrics", help="загрузить тексты песен RU-треков в cache/lyrics_text.json")
|
p_lyrics = sub.add_parser("lyrics", help="загрузить тексты песен RU-треков в cache/lyrics_text.json")
|
||||||
p_lyrics.add_argument("--limit", type=int, default=None, help="ограничить количество треков (для пробного запуска)")
|
p_lyrics.add_argument("--limit", type=int, default=None, help="ограничить количество треков (для пробного запуска)")
|
||||||
|
p_lyrics.add_argument(
|
||||||
|
"--all-languages",
|
||||||
|
action="store_true",
|
||||||
|
help="не фильтровать по языку - загрузить тексты всех треков с лирикой, а не только RU",
|
||||||
|
)
|
||||||
|
|
||||||
p_analyze = sub.add_parser(
|
p_analyze = sub.add_parser(
|
||||||
"analyze",
|
"analyze",
|
||||||
|
|
|
||||||
|
|
@ -13,13 +13,19 @@ from .ymclient import with_retries
|
||||||
LYRICS_TEXT_CACHE_FILE = "lyrics_text.json"
|
LYRICS_TEXT_CACHE_FILE = "lyrics_text.json"
|
||||||
|
|
||||||
|
|
||||||
def ru_lyric_track_ids(tracks_cache: dict[str, dict], lang_cache: dict[str, str | None]) -> list[str]:
|
def ru_lyric_track_ids(
|
||||||
"""Числовые id RU-треков, у которых вообще есть текст.
|
tracks_cache: dict[str, dict],
|
||||||
|
lang_cache: dict[str, str | None],
|
||||||
|
all_languages: bool = False,
|
||||||
|
) -> list[str]:
|
||||||
|
"""Числовые id треков, у которых вообще есть текст.
|
||||||
|
|
||||||
Гейт двойной: lyrics_available (иначе track_supplement заведомо вернёт запись без lyrics)
|
По умолчанию - только RU: на незнакомом языке текст песни несёт для языковой модели меньше
|
||||||
и RU - анализ INT-лирики вне скоупа фичи. Дедупликация нужна потому, что один и тот же
|
сигнала, чем разбор трека, который слушатель понимает дословно. all_languages=True снимает
|
||||||
трек может быть лайкнут с разных альбомов: ключи tracks_cache при этом разные, а числовой
|
языковой фильтр, оставляя только lyrics_available (иначе track_supplement заведомо вернёт
|
||||||
id (и, соответственно, ключ кэша текстов) - один.
|
запись без lyrics). Дедупликация нужна потому, что один и тот же трек может быть лайкнут с
|
||||||
|
разных альбомов: ключи tracks_cache при этом разные, а числовой id (и, соответственно, ключ
|
||||||
|
кэша текстов) - один.
|
||||||
"""
|
"""
|
||||||
ids: list[str] = []
|
ids: list[str] = []
|
||||||
seen: set[str] = set()
|
seen: set[str] = set()
|
||||||
|
|
@ -29,10 +35,12 @@ def ru_lyric_track_ids(tracks_cache: dict[str, dict], lang_cache: dict[str, str
|
||||||
tid = str(t["id"])
|
tid = str(t["id"])
|
||||||
if tid in seen:
|
if tid in seen:
|
||||||
continue
|
continue
|
||||||
lang = language.detect_language(t["title"], t["artists"], t["genre_raw"], lang_cache.get(tid))
|
if not all_languages:
|
||||||
if lang == "RU":
|
lang = language.detect_language(t["title"], t["artists"], t["genre_raw"], lang_cache.get(tid))
|
||||||
seen.add(tid)
|
if lang != "RU":
|
||||||
ids.append(tid)
|
continue
|
||||||
|
seen.add(tid)
|
||||||
|
ids.append(tid)
|
||||||
return ids
|
return ids
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,22 @@ def test_apply_without_yes_fails_regardless_of_source():
|
||||||
|
|
||||||
def test_lyrics_command_is_wired(monkeypatch):
|
def test_lyrics_command_is_wired(monkeypatch):
|
||||||
called = {}
|
called = {}
|
||||||
monkeypatch.setattr(cli, "cmd_lyrics", lambda args: called.update(limit=args.limit))
|
monkeypatch.setattr(
|
||||||
|
cli, "cmd_lyrics", lambda args: called.update(limit=args.limit, all_languages=args.all_languages)
|
||||||
|
)
|
||||||
|
|
||||||
cli.main(["lyrics", "--limit", "5"])
|
cli.main(["lyrics", "--limit", "5"])
|
||||||
|
|
||||||
assert called == {"limit": 5}
|
assert called == {"limit": 5, "all_languages": False}
|
||||||
|
|
||||||
|
|
||||||
|
def test_lyrics_command_all_languages_flag(monkeypatch):
|
||||||
|
called = {}
|
||||||
|
monkeypatch.setattr(cli, "cmd_lyrics", lambda args: called.update(all_languages=args.all_languages))
|
||||||
|
|
||||||
|
cli.main(["lyrics", "--all-languages"])
|
||||||
|
|
||||||
|
assert called == {"all_languages": True}
|
||||||
|
|
||||||
|
|
||||||
def test_analyze_command_is_wired(monkeypatch):
|
def test_analyze_command_is_wired(monkeypatch):
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,23 @@ def test_ru_lyric_track_ids_deduplicates_same_numeric_id():
|
||||||
assert lyrics.ru_lyric_track_ids(tracks_cache, lang_cache={}) == ["100"]
|
assert lyrics.ru_lyric_track_ids(tracks_cache, lang_cache={}) == ["100"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_ru_lyric_track_ids_all_languages_includes_int():
|
||||||
|
tracks_cache = {
|
||||||
|
"100:10": track(100, title="Тоска", artists=["Гражданская Оборона"]),
|
||||||
|
"200:10": track(200, title="Come as You Are", artists=["Nirvana"]),
|
||||||
|
}
|
||||||
|
|
||||||
|
ids = lyrics.ru_lyric_track_ids(tracks_cache, lang_cache={}, all_languages=True)
|
||||||
|
|
||||||
|
assert ids == ["100", "200"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_ru_lyric_track_ids_all_languages_still_gates_on_lyrics_available():
|
||||||
|
tracks_cache = {"100:10": track(100, lyrics_available=False)}
|
||||||
|
|
||||||
|
assert lyrics.ru_lyric_track_ids(tracks_cache, lang_cache={}, all_languages=True) == []
|
||||||
|
|
||||||
|
|
||||||
class FakeLyrics:
|
class FakeLyrics:
|
||||||
def __init__(self, full_lyrics):
|
def __init__(self, full_lyrics):
|
||||||
self.full_lyrics = full_lyrics
|
self.full_lyrics = full_lyrics
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue