From 9b4f8223860ad041f7f86d71425ea7b49cbf8c1e Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Sun, 27 Sep 2026 15:25:03 +0600 Subject: [PATCH] [2026-09-27] eagle: personal/plans/music-artist-albumartist-repair.md --- .../plans/music-artist-albumartist-repair.md | 187 +++++++++++++----- 1 file changed, 143 insertions(+), 44 deletions(-) diff --git a/personal/plans/music-artist-albumartist-repair.md b/personal/plans/music-artist-albumartist-repair.md index b1c14a3f..2f05ee1c 100755 --- a/personal/plans/music-artist-albumartist-repair.md +++ b/personal/plans/music-artist-albumartist-repair.md @@ -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 ` | RC: выгрузить секцию диффа по полю для ручной оценки | +| `rc_*_check.py` | RC: проверки аномалий `aa`/`genre`/`track`/`artist` | +| `verify_track.py` | верификация `new_track` (0 сентинелов, 0 `yes`) | | `scan_junk_album.py` | скан мусорных значений `new_album` |