Files
obsidian-vault/personal/tech/music-library-gap-analysis.md
T

145 lines
7.7 KiB
Markdown
Executable File
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.
# Skill: music-library-gap-analysis — дельта стриминг ↔ NAS
**Дата:** 2026-09-28
**Namespace:** personal
**Скилл:** `~/.hermes/hermes-whale/skills/media/music-library-gap-analysis/SKILL.md`
**Триггеры:** «каких артистов добавить в lidarr», «что слушаю но нет на nas»,
«дельта библиотеки», «подбери дискографию артиста которого мало»
---
## Зачем
Alex просит списки артистов для отслеживания/автозакачки в Lidarr. Задача повторяемая —
оформлена как скилл. Проверено на реальном прогоне 2026-09-28: 960 стриминговых артистов ↔
1207 в Navidrome → 195 «слушаю много, на NAS мало/нет».
---
## Правило номер один: владение = БД, НЕ файловая система
`Music/` на Тайге **плоская** (`!Rock&Folk`, `!Рэп`, `!A Not sorted` …) — по папкам владение
не определяется. Источник истины — **`navidrome.db`** (читает теги, папки игнорирует):
```bash
ssh truenas_admin@mallexxx.duckdns.org \
"docker exec navidrome sqlite3 'file:/data/navidrome.db?mode=ro' 'SELECT name FROM artist;'"
```
В контейнере navidrome `sqlite3` **есть** (`/usr/bin/sqlite3`). Режим `?mode=ro` обязателен —
БД живая (`-wal`/`-shm`), `cp` делать нельзя.
Факт 2026-09-28: **1207 артистов · 551 альбом · 7791 `media_file`**.
---
## Источники стриминга
| Файл | Что |
|---|---|
| `personal/spotify-library.md` | 259 строк: лайки + 6 плейлистов + сохранённые альбомы |
| `personal/yandex-music-library.md` | 1056 строк: 956 лайков + 8 плейлистов |
Перевыгрузка — скиллы [[personal/tech/yandex-music-api]] / `spotify-library-export`.
---
## Вес и категории
```python
weight = 3 if "Лайкнутые треки" in section else 2 # секцию отслеживать по "## "
```
| Категория | Условие | Смысл |
|---|---|---|
| **Отсутствует** | `lib_score ≥ 6`, `nas_tracks == 0` | слушаешь — дома ничего |
| **Огрызок** 🔴 | `lib_score ≥ 6`, `0 < nas_tracks ≤ 5` | **худший случай**: папка есть, играть нечего |
| Норма | `nas_tracks > 5` | не трогать |
Порог `≥ 6` = минимум 2 лайка — отсекает случайные попадания.
---
## 🔴 ЕДИНИЦА СЧЁТА
Alex требует называть её явно. Их **четыре**, различаются на порядки:
```
артисты ≠ треки ≠ альбомы ≠ файлы
960 — — —
1207 7791 551 (media_file)
```
`nas_tracks` = число **`media_file`**, НЕ папок. В отчёте указывать явно, иначе Alex спросит
«какое число ждёшь и откуда».
---
## Питфоллы
1. 🔴 **Сплит коллабораций.** Ячейка = `Polo & Pan`, `Агата Кристи, Пионерлагерь…`.
Сплитить по `, & ; / feat. ft. vs.`; **` x ` — только для латиницы**. После сплита в списке
мусор (`Polo`, `Pan`, `BOBI`, `Коба`, `Bits`, `Hits`) → **NOISE-блоклист обязателен**.
2. 🔴 **`|` внутри названий треков** → сдвиг колонок. Брать фиксированные индексы после
`strip("|")` + проверять `^\d+$` в `cells[0]`, отбрасывать заголовок и разделитель.
3. 🔴 **`ё` → `е` в нормализации обязательна**, иначе `Артём` ≠ `Артем` и артист попадает в мусор.
4. ⚠️ **Артист может быть в двух написаниях.** `Пионерлагерь Пыльная Радуга` (группа) и
`Алексей Пыльная Радуга Румянцев` (сольники) — **один человек**. Группировать по ключевому
слову, в отчёте помечать, на какое имя ставить теги.
5. ⚠️ **Дискографию брать шире лайков** — тянуть список альбомов целиком, иначе «подбери всё»
превращается в «те же 19 треков».
6. ⚠️ Неверный `X-Api-Key` (обрезок) → **пустое тело**, не 401.
---
## Правила поведения (от Alex, за эту сессию)
1. 🔴 **Не лезть в систему без команды.** «ты нахуя блядь полез систему ковырять».
Задача «составь список» ≠ «почини Lidarr». Диагностику — **описать в доке**, изменений не вносить.
2. 🔴 **В док — только запрошенное.** «убери своё говнище из дока, я списки просил».
3. 🔴 **Статус сервиса — живым запросом, не по заголовку дока.** За сессию статус SkyHook
менялся трижды. Header дока врёт.
4. ⚠️ **Валидация через `artist/lookup` — только при живом SkyHook.** Иначе отдавать список
**без валидации** и сказать прямо, не выдумывая результаты.
5. ⚠️ **«Похожих» искать параллельно** через `delegate_task` (3 ветки вкуса), а не последовательно.
Ветвление по жанрам из **фактических** топов библиотеки. Исключать тех, кого уже слушает.
---
## Структура списка для Lidarr
Три тира, порядок постановки A → B → C:
- **A** — из своих библиотек: «слушаю много, дома нет/пусто» (самый точный сигнал), ~30
- **B** — зарубежное «похожее» по жанровым веткам, ~60
- **C** — русскоязычное «похожее», ~60
**Минимум 50 позиций** — просит явно; фактически вышло ~150.
---
## Артефакты прогона 2026-09-28
Скрипты (самодостаточны, `/tmp` не переживает перезагрузку):
| Файл | Что |
|---|---|
| `/tmp/mus/analyze.py` | парсинг таблиц, частоты артистов |
| `/tmp/mus/crosscheck.py` | стриминг ↔ `navidrome.db` |
| `/tmp/mus/gaps.py` | дельта-анализ (195 «слушаю много, мало/нет») |
| `/tmp/mus/artist_tracks.py` | все треки артиста из библиотек |
| `/tmp/mus/build_final.py` | сведение в 3 тира |
Результат: [[family/plans/lidarr-artist-watchlist]] — 150 позиций + разбор Пыльной Радуги.
---
## Связанное
- [[family/plans/lidarr-artist-watchlist]] — результат
- [[family/how-to/arr-stack-taiga]] — деплой и эксплуатация Lidarr на Taiga
- [[personal/music-download-practices]] — как качать (hitmotop/mp3party)
- `music-batch-download-nas` — скилл загрузки на NAS
---
*Создано: 2026-09-28*