diff --git a/personal/plans/music-artist-albumartist-repair.md b/personal/plans/music-artist-albumartist-repair.md index e4ae7870..0f1a2afa 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: session13-collapse-fixed-radio-album-fixed-disk-naming-open +status: session14-junk-album-and-track-cleaned-171-rows tags: - music - metadata @@ -55,7 +55,79 @@ related: > ✅ Класс `A2` **дочищен**: `find_va_misuse.py` → 0, `find_va_author.py` → остались только > 2 защитимые папки (`Блестящие, Фриске`, `Eminem,50cent`). -## 🟢 АКТУАЛЬНО НА КОНЕЦ СЕССИИ 13 (2026-09-27) — читать это первым +## 🟢 АКТУАЛЬНО НА КОНЕЦ СЕССИИ 14 (2026-09-27) — читать это первым +> +> ``` +> APPLY-PLAN.csv 7861 строка md5 f16163f65336afca99b8d8087c6945f5 +> DIFF-new-vs-38.csv 2901 строка md5 0607c1152c8a43028de2d6ac84eb30ba +> tag-fix-plan.csv 7861 строка md5 203726ebfd2814e2328636df31337238 (НЕ ПРАВИТЬ) +> ``` +> +> **Состав диффа:** `ПАПКА` · `ТРЕК` · `НЕТ-В-38` 41 · `ТОЛЬКО-В-38` 85. +> Полнота: `ВСЕГО правок (трек-уровень) 18804 · OK: потерь нет`. +> +> 🔴 **СЕССИЯ 14 — ДВА КЛАССА МУСОРА ВЫЧИЩЕНЫ (171 строка).** +> +> ### Класс 1: мусорный `new_album` — 20 строк +> Корень: план копирует `cur_album` из тега **без фильтра**. Что вычищено: +> +> | Значение в теге | Куда попало | Стало | Источник мусора | +> |---|---|---|---| +> | `Non spécifié`, `NULL` | Benassi Bros (2) | `Benassi Bros` | франц. теггер / строка «NULL» | +> | `2005 ` | Банд Эрос (1) | `Банд Эрос` | только-год в теге | +> | `no title` | Муммий Тролль (1) | `Муммий Тролль` | плейсхолдер теггера | +> | `~melody.az - КняZz - Корсар~` | КняZz (1) | `КняZz` | водяной знак сайта + склейка | +> | ` mix ` | Каста (1) | `Каста` | служебная пометка | +> | `NoTitLe` | НТЛ (1) | `НТЛ` | плейсхолдер | +> | `Album` | Пилот/misc (1) | `Пилот` | плейсхолдер | +> | `New` | Король и Шут (1) | `Король и Шут` | техпапка | +> | `2007` | Pushnoy.ru/2007 (10) | `Pushnoy.ru` | год-подпапка | +> | `Íåèçâåñòíîå íàçâàíèå` | !Детские/Из чего же (1) | `` (пусто) | CP1251→UTF8 битьё | +> +> **Правило целевого значения:** имя корня артиста = последний сегмент `folder`; +> если корень — категория (`!*`) или папка-мусорка (`misc`/`base`/`plux`/`старые`) → +> берём артиста (сегмент после категории). `Pushnoy.ru` — сайт-источник, все подпапки +> (`2007`/`старые`/`NEW`) не альбомы → `Pushnoy.ru`. +> +> Скрипт: `~/Downloads/music-tags/fix_junk_album.py` (dry-run по умолчанию). +> Верификация: `verify_junk_album.py` → **9/9 контрольных точек OK, остатков мусора 0**. +> Бэкап: `APPLY-PLAN.csv.bak-junkfix-*`. +> +> ### Класс 2: мусорный/битый `new_track` — 151 строка +> +> | Значение | строк | Диагноз | Стало | +> |---|---:|---|---| +> | `yes` | 20 | 🔴 **мой баг**: `fix_junk_album.py` писал `data[i][14]="yes"` — индекс 14 = `new_track`, а не `changed` (15) | `cur_track` / пусто | +> | `238` | 56 | `Красная Плесень`: один номер на все альбомы | номер из имени (`#3_02` → `2`) | +> | `117` | 34 | `Король и Шут`: один номер на 4 папки, номера нет нигде | пусто | +> | `236` | 11 | счётчик скачивания теггера **muzmo.ru** (`cur_album='[muzmo.ru]'`) | пусто | +> | `99`, `51`, `46` | 7 | теггер-сентинелы «номера нет» (+ уцелели из-за `continue` после ветки A) | пусто | +> | `204` | 2 | не-трек из имени файла (`204-Infected…`) | пусто | +> | `117/099/051/046` | 4 | порядковый номер сборника из имени | пусто | +> | `1/2/3/46` | 10 | одиночки НТЛ без номера | пусто | +> +> **Сентинелы-плейсхолдеры:** `99 · 51 · 46 · 117 · 238 · 236 · 204 · 0 · 999`. +> **Номер из имени файла** (в порядке приоритета): `^#\d+_(\d{1,2})[-_]` → `^(\d{1,3})[-_ ]\D` +> → `^(\d{1,3}) ` → `^0(\d{2})[_-]` → `^(\d{1,2})[_-]\D`. +> +> Скрипты: `fix_track_v3.py` (основной, 144 правки) + `fix_track_rest7.py` (добить 7 +> пропущенных из-за `continue`). Верификация: `verify_track.py` → **все проверки 0/OK**. +> Бэкапы: `.bak-trackfinal-*`, `.bak-trackfinal2-*`. +> +> ### 🔴 МЕТОД-УРОК СЕССИИ 14: ВЕРИФИЦИРОВАТЬ СВОЙ ЖЕ СКРИПТ ПЕРЕЧИТЫВАНИЕМ, НЕ ЛОГИКОЙ +> Первый прогон отчитался «144 записано» и был **неполон**: `elif` в цикле пропускал +> сентинел-фильтр для строк, восстановленных из `yes`. `verify_track.py` (перечитать файл +> и сравнить с ожиданием) поймал 7 уцелевших. **Без верификации дефект ушёл бы в прод.** +> +> 🔴 **ИНДЕКСЫ КОЛОНОК `APPLY-PLAN.csv` (16 шт.):** +> `0 path · 1 folder · 2 class · 3 cur_title · 4 cur_artist · 5 cur_albumartist · +> 6 cur_album · 7 cur_genre · 8 cur_track · 9 new_title · 10 new_artist · +> 11 new_albumartist · 12 new_album · 13 new_genre · 14 new_track · 15 changed`. +> Всегда ставить `assert (H["new_track"], H["changed"]) == (14, 15)`. +> +> --- + +> ## 🟢 АКТУАЛЬНО НА КОНЕЦ СЕССИИ 13 (2026-09-27) — историческое > > ``` > APPLY-PLAN.csv 7861 строка md5 a6e440511e195668af2cee785e547fce @@ -339,18 +411,24 @@ Alex указал на `Алиса в Стране Чудес (Диск2)/04` = по mp3 (7861), поэтому эти форматы в него не попали by design. - `НЕТ-В-38` (41) = есть в новом плане, не было в 38-м. -### 📌 Что делать дальше (порядок приоритета, обновлён в сессии 13) +### 📌 Что делать дальше (порядок приоритета, обновлён в сессии 14) -1. **Ответить на 8 вопросов по `album`** (см. «❓ ВОПРОСЫ К ALEX» в сессии 13) — особенно #4 - (4 разных формата `album` внутри `!Radio`) и спор про `Benassi Bros`. -2. **Найти источник правила «`album` = имя корня папки»** — в бэкапах `APPLY-PLAN.csv.*` его НЕТ. - Проверить `tag-inventory3.csv`, `APPLY-PLAN-RAW.csv`, `archive/*`, `milestones/music-csv-2026-09-26/`. -3. **Дожать класс «жанр унаследован от `cur_genre`»** — `Enigma/Sleep` 13 строк `General Folk` +0. ✅ **ЗАКРЫТО в сессии 14:** мусорный `new_album` (20 строк) и мусорный `new_track` (151 строка). + `disk_v2/2 ALT,PUNK/HARD` → `RADIO 2 ALT,PUNK`. `disk/3 SHANSON/Трофим` — **не трогаем** + (Alex: «альбомы — это правильно»). +1. **Ответить на оставшиеся вопросы по `album`** — особенно #4 (4 разных формата `album` + внутри `!Radio`) и класс «`album` = название песни» (Алексин/Шалавы, Дискотека Авария). +2. **Дожать класс «жанр унаследован от `cur_genre`»** — `Enigma/Sleep` 13 строк `General Folk` (Enigma = нью-эйдж/эмбиент, не фолк). Тот же корень дефекта, что и 26 исправленных строк. +3. **Остались неразобранными из ручного прохода `album`:** `z Другое, Enigma, Ленинград` → + `Сосни попса`; `detskiy_hor_benassi_satisfaction.mp3` → `Горячие Синглы 2004`; + `Бутусов & Ю-Питер/Девушка По Городу`; корни артистов (Жуки, Потап & Каменских, Света, Серёга) + с `album` = имя артиста. 4. **Решить судьбу 51 папки с рваной нумерацией** — но сначала: стоит ли вообще трогать номера в подборках `!Radio`. 5. Перегенерировать `DIFF-new-vs-38.csv` после любых правок плана - (`python3 diff_new_vs_38.py > /tmp/log 2>&1`). + (`python3 diff_new_vs_38.py > /tmp/log 2>&1`) — **и всегда верифицировать свой скрипт + перечитыванием** (см. метод-урок сессии 14). 6. Применение плана к файлам — **отдельное «go»** от Alex, через `tagwriter:v2` (см. `[[personal/plans/tagwriter-container]]`). diff --git a/personal/tech/id3-tag-repair.md b/personal/tech/id3-tag-repair.md index 7e7ff5c7..07ad2a66 100755 --- a/personal/tech/id3-tag-repair.md +++ b/personal/tech/id3-tag-repair.md @@ -274,6 +274,55 @@ md5 out.csv && python3 gen.py > /tmp/run.log 2>&1 && md5 out.csv # MD5 обя запятой, `$1`/`$4` уезжают в фрагмент имени папки. `scope` считается правильно (`ПАПКА`/`ТРЕК` первое поле), а `field` — нет. Только `csv.DictReader`. +### 🔴 D10 — запись по ЧИСЛОВОМУ индексу вместо имени колонки затирает соседнее поле + +`APPLY-PLAN.csv` — 16 колонок; `changed` = **индекс 15**, а `new_track` = **14**. +Скрипт сессии 14 записал `data[i][14] = "yes"`, полагая, что это `changed` → у 20 строк +`new_track` затёрся на `"yes"`, а `changed` остался прежним. Обнаружено только верификацией. + +**Правило:** всегда `H = {c: i for i, c in enumerate(hdr)}` + `assert` на позиции ключевых +колонок. Карта индексов `APPLY-PLAN.csv`: +`0 path · 1 folder · 2 class · 3 cur_title · 4 cur_artist · 5 cur_albumartist · 6 cur_album · +7 cur_genre · 8 cur_track · 9 new_title · 10 new_artist · 11 new_albumartist · 12 new_album · +13 new_genre · 14 new_track · 15 changed`. +Обязательный `assert (H["new_track"], H["changed"]) == (14, 15)`. + +### 🔴 D11 — значения-СЕНТИНЕЛЫ в тегах: `99 / 51 / 46 / 117 / 238 / 236 / 204` + +Теггеры и сайты пишут в поля не «пусто», а магические числа. План копирует их как данные: + +| Значение | Смысл | Где найдено | +|---|---|---| +| `99`, `51`, `46` | «номера нет» (сентинел теггера) | все папки, одиночки | +| `236` | счётчик скачанных файлов теггера **muzmo.ru** | `cur_album='[muzmo.ru]'`, 11 строк | +| `204` | не-трек из имени (`204-Infected…`) | Infected Mushroom | +| `238` | один номер на ВСЕ альбомы (Красная Плесень) | 56 строк, 5 альбомов | +| `117` | один номер на 4 разные папки (Король и Шут) | 34 строки | + +**Признак сентинела:** одно и то же крупное число у МНОГИХ файлов разных альбомов/папок. +**Проверка:** `Counter(cur_track)` по папке; если одно значение >= 5 файлов и альбомы разные — мусор. +**Правило:** сентинел → пусто; но **сначала** попробовать вытащить номер из имени файла. + +### 🔴 D12 — мусорные значения `album` из тега: плейсхолдеры, годы, водяные знаки + +План копирует `cur_album` **без фильтра**. Найдено и вычищено 20 строк (сессия 14): + +| Значение | Тип | +|---|---| +| `Non spécifié`, `Non specifie` | плейсхолдер (франц. «не указано») | +| `NULL`, `NoTitLe`, `no title`, `Album`, `New`, `mix` | плейсхолдер теггера/техпапка | +| `Неизвестное название` (`Íåèçâåñòíîå…`) | тот же плейсхолдер в CP1251-битье | +| `2005 `, `2007` | только-год | +| `~melody.az - КняZz - Корсар~` | водяной знак сайта + склейка артист-трек | + +**Целевое значение = имя корня артиста** (последний сегмент `folder`); если корень — +категория (`!*`) или папка-мусорка (`misc`/`base`/`plux`/`старые`) → артист (сегмент +после категории). `Pushnoy.ru` — сайт-источник: все подпапки (`2007`/`старые`/`NEW`) +не альбомы → `Pushnoy.ru`. + +**Скрипт:** `~/Downloads/music-tags/fix_junk_album.py` (dry-run по умолчанию, `--apply` пишет). +**Верификация:** `verify_junk_album.py` — перечитывает файл, сверяет контрольные точки. + ## 🔴 Классы порчи `albumartist` (сессия 7, 2026-09-27) Три класса, найденных сплошным поиском по `APPLY-PLAN.csv`. Все три — из-за того, что правило