[2026-09-28] 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-28 00:11:55 +06:00
1 parent 3466ad094d
commit b718a09e95
2 files changed
+157 -10

No files matched your search

@@ -4,7 +4,7 @@ created: '2026-09-27'
updated: '2026-09-27'
type: plan
namespace: personal
status: ДИФФ-ОТ-БД-СВЕРЕН / СБОРЩИК-v2-НЕ-НАПИСАН (сборники вне дифа) / ПРОГОН-НЕ-ЗАПУСКАТЬ-БЕЗ-ПОДТВЕРЖДЕНИЯ
status: ДИФФ-v6-СОБРАН-ПОЛНЫЙ-ПРОХОД-ПО-СБОРНИКАМ / СБОРЩИК-НАПИСАН / DRY-RUN-НЕ-ЗАПУЩЕН / ПРОГОН-НЕ-ЗАПУСКАТЬ-БЕЗ-ПОДТВЕРЖДЕНИЯ
tags:
- music
- metadata
@@ -35,11 +35,95 @@ related:
**Что делаем:** привести ID3-теги библиотеки `/mnt/RED_2TB/storage/Music` (7861 файл)
в порядок, чтобы Navidrome показывал правильные альбомы/исполнителей/жанры.
**Главный артефакт на сейчас (27 сен, сессия ~36):**
**Главный артефакт на сейчас (27 сен, сессия 38):**
```
⚠️ ДИФФ ОТ БАЗЫ ГОТОВ, СВЕРЕН С ПЛАНОМ. ПРОГОН НЕ ЗАПУСКАТЬ БЕЗ ПОДТВЕРЖДЕНИЯ ALEX.
⚠️ ДИФФ v6 СОБРАН — ПОЛНЫЙ ПРОХОД ПО СБОРНИКАМ. ПРОГОН НЕ ЗАПУСКАТЬ БЕЗ ПОДТВЕРЖДЕНИЯ ALEX.
ДИФФ: ~/Downloads/music-tags/DIFF-v6.csv
102 строки · 553 правки · 282 файла
md5 b2b68bf9f3a0ca7645cb0ef90ec95f30
по полям: album 183 · artist 155 · albumartist 157 · track 58
сортировка: по АЛФАВИТУ field (album → albumartist → artist → track)
источник цели: БД Navidrome (то, что РЕАЛЬНО в тегах), НЕ канон
План: ~/Downloads/music-tags/apply-plan-v6.csv (7861 строка, md5 4480cc0d1ba81db6380b935a459e7eac)
Сборщик: ~/Downloads/music-tags/build_diff_v6.py ← 8 правил, заменил build_diff_from_db.py
Канон: ~/Downloads/music-tags/APPLY-PLAN.csv (2 882 935 B — эталон ручных правок, НЕ ПЕРЕЗАПИСЫВАТЬ)
Бэкапы: DIFF-v6.csv.bak-20260927-* · DIFF-db-to-fix.csv.bak-20260927-234901
ЧЕМ v6 ОТЛИЧАЕТСЯ ОТ v5 (DIFF-db-to-fix.csv):
album 60 → 183 файлов (+123: сборники, которых v5 не видел)
artist 154 → 155 (+1: Т9)
albumartist 157 → 157 (=)
track 58 → 58 (=)
```
🔴 **ГЛАВНЫЙ УРОК СЕССИИ 38: СБОРЩИК ПРАВИЛ ПО СОВПАДЕНИЮ, А НЕ ПО ПАПКЕ.**
`build_diff_from_db.py` содержал **три хардкод-префикса** (`!Рэп/Трофим/`, `!Рэп/Птаха…`,
`Тема дороги.mp3`) и **не знал правила сборников вообще**. Поэтому в дифф v5 не попали:
`!Retro` (46), `!Rock&Folk/!rock_o_pop` (24), `!Pop, Club, Любэ/!ZabuGor` (15),
`!Классика` (5), `9999 - Разное/*` (30), 3 корневых файла = **123 файла**.
Alex: «ты сказочный долбоёб. у меня даже слов нет на этом моменте».
🔑 **ПРАВИЛО: прежде чем отдавать дифф — сверить его не с самим собой, а с постановкой задачи.**
Я сверил `verify_v5_vs_diff.py` (дифф↔план, сходится 1:1) и объявил «готово» — но обе стороны
сравнения были построены на одном и том же кривом сборщике. **Сверка сама с собой ничего не доказывает.**
🔴 **ФАКТ: ПРОХОД v3 БЫЛ ТОЧЕЧНЫЙ, НЕ ПОЛНЫЙ — 18 папок из 23 правились по 1-3 файла.**
Правило в v3-скрипте срабатывало только при `album == title` или `album == имя файла`.
Файлы, у которых `album` был **чужим альбомом** (не равен ни title, ни файлу), проскакивали.
```
!Pop, Club, Любэ/!ZabuGor правилось 1 из 15 !Retro/Забугр 3 из 32
!Pop, Club, Любэ/Green Apelsin правилось 1 из 38 !Rock&Folk/!rock_o_pop 2 из 57
!Pop, Club, Любэ/Алексин правилось 1 из 14 !Rock&Folk/Ария, Кипелов 3 из 12
!Рэп/Птаха - Красивые… 1 из 8
ПОЛНЫХ проходов всего 6: Little Big (1/1) · Руки вверх (2/2) · Хабиб (1/1)
· Юрий Антонов (1/1) · Юрий Никулин (3/3) · Серьга (1/1)
```
🔑 **ДИАГНОСТИКА «проход был полным?»: `collections.Counter(cur_album)` по папке.**
Много уникальных значений = прохода не было. `!Retro`: **62 уникальных album на 236 файлов**.
Скрипты: `full_check_sborniki.py`, `why_resurface.py`.
✅ **ПРАВИЛА СБОРЩИКА v6 (`build_diff_v6.py`) — 8 штук, В КОДЕ:**
```
1. Папки '!*' → album = basename БЕЗ ведущих '!'
albumartist НЕ ТРОГАЕМ (Various Artists как есть)
artist НЕ ТРОГАЕМ
2. Папки 'Разное' → album = имя папки-владельца (НЕ имя файла)
9999 - Разное/X albumartist = владелец категории ('Агата Кристи', уже так)
3. Трофим album: срез префикса 'NN ' (только 01-04 Аристократия помойки)
albumartist 'Трофим' → 'Сергей Трофимов'
artist 'Трофим' → 'Сергей Трофимов'
фиты 'С.Трофимов,группа X' → 'Сергей Трофимов и группа «X»'
track: пусто → номер из имени файла (#N_MM_)
4. Птаха album 'Птаха - Красивые, богатые (2009)' → 'Красивые, богатые'
5. Ленинград/Тема дороги album 'саунд треки к фильму' → 'Ленинград'; artist 'Бумер' → 'Ленинград'
6. Адресно Radio !Pop, Club, Любэ/detskiy_hor_benassi… → album='Radio'
!Pop, Club, Любэ/!Radio/Stylemasters… → album='Radio'
7. artist НЕ ТРОГАЕМ нигде, кроме п.3 и п.5
8. Т9 - Вдох-Выдох album='Вдох-выдох', artist='Т9' (внешний источник, Discogs 2008)
```
🔑 **ЦЕЛЕВАЯ МОДЕЛЬ СБОРНИКОВ (окончательно, Alex 2026-09-27):**
```
album = имя папки-владельца БЕЗ '!' ← ЕДИНСТВЕННОЕ, ЧТО МЕНЯЕМ в сборниках
albumartist = 'Various Artists' (сборники) / 'Агата Кристи' (9999 - Разное)
artist = реальный исполнитель трека ← НЕ ТРОГАЕМ НИКОГДА
```
Alex дословно: «**АЛЬБОМ БЛЯДЬ rock_o_pop** не albumartist блядь! для сборников типа
rock_o_pop **artist = 'Various Artists'**!!!». `!` — служебный префикс сортировки, **в тег НЕ пишется
никогда**. Антидефект: в `!ZabuGor` у Marlyn Manson `album='!ZabuGor'` — `!` **попал в тег**.
✅ **ДИФФ v6 СВЕРЕН ПО ПАПКАМ — 16 album-строк, все ожидаемые на месте** (см. таблицу
в [[personal/tech/music-tags-repair-truenas]] § сессия 38).
✅ **ДУБЛИ ТРОФИМА — ПОДТВЕРЖДЕНО УДАЛЕНИЕ (проверка `find` на NAS).**
`!Рэп/Трофим/` **157 файлов** (эталон, живое дерево). Копии `!Radio/z Старое/disk*/3 SHANSON/Трофим`
— **0 живых**, остались только в `backup/` (220) и `backup_album_root_…-229/` (49).
🔑 Команда проверки: `find … -ipath "*Трофим*" -name "*.mp3" -printf "%h\n" | sort | uniq -c`.
**Главный артефакт ПРЕДЫДУЩЕЙ сессии (сессия 37) — АРХИВ:**
```
ДИФФ: ~/Downloads/music-tags/DIFF-db-to-fix.csv
16 857 B · 92 строки с заголовком = 91 ЗАПИСЬ (ПАПКА 26 · ТРЕК 65)
md5 a5f2b910826dcc46474b6e26513f414f
@@ -47,13 +131,9 @@ related:
⚠️ СЧЁТ: 91 запись ≠ 92 строки файла (заголовок) и ≠ 87
(2 файла с ДВОЙНОЙ правкой: Тема дороги album+artist,
Птаха album в одну сторону)
сортировка: по АЛФАВИТУ field (album → albumartist → artist → track)
источник цели: БД Navidrome (то, что РЕАЛЬНО в тегах), НЕ канон
🔴 УСТАРЕЛ: не содержит сборников (123 файла). Использовать DIFF-v6.csv.
План: ~/Downloads/music-tags/apply-plan-v5.csv (7861 строка, md5 d4392b11f143844c590a0a9c4a752208)
меняется 159 файлов · без изменений 7702
по полям: albumartist 157 · artist 154 · album 60 · track 58 · title 0 · genre 0
Сборщик: ~/Downloads/music-tags/build_diff_from_db.py
Канон: ~/Downloads/music-tags/APPLY-PLAN.csv (2 882 935 B — эталон ручных правок, НЕ ПЕРЕЗАПИСЫВАТЬ)
Сборщик: ~/Downloads/music-tags/build_diff_from_db.py ← 🔴 ЗАМЕНЁН на build_diff_v6.py
```
✅ **СВЕРКА ДИФФ ↔ ПЛАН (27 сен, сессия ~36) — СХОДИТСЯ.** Скрипт
+68 -1
View File
@@ -100,7 +100,74 @@ related:
> Файлы в сборниках (`disk/`, `disk_v2/`) **удалять нельзя** — указание Alex:
> «они корректно живут в сборниках». Удаляем ТОЛЬКО дубли альбомов.
> ## 🔴 АКТУАЛЬНОЕ СОСТОЯНИЕ (2026-09-27, сессия ~36) — ЧИТАЙ ЭТО ПЕРВЫМ
> ## 🔴 АКТУАЛЬНОЕ СОСТОЯНИЕ (2026-09-27, сессия 38) — ЧИТАЙ ЭТО ПЕРВЫМ
>
> 🔴🔴 **`apply` НЕ ЗАПУСКАТЬ БЕЗ ПРЯМОГО ПОДТВЕРЖДЕНИЯ ALEX.** Дословно: «**без подтверждения
> никакого apply блядь**». Дифф и dry-run — можно, запись — только «go».
>
> ✅ **ДИФФ v6 СОБРАН — ПОЛНЫЙ ПРОХОД ПО СБОРНИКАМ (главный результат сессии).**
> ```
> ~/Downloads/music-tags/DIFF-v6.csv
> 102 строки · 553 правки · 282 файла · md5 b2b68bf9f3a0ca7645cb0ef90ec95f30
> план: apply-plan-v6.csv — 7861 стр, md5 4480cc0d1ba81db6380b935a459e7eac
> ```
> | Поле | Файлов | Было в v5 |
> |---|---|---|
> | `album` | **183** | 60 |
> | `artist` | 155 | 154 |
> | `albumartist` | 157 | 157 |
> | `track` | 58 | 58 |
>
> Прирост `album` = **+123 файла** — ровно те сборники, что v5 не видел.
>
> ✅ **СБОРЩИК НАПИСАН: `~/Downloads/music-tags/build_diff_v6.py`** (заменил `build_diff_from_db.py`).
> Реализует 8 правил, читает локальную копию БД `~/Downloads/navidrome-db/navidrome-after-v3.db`.
> 🔑 **Правила сборников теперь В КОДЕ, а не в хардкод-списке из 3 префиксов.**
>
> ✅ **СВЕРКА `DIFF-v6.csv` ПО ПАПКАМ — 16 album-строк:**
> ```
> !Retro 32 разных → 'Retro'
> !Rock&Folk/!rock_o_pop 16 разных → 'rock_o_pop'
> !Pop, Club, Любэ/!ZabuGor 8 разных → 'ZabuGor'
> !Классика 5 разных → 'Классика'
> 9999 - Разное/{Кавер-версии,Неизданное,Проекты} → имя вложенной папки (30 файлов)
> !Pop, Club, Любэ/detskiy_hor_benassi… → 'Radio' (адресно)
> !Pop, Club, Любэ/!Radio/Stylemasters… → 'Radio' (адресно)
> !Рэп/03. Т9 - Вдох-Выдох… → 'Вдох-выдох' + artist 'Т9'
> !Рэп/Птаха - Красивые… → 'Красивые, богатые'
> !Рэп/Трофим/01-04 Аристократия помойки → срез префикса NN_
> z Другое…/Тема дороги.mp3 → 'Ленинград' + artist 'Ленинград'
> ```
>
> 🔴 **Т9 - «Вдох-Выдох» — АЛЬБОМ УСТАНОВЛЕН ПО ВНЕШНЕМУ ИСТОЧНИКУ (Discogs).**
> Файл `!Рэп/03. Т9 - Вдох-Выдох (Ода Нашей Любви).mp3` лежал в корне `!Рэп` с мусорным
> `album='Record Super Chart #1'` и `artist='Вдох-Выдох'` (часть названия песни!).
> Релиз `Т9 — Вдох-Выдох`, CD Album, **2008** (Discogs r3300495).
> **Решение Alex: `album='Вдох-выдох'`, `artist='Т9'`** ✅ подтверждено.
> 🔑 **МЕТОД: реальный альбом одиночного файла ставится по внешнему источнику (Discogs/MusicBrainz),
> НЕ по имени папки.** Иначе в тег уедет `Record Super Chart #1`.
>
> 🔴 **ПРАВИЛО КОРНЕВЫХ ФАЙЛОВ (закрыто):** файл прямо в категории (`!Рэп/x.mp3`,
> `!Pop, Club, Любэ/x.mp3`) → `album` = имя категории БЕЗ `!`. Для `!Radio` внутри —
> `album='Radio'`. Вложенные `!Radio/v 2009-03 mIr.vEsNЫ/…` **НЕ ТРОГАЕМ** (Alex: их
> значение `2009-03 mIr.vEsNЫ` верное — это дата-папка релиза, не дефект).
> ⚠️ **Питфолл: я спрашивал про `Record Super Chart #1` как про «папку» — такой ПАПКИ НЕТ.**
> Это значение поля `album`. **Прежде чем спрашивать — читать `os.path.dirname`, а не гадать.**
>
> ✅ **ДУБЛИ ТРОФИМА ПОДТВЕРЖДЕНЫ УДАЛЁННЫМИ (проверено `find` на NAS):**
> ```
> !Рэп/Трофим/ 157 файлов ← ЭТАЛОН (живое дерево)
> backup/!Рэп/Трофим/ 220 файлов ← бэкап
> backup_album_root_…-229/…/3 SHANSON/Трофим 49 файлов ← бэкап
> ```
> Живых копий `!Radio/z Старое/disk*/3 SHANSON/Трофим` — **0**. Удаление 50 файлов выполнено ✅.
> 🔑 **Проверка: `find … -ipath "*Трофим*" -name "*.mp3" -printf "%h\n" | sort | uniq -c`.**
> Префикс `backup` в пути = бэкап; живое дерево всегда без него.
>
> ⚠️ **ОСТАЛОСЬ (перед apply):** **dry-run v6 не запущен.** Плюс висят решения Alex по
> `10 Ностальгия`/`Боже, какой пустяк` и `Sbornik_Novij_Rok` genre.
> ## 🔴 АКТУАЛЬНОЕ СОСТОЯНИЕ (2026-09-27, сессия 37) — АРХИВ
>
> 🔴🔴 **`apply` НЕ ЗАПУСКАТЬ БЕЗ ПРЯМОГО ПОДТВЕРЖДЕНИЯ ALEX.** Дословно 27 сен:
> «**без подтверждения никакого apply блядь**». Дифф и dry-run — можно, запись — только «go».