Медленная/нестабильная сеть до api.music.yandex.net роняла весь процесс при первом же таймауте (5с по умолчанию у библиотеки). Добавлен with_retries с экспоненциальной паузой на всех сетевых точках входа (fetch, language, genres, apply, client.init), таймаут запроса поднят до 20с (настраивается в config.toml). Заодно поправлен скрытый баг: language.py раньше кэшировал таймаут как "текста нет" навсегда - теперь только настоящий NotFoundError трактуется так. |
||
|---|---|---|
| sort_ym | ||
| tests | ||
| .gitignore | ||
| ARCHITECTURE.md | ||
| config.toml | ||
| README.md | ||
| requirements-dev.txt | ||
| requirements.txt | ||
Sort YM
Раскладывает лайкнутые треки Яндекс.Музыки по плейлистам вида Жанр — RU / Жанр — INT.
$ python -m sort_ym report
Распределение по плейлистам:
Рок — INT: 143
Рок — RU: 287
Рэп — RU: 512
...
Отчёт сохранён: out/report.csv
Установка
Требования: Python 3.11+ (используется tomllib из стандартной библиотеки), Windows/Linux/macOS, доступ в интернет.
python -m venv .venv
.venv\Scripts\pip install -r requirements.txt
Для разработки (тесты):
.venv\Scripts\pip install -r requirements-dev.txt
Что делает
auth— вход в аккаунт Яндекса через OAuth device-flow: покажет код, вы подтверждаете вход на странице Яндекса, токен сохраняется в.token(локально, в.gitignore).fetch— скачивает список лайкнутых треков и их метаданные (жанр альбома, доступность текста) вcache/tracks.json. Повторный запуск докачивает только новые треки.report— определяет жанр (крупная группа) и язык (RU/иностранный) каждого трека, считает распределение по будущим плейлистам и сохраняетout/report.csvдля проверки. Ничего не меняет в аккаунте.apply --yes— создаёт недостающие плейлисты и добавляет в них треки. Уже добавленные треки не дублируются при повторном запуске. Лайки не трогает, ничего не удаляет.
Как определяется жанр и язык
- Жанр: у трека берётся жанр альбома, затем он сопоставляется с одной из ~11 крупных
групп (Поп, Рок, Метал, Рэп, Электроника, Джаз и блюз, Классика, Фолк и world, Инди и
альтернатива, Саундтреки, Разное) через реальное дерево жанров Яндекса
(
sort_ym/genres.py, таблицаROOT_BUCKET— легко дополняется). - Язык — гибрид:
- Если у трека есть текст песни — реальный язык из API (
ru→ RU, иначе → INT). - Иначе — подсказка по жанру (
rusrap,shanson,bard, ...). - Иначе — по алфавиту названия/исполнителя (кириллица/латиница).
- Если ничего не сработало — трек попадает в
... — Не определено.
- Если у трека есть текст песни — реальный язык из API (
После report в консоли также печатается список нераспознанных жанров (попавших в «Разное»),
чтобы можно было дополнить таблицу в sort_ym/genres.py.
Handy things
- Первый прогон
applyделайте с--limit 20 --yesи проверьте результат в приложении, прежде чем запускать на все ~2000 треков. - Все промежуточные данные лежат в
cache/— их можно удалить, чтобы пересчитать с нуля. - Настройки задержек между запросами — в
config.toml([throttle]).
Риски (неофициальный API)
Официального API для личной библиотеки Яндекс.Музыки нет — инструмент использует
неофициальную библиотеку yandex-music. OAuth-токен в .token даёт полный доступ к аккаунту
Яндекса — храните его локально и не публикуйте. Инструмент выполняет только безопасные действия
(чтение лайков, создание плейлистов, добавление треков) и ничего не удаляет.
For developers
Python 3.11+, yandex-music==3.0.0, стандартная библиотека (tomllib, csv, unicodedata).
.venv\Scripts\python -m pytest tests/ -v
.venv\Scripts\python -m sort_ym auth
.venv\Scripts\python -m sort_ym fetch
.venv\Scripts\python -m sort_ym report
.venv\Scripts\python -m sort_ym apply --limit 20 --yes
Структура кода и поток данных — в ARCHITECTURE.md.