From fadfb9f4d2ad8a66e2f2bdbf5c5c34590911d8f3 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Mon, 28 Sep 2026 01:17:45 +0600 Subject: [PATCH] [2026-09-28] eagle: personal/tech/music-tags-repair-truenas.md --- personal/tech/music-tags-repair-truenas.md | 53 ++++++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/personal/tech/music-tags-repair-truenas.md b/personal/tech/music-tags-repair-truenas.md index efaa5d78..30eed3d5 100755 --- a/personal/tech/music-tags-repair-truenas.md +++ b/personal/tech/music-tags-repair-truenas.md @@ -9,7 +9,8 @@ diff_v6_md5: a2a777f65eb1b6c0729f16bbafe0acc6 diff_v6_status: OK — 394 файла / 398 правок, покрытие ПОЛНОЕ (папок с разным album после дифа: 0; путей вне БД: 0). НЕ ПРИМЕНЁН, dry-run не запускался, апрува нет. diff_v6_last_good: DIFF-v6.csv (394/398); история бэкапов в блоке «СЕССИЯ 28» last_session: 28 -blocker: апрув Alex на DIFF-v6.csv (394/398) — без него dry-run/apply не запускаются. Плюс не выполнено согласованное удаление папки «Король и шут-1». +blocker: НЕТ apply-plan под DIFF-v6.csv (дифф собран из БД, не из плана). apply_tags_v2.py читает только /app/data/apply-plan.csv (14 колонок, путь с /storage/Music/). Нужен сборщик build_applyplan_v6.py в ~/Downloads/music-tags/ и план apply-plan-v7.csv (7807 строк). Затем апрув Alex → dry-run → apply. +done_session28: удалена папка !Rock&Folk/Король и Шут/Король и шут-1 (17 файлов, 59 МБ); база navidrome.db НЕ тронута. tags: - music - jellyfin @@ -831,7 +832,7 @@ related: > Это **чужие сборники**, откуда файлы выдраны, а не релизы артистов. Все — ремиксы/версии. > Решение: `album` = имя папки (`Global Deejays`, `The Prodigy`), как и везде. > -> ### 🗑 УДАЛЕНИЕ `Король и шут-1` — СОГЛАСОВАНО, НЕ ВЫПОЛНЕНО +> ### 🗑 УДАЛЕНИЕ `Король и шут-1` — ✅ ВЫПОЛНЕНО > > `!Rock&Folk/Король и Шут/Король и шут` и `…/Король и шут-1` — **физические дубли**. > Замер из БД (`/tmp/dup_korol.py`), не по именам, а по size: @@ -839,10 +840,13 @@ related: > 17 файлов в каждой, имена совпадают ПОЛНОСТЬЮ (set(k1) == set(k2) → True) > одинаковый size: 17 | разный size: 0 bit_rate 160 у всех, duration совпадает > ``` +> ```bash +> ssh -i ~/.ssh/id_rsa truenas_admin@mallexxx.duckdns.org \ +> 'rm -rf "/mnt/RED_2TB/storage/Music/!Rock&Folk/Король и Шут/Король и шут-1"' > ``` -> удалить: /mnt/RED_2TB/storage/Music/!Rock&Folk/Король и Шут/Король и шут-1/ (~57 МБ) -> остаётся: /mnt/RED_2TB/storage/Music/!Rock&Folk/Король и Шут/Король и шут/ -> ``` +> Результат: `УДАЛЕНО`, в родительской папке остался только `Король и шут` (17 файлов). +> Освобождено ~59 МБ. База `navidrome.db` НЕ тронута (27303936 B, 27 сен 11:50) — +> по прямому требованию Alex «да. не смей грохать базу только». > 🔑 **Удаление без бэкапа — по прямому указанию Alex. `rm -rf` подтверждать отдельно.** > > ### ✅ ПРОВЕРЕНО И НЕ ДЕФЕКТ (не трогать) @@ -883,11 +887,42 @@ related: > /tmp/sk48.py вывод папок без доминанты > /tmp/restore_135.py восстановление базы 135 > ``` +> ### 🔴🔴 ДИФФ ≠ ПЛАН: `apply-plan` ПО ЭТОМУ ДИФФУ НЕ СУЩЕСТВУЕТ +> +> **Alex: «у нас apply делается как? по apply-plan, так в доке записано?» → «где apply plan +> по которому ты строил diff-v6? как файл называется?»** +> +> Честный ответ: **никак.** `DIFF-v6.csv` построен **не из плана**, а из **базы Navidrome**: +> ``` +> источник дифа: ~/Downloads/music-tags/navidrome-fresh.db (7808 треков) +> + ~/Downloads/music-tags/DIFF-v6.csv.prev-0055 (предыдущий срез 40/44) +> сборщики: /tmp/restore_135.py · add_outliers.py · add_rest42.py · add_skip9.py +> ``` +> ⚠️ **`apply_tags_v2.py` читает план, а не дифф.** `CSV_IN` захардкожен = +> `/app/data/apply-plan.csv`; формат плана — 14 колонок +> `path,cur_*,new_*,changed`, путь **с префиксом `/storage/Music/`**. +> `DIFF-v6.csv` — это 6 колонок `scope,folder,path,field,old,new`, путь **БЕЗ префикса**. +> **Подать дифф в apply нельзя — dry-run уйдёт в MISSING.** +> +> ### ✅ ПЛАН v6 УЖЕ СОВПАДАЕТ С ДИФФОМ (проверено замером) +> ``` +> ~/Downloads/music-tags/apply-plan-v6.csv 7808 строк, 2420993 B, 14 колонок +> правок дифа, чей путь есть в плане: 397 из 398 ← путь снят/добавлен префиксом +> путей дифа нет в БД: 0 +> ``` +> Отличается **1 путь**: `!Rock&Folk/Король и Шут/Король и шут-1/…` (папка удалена) — +> его надо вычистить, получится **7807 строк**. +> +> **Решение Alex (в конце сессии):** сборщик плана восстановить в папке проекта — +> `~/Downloads/music-tags/build_applyplan_v6.py`. Прежний сборщик жил в `/tmp` и **потерян**, +> что прямо нарушает правило доки (стр. 57: «Сборщик живёт в папке проекта, НЕ в /tmp»). +> > ⏳ **NEXT (в порядке):** -> 1. Удалить `Король и шут-1` (согласовано, жду «да» на `rm -rf`). -> 2. **Апрув Alex на DIFF-v6.csv 394/398** — без него ничего не запускается. -> 3. Dry-run на NAS → сверить число с 398 правками. -> 4. Приёмка с диска → пересбор БД Navidrome (снос согласовывать ОТДЕЛЬНО). +> 1. Восстановить `build_applyplan_v6.py` в `~/Downloads/music-tags/` → собрать +> `apply-plan-v7.csv` (7807 строк, `new_*` из `DIFF-v6.csv`, префикс `/storage/Music/`). +> 2. **Апрув Alex на DIFF-v6.csv 394/398 + новый план** — без него ничего не запускается. +> 3. Dry-run на NAS → число должно совпасть с 398 правками. +> 4. Apply → приёмка read-back с диска → пересбор БД Navidrome (снос согласовывать ОТДЕЛЬНО). > 5. Досмотреть 53 папки-одиночки (единственный непройденный срез). > > ---