Sort_YM/sort_ym/classify.py
Andrew Pimenov ff452b0162 add --source flag to read/sort an arbitrary playlist by link
report/apply/digest can now point at any Yandex Music playlist via a
share link instead of only the account's likes. Fetches the playlist's
tracks and artist genres straight into memory (no disk cache, nothing
persisted) and feeds them through the existing build_rows/render_digest/
apply_classification pipeline. apply supports --label to keep a foreign
playlist's tracks in separate genre playlists instead of merging them
into your own. Closes a gap where UnauthorizedError went uncaught anywhere.
2026-08-09 11:59:39 +03:00

78 lines
3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
# Крупные корзины (11 штук) - используются, когда под-жанровая группа слишком мала
# и схлопывается в родителя (см. report.build_rows).
BUCKET_LABELS: dict[str, str] = {
"pop": "Поп",
"rock": "Рок",
"metal": "Метал",
"rap": "Рэп",
"electronic": "Электроника",
"jazz-blues": "Джаз и блюз",
"classical": "Классика",
"folk-world": "Фолк и world",
"indie-alt": "Инди и альтернатива",
"soundtrack": "Саундтреки",
"other": "Разное",
}
# Под-жанры (root_id из реального дерева client.genres()) - используются, когда группа
# достаточно большая, чтобы получить отдельный плейлист (см. config.small_group_min).
FINE_LABELS: dict[str, str] = {
"allrock": "Рок",
"alternative": "Альтернатива",
"indie": "Инди",
"punk": "Панк",
"metal": "Метал",
"rap": "Рэп",
"electronics": "Электроника",
"dance": "Танцевальная",
"jazz": "Джаз",
"blues": "Блюз",
"classicalmusic": "Классика",
"pop": "Поп",
"estrada": "Эстрада",
"rnb": "R&B",
"folk": "Музыка мира",
"folkgenre": "Фолк",
"bard": "Авторская песня",
"shanson": "Шансон",
"country": "Кантри",
"reggae": "Регги",
"ska": "Ска",
"islamicgenre": "Исламская музыка",
"soundtrack": "Саундтреки",
"all": "Микс",
"other": "Разное",
"relax": "Лёгкая музыка",
"children": "Детская музыка",
"forchildren": "Детская",
"poemsforchildren": "Стихи для детей",
"fairytales": "Аудиосказки",
"audiobooks": "Разговорное",
"booksnotinrussian": "Аудиокниги на ин. языке",
"fiction": "Художественная литература",
"nonfictionliterature": "Нон-фикшн",
"podcasts": "Подкасты",
"naturesounds": "Звуки природы",
}
_ALL_LABELS: dict[str, str] = {**FINE_LABELS, **BUCKET_LABELS}
LANG_LABELS: dict[str, str] = {
"RU": "RU",
"INT": "INT",
"UNKNOWN": "Не определено",
}
def playlist_name(bucket: str, lang: str) -> str:
"""bucket - либо под-жанр (root_id), либо крупная корзина (после схлопывания)."""
bucket_label = _ALL_LABELS.get(bucket, BUCKET_LABELS["other"])
lang_label = LANG_LABELS.get(lang, LANG_LABELS["UNKNOWN"])
return f"{bucket_label} — {lang_label}"
def with_label(name: str, label: str) -> str:
"""Добавляет метку источника к имени целевого плейлиста: "Рок — RU" -> "Рок — RU (Метка)"."""
return f"{name} ({label})"