[2026-09-27] eagle: family/projects/watchlist-automation.md family/projects/watchlist-sync.md personal/plans/music-artist-albumartist-repair.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-27 22:05:21 +06:00
1 parent a143f8ab2e
commit e91e3c3ae5
3 files changed
+251 -24

No files matched your search

+117 -24
View File
@@ -4,7 +4,7 @@ created: '2026-09-27'
updated: '2026-09-27'
type: plan
namespace: personal
status: dry-run-done / boevoy-zapusk-pravilnyy-cmd-ne-podtverzhden
status: БОЕВОЙ-ПРОГОН-ВЫПОЛНЕН / TCON-4359-ЗАПИСАН / verify-0-mismatch
tags:
- music
- metadata
@@ -46,17 +46,16 @@ related:
Канон: ~/Downloads/music-tags/APPLY-PLAN.csv (7861 строка — НЕ ПЕРЕЗАПИСЫВАТЬ)
```
**Состояние (27 сен, сессия ~30):** ✅ **dry-run ВЫПОЛНЕН УСПЕШНО** — `7653 к правке`,
`mp3 на диске 7861`, `не найдено 0`. Требование Alex «совпасть по цифрам с
APPLY-PLAN-v3-changes» **снято самим Alex** («нихуя не понял… очевидно что полный набор»):
дифф считает группы, dry-run — файлы, совпадение недостижимо by design. Решение Alex:
**пишем полный набор полей** (не только `TCON`).
**Состояние (27 сен, сессия ~31):** ✅ **БОЕВОЙ ПРОГОН ВЫПОЛНЕН УСПЕШНО.**
`7653/7653 ok, err=0`; **`TCON` записан в 4359 файлов** — открытый дефект с 27 сен ЗАКРЫТ.
Проверка чтением файлов (не по логу): `7861/7861 имеют TCON`, `mismatches 0`, `read errors 0`.
🔴 **БОЕВОЙ ПРОГОН НЕ СОСТОЯЛСЯ — запущен с неверным аргументом.** См. § БОЕВОЙ ПРОГОН,
немедленно читать перед повтором.
Скрипт пишет **все 6 полей сразу** (`TIT2 TPE1 TPE2 TALB TCON TRCK`) — режима «только genre» нет.
Решение Alex: **полный набор**, дифф не пересобираем; требование «совпасть по цифрам с
APPLY-PLAN-v3-changes» снято самим Alex (дифф = ГРУППЫ, прогон = ФАЙЛЫ).
**Открытый дефект:** жанры (`TCON`) в тегах отсутствуют. Скрипт исправлен, dry-run доказал,
что `TCON` пишется. Боевой прогон — ждёт корректной команды.
⏳ **Осталось:** пересканить Navidrome (`stop → rm navidrome.db* → up -d`) и убедиться в UI,
что альбомы/жанры встали без дублей. **Кэш БД не чищен.**
**Доступ к NAS:** `ssh -i ~/.ssh/id_rsa truenas_admin@mallexxx.duckdns.org`
⚠️ `192.168.1.100` — ЧУЖАЯ подсеть, не использовать. Подробнее → [[family/how-to/truenas-access]]
@@ -77,7 +76,9 @@ APPLY-PLAN-v3-changes» **снято самим Alex** («нихуя не пон
| 8 | 27 сен | **Канонный дифф v3 собран** — сортировка по `field`, схлопывание, шум убран | `DIFF-base-vs-applyplan-v3.csv` |
| 9 | 27 сен | **Верификация артефактов v3 перед dry-run** — 3 расхождения вскрыты, см. § ВЕРИФИКАЦИЯ | `/tmp/verify_v3*.py` |
| 10 | 27 сен | **Dry-run выполнен: 7653 к правке, не найдено 0** — `TCON` пишется | `/tmp/dryrun.log` |
| 11 | 27 сен | 🔴 **Боевой прогон не состоялся** — `CMD=--dry-run` образа подставился | `/tmp/tw306/run.log` |
| 11 | 27 сен | 🔴 **Прогон №1 сорвался** — `CMD=--dry-run` образа подставился | `/tmp/tw306/run.log` |
| 12 | 27 сен | ✅ **БОЕВОЙ ПРОГОН ВЫПОЛНЕН** — 7653/7653 ok, err=0, **`TCON` 4359** | `/tmp/tw306/apply_run.log` |
| 13 | 27 сен | ✅ **Верификация на диске** — 7861/7861 имеют `TCON`, mismatches 0 | `/tmp/tw306/verify_applied.py` |
---
@@ -143,13 +144,20 @@ docker create --name twdry --entrypoint python3 \
tagwriter:latest /app/apply_tags_v2.py --dry-run
docker start -a twdry
# 3. БОЕВОЙ ПРОГОН — CMD переопределить явно, иначе будет dry-run (см. ПИТФОЛЛ 13):
# 3. БОЕВОЙ ПРОГОН — 3 ОТДЕЛЬНЫЕ КОМАНДЫ, не одной строкой (см. ПИТФОЛЛ 17):
docker rm -f twrun >/dev/null 2>&1
docker create --name twrun --entrypoint python3 \
-v /tmp/tw306:/app/data:ro -v /mnt/RED_2TB/storage/Music:/music:rw \
tagwriter:latest /app/apply_tags_v2.py --apply # ← ФЛАГ ПОДТВЕРДИТЬ В СКРИПТЕ
docker start -a twrun
tagwriter:latest /app/apply_tags_v2.py --apply # ✅ ФЛАГ ПОДТВЕРЖДЁН РАБОЧИМ
docker inspect twrun --format 'CMD={{json .Config.Cmd}}' # должен быть --apply, БЕЗ --dry-run
docker start twrun # НЕ `start -a` — не держать терминал
```
⚠️ `docker start twrun` **без `-a`**: прогон идёт ~7 минут, `-a` держит SSH-сессию открытой
и ход легко прерывается. Прогресс — `docker ps --filter name=twrun`, ожидание —
`docker wait twrun`, лог — `docker logs twrun > /tmp/tw306/apply_run.log`.
🔴 **Лог появляется только в КОНЦЕ** (скрипт буферизует): пустой `docker logs` при живом
процессе — это НЕ зависание. Проверять `docker top twrun` / `docker stats twrun`.
- Образ `tagwriter:latest` (НЕ `v2`), uid 950:950, amd64 · 25971 байт `apply_tags_v2.py`
- **План читается ТОЛЬКО как `/app/data/apply-plan.csv`** → подкладывать
`/tmp/apply-plan-v3.csv` под этим именем
@@ -209,6 +217,7 @@ backup_raw
/tmp/verify_v3c.py верификация: аномалии (genre-дубли, Sbornik, пропуск пути)
/tmp/parse_dry.py разбор лога dry-run по полям (только показанные 40 файлов!)
/tmp/dryrun.log вывод успешного dry-run (копия с NAS)
/tmp/verify_applied.py верификация ПОСЛЕ прогона: читает TCON/TPE2/TALB из файлов
~/Developer/personal-os/tools/music-tags/build_fix_plan2.py генератор плана (пофикшен)
```
@@ -279,11 +288,12 @@ Dry-run считает ФАЙЛЫ: album 28 · albumartist 6 · genre 4359 (в
| Дефект | Факт | Статус |
|--------|------|--------|
| **Жанры не в тегах** | В БД `genre` пусто у всех 7861; прогон 27 сен не писал `TCON` | Скрипт исправлен, dry-run доказал `TCON`. **Боевой прогон нужен** |
| 🔴 **Боевой прогон сорвался** | Запущен без переопределения `CMD` → подставился `--dry-run` образа | **Ничего не записано. Повтор с явным CMD** |
| **Жанры не в тегах** | В БД `genre` было пусто у всех 7861; прогон 27 сен не писал `TCON` | ✅ **ЗАКРЫТ 27 сен:** `TCON` записан в 4359 файлов, на диске 7861/7861, mismatches 0 |
| Жанры в диффе | 427 строк / 911 групп, покрытие 7861 — не «правка», а повторная запись | Учтено |
| Лог v3 устарел | 3 строки + 1 путь расходятся с планом после `fix_ruki`/`fix_rockopop` | Решено: план — эталон, лог не пересобираем |
| Дифф: genre-группы | 211 ТРЕК-строк дублируют `new_genre`; 7 одиночек не добраны | **Alex снял вопрос:** пишем полный набор, дифф не пересобираем |
| `track` −4 от плана | 4 файла `changed=yes`, расхождений нет → скрипт не писал | **Не дефект**, ожидаемо |
| **Navidrome-кэш не чищен** | Теги на диске новые, БД Navidrome — старая (музыку не сканировали) | ⏳ **Ждёт перескана: `stop → rm navidrome.db* → up -d`** |
---
@@ -327,7 +337,7 @@ genre 4359 · albumartist 7213 · album 2031 · track 441 · artist 381 · title
plan.changed=yes 7653
```
### 🔴 БОЕВОЙ ПРОГОН — НЕ СОСТОЯЛСЯ (запущен с неверным аргументом)
### 🔴 ПРОГОН №1 — НЕ СОСТОЯЛСЯ (запущен с неверным аргументом)
Запущено:
```bash
@@ -348,8 +358,84 @@ CMD = ["--dry-run"]
**✅ Ничего не записано, музыка не тронута, бэкап не потребовался.**
**Осталось перед повтором:** подтвердить в скрипте флаг боевого режима (в доках он
не зафиксирован — проверялись только `--dry-run`), затем `docker create` **с явным CMD**.
---
### ✅ ПРОГОН №2 — БОЕВОЙ, ВЫПОЛНЕН УСПЕШНО (27 сен, сессия ~31)
Флаг боевого режима — **`--apply`** (подтверждён рабочим). CMD переопределён явно:
```bash
docker rm -f twrun >/dev/null 2>&1
docker create --name twrun --entrypoint python3 \
-v /tmp/tw306:/app/data:ro -v /mnt/RED_2TB/storage/Music:/music:rw \
tagwriter:latest /app/apply_tags_v2.py --apply
docker inspect twrun --format 'CMD={{json .Config.Cmd}}'
# CMD=["/app/apply_tags_v2.py","--apply"] ENTRY=["python3"] ← проверено ДО старта
docker start twrun # без -a; затем docker wait twrun
```
**Результат** (`/tmp/tw306/apply_run.log`, `exit=0`):
```
строк в плане: 7861
mp3 на диске: 7861 пропущено не-mp3: 562
пропущено changed=no: 208
не найдено на диске: 0
к обработке: 7653
=== APPLY: 7653 файлов ===
... 7653/7653 (100%) ok=7653 err=0
=== ИТОГ APPLY ===
обработано: 7653 · успешно: 7653 · ошибок: 0
изменения по полям:
TIT2 (title): 8
TPE1 (artist): 381
TPE2 (albumartist): 7213
TALB (album): 2031
TCON (genre): 4359 ← ЖАНРЫ ЗАПИСАНЫ
TRCK (track): 437
```
**Сверка с планом** — все поля совпали, кроме `track`:
| поле | записано | в плане | ✓ |
|---|---|---|---|
| `TCON` genre | **4359** | 4359 | ✓ |
| `TPE2` albumartist | 7213 | 7213 | ✓ |
| `TALB` album | 2031 | 2031 | ✓ |
| `TPE1` artist | 381 | 381 | ✓ |
| `TIT2` title | 8 | 8 | ✓ |
| `TRCK` track | 437 | 441 | −4 |
Минус 4 по `track` = те самые 4 файла `changed=yes`, но без расхождений
(Infected Mushroom ×3, `Пушной/Город Омск`) — скрипт им ничего не писал. **Не дефект.**
---
### ✅ ВЕРИФИКАЦИЯ ПОСЛЕ ПРОГОНА — ЧТЕНИЕМ ФАЙЛОВ (не по логу)
Скрипт `/tmp/verify_applied.py` (на NAS `/tmp/tw306/verify_applied.py`), прогон:
```bash
docker create --name verapp --entrypoint python3 \
-v /tmp/tw306:/app/data:ro -v /mnt/RED_2TB/storage/Music:/music:ro \
tagwriter:latest /app/data/verify_applied.py
docker start verapp && docker wait verapp && docker logs verapp
```
⚠️ Обход 7861 файла НЕ укладывается в 180-секундный форграунд-лимит → запускать
через `docker create` + `docker start` (без `-a`), результат забирать `docker logs`.
Результат:
```
files_read = 7861
has TCON (genre) = 7861 ← жанр у КАЖДОГО файла
has TPE2 (albumart) = 7861
has TALB (album) = 7861
TCON mismatches = 0
read errors = 0
```
**Открытый дефект «жанры не в тегах» (с 27 сен) — ЗАКРЫТ.**
**Проверяет Alex:** открыть Navidrome — альбомы должны показывать жанры.
---
@@ -358,8 +444,8 @@ CMD = ["--dry-run"]
```
Библиотека: 7861 живых файлов = строкам плана
Бэкапы: 535 файлов (6 папок, в .ndignore)
Боевой прогон: 27 сен, 7649/7649 ok, err=0, VERIFY 7649
Поля прогона: TPE2 7213 · TCON 4359 · TALB 1659 · TPE1 381 · TRCK 344 · TIT2 8
Прогон 27 сен №1: 7649/7649 ok, err=0, VERIFY 7649 (без TCON — старый скрипт)
Поля прогона №1: TPE2 7213 · TCON 4359 · TALB 1659 · TPE1 381 · TRCK 344 · TIT2 8
Поля плана (cur!=new): album 2031 · albumartist 7213 · genre 4359 · artist 381 ·
title 8 · track 441 ; plan.changed=yes 7653
Дифф v3: 945 строк (ПАПКА 711 · ТРЕК 234)
@@ -369,17 +455,24 @@ CMD = ["--dry-run"]
Dry-run 27 сен: план 7861 · mp3 на диске 7861 · не найдено 0 · к обработке 7653
(пропущено changed=no 208, не-mp3 562) · лог печатает 40 файлов
changed=yes но расхождений нет: 4 файла (Infected Mushroom ×3, Пушной)
Боевой прогон: НЕ СОСТОЯЛСЯ — подставился `CMD=--dry-run` образа
БОЕВОЙ прогон №2: ✅ ВЫПОЛНЕН — 7653/7653 ok, err=0, exit=0
TCON 4359 · TPE2 7213 · TALB 2031 · TPE1 381 · TRCK 437 · TIT2 8
(= плану, кроме track −4: 4 файла без расхождений)
Верификация диска: files_read 7861 · has TCON 7861 · TCON mismatches 0 · read errors 0
Navidrome: ⏳ кэш БД НЕ чищен, рескан не делался
```
---
## 📁 ФАЙЛЫ НА NAS (рабочие, `/tmp/tw306/`)
```
apply-plan.csv md5 6b9e49b2baa3f1d1708e4566972266a9 (= /tmp/apply-plan-v3.csv)
apply-plan.csv 2882525 B, md5 6b9e49b2baa3f1d1708e4566972266a9 (= /tmp/apply-plan-v3.csv)
dryrun.log 21955 B — вывод успешного dry-run (есть копия на Mac /tmp/dryrun.log)
run.log вывод сорвавшегося боевого прогона (снова DRY-RUN)
run.log прогон №1: снова DRY-RUN, ничего не записано (CMD образа)
apply_run.log ✅ прогон №2 БОЕВОЙ: 7653/7653 ok, err=0, exit=0
verify_applied.py верификация на диске: 7861/7861 TCON, mismatches 0
check_album_applied*.py / verify_306*.py вспомогательные проверки
```
---