# 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*