[2026-09-27] eagle: personal/plans/music-artist-albumartist-repair.md personal/plans/tagwriter-container.md personal/tech/id3-tag-repair.md personal/tech/music-tags-repair-truenas.md personal/tech/scripts/find_aa_hijack.py personal/tech/scripts/find_va_misuse.py
This commit is contained in:
1 parent
463a77ac5d
commit
2520fda13b
6 files changed
+359
-47
No files matched your search
@@ -4,7 +4,7 @@ created: '2026-09-27'
|
||||
updated: '2026-09-27'
|
||||
type: plan
|
||||
namespace: personal
|
||||
status: session8-done-va-over-single-artist-fixed-5-pending-alex
|
||||
status: session9-done-va-class-cleared-category-root-rolled-back
|
||||
tags:
|
||||
- music
|
||||
- metadata
|
||||
@@ -23,6 +23,36 @@ related:
|
||||
|
||||
# Music `artist` + `albumartist` Repair — правила Alex и ход работ
|
||||
|
||||
> ## 🔴 АКТУАЛЬНО НА КОНЕЦ СЕССИИ 9 (2026-09-27)
|
||||
>
|
||||
> ```
|
||||
> APPLY-PLAN.csv 7861 строка md5 82492a0b2b93dbb6c7444a4040a21a03
|
||||
> DIFF-new-vs-38.csv 4946 строк md5 dd67d4fe64bc6365c478a0831cda634c
|
||||
> tag-fix-plan.csv не тронут (база 38-го, источник истины для диффа)
|
||||
> ```
|
||||
>
|
||||
> **Пустых полей в плане — 0.** Дифф проверен: `ПОТЕРЯНО 0 · ЛИШНИХ 0 · ПОТЕРЬ НЕТ, дифф ПОЛНЫЙ`.
|
||||
>
|
||||
> ✅ **Второй класс `Various Artists` ДОЧИЩЕН полностью** (99 строк): `!Рэп/НТЛ` (63) +
|
||||
> `!Рэп/НТЛ/2003 - Выход` (17) → `НТЛ`, `Ария, Кипелов` (12) → `Ария`, `Тест Сабвуфера` (4) →
|
||||
> `Тест Сабвуфера`. Детектор `find_va_misuse.py` теперь даёт **`ПАПОК-КАНДИДАТОВ: 0`**.
|
||||
>
|
||||
> ✅ **`z Другое…` корень — ОТКАЧЕНО по требованию Alex.** Было `Various Artists`, стало
|
||||
> **собственный `artist` файла** (`Красная Плесень` ×2, `ВИА МЕА` ×1). Корень папки-категории
|
||||
> альбомом **не считается** — см. правило **A4** в `[[personal/tech/id3-tag-repair]]`.
|
||||
>
|
||||
> ✅ **`Би-2/Нечётный Воин` — `artist` вытащен из имён файлов** (46 строк): заглушки
|
||||
> `Нечетный Воин` / `Нечётный воин 2` → реальные исполнители (`Би-2 + Агата кристи`,
|
||||
> `Лакмус + Александр Ф.Скляр`, …), `albumartist` → `Би-2`. См. раздел «🔷 СЕССИЯ 9».
|
||||
>
|
||||
> ⚠️ Все 5 папок из сессии 8 закрыты: `!Рэп/НТЛ`, `Ария, Кипелов`, `Тест Сабвуфера`,
|
||||
> `z Другое…` корень — решены; правок в ожидании нет.
|
||||
>
|
||||
> **Суммарно за сессии 7-9 исправлено 313 строк** по четырём классам (см. A1/A2/A3/A4 в tech-доке).
|
||||
>
|
||||
> ⏳ **Открыто:** `album` файлов `Би-2/Нечётный Воин/*` (`Нечетный Воин (CD1)`, `Медленная Звезда`,
|
||||
> `Нечётный воин 2`) — вопрос задан, ответа нет, **не трогать**.
|
||||
>
|
||||
> ## 🔴 АКТУАЛЬНО НА КОНЕЦ СЕССИИ 8 (2026-09-27)
|
||||
>
|
||||
> ```
|
||||
@@ -40,7 +70,7 @@ related:
|
||||
>
|
||||
> ⏳ **Детектор `find_va_misuse.py` нашёл 5 папок того же класса — ждут решения Alex:**
|
||||
> `!Рэп/НТЛ` (75), `!Rock&Folk/Ария, Кипелов` (8/12), `z Другое…/Тест Сабвуфера` (3/4),
|
||||
> `z Другое…` корень (2/3).
|
||||
> `z Другое…` корень (2/3). → **ЗАКРЫТО в сессии 9, см. выше.**
|
||||
>
|
||||
> ## 🔴 АКТУАЛЬНО НА КОНЕЦ СЕССИИ 7 (2026-09-27)
|
||||
>
|
||||
@@ -2887,6 +2917,144 @@ z Другое… (корень) 2/3 artist='К
|
||||
2. Повторный прогон `find_va_misuse.py` до пустого результата.
|
||||
3. Глазами пройти `field=albumartist` в диффе (571 строка папок).
|
||||
|
||||
---
|
||||
|
||||
# 🔷 СЕССИЯ 9 (2026-09-27) — ДОЧИСТКА `Various Artists` + `Би-2/Нечётный Воин`
|
||||
|
||||
Продолжение сессии 8: 5 папок из детектора закрыты, плюс новый разбор проекта «Нечётный Воин».
|
||||
|
||||
## 📊 ФИНАЛЬНОЕ СОСТОЯНИЕ (конец сессии 9)
|
||||
|
||||
```
|
||||
APPLY-PLAN.csv 7861 строка md5 82492a0b2b93dbb6c7444a4040a21a03
|
||||
DIFF-new-vs-38.csv 4946 строк md5 dd67d4fe64bc6365c478a0831cda634c
|
||||
tag-fix-plan.csv не тронут (база 38-го, источник истины для диффа)
|
||||
verify_diff_completeness.py — независимый контроль полноты
|
||||
```
|
||||
|
||||
**Пустых полей в плане — 0** (все пять `new_*`).
|
||||
Дифф: `ПОТЕРЯНО 0 · ЛИШНИХ 0 · НЕТ-В-38 41=41 · ТОЛЬКО-В-38 85=85 · ПОТЕРЬ НЕТ, дифф ПОЛНЫЙ`.
|
||||
`ВСЕГО правок (трек-уровень): 18558` — не изменилось (правки меняют значения, не число расхождений).
|
||||
|
||||
## ✅ A. ВТОРОЙ КЛАСС `Various Artists` ДОЧИЩЕН ПОЛНОСТЬЮ (99 строк)
|
||||
|
||||
Решение Alex: «Арию ставь в albumartist. исправляй что нашел. `Тест Сабвуфера` — наверное
|
||||
должен быть `Тест Сабвуфера` а не Various».
|
||||
|
||||
| Папка | Файлов | Было | Стало | Основание |
|
||||
|---|---:|---|---|---|
|
||||
| `!Рэп/НТЛ` | 63 | `Various Artists` | **`НТЛ`** | Alex: «исправляй что нашел» |
|
||||
| `!Рэп/НТЛ/2003 - Выход` | 17 | `Various Artists` | **`НТЛ`** | то же |
|
||||
| `!Rock&Folk/Ария, Кипелов` | 12 | `Various Artists` | **`Ария`** | Alex: «Арию ставь» |
|
||||
| `z Другое…/Тест Сабвуфера` | 4 | `Various Artists` | **`Тест Сабвуфера`** | Alex: «наверное должен быть Тест Сабвуфера» |
|
||||
| `z Другое…` (корень) | 3 | `Various Artists` | см. B | откат |
|
||||
|
||||
**Детектор `find_va_misuse.py` теперь даёт `ПАПОК-КАНДИДАТОВ: 0`** — класс вычищен.
|
||||
|
||||
> ⚠️ **Отмена прежнего противоречия:** в сессии 8 помечено, что `!Рэп/НТЛ` формально попадает
|
||||
> под правило «треки в корне артиста при наличии подпапок-альбомов → СБОРНИК (кейс НТЛ)».
|
||||
> Alex решил **в пользу артиста** (`НТЛ`), не сборника. Правило «кейс НТЛ = сборник» из сессии 5
|
||||
> **отменено** — детектор был прав, таблица правил устарела.
|
||||
|
||||
## ✅ B. `z Другое…` КОРЕНЬ — ОТКАЧЕНО (3 строки)
|
||||
|
||||
> Alex: «стоп. нет. красную плесень в красную плесень — виа меа в виа меа — не объединять
|
||||
> корень Другого в альбом»
|
||||
|
||||
```
|
||||
ВИА МЕА aa='ВИА МЕА' album='Дерьмо Моржа'
|
||||
Красная Плесень aa='Красная Плесень' album='Сосни попса'
|
||||
Красная Плесень aa='Красная Плесень' album='Сосни попса'
|
||||
```
|
||||
|
||||
**Правило (зафиксировано):** корень папки-**категории** (`z Другое, Enigma, Ленинград` —
|
||||
контейнер из подпапок разных исполнителей) **альбомом НЕ считается**.
|
||||
`albumartist` = **собственный `artist` файла**, НЕ `Various Artists`.
|
||||
Разные исполнители в корне категории — **не повод** для `Various Artists`.
|
||||
|
||||
## ✅ C. `Би-2/Нечётный Воин` — `artist` вытащен из имён файлов (46 строк)
|
||||
|
||||
> Alex: cur_artist = `Нечётный воин 2` / `Нечетный Воин` → «исправляй артиста значит»
|
||||
|
||||
### Как выявлено
|
||||
|
||||
`new_albumartist` содержал имя ПРОЕКТА вместо артиста:
|
||||
`Нечетный Воин` (CD1/CD2/Медленная Звезда, 27 файлов) и `Нечётный воин 2` (16 файлов).
|
||||
А `new_artist` дублировал ту же заглушку — реальные исполнители были **только в имени файла**
|
||||
в скобках: `02 Все, как он сказал (Би-2 + Агата кристи).mp3`.
|
||||
|
||||
⚠️ **Важно:** это **НЕ порча планом** — в ОРИГИНАЛЕ (`cur_artist`) уже стояло
|
||||
`Нечётный воин 2`. Проверено сравнением с `tag-fix-plan.csv`: `cur == new` в обоих CSV.
|
||||
План просто не трогал эти поля. Мой оборот «прочерк» был неверным словом — Alex отреагировал:
|
||||
«че блядь значит прочерк? почему? они не стояли на оригиналах?»
|
||||
|
||||
### Правка
|
||||
|
||||
| Папка | Файлов | `artist` было | `artist` стало | `aa` |
|
||||
|---|---:|---|---|---|
|
||||
| `2005 Нечетный Воин/CD1` | 11 | `Нечетный Воин` | `Би-2 + И.Желанная`, `Серьга`, `Линда`, `Агата Кристи`, `М.Карасёв`, `Brainstorm`, `Неонавт`, `Сети`, `Би-2` ×3 | → `Би-2` |
|
||||
| `2005 Нечетный Воин/CD2` | 11 | `Нечетный Воин` | `Т.Литвиненко`, `Э.Шклярский`, `Лакмус`, `О.Нестров`, `Н.Борзов`, `О.Петрыкина`, `Лена Т.`, `Би-2 + C.Fereira`, `Би-2` ×3 | → `Би-2` |
|
||||
| `2005 Медленная Звезда` | 5 | `Нечетный Воин` | `Би-2` (все — скобок в именах нет) | → `Би-2` |
|
||||
| `2008 Проект Нечетный Воин 2` | 16 | `Нечётный воин 2` | `Би-2 + Агата кристи` ×2, `Лакмус + Александр Ф.Скляр`, `Роман Суслов + David Brown`, `Сергей Мазаев + Татьяна Литвиненко`, `А.Кортнев + И.Богушевская`, `Би-2 + Диана Арбенина` ×2, `Би-2 + Инна Желанная`, `Би-2 + Punk tv`, `Truffele`, `Алексей Романов`, `David Brown`, `Louis Frank`, `А.Севидов, Electro-punk`, `Би-2` (Intro) | → `Би-2` |
|
||||
|
||||
### 🔴 ПИТФОЛЛ: вложенные скобки в имени файла ломают экстрактор
|
||||
|
||||
Регулярка `re.findall(r'\(([^()]*)\)', stem)` берёт **последнюю** группу скобок. Три файла
|
||||
с вложенными/битыми скобками дали НЕВЕРНЫЙ `artist` — потребовался ручной доп-фикс:
|
||||
|
||||
| Файл | Автоматически | Правильно |
|
||||
|---|---|---|
|
||||
| `03 Kao sun road (David Brown (Brazzaville).mp3` | `Brazzaville` | **`David Brown`** |
|
||||
| `11 Michael (Louis Frank (Esthetic education).mp3` | `Esthetic education` | **`Louis Frank`** |
|
||||
| `16 Все, как он сказал (А.Севидов, Electro-punk.mp3` | `Би-2` | **`А.Севидов, Electro-punk`** |
|
||||
|
||||
**Мораль:** после массовой экстракции из имён — **всегда глазами просмотреть результат**,
|
||||
имена с вложенными скобками дают мусор.
|
||||
|
||||
### ⏳ ОТКРЫТО
|
||||
|
||||
`album` у этих файлов остался неоднородным: `Нечетный Воин (CD1)`, `Нечетный Воин (CD2)`,
|
||||
`Медленная Звезда`, `Нечётный воин 2`. Вопрос Alex задан («оставить или унифицировать?`Нечётный Воин`/`Нечётный воин 2`») — **ответа нет, не трогать**.
|
||||
|
||||
## 🧰 ИНСТРУМЕНТЫ СЕССИИ 9
|
||||
|
||||
| Файл | Назначение |
|
||||
|---|---|
|
||||
| `/tmp/fix_va_rest.py` | дочистка `Various Artists` (НТЛ, Ария, Тест Сабвуфера) |
|
||||
| `/tmp/rollback_z_drugoe.py` | откат `z Другое…` корня |
|
||||
| `/tmp/fix_nechetny.py` | `aa` `Нечетный Воин` → `Би-2` |
|
||||
| `/tmp/fix_nechetny_artist.py` | экстрактор `artist` из скобок имён файлов |
|
||||
| `/tmp/fix_nested.py` | ручной фикс 3 файлов с вложенными скобками |
|
||||
| `/tmp/find_va_misuse.py` | детектор `Various Artists` (повторный прогон → 0) |
|
||||
|
||||
### Бэкапы сессии 9
|
||||
|
||||
```
|
||||
APPLY-PLAN.csv.bak-before-va-rest-20260927-141317
|
||||
APPLY-PLAN.csv.bak-before-z-drugoe-va-20260927-141339
|
||||
APPLY-PLAN.csv.bak-before-z-drugoe-rollback-20260927-141422
|
||||
APPLY-PLAN.csv.bak-before-nechetny-20260927-141459
|
||||
APPLY-PLAN.csv.bak-before-nechetny-artist-20260927-141705
|
||||
APPLY-PLAN.csv.bak-before-nested-fix-20260927-141715
|
||||
```
|
||||
|
||||
## 📊 ИТОГ ТРЁХ СЕССИЙ (7-9): 313 строк по четырём классам
|
||||
|
||||
| Класс | Проявление | Детектор | Объём |
|
||||
|---|---|---|---|
|
||||
| **A1** чужое значение `albumartist` из корня папки | `DJ Feel`, `VIP77`, `Бумер`, `КняZz`, `Мика Ньютон`, `Виктор Жуков`, `ДА и Меньшиков` | `find_aa_hijack.py` | 40 |
|
||||
| **A2** `Various Artists` поверх одного артиста | Агата Кристи 95, НТЛ 80, Бенасси 20, Tiesto 14, Иванушки 8, Магомаев 7, ИМ 5, Ария 12, Тест Сабвуфера 4 | `find_va_misuse.py` | ~250 |
|
||||
| **A3** имя папки/склейка в `album` | `Rammstein - misc` → `misc`, `Infected Mushroom - Other Track's` → `Other Tracks` | `find_folder_as_album.py` | 5 |
|
||||
| **A4** корень папки-категории как альбом | `z Другое…` | — | 3 (откат) |
|
||||
|
||||
## ⏭ СЛЕДУЮЩИЙ ШАГ
|
||||
|
||||
1. `album` для `Би-2/Нечётный Воин/*` — оставить или унифицировать (ждёт Alex).
|
||||
2. Глазами пройти `field=album` в диффе (305 строк, из них ПАПКА — 72) — содержательные решения.
|
||||
3. Затем `field=albumartist` (571 строка папок).
|
||||
4. Боевой прогон `--apply --verify` — **не запущен**, ждёт отдельного «go».
|
||||
5. Контейнер `snapcur` на NAS (только чтение, `:ro`) — **не убран**, Alex не подтвердил.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,12 +20,13 @@ related:
|
||||
---
|
||||
# tagwriter — применение тегов к MP3 (TrueNAS)
|
||||
|
||||
> 🔴 **СТАТУС: БОЕВОЙ ПРОГОН НЕ ЗАПУЩЕН.** План правится в сессии 8
|
||||
> (дифф против 38-го прогона) — подробности в [[personal/plans/music-artist-albumartist-repair]] § «СЕССИЯ 8».
|
||||
> Актуальные MD5: `APPLY-PLAN.csv` = `48439e06afeb7bdc28e78be5448f44f7` (7861 стр),
|
||||
> `DIFF-new-vs-38.csv` = `047755613601bcf31c23ff8f22e69b22` (4945 стр).
|
||||
> Открыто: `track` (56 файлов с `238` + 9 с пустым при непустом `cur_track`),
|
||||
> 5 папок с `Various Artists` поверх одного артиста (`!Рэп/НТЛ` и др.).
|
||||
> 🔴 **СТАТУС: БОЕВОЙ ПРОГОН НЕ ЗАПУЩЕН.** План правится в сессиях 8-9
|
||||
> (дифф против 38-го прогона) — подробности в [[personal/plans/music-artist-albumartist-repair]] § «СЕССИЯ 8/9».
|
||||
> Актуальные MD5: `APPLY-PLAN.csv` = `d1fa36dc0fba72faeff08856369fca46` (7861 стр),
|
||||
> `DIFF-new-vs-38.csv` = `374ed1fed3abb7d9ec397025c0c88a2b` (4945 стр).
|
||||
> **Класс `Various Artists` поверх одного артиста — вычищен полностью** (детектор
|
||||
> `find_va_misuse.py` → `ПАПОК-КАНДИДАТОВ: 0`), корень `z Другое…` откачен на собственный `artist`.
|
||||
> Открыто: `track` (56 файлов с `238` + 9 с пустым при непустом `cur_track`), контейнер `snapcur` на NAS.
|
||||
|
||||
> ## 🔴 ПУТИ: `~/milestones` БОЛЬШЕ НЕТ
|
||||
>
|
||||
|
||||
@@ -232,6 +232,151 @@ assert covered + len(file_lines) == sum(field_counts.values()), "ПОТЕРЯ П
|
||||
Никаких третьих форм. «Одинаковое значение по папке» должно быть организовано **в плане**,
|
||||
дифф лишь объединяет — так формулирует Alex.
|
||||
|
||||
### 🔴 D7 — рассинхрон MD5 после «успешного» прогона = скрипт умер на SIGPIPE
|
||||
|
||||
Отдельная проверка к D4. Симптом: отчёт напечатан полностью, `exit=0` на вид, но
|
||||
`md5` выходного CSV **тот же, что до запуска**, и `wc -l` не изменился. Значит запись
|
||||
не произошла. Всегда сверять **до/после**:
|
||||
|
||||
```bash
|
||||
md5 out.csv && python3 gen.py > /tmp/run.log 2>&1 && md5 out.csv # MD5 обязан смениться
|
||||
```
|
||||
|
||||
### 🔴 D8 — состояния файла и плана расходятся: колонка `changed`
|
||||
|
||||
`APPLY-PLAN.csv` содержит колонку `changed` (`yes` 7648 / `no` 213). Дифф её **не отражает** —
|
||||
он сравнивает `new_*` плана с `new_*` 38-го прогона, а не с тегами на диске. Поэтому 50 файлов
|
||||
(`changed=no`, 61 строка) попадают в дифф как «изменения», хотя на диске ничего не поменяется.
|
||||
Флаг при этом честный: проверка «`changed=no`, но `new_* != cur_*`» даёт **0**. Класс шире:
|
||||
«появление колонки» (D3) — тоже не изменение на диске, а правка плана.
|
||||
|
||||
### 🔴 D9 — `folder` из CSV содержит запятую, `awk -F,` врёт
|
||||
|
||||
Продолжение D6 для любого анализа, а не только диффа: `!Pop, Club, Любэ/...` рвётся по
|
||||
запятой, `$1`/`$4` уезжают в фрагмент имени папки. `scope` считается правильно (`ПАПКА`/`ТРЕК`
|
||||
первое поле), а `field` — нет. Только `csv.DictReader`.
|
||||
|
||||
## 🔴 Классы порчи `albumartist` (сессия 7, 2026-09-27)
|
||||
|
||||
Три класса, найденных сплошным поиском по `APPLY-PLAN.csv`. Все три — из-за того, что правило
|
||||
выводилось из **имени папки**, а не из данных файла.
|
||||
|
||||
### 🔴 A1 — значение от СЛУЧАЙНОГО файла корня размножается на всю папку
|
||||
|
||||
`albumartist` папки брался от первого/последнего файла и присваивался всем. Если в корне
|
||||
папки лежит один чужой трек из сборника — его `albumartist` уезжает на весь альбом:
|
||||
|
||||
```
|
||||
!Pop, Club, Любэ/The Prodigy DJ Feel → должно The Prodigy (4 файла, 1 из них реально DJ Feel)
|
||||
!Pop, Club, Любэ/Банд Эрос VIP77 → Банд'Эрос (7, 1 реально VIP77)
|
||||
!Pop, Club, Любэ/Жуки Виктор Жуков → Жуки (12, 1 реально Рома Жуков)
|
||||
!Pop, Club, Любэ/Дискотека Авария ДА и Меньшиков → Дискотека Авария
|
||||
!Pop, Club, Любэ/Потап & Каменских Мика Ньютон → Потап и Настя Каменских
|
||||
!Rock&Folk/Король и Шут КняZz → Король и Шут (4, 1 реально КняZz)
|
||||
z Другое/Ленинград Бумер → Ленинград (+ Сергей Шнуров)
|
||||
```
|
||||
|
||||
**Правило:** `albumartist` трека = **его собственный `artist`**, если альбом не сборник.
|
||||
Значение из чужого файла не размножается. Миноритарные артисты в корне получают **своё имя**
|
||||
(`КняZz`, `Рома Жуков`, `Мика Ньютон`, `VIP77`, `Бумер`, `DJ Feel` — остаются у своего 1 файла).
|
||||
|
||||
Детектор: `personal/tech/scripts/find_aa_hijack.py` — находит папки, где `albumartist` совпадает
|
||||
с `artist` **миноритарного** файла, но не с топ-артистом и не с именем папки. 40 строк исправлено.
|
||||
|
||||
Ложные срабатывания детектора (НЕ порча): `Re Sfaction` (решение Alex), `S Is Here` (решение
|
||||
Alex), `ДДТ/2008 L'Echoppe` (сборник ДДТ, 10 файлов = дуэт Шевчук & Казански), `Сборка/L`
|
||||
(сборник), `z Другое` (корень-категория).
|
||||
|
||||
### 🔴 A2 — `Various Artists` там, где исполнитель ОДИН
|
||||
|
||||
Правило «разные `artist` → Various Artists» срабатывало на разнобое написания одного имени
|
||||
(`Иванушки` / `Иванушки Int.` / `Иванушки International`) и на фитах. Затронуто:
|
||||
|
||||
```
|
||||
!Rock&Folk/Агата Кристи 95 файлов → Агата Кристи (вкл. Кавер-версии 24, Проекты 12)
|
||||
!Рэп/НТЛ + 2003 - Выход 80 → НТЛ
|
||||
!Pop, Club, Любэ/Benassi Bros (2 папки) 20 → Benassi Bros
|
||||
!Pop, Club, Любэ/Dj Tiesto 14 → Tiesto (DJ-микс: aa = автор компиляции)
|
||||
Ария, Кипелов 12 → Ария
|
||||
!Retro/Иванушки 8 → Иванушки
|
||||
!Retro/Муслим Магомаев 7 → Муслим Магомаев
|
||||
Infected Mushroom (2 папки) 5 → Infected Mushroom
|
||||
Тест Сабвуфера 4 → Тест Сабвуфера
|
||||
```
|
||||
|
||||
**Правило:** `Various Artists` ставить ТОЛЬКО когда исполнители **действительно разные**.
|
||||
Один артист (в т.ч. с вариациями написания) → ставить **его**.
|
||||
|
||||
Детектор: `personal/tech/scripts/find_va_misuse.py` — папки с `aa='Various Artists'`, где
|
||||
>50% файлов имеют одного `artist`. Итог: `ПАПОК-КАНДИДАТОВ: 0` (класс вычищен).
|
||||
|
||||
### 🔴 A3 — имя подпапки уезжает в `album`/`albumartist` склейкой
|
||||
|
||||
```
|
||||
❌ new_album = 'Rammstein - misc' (я придумал сам, Alex не просил)
|
||||
✅ new_album = 'misc'
|
||||
```
|
||||
|
||||
`misc` / `base` / `plux` / `рап` — имя **подпапки**, оно идёт в `album` как есть, но **никогда**
|
||||
не в `albumartist`. Склейка `Родитель - Папка` запрещена в обоих полях.
|
||||
|
||||
Реакция Alex: «**albumartist = Ленинград, Rammstein, какой misc нахуй? это альбом - misc**».
|
||||
|
||||
### 🔴 A4 — корень папки-КАТЕГОРИИ не считается альбомом
|
||||
|
||||
`z Другое, Enigma, Ленинград` — категория-солянка. Сначала файлы-сироты в её корне получили
|
||||
`album` = имя категории (мусор), затем `albumartist = Various Artists` — тоже неверно.
|
||||
|
||||
**Правило:** для корня категории `albumartist` = **собственный `artist` файла**, даже если
|
||||
файлов несколько и они разные. Не `Various Artists`, не имя папки.
|
||||
|
||||
```
|
||||
ВИА МЕА aa='ВИА МЕА' album='Дерьмо Моржа'
|
||||
Красная Плесень aa='Красная Плесень' album='Сосни попса'
|
||||
```
|
||||
|
||||
Реакция Alex (со «стоп»): «**красную плесень в красную плесень - виа меа в виа меа -
|
||||
не объединять корень Другого в альбом**».
|
||||
|
||||
### 🔴 A5 — имя ПРОЕКТА вместо артиста + вложенные скобки в имени файла (сессия 9)
|
||||
|
||||
Класс: `artist` (и `albumartist`) = **название музыкального проекта**, а реальные исполнители
|
||||
треков лежат **только в имени файла в скобках**. План такие поля не трогал — в ОРИГИНАЛЕ
|
||||
(`cur_artist`) уже стояло имя проекта, поэтому в диффе это выглядело как «не изменение».
|
||||
|
||||
```
|
||||
Папка: !Rock&Folk/Би-2/Нечетный Воин/* (проект Шнурова/Самойлова «Нечётный Воин»)
|
||||
cur_artist = 'Нечетный Воин' ← реальный тег файла
|
||||
new_artist = 'Нечетный Воин' ← план не менял
|
||||
файл: 02 Все, как он сказал (Би-2 + Агата кристи).mp3 ← артист ТОЛЬКО здесь
|
||||
```
|
||||
|
||||
**Правка:** `artist` извлекается из **скобок имени файла** (правило Alex: «artist — есть в скобках
|
||||
в имени файла → брать из скобок»), `albumartist` → `Би-2` (владелец проекта).
|
||||
|
||||
```
|
||||
Нечетный Воин → Би-2 + И.Желанная | Серьга | Линда | Агата Кристи | Т.Литвиненко | Лакмус
|
||||
Нечётный воин 2 → Би-2 + Агата кристи | Лакмус + Александр Ф.Скляр | Роман Суслов + David Brown
|
||||
Би-2 (скобок нет) → Би-2
|
||||
```
|
||||
|
||||
🔴 **Питфолл экстрактора: вложенные скобки.** Регулярка `re.findall(r'\(([^()]*)\)', stem)`
|
||||
берёт **последнюю** группу. Три файла получили мусор вместо артиста:
|
||||
|
||||
| Файл | Автоматика дала | Правильно |
|
||||
|---|---|---|
|
||||
| `03 Kao sun road (David Brown (Brazzaville).mp3` | `Brazzaville` | **`David Brown`** |
|
||||
| `11 Michael (Louis Frank (Esthetic education).mp3` | `Esthetic education` | **`Louis Frank`** |
|
||||
| `16 Все, как он сказал (А.Севидов, Electro-punk.mp3` | `Би-2` | **`А.Севидов, Electro-punk`** |
|
||||
|
||||
**Мораль:** после массовой экстракции `artist` из имён файлов **обязателен глазной проход**
|
||||
по результату — вложенные/битые скобки дают неверного артиста без всякой ошибки.
|
||||
|
||||
⚠️ **Не путать с порчей:** `cur == new` в обоих CSV (`APPLY-PLAN` и `tag-fix-plan`) — значит
|
||||
план **не портил**, а просто не заполнял. Оборот «прочерк» неверен, если `cur_artist` непуст:
|
||||
Alex отреагировал «че блядь значит прочерк? почему? они не стояли на оригиналах?».
|
||||
**Проверять первоисточник (`cur_*` в обоих CSV) до слова «порча».**
|
||||
|
||||
## 🖊 Слой ЗАПИСИ — ID3v1 vs ID3v2 (добавлено 2026-09-27)
|
||||
|
||||
Зеркало правил W1–W15 скилла. Полные формулировки — в `id3-tag-repair/SKILL.md`.
|
||||
|
||||
@@ -23,23 +23,26 @@ related:
|
||||
|
||||
# Music Tags Repair — TrueNAS (7906 → 7905 файлов)
|
||||
|
||||
> ## 🔴 АКТУАЛЬНОЕ СОСТОЯНИЕ (2026-09-27, конец сессии 6) — ЧИТАЙ ЭТО ПЕРВЫМ
|
||||
> ## 🔴 АКТУАЛЬНОЕ СОСТОЯНИЕ (2026-09-27, конец сессии 9) — ЧИТАЙ ЭТО ПЕРВЫМ
|
||||
>
|
||||
> **Этот файл — исторический лог волны 38 (завершена). Актуальная работа идёт здесь:**
|
||||
>
|
||||
> | Документ | О чём |
|
||||
> |---|---|
|
||||
> | **[[personal/plans/tagwriter-container]]** | ⭐ скрипт-писатель `apply_tags_v2.py` (566 стр): логика полей, ID3v1-снос, тесты, 18 питфоллов, запуск |
|
||||
> | **[[personal/plans/music-artist-albumartist-repair]]** | ⭐ **правила формирования плана, `APPLY-PLAN.csv`, дифф `DIFF-new-vs-38.csv`, сессии 1-6** |
|
||||
> | **[[personal/plans/music-artist-albumartist-repair]]** | ⭐ **правила формирования плана, `APPLY-PLAN.csv`, дифф `DIFF-new-vs-38.csv`, сессии 1-9** |
|
||||
> | **[[personal/tech/music-broken-toload]]** | 29 битых/DRM файлов на перезагрузку |
|
||||
>
|
||||
> **Состояние:** план `APPLY-PLAN.csv` доведён до **0 пустых полей** и проверенного диффа
|
||||
> (`ПОТЕРЯНО 0 · ЛИШНИХ 0`). **Боевой прогон НЕ запущен — ждёт «go» от Alex.**
|
||||
> 🔴 Открыт класс дефекта **«`albumartist` размножен от чужого файла в корне папки»** (7 папок) —
|
||||
> см. сессию 6 в [[personal/plans/music-artist-albumartist-repair]].
|
||||
> ✅ Класс **«`albumartist` размножен от чужого файла в корне папки»** — ИСПРАВЛЕН (7 папок, 40 строк).
|
||||
> ✅ Класс **«`Various Artists` поверх одного артиста»** — ВЫЧИЩЕН ПОЛНОСТЬЮ
|
||||
> (`find_va_misuse.py` → `ПАПОК-КАНДИДАТОВ: 0`). Разбор классов **A1-A4** —
|
||||
> в [[personal/tech/id3-tag-repair]] § «Классы порчи `albumartist`».
|
||||
> ✅ **`Би-2/Нечётный Воин`** — `artist` вытащен из имён файлов (46 строк), `albumartist` → `Би-2`.
|
||||
>
|
||||
> Боевой вход: `/Users/admin/Downloads/music-tags/APPLY-PLAN.csv` (**7861 строка**,
|
||||
> md5 `c8d43cc56d82cd35a67a0efe8173cd4b`). Рабочая папка — **`~/Downloads/music-tags/`**
|
||||
> md5 `82492a0b2b93dbb6c7444a4040a21a03`). Рабочая папка — **`~/Downloads/music-tags/`**
|
||||
> (`~/milestones/` больше НЕ существует). Скрипты: `~/Automation/music-tags/`.
|
||||
>
|
||||
> ⚠️ Волна 38 (TIT2/TPE1/TALB/TRCK, 7041 файл) — **завершена**, описывается ниже как история.
|
||||
|
||||
@@ -1,26 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Детектор класса «albumartist размножен от чужого файла в корне папки».
|
||||
"""Detector A1 — albumartist hijacked from a random ROOT file of the folder.
|
||||
|
||||
Сессия 6, 2026-09-27. Нашёл 7 испорченных папок из 11 подозреваемых
|
||||
(The Prodigy->DJ Feel, Банд Эрос->VIP77, Дискотека Авария, Жуки,
|
||||
Потап & Каменских, Король и Шут, Ленинград).
|
||||
Rule (Alex): a track's albumartist = its OWN artist, unless the album is a genuine
|
||||
compilation. A value taken from one stray file in the root must NOT be propagated.
|
||||
|
||||
ПРИЗНАК ПОРЧИ:
|
||||
для папки, где new_albumartist ОДИН на всю папку:
|
||||
он не совпадает с top-артистом папки
|
||||
И не совпадает с именем папки
|
||||
И совпадает с МИНОРИТАРНЫМ артистом папки
|
||||
-> ПОДОЗРЕВАЕМЫЙ
|
||||
Finds folders where the folder-level albumartist equals the `artist` of a MINORITY
|
||||
file, but is neither the top artist nor the folder name.
|
||||
|
||||
ЗАПУСК: python3 find_aa_hijack.py
|
||||
Не меняет файлы. Только печатает.
|
||||
Benign hits to review manually (NOT corruption):
|
||||
- eponymous compilation (ДДТ/2008 L'Echoppe — files are a duet credit)
|
||||
- letter sub-folder of a set (Сборка Песни для детей/L)
|
||||
- category root (z Другое, Enigma, Ленинград)
|
||||
- any folder the user explicitly decided (Re Sfaction, S Is Here)
|
||||
|
||||
Usage:
|
||||
python3 find_aa_hijack.py [путь_к_APPLY-PLAN.csv]
|
||||
"""
|
||||
import sys
|
||||
|
||||
import csv
|
||||
import collections
|
||||
import os
|
||||
|
||||
P = '/Users/admin/Downloads/music-tags/APPLY-PLAN.csv'
|
||||
P = sys.argv[1] if len(sys.argv) > 1 else '/Users/admin/Downloads/music-tags/APPLY-PLAN.csv'
|
||||
rows = list(csv.DictReader(open(P, encoding='utf-8-sig', newline='')))
|
||||
|
||||
|
||||
@@ -36,13 +39,14 @@ suspects = []
|
||||
for folder, rs in sorted(by_folder.items()):
|
||||
aa_vals = collections.Counter(s(r['new_albumartist']) for r in rs if s(r['new_albumartist']))
|
||||
if len(aa_vals) != 1:
|
||||
continue # смешанные папки — отдельный случай
|
||||
continue # mixed folder — separate case
|
||||
aa = next(iter(aa_vals))
|
||||
art = collections.Counter(s(r['new_artist']) for r in rs if s(r['new_artist']))
|
||||
if not art:
|
||||
continue
|
||||
top_artist, top_n = art.most_common(1)[0]
|
||||
folder_name = os.path.basename(folder)
|
||||
# albumartist matches a MINORITY artist, not the top one, not the folder name
|
||||
if aa != top_artist and aa != folder_name and aa in art:
|
||||
minority = art[aa]
|
||||
if minority < top_n:
|
||||
|
||||
@@ -1,31 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Детектор: aa='Various Artists' у папки, где БОЛЬШИНСТВО файлов имеет одного artist.
|
||||
"""Detector A2 — 'Various Artists' on a folder that has only ONE artist.
|
||||
|
||||
Класс дефекта (сессия 8, 2026-09-27):
|
||||
Папка-АЛЬБОМ помечена 'Various Artists', хотя исполнитель один.
|
||||
Причины ложного срабатывания критерия «разные artist = сборник»:
|
||||
1. разнобой написания одного исполнителя
|
||||
('Иванушки' / 'Иванушки Int.' / 'Иванушки International');
|
||||
2. несколько чужих файлов в корне папки артиста
|
||||
(7 чужих треков среди 52 треков 'Агата Кристи').
|
||||
Rule (Alex): Various Artists ONLY when the performers are genuinely different.
|
||||
One artist — including spelling variants (Иванушки / Иванушки Int. / Иванушки
|
||||
International) and featured credits — gets THAT artist. For a DJ-mix compilation the
|
||||
albumartist is the DJ who compiled it, not Various Artists.
|
||||
|
||||
Правило Alex: «Папка с 1 уникальным артистом → АЛЬБОМ, albumartist = artist».
|
||||
Iterate until it reports zero candidates: the classes are nested — fixing one reveals
|
||||
the next (e.g. Агата Кристи → 9999 - Разное/Проекты).
|
||||
|
||||
Запуск:
|
||||
Usage:
|
||||
python3 find_va_misuse.py [путь_к_APPLY-PLAN.csv]
|
||||
|
||||
Выход: список папок-кандидатов с частотой доминирующего артиста.
|
||||
⚠️ Кандидат ≠ дефект. Каждый случай подтверждать у Alex (правило сессии 7:
|
||||
«не отвечать за Alex»). Спорный случай: '!Рэп/НТЛ' — формально попадает
|
||||
под правило сборника из сессии 5 (треки в корне при наличии подпапок-альбомов).
|
||||
|
||||
Контроль после правок: гонять детектор, пока он не вернёт пусто или только
|
||||
подтверждённые Alex спорные случаи (класс выявляется итеративно).
|
||||
"""
|
||||
import sys
|
||||
|
||||
import csv
|
||||
import collections
|
||||
import sys
|
||||
|
||||
P = sys.argv[1] if len(sys.argv) > 1 else '/Users/admin/Downloads/music-tags/APPLY-PLAN.csv'
|
||||
rows = list(csv.DictReader(open(P, encoding='utf-8-sig', newline='')))
|
||||
@@ -49,7 +40,7 @@ for folder, rs in sorted(by.items()):
|
||||
continue
|
||||
top, n = art.most_common(1)[0]
|
||||
total = len(rs)
|
||||
# доминирует один артист: >50% файлов
|
||||
# one artist dominates — folder is NOT a genuine compilation
|
||||
if n / total > 0.5 and n >= 2:
|
||||
suspects.append((n, total, top, folder))
|
||||
|
||||
|
||||
Reference in new issue
Block a user