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

This commit is contained in:
Alexey Martemyanov committed 2026-09-27 15:25:03 +06:00
1 parent b959935ff5
commit 9b4f822386
1 file changed
+143 -44
+143 -44
View File
@@ -4,7 +4,7 @@ created: '2026-09-27'
updated: '2026-09-27'
type: plan
namespace: personal
status: session15-root-files-one-album-rule-78-rows
status: RC-complete-9-defects-found-pending-fix
tags:
- music
- metadata
@@ -19,28 +19,108 @@ related:
- '[[personal/tech/music-tags-repair-truenas]]'
- '[[personal/plans/tagwriter-container]]'
- '[[family/how-to/navidrome-truenas-android]]'
---
status: RC-complete-9-defects-found-pending-fix
# Music `artist` + `albumartist` Repair — правила Alex и ход работ
## 🟢 АКТУАЛЬНО НА КОНЕЦ СЕССИИ 15 (2026-09-27) — читать это первым
## 🟢 АКТУАЛЬНО НА КОНЕЦ СЕССИИ 16 (2026-09-27) — читать это первым
> ```
> APPLY-PLAN.csv 7861 строка md5 bd14e6c64a93b422bbdfdaa554dea0c9
> DIFF-new-vs-38.csv (перегенерировать — см. «Что делать дальше»)
> APPLY-PLAN.csv 7861 строка md5 70f67d0fd625f9198a88aef986d7a9be
> DIFF-new-vs-38.csv 2843 строки md5 68439443ecba9d93372ce9c4ee4a9515
> tag-fix-plan.csv 7861 строка md5 203726ebfd2814e2328636df31337238 (НЕ ПРАВИТЬ)
> Снапшот RC: ~/Downloads/music-tags/milestones/RC-20260927/
> ```
>
> ### 🔴 ГЛАВНОЕ ПРАВИЛО СЕССИИ 15 — КОРЕНЬ АРТИСТА = ОДИН АЛЬБОМ
> **Статус: RC (release candidate). Проведён ручной проход всего диффа — найдено 9 дефектов,
> ждут правки. Боевой прогон не запущен.**
>
> Alex прямым текстом:
> > «Муммий Тролль, Агата, Ария, Rammstein, Жуки, Князь, Benassi, банд эрос — то что в корне
> > лежит мы **считаем одним альбомом**. И `albumartist` соответственно **титульного исполнителя**
> > ставим. **не надо ничего `cur` брать!** редактируешь блядь csv!»
> ## 🔴 ГЛАВНЫЕ ПРАВИЛА (подтверждены Alex дословно)
>
> | Правило | Текст Alex / факт |
> |---|---|
> | **Корень артиста = ОДИН альбом** | «Муммий Тролль, Агата, Ария, Rammstein, Жуки, Князь, Benassi, банд эрос — то что в корне лежит мы **считаем одним альбомом**. И `albumartist` соответственно **титульного исполнителя** ставим.» |
> | **Никаких `cur_*`** | «не надо ничего `cur` брать! **редактируешь блядь csv**!» |
> | **`Various Artists`** | только при РАЗНЫХ исполнителях в настоящем сборнике (проверено: 0 нарушений / 1229 файлов) |
> | **Не выдумывать** | «нет, не надо блядь выдумывать. делай че я говорю» |
> | **`album` ≠ название песни** | запрещено (`Шалавы`, `Песенка разбойников`) |
> | **Склейка `Артист - Трек` в album/aa** | запрещена |
> | **Порядок приёмки** | коммит ДО → правка → **ПРОВЕРКА АЛЕКСОМ** → коммит ПОСЛЕ. «Мой read back» ≠ «работает» |
> | **«Готово» = факт** | вывод `grep -c` / скрипта по САМОМУ файлу, не рассуждение о коде |
>
> ## ✅ СДЕЛАНО В СЕССИИ 16 (после сессии 15)
>
> | # | Класс | Строк | Итог |
> |---|---:|---:|---|
> | 1 | `album`: мусорные значения (`Non spécifié`, `NULL`, `no title`, `Album`, `NoTitLe`, `New`, `mix`, `2005`, `2007`, `Неизвестное название`, `melody.az`) | 20 | → имя корня / `Pushnoy.ru` |
> | 2 | `track`: сентинелы-плейсхолдеры `99`/`51`/`46`/`204` | 9 | → пусто |
> | 3 | `track`: `236` (счётчик скачивания теггера `muzmo.ru`, `cur_album='[muzmo.ru]'`) | 11 | → пусто |
> | 4 | `track`: `238` в `Красная Плесень` (один номер на все альбомы) | 56 | → номер из имени файла (`#3_02-` → `2`) |
> | 5 | `track`: `117` в `Король и Шут` (один номер на 4 папки) | 34 | → пусто (номера нет нигде) |
> | 6 | 🐛 **мой баг**: запись `'yes'` в `new_track` (индекс 14 вместо 15 = `changed`) | 20 | восстановлено из `cur_track` |
> | 7 | `track >= 100` вне сборников: годы (`1988`, `2009`), сквозные номера `!Radio` (`237`, `2638`, `207`) | 80 | → пусто |
> | 8 | Корни артистов = один альбом (7 корней) | 78 | `album`+`aa` = имя корня |
> | 9 | `Муммий Тролль` → каноническое `Мумий Тролль` (папка с опечаткой) | 13 | ✅ **Alex ответил: `Мумий Тролль`** |
> | 10 | `!Рэп/Eminem,50cent`: `aa='Various Artists'` → artist файла | 6 | `Eminem`, `50 Cent` |
> | 11 | Дифф: удалена дублирующая служебная секция `НЕТ-В-38` (41 пустая строка) | — | вводила в заблуждение |
>
> ### ✅ РЕШЕНО АХИЛЛЕСОВО: `Муммий Тролль`
> Папка названа с опечаткой (две «м»). Alex выбрал **каноническое написание группы `Мумий Тролль`**.
> Реализация — `OVERRIDE = {"Муммий Тролль": "Мумий Тролль"}` в `fix_root_album.py`.
>
> ## 📋 РУЧНОЙ ПРОХОД ДИФФА (RC) — НАЙДЕНО 9 ДЕФЕКТОВ, ЖДУТ ПРАВКИ
>
> Проход по всем полям: `album` (143) · `albumartist` (642) · `artist` (134) · `genre` (911) ·
> `title` (42) · `track` (883).
>
> | # | Поле | Дефект | Строк | Фикс |
> |---|---:|---|---:|---|
> | 1 | `album` | `'старые'` / `'misc'` — имя подпапки-мусорки | 2 | `Старое`, `Rammstein` |
> | 2 | `album` | = название песни (`Шалавы`, `Песенка разбойников`, `Это любовь`) | 3 | реальный альбом / убрать |
> | 3 | `album` | `'Сосни попса'` на весь корень `z Другое, Enigma, Ленинград` (там 20+ артистов) | 1 | по артистам |
> | 4 | `album` | `'Infected Mushroom - Compilations Tracks'` — склейка «Артист - Трек» | 1 | убрать склейку |
> | 5 | `album` | `Pushnoy.ru` / `Pushnoy.ru NEW` / `2007` / `старые` — разнобой в одной ветке | 3 папки | единый `Pushnoy.ru` |
> | 6 | `albumartist` | `aa='Сказки'` — **категория** вместо артиста (у файлов есть свой `artist`) | 248 | `aa` = `artist` файла |
> | 7 | `artist` | `'11 Track 11'` (`cur_artist` битый) | 1 | `Josh Wink` (из имени файла) |
> | 8 | `artist` | `'Простоквашено'` — опечатка | 2 | `Простоквашино` |
> | 9 | `artist` | `'Би-2 + Агата кристи'` — строчная «к» | 2 | `Агата Кристи` |
>
> ### ✅ ПРОВЕРЕНО И ПРИЗНАНО КОРРЕКТНЫМ (НЕ трогать)
>
> | Что | Объём | Вывод |
> |---|---:|---|
> | `genre` | 911 | все значения осмысленны; `Сказки`(248)/`Детские`(322)/`Бардовская песня`(277)/`Game`(74)/`Humour`(7) — **ложная тревога**, это реальные жанры |
> | `track` | 883 | 4+ знака — **0**; форматы: 753 число 1-3 знака · 117 `N/M` (двухдиски) · 13 пусто — **аномалий нет** |
> | `track >= 100` | 158 | остались только `Sbornik_Novij_Rok` (101, номера 100..200) и `Детский хит` (57) — у всех номер уникален и из имени файла |
> | `aa='Various Artists'` | 1229 / 45 папок | нарушений правила — **0** |
> | `aa='Детские песни'` | 322 | осознанная заглушка (187 файлов имеют `artist='Детские песни'`) |
> | `Гладков` | 18 | `Григорий` и `Геннадий` — **разные композиторы**, оба верны |
> | `НЕТ В 38-м` | 96 | реальные правки с непустым `new_apply_plan`; маркер `old_38` = «файла не было в 38-м плане», данные применяются |
>
> ## 🔴 МЕТОД-УРОКИ СЕССИИ 15–16: НЕ ИЗОБРЕТАТЬ ДЕФЕКТЫ, ЧИТАТЬ ФАКТЫ
>
> Alex многократно ловил на преждевременных выводах:
> 1. Объявил «нечего исправлять» по Агате — на деле **72 нарушения `album` + 29 `albumartist`**.
> 2. Предположил, что `117`/`099` в `Sbornik_Novij_Rok` — «порядковые номера сборников» и
> обнулил их. **Неверно:** у 196/200 файлов папки номер в том же формате → это **реальный
> номер трека**. Откат: `fix_track_restore.py`, 8 строк восстановлено.
> 3. Детектор `check_root_files.py` дал 420 «нарушений», из них **413 — ложные** (обычные
> сборники `Various Artists` с разными артистами). Реальных — 7.
> 4. Объявил `album='Агата Кристи'` дефектом — на деле верный fallback (в тегах валидного альбома нет).
> 5. Объявил дефектом `genre='Сказки'`/`'Детские'`/`'Бардовская песня'` — на деле реальные жанры.
>
> **Следствие:** перед «исправлением» класса — проверить его на **соседних файлах** И на отсутствие
> лучшего источника данных. **«Нашёл дефект» без проверки фактов = ложная тревога, которая стоит
> сессию времени.**
>
> **Питфолл `execute_code`:** падает с `No module named 'psutil'` → писать скрипт в файл и запускать
> через `terminal`. Heredoc через `terminal` блокируется апрувом → **только файл-скрипт**.
>
> ──
>
> | Поле | Значение для файла ПРЯМО в корне артиста |
> |---|---|
> | `album` | **имя корня** (= имя папки-артиста как есть, включая двойную «мм»: `Муммий Тролль`) |
> | `album` | **имя корня** (= имя папки-артиста; исключение — папка с опечаткой `Муммий Тролль` → каноническое `Мумий Тролль`) |
> | `albumartist` | **имя корня** (титульный исполнитель) |
> | `cur_album` / `cur_artist` | **НЕ ИСПОЛЬЗОВАТЬ ВООБЩЕ** — теги этих файлов мусорные (см. ниже) |
>
@@ -72,15 +152,13 @@ related:
> | `Банд Эрос` | 7 | `Коламбия Пикчерз не Представляет`×2, `Russian R'n'B vol.1` → `Банд Эрос` | `Банд'Эрос`×6, `VIP77` → `Банд Эрос` |
> | `Ария` | 0 | — (в корне нет файлов) | — |
>
> ### ⏳ ОТКРЫТО: `Муммий Тролль` — 23 строки, вопрос задан, ответа НЕТ
> ### ✅ РЕШЕНО В СЕССИИ 16: `Муммий Тролль` — 13 строк
>
> Папка называется **`Муммий Тролль`** (две «м»), а в файлах `albumartist='Мумий Тролль'`
> (одна «м» — правильное написание группы). Вопрос Alex: ставить как в папке или правильное
> написание? **НЕ ПРАВИТЬ, пока Alex не ответит.**
> ```
> album: 7× '(Муммий Тролль)', 1× 'Музыка.ру 5', 1× 'Other' (9 нарушений)
> albumartist: 13× 'Мумий Тролль' (13 нарушений)
> ```
> Папка называется **`Муммий Тролль`** (две «м» — опечатка), правильно: `Мумий Тролль`.
> **Alex выбрал каноническое написание** — ставим `Мумий Тролль` и в `album`, и в `albumartist`.
> Реализовано `OVERRIDE = {"Муммий Тролль": "Мумий Тролль"}` в `fix_root_album.py`.
> Итог: 13 строк записаны, проверено перечитыванием (`album` и `aa` = `Мумий Тролль` у всех 13).
> На момент открытия вопроса было 22 нарушения (9 `album` + 13 `albumartist`), все закрыты.
>
> ### 🔴 МЕТОД-УРОК СЕССИИ 15: НЕ ИЗОБРЕТАТЬ ДЕФЕКТЫ, ЧИТАТЬ ФАКТЫ
>
@@ -490,40 +568,61 @@ Alex указал на `Алиса в Стране Чудес (Диск2)/04` =
по mp3 (7861), поэтому эти форматы в него не попали by design.
- `НЕТ-В-38` (41) = есть в новом плане, не было в 38-м.
### 📌 Что делать дальше (порядок приоритета, обновлён в сессии 15)
### 📌 Что делать дальше (порядок приоритета, обновлён в сессии 16 — RC)
0. ✅ **ЗАКРЫТО в сессии 15:** корни артистов = один альбом (78 строк, 7 корней);
класс `Various Artists` проверен (0 нарушений); мусорный `new_album`/`new_track` (сессия 14).
Откат моей ошибки: 8 строк `track` в `Sbornik_Novij_Rok` / `Детский хит` восстановлены.
1. ⏳ **ОТВЕТ ALEX НУЖЕН:** `Муммий Тролль` — 23 строки. `album`/`albumartist` = `Муммий Тролль`
(как папка, две «м») или `Мумий Тролль` (правильное написание группы, одна «м»)?
**НЕ ПРАВИТЬ до ответа.**
2. **Ответить на оставшиеся вопросы по `album`** — особенно #4 (4 разных формата `album`
внутри `!Radio`) и класс «`album` = название песни» (Алексин/Шалавы, Дискотека Авария).
3. **Дожать класс «жанр унаследован от `cur_genre`»** — `Enigma/Sleep` 13 строк `General Folk`
(Enigma = нью-эйдж/эмбиент, не фолк). Тот же корень дефекта, что и 26 исправленных строк.
4. **Остались неразобранными из ручного прохода `album`:** `z Другое, Enigma, Ленинград` →
`Сосни попса`; `detskiy_hor_benassi_satisfaction.mp3` → `Горячие Синглы 2004`;
`Бутусов & Ю-Питер/Девушка По Городу`.
5. **Решить судьбу 51 папки с рваной нумерацией** — но сначала: стоит ли вообще трогать
номера в подборках `!Radio`.
6. 🔴 **ОБЯЗАТЕЛЬНО: перегенерировать `DIFF-new-vs-38.csv`** после правок сессии 15
(`python3 diff_new_vs_38.py > /tmp/log 2>&1`) — **и всегда верифицировать свой скрипт
перечитыванием** (см. метод-урок сессии 15: не изобретать дефекты, читать факты).
7. Применение плана к файлам — **отдельное «go»** от Alex, через `tagwriter:v2`
0. ✅ **ЗАКРЫТО:** корни артистов = один альбом (91 строка, 8 корней вкл. `Мумий Тролль`);
`Various Artists` (0 нарушений); мусорный `album` (20); сентинелы/годы/сквозные `track` (151+80);
`Eminem,50cent` (6); служебная секция `НЕТ-В-38` удалена из диффа.
1. 🔴 **ПРАВИТЬ 9 ДЕФЕКТОВ RC** — полный список в таблице «РУЧНОЙ ПРОХОД ДИФФА» вверху файла:
- `album` = подпапка-мусорка (`старые`, `misc`) — 2
- `album` = название песни (`Шалавы`, `Песенка разбойников`, `Это любовь`) — 3
- `album='Сосни попса'` на весь `z Другое, Enigma, Ленинград` — 1
- `album='Infected Mushroom - Compilations Tracks'` (склейка) — 1
- `Pushnoy.ru`/`Pushnoy.ru NEW`/`2007`/`старые` разнобой — 3 папки
- **`aa='Сказки'` — 248 строк** (крупнейший; `aa` = `artist` файла)
- `artist='11 Track 11'` → `Josh Wink` — 1
- `artist='Простоквашено'` → `Простоквашино` — 2
- `artist='Би-2 + Агата кристи'` → `Агата Кристи` — 2
2. 🔴 **Перегенерировать `DIFF-new-vs-38.csv`** после правок RC:
`python3 diff_new_vs_38.py > /tmp/diff.log 2>&1` — **и всегда верифицировать свой скрипт
перечитыванием** (метод-урок: не изобретать дефекты, читать факты).
3. **Мелкие незакрытые:** `Enigma/Sleep` `General Folk` (не подтвердилось в текущем плане —
`rc_gen_check.py` не нашёл); `detskiy_hor_benassi_satisfaction.mp3` → `Горячие Синглы 2004`
(оставлено как есть).
4. **Судьба 51 папки с рваной нумерацией** — сначала решить, стоит ли трогать номера в `!Radio`.
5. Применение плана к файлам — **отдельное «go»** от Alex, через `tagwriter:v2`
(см. `[[personal/plans/tagwriter-container]]`).
### 🛠 Инструменты сессии 15 (`~/Downloads/music-tags/`)
### 💾 МАЙЛСТОУН RC (`~/Downloads/music-tags/milestones/`)
| Файл | Содержимое |
|---|---|
| `RC-20260927/APPLY-PLAN.csv` | md5 `70f67d0fd625f9198a88aef986d7a9be` |
| `RC-20260927/DIFF-new-vs-38.csv` | md5 `68439443ecba9d93372ce9c4ee4a9515` |
| `APPLY-PLAN-20260927-151314.{csv,md}` | первый майлстоун + опись правок |
**Правило Alex: «сохраняй снапшот csv как майлстоун»** — при каждом закрытии блока работ
копировать `APPLY-PLAN.csv` + `DIFF-new-vs-38.csv` в `milestones/` со штампом времени
и `.md`-описью изменений; **сверять md5 копии с оригиналом**.
### 🛠 Инструменты сессии 15–16 (`~/Downloads/music-tags/`)
| Скрипт | Назначение |
|---|---|
| `fix_root_album.py` | правило «корень артиста = один альбом», 78 строк, dry-run по умолчанию |
| `fix_root_album.py` | правило «корень артиста = один альбом», 91 строка, dry-run по умолчанию, `OVERRIDE` для Муммий→Мумий |
| `check_root_rule.py` | верификация: `album`/`albumartist` == имя корня → 0 нарушений |
| `check_va.py` | проверка класса `Various Artists` (1229 файлов / 45 папок → 0 нарушений) |
| `check_root_files.py` | детектор файлов в корне; ⚠️ даёт много ложных (сборники) |
| `fix_junk_album.py` + `verify_junk_album.py` | мусорный `new_album` (20 строк, сессия 14) |
| `fix_track_v3.py` + `fix_track_rest7.py` + `verify_track.py` | мусорный `new_track` (151 строка) |
| `fix_track_restore.py` | 🔴 откат моей ошибки: 8 реальных номеров треков восстановлены |
| `fix_junk_album.py` + `verify_junk_album.py` | мусорный `new_album` (20 строк, сессия 14–16) |
| `fix_track_v3.py` | сентинелы/восстановление колонок `track` (144 строки) |
| `fix_track_rest7.py` | добивание уцелевших сентинелов (7 строк) |
| `fix_track_restore.py` | откат моей ошибки: реальные номера `Sbornik_Novij_Rok`/`Детский хит` (8 строк) |
| `fix_bigtracks.py` | `track >= 100` вне сборников: годы + сквозные `!Radio` (80 строк) |
| `verify_bigtracks.py` | финальная проверка 100+: уникальность + номер из имени → 0 необоснованных |
| `fix_eminem_aa.py` | `!Рэп/Eminem,50cent`: `aa` → artist файла (6 строк) |
| `rc_dump_field.py <field>` | RC: выгрузить секцию диффа по полю для ручной оценки |
| `rc_*_check.py` | RC: проверки аномалий `aa`/`genre`/`track`/`artist` |
| `verify_track.py` | верификация `new_track` (0 сентинелов, 0 `yes`) |
| `scan_junk_album.py` | скан мусорных значений `new_album` |