[2026-09-27] eagle: personal/plans/music-artist-albumartist-repair.md personal/tech/id3-tag-repair.md
This commit is contained in:
1 parent
6576b53834
commit
85f0f009dd
2 files changed
+171
-21
No files matched your search
@@ -35,6 +35,10 @@ related:
|
||||
> раздельных циклах бесполезна); **D11** (`new_track` теряется при пустом `cur_track`);
|
||||
> **D12** (`new_track` «ни к чему не привязан» → сдвинутый ряд пересчитать, иначе убрать).
|
||||
>
|
||||
> ⚠️ **Обновлён до v1.8.0 (сессия 13, вторая половина):** **D16** (схлопывание диффа: ключ
|
||||
> `(папка, поле, НОВОЕ значение)`, `old` в ключ не входит), **D17** (`album` унаследован от
|
||||
> `cur_album` для подборок `!Radio` — 203 строки; метод: имя подборки = значение большинства).
|
||||
>
|
||||
> ⚠️ **Обновлён до v1.7.0 (сессия 13):** **D12 ОТКАЧЕН** — см. **D12-R** ниже (сквозная
|
||||
> нумерация многодисковых изданий НЕ трогать). Добавлены **D13** (жанр унаследован от
|
||||
> `cur_genre` без проверки), **D14** (статус «привязан/сирота» для `track`), **D15** (поиск
|
||||
@@ -531,6 +535,68 @@ lost = [r for r in rows if r["field"] == "track"
|
||||
|
||||
Скрипт: `/tmp/classify_track.py`.
|
||||
|
||||
### 🔴 D16 — схлопывание диффа: ключ `(папка, поле, НОВОЕ значение)`, НЕ `old` (сессия 13)
|
||||
|
||||
Первая версия схлопывала только когда у **всех** файлов папки совпадал **и `old`, и `new`**:
|
||||
```python
|
||||
combos = set((ov, nv) for _, ov, nv in lst)
|
||||
if len(combos) == 1 and len(lst) > 1: collapse...
|
||||
else: для каждого файла отдельная строка
|
||||
```
|
||||
Это **почти никогда не срабатывало**: `old_38` у каждого файла свой (`'Дискотека Арлекина 2009'`,
|
||||
`'Record Super Chart ¹ 90 (30.05.2009)'`, `''`, `'Ticker / Sensor'` …). Папка из 43 файлов
|
||||
давала 43 строки при **одном** новом значении.
|
||||
|
||||
Alex: «схлопывание по `field+value` делается, а не по `old` — очевидно что он блядь у всех разный!»
|
||||
|
||||
**Правильно — группировать по новому значению внутри `(папка, поле)`:**
|
||||
```python
|
||||
groups = defaultdict(list)
|
||||
for rel, ov, nv in lst:
|
||||
groups[nv].append((rel, ov)) # ключ НЕ включает old
|
||||
for nv, members in groups.items():
|
||||
if len(members) > 1:
|
||||
olds = sorted({ov for _, ov in members})
|
||||
label = olds[0] if len(olds) == 1 else f"<{len(olds)} разных>"
|
||||
collapse_lines.append((fld, fname, label, nv, len(members)))
|
||||
else:
|
||||
rel, ov = members[0]
|
||||
file_lines.append((fld, rel, fname, ov, nv))
|
||||
```
|
||||
|
||||
🔴 **Питфолл отчёта:** в колонку `old_38` схлопнутой строки **нельзя** подставлять одно из
|
||||
нескольких старых значений — это враньё в отчёте. Если старых значений больше одного, писать
|
||||
`<N разных>`.
|
||||
|
||||
**Эффект:** `!Radio/t 2009-07 c6Or_NICK` `field=album` — 43 строки → 1 (`'<7 разных>' -> '2009-07 c6Or_NICK'`).
|
||||
Дифф целиком 4996 → 2864 строк (`ПАПКА` 1123→1485 · `ТРЕК` 3747→1253).
|
||||
Контроль полноты на трек-уровне не меняется (`assert covered + len(file_lines) == sum(field_counts)`).
|
||||
|
||||
### 🔴 D17 — `album` унаследован от `cur_album` для подборок `!Radio` (сессия 13, 203 строки)
|
||||
|
||||
Тот же корень, что и **D13**: план копирует значение из тега файла, не проверяя, уместно ли оно.
|
||||
Здесь — `new_album` ← `cur_album`. Для подборок `!Radio` **`album` = имя папки-подборки**
|
||||
(правило сессии 7), а не альбом, из которого трек взят.
|
||||
|
||||
```
|
||||
!Radio/t 2009-07 c6Or_NICK/plux/Би-2 и Агата Кристи - Теряю свет.mp3
|
||||
cur_album='Нечетный воин 2' → new_album='Нечётный Воин 2' ❌
|
||||
правильно: '2009-07 c6Or_NICK'
|
||||
```
|
||||
Один и тот же трек, но в **папке-альбоме** `!Rock&Folk/Би-2/Нечетный Воин/2008 Проект…`
|
||||
(`class='АЛЬБОМ'`) — там `album='Нечётный Воин 2'` и `albumartist='Би-2'` **верны**.
|
||||
|
||||
**Метод фикса (без выдумывания значений):** целевое имя папки-подборки берётся как значение,
|
||||
которое **уже стоит у большинства** файлов папки (значит оно проставлено ранее правилом), плюс
|
||||
требование `cnt >= 2`. Папки, где такого большинства нет либо `class='АЛЬБОМ'` — **пропускать**.
|
||||
|
||||
**Детектор разнобоя:** для каждой папки `Counter(new_album)`; `len(vals) > 1` = дефект.
|
||||
Скрипты: `/tmp/audit_radio_album.py` (поиск), `/tmp/fix_radio_album.py` (правка, сухой прогон по умолчанию).
|
||||
До: 19 папок / 469 строк. После: 2 папки (обе `3 SHANSON/Трофим` — там альбомы Трофима, пропущены намеренно).
|
||||
|
||||
🔴 **Не путать с правильными случаями:** `z Старое/disk/N NAME` → `'RADIO N NAME'` — это
|
||||
**одно** значение на папку и оно верно; дефект только там, где значения разные.
|
||||
|
||||
### 🔴 D15 — поиск по бэкапам: фильтр `.csv` отсекает `APPLY-PLAN.csv.bak-*` (сессия 13)
|
||||
|
||||
`glob(f"{B}/APPLY-PLAN.csv*")` + условие `p.endswith(".csv")` **выбрасывает все бэкапы**,
|
||||
|
||||
Reference in new issue
Block a user