[2026-09-27] eagle: personal/plans/music-artist-albumartist-repair.md personal/plans/tagwriter-container.md personal/tech/id3-tag-repair-skill-notes.md personal/tech/music-tags-repair-truenas.md
This commit is contained in:
1 parent
50f91752bc
commit
8ce2b1e6a4
4 files changed
+413
-1353
No files matched your search
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: Skill — id3-tag-repair (питфоллы и уроки)
|
||||
created: '2026-09-26'
|
||||
updated: '2026-09-26'
|
||||
updated: '2026-09-27'
|
||||
type: tech
|
||||
namespace: personal
|
||||
tags:
|
||||
@@ -13,6 +13,7 @@ tags:
|
||||
related:
|
||||
- '[[personal/tech/music-tags-repair-truenas]]'
|
||||
- '[[personal/tech/music-tags-final-review]]'
|
||||
- '[[personal/plans/tagwriter-container]]'
|
||||
---
|
||||
|
||||
# Skill `id3-tag-repair` — зеркало Obsidian
|
||||
@@ -20,6 +21,10 @@ related:
|
||||
Скилл: `media/id3-tag-repair` (`~/.hermes/hermes-whale/skills/media/id3-tag-repair/SKILL.md`).
|
||||
Здесь — durable-правила, выученные на проекте Music Tags TrueNAS. Полный текст — в скилле.
|
||||
|
||||
> 🆕 **Скилл обновлён 2026-09-27 (v1.1.0):** добавлен раздел **«Writing tags back: the ID3v1 /
|
||||
> ID3v2 block layer»** (правила W1–W13) — класс дефектов «применение отчиталось об успехе, данные
|
||||
> потеряны». См. § ID3v1/ID3v2 ниже (пункты 14–23).
|
||||
|
||||
## Пакетные правки данных
|
||||
|
||||
1. **Идемпотентность обязательна.** Цель считать от ИСХОДНОГО значения (номер в имени файла),
|
||||
@@ -64,3 +69,57 @@ related:
|
||||
grep -c "^Benny Benassi," artists-single-track.csv # ожидание 0
|
||||
grep -c "^Benny Benassi," artists-multi-track.csv # ожидание всех
|
||||
```
|
||||
|
||||
## 🔴 ID3v1 / ID3v2 — выучено 2026-09-27 (v13)
|
||||
|
||||
14. 🔴 **ID3v1 — скрытый источник мусора, его надо СНОСИТЬ.** `ID3()` (mutagen) читает
|
||||
**только v2-блок**; ID3v1 (128 байт в конце файла) он не видит, а `save(v2_version=3)`
|
||||
его **не удаляет**. Найденo: **1099 из 2004 файлов** имеют v1. В v1 — latin-1
|
||||
(`'????? ????????? ???????'`) и обрезка полей до 30 байт. Плеер читает v1 **первым** →
|
||||
показывает мусор вместо правильного v2. **Фикс: `tags.save(disk, v1=0, v2_version=3)`.**
|
||||
|
||||
15. 🔴 **Граница «что из CSV, что из файла» проходит по КОЛОНКАМ CSV, а не по «есть/нет в файле».**
|
||||
```
|
||||
6 управляемых полей (TIT2/TPE1/TPE2/TALB/TCON/TRCK) → ТОЛЬКО из CSV.
|
||||
Пусто в CSV => тег УДАЛЯЕТСЯ. Старое значение НЕ подставляется.
|
||||
Поля вне CSV (APIC/TDRC/COMM/TCOM/WXXX… ) → из ID3v2; нет в v2 → из ID3v1
|
||||
ID3v1 → сносится
|
||||
```
|
||||
Неправильная трактовка («пусто в CSV → взять старое») приводит к тому, что чистка мусора
|
||||
не работает.
|
||||
|
||||
16. 🔴 **Из ID3v1 переносятся только 2 поля** — остальные 4 (title/artist/album/genre)
|
||||
дублируют управляемые, их значения всё равно придут из CSV:
|
||||
| v1 | → v2 | Условие |
|
||||
|---|---|---|
|
||||
| `year` | `TDRC` | нет TDRC в v2 **и** год = ровно `\d{4}` |
|
||||
| `comment` | `COMM` | нет ни одного COMM в v2 |
|
||||
|
||||
17. 🔴 **Год из ID3v1 бывает байтовым мусором.** Реальный кейс: `year = '\x00\x00\x000'` →
|
||||
записался бы `TDRC='\x00\x00\x000'`. Чистить нули/пробелы с **обеих** сторон,
|
||||
отбрасывать строки с управляющими символами, год валидировать `re.fullmatch(r"\d{4}", y)`.
|
||||
|
||||
18. 🔴 **Нормализатор обязан иметь тесты на ведущие нули.** Регексп `^[1-9]\d{0,3}…` «незаметно»
|
||||
отвергал `'095'` → 133 файла получили бы **пустой** `TRCK` вместо номера.
|
||||
Поймано юнит-тестом, не глазом. Рабочий: `^\d{1,4}(/\d{1,4})?$` + `int()`.
|
||||
|
||||
19. 🔴 **Инвариант обязан использовать значения, проходящие собственную валидацию.**
|
||||
`_self_check()` собирал probe `{"new_track": "x"}` → `normalize_track("x")==""` → фрейм
|
||||
«не создаётся» → **ложный ABORT**. Для числовых полей probe = `"1"`.
|
||||
|
||||
20. 🔴 **Скрипт-генератор НЕ должен перезаписывать файл, который правится параллельно.**
|
||||
`fix_track_and_selfcheck.py` правил CSV **и** перезаписывал `apply_tags_v2.py` целиком →
|
||||
повторный прогон затёр ручные правки. Разделять: CSV-нормализатор + `patch`.
|
||||
|
||||
21. 🔴 **Тест обязан ИМПОРТИРОВАТЬ функции из скрипта, а не дублировать их** — иначе тест
|
||||
проверяет свою копию логики и показывает устаревший результат (дал 2 ложных FAIL).
|
||||
|
||||
22. 🔴 **Docker-образ содержит СВОЮ копию скрипта.** Заливка нового файла в монтируемую `data/`
|
||||
не влияет — выполняется старая версия из образа. Симптом:
|
||||
`AttributeError: module 'at2' has no attribute '_read_id3v1'`.
|
||||
**`docker cp <new> <container>:/app/script.py` обязателен.**
|
||||
|
||||
23. 🔴 **Договорённость, не записанная в файл, не существует.** Контекст диалога сбрасывается,
|
||||
файл — нет. Alex: «это неоднократно». За одну задачу потерялось 5 решений
|
||||
(`v1=0`, колонка `track`, тестовые файлы, патч-скрипт, нормализатор). Фиксировать в файл
|
||||
в том же ходе.
|
||||
@@ -23,6 +23,24 @@ related:
|
||||
|
||||
# Music Tags Repair — TrueNAS (7906 → 7905 файлов)
|
||||
|
||||
> ### 🔴 АКТУАЛЬНОЕ СОСТОЯНИЕ (2026-09-27) — ЧИТАЙ ЭТО ПЕРВЫМ
|
||||
>
|
||||
> **Этот файл — исторический лог волны 38 (завершена). Актуальная работа идёт здесь:**
|
||||
>
|
||||
> | Документ | О чём |
|
||||
> |---|---|
|
||||
> | **[[personal/plans/tagwriter-container]]** | ⭐ скрипт-писатель `apply_tags_v2.py` (566 стр): логика полей, ID3v1-снос, тесты, 18 питфоллов, запуск |
|
||||
> | **[[personal/plans/music-artist-albumartist-repair]]** | правила формирования плана, сборка `APPLY-PLAN-FINAL2.csv` |
|
||||
> | **[[personal/tech/music-broken-toload]]** | 29 битых/DRM файлов на перезагрузку |
|
||||
>
|
||||
> **Состояние:** скрипт готов и протестирован, **боевой прогон НЕ запущен — ждёт «go» от Alex.**
|
||||
> Боевой вход: `~/Downloads/music-tags/APPLY-PLAN-FINAL2.csv` (7861 строка).
|
||||
> Скрипты: `~/Automation/music-tags/`.
|
||||
>
|
||||
> ⚠️ Волна 38 (TIT2/TPE1/TALB/TRCK, 7041 файл) — **завершена**, описывается ниже как история.
|
||||
> Её дефекты (`apply_tags.py` испортил 16 не-MP3, `fix40.py` убил 40 MP3) разобраны в
|
||||
> `tagwriter-container.md` § 8 «Питфоллы».
|
||||
|
||||
> ## ⏭ НОВАЯ ЗАДАЧА (2026-09-27): `artist` + `albumartist` + `album` ПО ВСЕЙ БИБЛИОТЕКЕ
|
||||
>
|
||||
> Волна 38 закрыла **MP3-план** (TIT2/TPE1/TALB/TRCK). Но Alex поставил задачу **шире**:
|
||||
|
||||
Reference in new issue
Block a user