[2026-09-27] eagle: personal/plans/music-artist-albumartist-repair.md personal/tech/id3-tag-repair.md
This commit is contained in:
1 parent
d0a8cd1601
commit
981a59781e
2 files changed
+189
-7
No files matched your search
@@ -29,6 +29,11 @@ related:
|
||||
> ⚠️ **Обновлён до v1.5.0 (сессия 11):** правила **D9** (порядок блоков: монотонность ≠
|
||||
> читаемость) и **D10** (служебные секции полноты в хвосте диффа). См. тот же раздел,
|
||||
> а также `personal/plans/music-artist-albumartist-repair.md` § «🔷 СЕССИЯ 11».
|
||||
>
|
||||
> ⚠️ **Обновлён до v1.6.0 (сессия 12):** **D9** — починка порядка (слить `collapse_lines`
|
||||
> и `file_lines` в один список, `field` первым + `scope` вторым; правка `key=` в двух
|
||||
> раздельных циклах бесполезна); **D11** (`new_track` теряется при пустом `cur_track`);
|
||||
> **D12** (`new_track` «ни к чему не привязан» → сдвинутый ряд пересчитать, иначе убрать).
|
||||
|
||||
## 📁 Артефакты проекта
|
||||
|
||||
@@ -381,7 +386,83 @@ z Другое…/C.Шнуров - Бумер (2003) 19 → Сергей
|
||||
**Правило:** для отчёта о структуре выводить **явный список границ блоков** (`prev != cur` →
|
||||
новая строка) с номерами строк, а не агрегат по `Counter`. Монотонность ≠ читаемость.
|
||||
|
||||
См. `personal/plans/music-artist-albumartist-repair.md` § «🔷 СЕССИЯ 11».
|
||||
✅ **РЕШЕНО в сессии 12** — порядок: `field` первым, `scope` вторым. Дифф стал едиными
|
||||
блоками по полю (`album` ПАПКА+ТРЕК, `albumartist` ПАПКА+ТРЕК, …), стык `track(ПАПКА) →
|
||||
album(ТРЕК)` исчез.
|
||||
|
||||
🔴 **Питфолл починки (стоил 3 итерации):** правка `key=` внутри **двух раздельных циклов
|
||||
записи** (`for … collapse_lines`, затем `for … file_lines`) **не даёт эффекта** — `scope`
|
||||
в ключе не может поднять `ТРЕК album` выше `ПАПКА track`, потому что списки пишутся
|
||||
последовательно. Нужно **слить оба списка в один** и отсортировать одним ключом:
|
||||
|
||||
```python
|
||||
out_rows = []
|
||||
for fld, fname, ov, nv, n in collapse_lines:
|
||||
out_rows.append((fkey(fname), 0, fld, "", "ПАПКА", fld, "", fname, ov, nv))
|
||||
for fld, rel, fname, ov, nv in file_lines:
|
||||
out_rows.append((fkey(fname), 1, fld, rel, "ТРЕК", fld, rel, fname, ov, nv))
|
||||
out_rows.sort(key=lambda x: x[:4])
|
||||
```
|
||||
|
||||
**Признак, что правка не применилась:** `md5` файла **не изменился**. Проверять эффект
|
||||
только по md5 + перечитыванию строк — «правка выглядит правильной» ничего не значит.
|
||||
|
||||
### 🔴 D11 — `new_track` теряется, когда `cur_track` пустой
|
||||
|
||||
Логика заполнения пропускает файл с пустым текущим тегом → номер из плана 38-го прогона
|
||||
**не восстанавливается**. Найдено 4 строки:
|
||||
|
||||
```
|
||||
old_38=17 → '' !Детские/Сказки/Алиса в Стране Чудес (Диск2)/04 - Песня про ребенка-поросенка.mp3
|
||||
old_38= 8 → '' !Pop, Club, Любэ/Света/2003 - Зеркала/08 - Жизнь моя.mp3
|
||||
old_38= 0 → '' !Pop, Club, Любэ/!Radio/t 2009-07 c6Or_NICK/00 Geo da Silva - ....mp3
|
||||
old_38= 0 → '' !Rock&Folk/ЗАХАР МАЙ/2011 - Казань против диабета/00-intro-family-affair.mp3
|
||||
```
|
||||
|
||||
**Детектор (гонять после каждой перегенерации плана) — по самому диффу:**
|
||||
|
||||
```python
|
||||
lost = [r for r in rows if r["field"] == "track"
|
||||
and (r["old_38"] or "").strip() and not (r["new_apply_plan"] or "").strip()]
|
||||
```
|
||||
|
||||
Если `old_38` было числом, а `new_apply_plan` пусто — это **потеря**, а не правка.
|
||||
Восстановление: перенести значение из `old_38` (`/tmp/restore_lost_track.py`).
|
||||
|
||||
### 🔴 D12 — `new_track` «ни к чему не привязан» → пересчитать или убрать
|
||||
|
||||
Правило Alex (сессия 12):
|
||||
> «если там есть порядковый номер в альбоме — то ты его оставляешь»
|
||||
> «если он ни к чему не привязан то убираешь»
|
||||
|
||||
Косяк, на который он указал: `!Детские/Сказки/Алиса в Стране Чудес (Диск2)/04` имел
|
||||
`track=17` при **13 файлах** в папке (ряд `14..26` — это нумерация **диска 2**
|
||||
многодискового издания, протёкшая в отдельную папку).
|
||||
|
||||
**Классификация по папке** (полный ряд проверять по числу файлов **с номерами**, не по
|
||||
числу файлов):
|
||||
|
||||
| Класс | Признак | Действие | Строк |
|
||||
|---|---|---|---|
|
||||
| A. Ряд **сдвинут** | уникальные номера идут подряд без дыр, `len(uni)==n_files`, `uni[0] != 1` | пересчитать `1..N`: `new = old - (min(nums) - 1)` | 269 |
|
||||
| B. **Полного ряда нет** | есть дыры/дубли/номера вне диапазона | номер из имени файла, иначе **пусто** | 1107 |
|
||||
| C. Ряд `1..N` корректный | `nums == range(1, len(nums)+1)` | не трогать | 371 папок |
|
||||
|
||||
Извлечение номера из имени: `re.match(r"^(\d{1,3})\s*[-._)]?\s+", filename)`, диапазон `1..300`.
|
||||
|
||||
Примеры класса A: `Алиса (Диск2)` 14..26 → 1..13 · `Трое из Простоквашино (Диск 2)` 10..20 →
|
||||
1..11 · `Принц и нищий (Диск 2)` 8..14 → 1..7 · `Малыш и Карлсон (Диск 2)` 4..6 → 1..3.
|
||||
|
||||
🔴 **Класс A требует полного ряда без дыр** — иначе пересчёт «съест» пропущенный трек.
|
||||
Именно поэтому 51 папка `!Radio/*` (рваные ряды, дубли `2,2,3,3,5,5` у `x 2008-04`) **осталась
|
||||
нетронутой** — для них правило ещё не получено.
|
||||
|
||||
**Не путать с `TRCK`-классом «`99` как плейсхолдер»:** `!Рэп/НТЛ` имеет 8 файлов с
|
||||
`track=99` и 6 с `track=51` (`cur == new`, значение унаследовано). Это не номер трека.
|
||||
|
||||
Скрипты: `/tmp/fix_track_bugs.py` (сухой прогон по умолчанию, `--apply` для записи),
|
||||
`/tmp/restore_lost_track.py`, `/tmp/audit_track_seq.py`, `/tmp/classify_track.py`.
|
||||
См. `personal/plans/music-artist-albumartist-repair.md` § «🟢 СЕССИЯ 12».
|
||||
|
||||
### 🔴 D10 — секции полноты в хвосте диффа читаются как мусор
|
||||
|
||||
|
||||
Reference in new issue
Block a user