diff --git a/family/how-to/navidrome-truenas-android.md b/family/how-to/navidrome-truenas-android.md index ba89b406..d89a3b0c 100755 --- a/family/how-to/navidrome-truenas-android.md +++ b/family/how-to/navidrome-truenas-android.md @@ -56,6 +56,35 @@ Scanner: Error marking DB analysis pending > ⚠️ **Пустой `.ndignore` = «игнорировать ВСЁ»** (не «не игнорировать ничего») — сообщение > `Scanner: .ndignore file is empty, ignoring everything`. **Не создавать пустым.** +## 🔴 ПРИЁМКА В UI ВСКРЫЛА ДЕФЕКТ ПЛАНА: `album` со скобочным мусором + +Navidrome поднялся и просканировал **8043 трека**. Приёмка в UI дала сразу два результата: + +**✅ Главный — движок работает правильно.** Артисты и альбомы строятся **по ТЕГАМ**, папки игнорируются +(`!Rock&Folk/ДДТ`, `!Рэп/НТЛ`, `z Другое/Красная Плесень` — разложены по тегам). **Багу Jellyfin #18162 +здесь места нет** — главная причина, по которой выбирали Navidrome, **подтверждена на живых данных**. + +**🔴 Побочный — вскрыт дефект входного плана.** Alex, открыв UI: + +> «Откуда альбомы в скобках взялись? Типа `Дискотека Авария` — для корня, а `(Авария)` — откуда??» + +**Ответ (факт, `ffprobe` внутри контейнера):** `TAG:album=(Авария)` — **это реальный тег в файле**, +не подстановка Navidrome. Мусор вписал mp3-граббер (`comment=This File from http://rmp.ru`). +Механика: план `APPLY-PLAN.csv` заполнял `new_album` **копией `cur_album`** при любом непустом +значении → мусор из диска прошёл в целевое значение и был записан обратно. + +| | | +|---|---:| +| `new_album == cur_album` (оставлено как есть) | **6202 из 7861 (79%)** | +| Реальный скобочный мусор | **306 строк / 15 папок** | + +**Итог:** 306 строк исправлены, сгенерирован новый дифф `DIFF-new-vs-38-v2.csv`. +Полный разбор — [[personal/plans/music-artist-albumartist-repair]] §СЕССИЯ 18. + +> 🔑 **Приёмка в UI — единственный способ поймать дефект такого класса.** Ни валидатор плана +> («пустых 0»), ни дифф (`new_album` плана vs базы 38-го прогона — мусор стоял в обоих → «совпало») +> его не видят. **Смотреть глазами в UI после деплоя — обязательно.** + ## ПЛАН ДЕПЛОЯ (выполнен по шагам) ### Шаг 1 — каталог `/mnt/RED_2TB/docker/navidrome/` @@ -396,17 +425,19 @@ artist=Maria Makarova (organ) ← исполнитель вмес `~/Downloads/music-tags/REPORT-new-album-equals-cur.csv` (6202 строки) + `REPORT-album-kept-all-folders.csv` (558 папок с классификацией kind). **Уточнено: реальный мусор — 9 папок / 265 треков** (только значения-огрызки в скобках). -- [x] ~~Решение Alex по правке `album` для мусорных папок~~ → ✅ **ПРАВИЛА ПОЛУЧЕНЫ 2026-09-27**: +- [x] ~~Решение Alex по правке `album` для мусорных папок~~ → ✅ **ВСЕ РЕШЕНИЯ ПОЛУЧЕНЫ И ПРИМЕНЕНЫ** - файл в **корне папки артиста** → `album` = имя папки артиста (`Дискотека Авария`) - файл в **подпапке-альбоме** → `album` = имя подпапки (`Москва пьёт пиво`) - - **папка-сборник** (`!Retro`, `!Radio`) → `album='Retro'`, `albumartist='Various Artists'` + - **папка-сборник** (`!Retro`) → `album='Retro'` - правило корня подтверждено из Zulip (сообщение 128410): «то что в корне лежит мы считаем - одним альбомом». **Атрибуты и скобочный мусор разобраны — 306 строк.** - - ⚠️ **Открыто:** расхождение «убрать скобки» vs «имя подпапки» на 3 папках - (`Филосовские`, `Разное`, `Из сказок`) — ждёт ответа Alex. + одним альбомом». **306 строк исправлены, мусора 0 — проверено по файлу.** + - 3 спорные папки закрыты (Alex «Да»): `Филосовские`→`Философские`, `Разное`→`Разное`, + `Из сказок`→`Из Сказок` + - `Птаха` → `album='Красивые, богатые'` (без артиста и года) Разбор — [[personal/plans/music-artist-albumartist-repair]] §СЕССИЯ 18. -- [ ] 🔴 **Сгенерировать НОВЫЙ дифф** со всеми 306 строками `album` внутри. - **Старый `DIFF-new-vs-38.csv` НЕ трогать** (прямое указание Alex). +- [ ] ⚠️ **Проверить `albumartist='Various Artists'` для 5 файлов `!Retro`** — `album=Retro` + проставлен, но `albumartist` не менялся. +- [ ] 🔴 **Alex вычитывает `DIFF-new-vs-38-v2.csv`** — секция `album` (+12 записей против старого). - [ ] 🔴 **Валидатор смысла `new_album`** — паттерн «значение целиком в скобках» `^\(.+\)$`, заглушки (`нет альбома`, `NULL`, `no title`, `Non spécifié`), спам-URL. В пайплайне ОТСУТСТВУЕТ: это и есть причина дефекта (дифф двух планов мусор не ловит — он стоит в обоих). @@ -424,6 +455,7 @@ artist=Maria Makarova (organ) ← исполнитель вмес - [ ] Собрать `TPE2` по плану выше (нужен **НОВЫЙ** план правок с колонкой `album_artist` — в `tag-fix-plan.csv` её не было) - [ ] **Создать админа Navidrome при первом входе** (дефолтного логина НЕТ — форма «Create admin») + — ⏳ Alex увидел форму, подтвердил, что это ожидаемое поведение - [ ] Установить Symfonium на Android, подключить к `https://music.mallexxx.duckdns.org` ## Связанные заметки diff --git a/personal/plans/music-artist-albumartist-repair.md b/personal/plans/music-artist-albumartist-repair.md index 0c1b170b..3cddccee 100755 --- a/personal/plans/music-artist-albumartist-repair.md +++ b/personal/plans/music-artist-albumartist-repair.md @@ -19,18 +19,19 @@ related: - '[[personal/tech/music-tags-repair-truenas]]' - '[[personal/plans/tagwriter-container]]' - '[[family/how-to/navidrome-truenas-android]]' -status: session18-navidrome-deployed-album-rules-recovered +status: session18-album-306-fixed-new-diff-generated # Music `artist` + `albumartist` Repair — правила Alex и ход работ -## 🟣 СЕССИЯ 18 (2026-09-27) — NAVIDROME РАЗВЁРНУТ, ДЕФЕКТ-КЛАСС ВСКРЫТ, ПРАВИЛА ВОССТАНОВЛЕНЫ ИЗ ZULIP +## 🟣 СЕССИЯ 18 (2026-09-27) — NAVIDROME РАЗВЁРНУТ, ДЕФЕКТ-КЛАСС ВСКРЫТ, ПРАВИЛА ВОССТАНОВЛЕНЫ ИЗ ZULIP, 306 СТРОК ИСПРАВЛЕНЫ, НОВЫЙ ДИФФ ГОТОВ -> **СТАТУС СЕССИИ 18:** Navidrome ✅ развёрнут и работает (см. ниже + `[[family/how-to/navidrome-truenas-android]]`). -> Вскрыт дефект-класс `new_album == cur_album` (6202 строки, 79%). Масштаб реального мусора: -> **9 папок / 265 треков** (не 28 папок). **Правила `album` восстановлены из базы Zulip** -> (см. §ПРАВИЛА ВОССТАНОВЛЕНЫ). **Финальные решения по 306 строкам приняты.** -> ⚠️ Один открытый вопрос — расхождение двух правил на 3 папках Высоцкого (ждёт Alex). -> Артефакты: `REPORT-new-album-equals-cur.csv`, `REPORT-album-kept-all-folders.csv`, `ALBUM-FIX-TABLE.csv`. -> **Дальше: генерация НОВОГО диффа (старый `DIFF-new-vs-38.csv` НЕ трогать).** +> **СТАТУС СЕССИИ 18 (финал):** Navidrome ✅ развёрнут и работает (см. ниже + +> `[[family/how-to/navidrome-truenas-android]]`). Дефект-класс `new_album == cur_album` +> вскрыт (6202 строки, 79%), реального мусора **9 папок / 265 треков→306 строк**. +> Правила `album` восстановлены из базы Zulip. **Все 306 строк исправлены в `APPLY-PLAN.csv` +> (мусора 0 — проверено по файлу). НОВЫЙ дифф `DIFF-new-vs-38-v2.csv` сгенерирован** +> (164 album-строки, +12 к старому). Старый `DIFF-new-vs-38.csv` не тронут. +> ⚠️ Осталось: `albumartist` для 5 файлов `!Retro`, вычитка диффа Alex, валидатор смысла. +> См. §ВОПРОС ПО 3 ПАПКАМ, §СДЕЛАНО: правка 306 строк, §НОВЫЙ ДИФФ. > **Контекст:** Navidrome поднят и просканировал библиотеку (8043 трека). Alex открыл UI и > спросил: «**Откуда альбомы в скобках взялись?** Типа `Дискотека Авария` — для корня, @@ -302,17 +303,105 @@ base/plux/pan → не надо, пусть будет родительски > 🔴 **Скобочный мусор в подпапках (`(Авария)` в `Москва пьёт пиво`/`Старые хиты`) — это мусор > ПОВЕРХ правильного имени подпапки. Ставить имя подпапки, а не снятые скобки (`Авария`).** -### ⚠️ ОТКРЫТЫЙ ВОПРОС (единственный, ждёт ответа Alex) +### ✅ ВОПРОС ПО 3 ПАПКАМ — ЗАКРЫТ (Alex: «Да») -Расхождение между двумя правилами — «убрать скобки» vs «имя подпапки» — **на 3 папках**: +Alex подтвердил **вариант A для всех трёх** (скобки убрать, имя папки не использовать): -| Папка | A: скобки убрать | B: имя подпапки | файлов | -|---|---|---|---:| -| `Владимир Высоцкий/Филосовские` | `Философские` | `Филосовские` (опечатка в имени!) | 97 | -| `Владимир Высоцкий/Разное` | `Высоцкий - Разное` | `Разное` | 44 | -| `Владимир Высоцкий/Из сказок` | `Из Сказок` | `Из сказок` (нижний регистр) | 16 | +| Папка | файлов | было | ✅ стало | +|---|---:|---|---| +| `Владимир Высоцкий/Филосовские` | 97 | `(Философские)` | **`Философские`** (исправлена опечатка папки) | +| `Владимир Высоцкий/Разное` | 44 | `(Высоцкий - Разное)` | **`Разное`** | +| `Владимир Высоцкий/Из сказок` | 16 | `(Из Сказок)` | **`Из Сказок`** (капитализация) | -**Совпадают (расхождения нет):** `Блатные`, `Морские`, `Спортивные`. +🔴 **Плюс отдельное решение по `Птаха`:** `album` = **`Красивые, богатые`** — без артиста и без года. +Первоначально я подставил имя папки целиком (`Птаха - Красивые, богатые (2009)`) — **неверно**, +это нарушает правило «имя артиста и год в `album` не кладём». + +### 🔴 `Философские` НИКОГДА НЕ БЫЛО В ПЛАНЕ — проверено по 40+ бэкапам + +Alex: «Философские — ты блядь уже правил! Куда оно делось?!» + +**Факт:** прогнал все `APPLY-PLAN.csv.bak-*` (40+ файлов) — **во всех стоит `(Философские)` ×97.** +Значение `Философские` (без скобок) не встречается НИ В ОДНОМ бэкапе. + +``` +APPLY-PLAN.csv.bak-before-2009-04-20260927-134232 {'(Философские)': 97} ← первый бэкап +... все последующие — то же самое +``` + +> **Вывод: правка не была применена и НЕ была потеряна — её не было вовсе.** +> Обсуждали на словах, в CSV не записали. **Правило: прежде чем отвечать «куда делось» — +> прогнать все `.bak-*` и показать, было ли значение вообще.** + +### ✅ СДЕЛАНО: правка 306 строк + НОВЫЙ дифф + +**Скрипт:** `/tmp/fix_album_306.py` — применил финальные правила к `APPLY-PLAN.csv`. + +| Тип | Правило | +|---|---| +| **КОРЕНЬ** (файл прямо в папке артиста) | `album` = имя папки артиста | +| **ПОДПАПКА** (файл в папке-альбоме) | `album` = имя подпапки (с исправлением 3 опечаток) | +| **СБОРНИК** (`!Retro`) | `album` = `Retro` | +| **ПТАХА** (особый случай) | `album` = `Красивые, богатые` | + +**Итоговая таблица правок (306 строк):** + +``` +!Pop, Club, Любэ/Дискотека Авария 2 (Авария) -> Дискотека Авария КОРЕНЬ +!Pop, Club, Любэ/Дискотека Авария/Москва пьёт пиво 17 (Авария) -> Москва пьёт пиво ПОДПАПКА +!Pop, Club, Любэ/Дискотека Авария/Старые хиты 7 (Авария) -> Старые хиты ПОДПАПКА +!Retro 5 (Авария)/(Вилли Т.) -> Retro СБОРНИК +!Rock&Folk/NONSONS - zvezda 11 (zvezda) -> NONSONS - zvezda КОРЕНЬ +!Rock&Folk/Несчастный Случай 4 (Несчастный Случай) -> Несчастный Случай КОРЕНЬ +!Барды/Владимир Высоцкий 25 (Высоцкий)/(Блатные)-> Владимир Высоцкий КОРЕНЬ +!Барды/Владимир Высоцкий/Блатные 42 (Блатные) -> Блатные ПОДПАПКА +!Барды/Владимир Высоцкий/Из сказок 16 (Из Сказок) -> Из Сказок ПОДПАПКА +!Барды/Владимир Высоцкий/Морские 17 (Морские) -> Морские ПОДПАПКА +!Барды/Владимир Высоцкий/Разное 44 (Высоцкий - Разное) -> Разное ПОДПАПКА +!Барды/Владимир Высоцкий/Спортивные 14 (Спортивные) -> Спортивные ПОДПАПКА +!Барды/Владимир Высоцкий/Филосовские 97 (Философские) -> Философские ПОДПАПКА +!Рэп/Вилли Токарев 4 (Вилли Токарев) -> Вилли Токарев КОРЕНЬ +!Рэп/Птаха - Красивые, богатые (2009) 1 (prod. Shorty) -> Красивые, богатые ПТАХА +``` + +**ПРОВЕРКА ФАКТОМ ПО САМОМУ ФАЙЛУ** (не рассуждение): + +``` +Всего строк: 7861 +Осталось строк с мусорным cur_album: 306 +ИЗ НИХ new_album ВСЁ ЕЩЁ мусорный: 0 ✅ +``` + +### ✅ НОВЫЙ ДИФФ: `DIFF-new-vs-38-v2.csv` (старый НЕ тронут) + +| | album-строк | ПАПКА | ТРЕК | +|---|---:|---:|---:| +| `DIFF-new-vs-38.csv` (старый, mtime 15:46) | 152 | 101 | 51 | +| **`DIFF-new-vs-38-v2.csv` (новый)** | **164** | **112** | **52** | +| Прибавка | **+12** | | | + +Схлопывание сработало: 306 строк → **15 записей по папкам** (значение одинаково у всех +файлов папки — правило 2 диффа). Все 15 целевых значений проверены и найдены в диффе. + +**Скрипт нового диффа:** `~/Downloads/music-tags/diff_new_vs_38_v2.py` +(копия `diff_new_vs_38.py` c единственной правкой `OUT = DIFF-new-vs-38-v2.csv`; +сам `diff_new_vs_38.py` НЕ изменён — старый дифф воспроизводим). + +### ⚠️ НЕ ЗАКРЫТО: `albumartist` для `!Retro` + +`album=Retro` проставлен, но `albumartist` для 5 файлов `!Retro` **не менялся** — +нужно проверить и доставить `Various Artists` (общее правило сборника). + +### ⏭ Что осталось + +1. ⚠️ Проверить/доставить `albumartist='Various Artists'` для 5 файлов `!Retro`. +2. **Alex вычитывает `DIFF-new-vs-38-v2.csv`** — секция `album` (+12 записей). +3. **Валидатор смысла `new_album`** — паттерны: огрызок в скобках `^\(.+\)$`, заглушки + (`нет альбома`, `NULL`, `no title`, `Album`, `Non spécifié`), спам-URL. **В пайплайне его нет.** +4. Регистровые дубли (`Четверо Парней`/`Четверо парней`, `Бунт на Корабле`) — канонизация. +5. 🔴 **Правило «на всю папку»:** `album` решать на уровне ПАПКИ, не построчно. + Построчное наследие `cur_album` — корень дефекта. +6. Приёмка: **видно в UI Navidrome**, не read-back ассистента. ### ✅ Артефакты сессии 18 @@ -320,23 +409,21 @@ base/plux/pan → не надо, пусть будет родительски |---|---| | `~/Downloads/music-tags/REPORT-new-album-equals-cur.csv` | **6202 строки**: `folder, album_kept, count, path, title, artist, albumartist, genre` | | `~/Downloads/music-tags/REPORT-album-kept-all-folders.csv` | 558 папок: `kind, folder, files, unique_albums, values` | -| `~/Downloads/music-tags/ALBUM-FIX-TABLE.csv` | 306 строк: `folder, cur_album, new_album, path, title` (черновик, до финальных правил) | +| `~/Downloads/music-tags/ALBUM-FIX-TABLE.csv` | 306 строк (черновик, до финальных правил) | +| `~/Downloads/music-tags/ALBUM-FIX-306.csv` | ✅ **306 строк финальных правок**: `kind, folder, cur_album, new_album_was, new_album_now, old_albumartist, new_albumartist, path` | +| ⭐ `~/Downloads/music-tags/APPLY-PLAN.csv` | ✅ **ОБНОВЛЁН** — 306 строк исправлено, мусора 0 | +| `APPLY-PLAN.csv.bak-before-album-305fix-20260927-173213` | бэкап плана до правки | +| ⭐ `~/Downloads/music-tags/DIFF-new-vs-38-v2.csv` | ✅ **НОВЫЙ дифф** (164 album-строки) | +| `~/Downloads/music-tags/diff_new_vs_38_v2.py` | скрипт нового диффа | +| `~/Downloads/music-tags/DIFF-new-vs-38.csv` | **НЕ ТРОНУТ** (прямое указание Alex) | +| `/tmp/fix_album_306.py` | применение финальных правил к плану | +| `/tmp/find_filosof_value.py` | проверка по 40+ бэкапам: было ли `Философские` | | `/tmp/report_kept_album.py` | группировка папка → значение → count | | `/tmp/report_all_junk_folders.py` | классификация папок (МУСОР/СМЕШАННАЯ/OK) | | `/tmp/check_diff_coverage.py` | проверка покрытия дефекта диффом (7,6%) | | `/tmp/where_avaria.py` | где физически лежат файлы `(Авария)` | | `/tmp/album_rules_v2.py` | применение финальных правил (КОРЕНЬ/ПОДПАПКА/СБОРНИК) | - -### ⏭ Что осталось - -1. 🔴 **Ждёт Alex:** ответ по 3 папкам (A или B выше). -2. **Сгенерировать НОВЫЙ дифф** со всеми 306 строками `album` внутри. **Старый - `DIFF-new-vs-38.csv` НЕ трогать** (прямое указание Alex). -3. **Валидатор смысла `new_album`** — паттерны: огрызок в скобках `^\\(.+\\)$`, заглушки - (`нет альбома`, `NULL`, `no title`, `Album`, `Non spécifié`), спам-URL. **В пайплайне его нет.** -4. Регистровые дубли (`Четверо Парней`/`Четверо парней`, `Бунт на Корабле`) — канонизация. -5. 🔴 **Правило «на всю папку»:** `album` решать на уровне ПАПКИ, не построчно. - Построчное наследование `cur_album` — корень дефекта. +| `/tmp/verify_new_diff.py` | проверка попадания 15 групп в новый дифф | ---