[2026-09-27] eagle: personal/plans/music-artist-albumartist-repair.md personal/tech/music-tags-repair-truenas.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-27 19:53:36 +06:00
1 parent fcadd58cf0
commit e9c2135642
2 files changed
+318 -1

No files matched your search

@@ -4507,6 +4507,87 @@ precomposed-символ, а другая — combining `U+0306`. Визуаль
Плюс находка: **597 строк** имеют номер в имени файла, но пустой `new_track` → падали в
«single-track». Номер сборника (`Sbornik_*`, 199 строк) **ставится в `track`** — решение Alex.
## 🔴 30-я волна — КАНОННЫЙ ФОРМАТ ДИФФА (обязателен к соблюдению)
> Источник: сессия 27 плана `[[personal/plans/music-artist-albumartist-repair]]`.
> Alex: **«И заебись что нибудь сделай с форматом блядь! и там где вычистка полей от спама!»**
### ✅ КАНОННЫЙ ФОРМАТ `DIFF-new-vs-38-<N>.csv`
```
scope, folder, path, field, old_38, new_apply_plan
```
Генератор — **`~/Downloads/music-tags/diff_new_vs_38_v2.py`**. Входы:
`tag-fix-plan.csv` (**38-я волна**) vs `APPLY-PLAN.csv`. Сравниваются **только `new_*`**
(то, что уйдёт в файлы), `cur_*` игнорируется полностью.
| Правило | Смысл |
|---|---|
| `scope` = `ПАПКА` / `ТРЕК` | схлопывание: одна строка = N файлов, если новое значение одинаково |
| `old_38` | значение из плана **38-й волны** (не из БД, не с диска!) |
| `<НЕТ В 38-м>` | трека не было в 38-й → все поля новые |
| `<КОЛОНКИ НЕ БЫЛО>` | `albumartist`/`genre` в 38-й отсутствовали как колонки |
| `<N разных>` | в папке N старых значений, новое — одно |
| Секция `ТОЛЬКО-В-38` | служебный список, **НЕ правки** |
**Факт прогона:** 7861 (NEW) vs 7905 (OLD) → 2856 строк = `ПАПКА 1501` + `ТРЕК 1267` +
`ТОЛЬКО-В-38 85` + заголовок. Всего правок трек-уровня — **19288** (контроль сходится,
потерь нет: `covered + file_lines == sum(field_counts)`).
### 🔴 ЧЕГО В ФОРМАТЕ БЫТЬ НЕ ДОЛЖНО
- ❌ своих колонок (`was`/`now`, `class`, `in_7649`, `rule_target`) — не изобретать;
- ❌ базы сравнения «БД Navidrome» или «теги на диске» — **только две версии плана**;
- ❌ построчного вывода там, где значение одинаково у всей папки — **обязано схлопываться**.
> 🔑 **Почему БД/диск — плохая база для дифа:** даёт **ложные срабатывания** на файлах,
> обновлённых после последнего скана (пример: `Птаха - Красивые, богатые (2009)`, где `album`
> уже поправлен на диске, а БД отстала). Дифф «план vs план» от диска и БД **не зависит вообще**.
### 🔴 ПИТФОЛЛ: генератор пишет В ТОТ ЖЕ ПУТЬ
```python
OUT = f"{BASE}/DIFF-new-vs-38-v2.csv" # перезаписывает! backup не делает
```
**Запуск генератора без апрува = перезапись файла Alex.** В сессии 27 это произошло
(mtime 17:41 → 19:41); ущерба не было только потому, что вход `APPLY-PLAN.csv` не менялся
и **md5 `7bc222a1087787c390026d624af932f3` совпал** (2854 строки).
> **ПРАВИЛО:** перед запуском любого генератора дифа — либо `cp -p` в `.bak-<timestamp>-NEXT`,
> либо явный апрув Alex. Проверять результат **по md5**, а не по mtime.
### 📎 «Вычистка полей от спама» — что это значит в каноне
Отдельного шага вычистки **нет**; мусор обнажается сравнением с 38-й волной:
пустое ≠ пустое не пишется; появившаяся колонка помечается `<КОЛОНКИ НЕ БЫЛО>`; дубли схлопываются.
**Факт по канонному диффу:** `old_38` с мусором **0**, `new_apply_plan` с мусором **6**
(и это правки `Pushnoy.ru`), пустой `new_apply_plan` **13** (удаление тега, в основном `track`).
### 🔴 НОВЫЙ КЛАСС ДЕФЕКТА: ИМЯ САЙТА В `album` (`Pushnoy.ru`, 6 строк)
```
z Другое…/Pushnoy.ru/2005-2006 cur '2005-2006' -> new 'Pushnoy.ru' ← адрес сайта в album
z Другое…/Pushnoy.ru/старые cur 'старые' -> new 'Pushnoy.ru'
```
**Причина:** корень `Pushnoy.ru` **не является артистом** (артист — `Александр Пушной`) →
правило «корень = папка артиста» не сработало → генератор откатился на **предка** вместо
листовой подпапки. Верные значения — имена листовых подпапок, и они **уже были в `cur_album`**.
### 🛠 ИНСТРУМЕНТЫ
| Файл | Назначение |
|---|---|
| `~/Downloads/music-tags/diff_new_vs_38_v2.py` | канонный генератор дифа (⚠️ перезаписывает OUT) |
| `/tmp/check_canon_diff.py` | поиск мусора в `old_38`/`new_apply_plan`, пустых значений |
| `/tmp/find_in_canon.py` | точечный поиск папок/файлов в канонном дифе |
| `/tmp/ptaha_disk_go.py` | ✅ чтение `TALB` **контейнером** `tagwriter:latest` (mutagen) |
> ⚠️ **mutagen на хосте NAS НЕТ** — читать теги с диска только внутри контейнера
> `tagwriter:latest` (монтирование `${MUSIC}:/music:ro`).
## Связанные заметки
- [[family/how-to/jellyfin-config]] — живой инстанс Jellyfin на Taiga, план добавления Music-библиотеки