[2026-09-27] eagle: family/how-to/navidrome-truenas-android.md personal/plans/tagwriter-container.md
This commit is contained in:
1 parent
1261d89943
commit
96123c9825
2 files changed
+171
-1
No files matched your search
@@ -320,6 +320,45 @@ folder="!Pop, Club, Любэ/Дискотека Авария/Москва пьё
|
||||
**Артефакт для просмотра (запрошен у Alex, ещё не выгружен):** CSV `путь + текущий album + title`
|
||||
по **306** файлам со «скобочным» album, топ-20 для глазной вычитки.
|
||||
|
||||
## ⏳ АКТИВНО (2026-09-27): БОЕВОЙ ПРОГОН 306 ВЫПОЛНЕН — НУЖЕН ПОЛНЫЙ RESCAN
|
||||
|
||||
> **Alex: «Navidrome rescan теперь надо»**
|
||||
|
||||
**Факт: теги на диске исправлены, но БД Navidrome содержит И СТАРЫЕ, И НОВЫЕ альбомы.**
|
||||
|
||||
```bash
|
||||
DB=/mnt/RED_2TB/docker/navidrome/data/navidrome.db
|
||||
sqlite3 "file:$DB?mode=ro" "SELECT COUNT(*) FROM album WHERE name LIKE '(%';" # → 14
|
||||
```
|
||||
|
||||
| Что | Значение |
|
||||
|---|---|
|
||||
| альбомов в БД | 967 |
|
||||
| `album` целиком в скобках | **14** ← не вычищены |
|
||||
| новые значения (`Философские`, `Морские`, `Москва пьёт пиво`, `Старые хиты`, `Дискотека Авария`, `Retro`, `Владимир Высоцкий`, `Несчастный Случай`, `zvezda`) | ✅ присутствуют |
|
||||
|
||||
**Причина:** `ND_SCANSCHEDULE=1h` + watcher **добавили** новые альбомы, но **не удалили** старые
|
||||
записи, оставшиеся без файлов. Инкрементальный скан в Navidrome не чистит сироты сам.
|
||||
|
||||
**Варианты rescan (не выполнено, ждёт слова Alex):**
|
||||
|
||||
| # | Способ | Оценка |
|
||||
|---|---|---|
|
||||
| 1 | `docker restart navidrome` — полный скан на старте | ✅ предпочтительно, пароль не нужен |
|
||||
| 2 | Дождаться планового скана (`1h`) | ⏳ не чистит автоматически, вероятно не поможет |
|
||||
| 3 | Rescan через UI/API | требует пароль `navi_admin` — **неизвестен, не выдумывать** |
|
||||
|
||||
**Проверка после rescan:** тот же запрос `LIKE '(%'` → должно стать **0**, и в UI не должно
|
||||
остаться дублей «альбом со скобками» + «альбом без скобок».
|
||||
|
||||
> 🔴 **ВАЖНО на будущее: `sqlite3` ЕСТЬ на NAS напрямую (`/usr/bin/sqlite3`, 3.40.1)** —
|
||||
> не нужно `docker exec`. В доке выше есть устаревшее утверждение «`docker exec navidrome sqlite3`»:
|
||||
> работает и так, и так, но напрямую по `file:…?mode=ro` быстрее и не требует запуска контейнера.
|
||||
> В контейнере `tagwriter:v2` sqlite3 **нет** (`python3 -c "import sqlite3"` тоже недоступен —
|
||||
> только `mutagen`).
|
||||
|
||||
Боевой прогон и приёмка — [[personal/plans/tagwriter-container]] §СЕССИЯ 21.
|
||||
|
||||
## Остаточные дефекты после деплоя
|
||||
|
||||
| # | Что | Статус |
|
||||
|
||||
@@ -4,7 +4,7 @@ created: '2026-09-26'
|
||||
updated: '2026-09-27'
|
||||
type: plan
|
||||
namespace: personal
|
||||
status: session20-dry-run-306-verified-awaiting-apply-go
|
||||
status: session21-apply-306-done-navidrome-rescan-pending
|
||||
tags:
|
||||
- music
|
||||
- truenas
|
||||
@@ -13,6 +13,7 @@ tags:
|
||||
- id3v1
|
||||
- plan
|
||||
- audit
|
||||
- navidrome
|
||||
related:
|
||||
- '[[personal/plans/music-artist-albumartist-repair]]'
|
||||
- '[[personal/tech/music-tags-repair-truenas]]'
|
||||
@@ -20,6 +21,136 @@ related:
|
||||
---
|
||||
# tagwriter — применение тегов к MP3 (TrueNAS)
|
||||
|
||||
## ✅ СЕССИЯ 21 (2026-09-27) — БОЕВОЙ ПРОГОН 306 ВЫПОЛНЕН, ПРОВЕРЕН READ-BACK; ОТКРЫТ NAVidrome RESCAN
|
||||
|
||||
> **ТРИГГЕР:** Alex: «**Гони боевой.**» — после того как задача была сформулирована однозначно:
|
||||
> «**Задача блядь dry run получить с 306 правок так?!**» → «**Да!!**»
|
||||
>
|
||||
> **СОСТОЯНИЕ:** ✅ **306/306 применено, ошибок 0, read-back с диска 306/306 совпало.**
|
||||
> ⏳ Открыто: **Navidrome показывает и старые, и новые album одновременно — нужен полный rescan.**
|
||||
|
||||
### ✅ БОЕВОЙ ПРОГОН — ФАКТ
|
||||
|
||||
```bash
|
||||
# бэкап 306 файлов ПЕРЕД записью (обязательно)
|
||||
scp /tmp/backup_306.py truenas_admin@mallexxx.duckdns.org:/tmp/
|
||||
ssh … 'python3 /tmp/backup_306.py'
|
||||
# → скопировано: 306 · не найдено: 0 · md5 до/после сверены
|
||||
# → /mnt/RED_2TB/storage/Music/backup_before_306/20260927-051727 (+ _MANIFEST.tsv)
|
||||
|
||||
# боевой прогон
|
||||
ssh … 'docker run --rm \
|
||||
-v /tmp/tw306:/app/data:ro \
|
||||
-v /mnt/RED_2TB/storage/Music:/music:rw \
|
||||
tagwriter:v2 --apply'
|
||||
```
|
||||
|
||||
**Вывод apply:**
|
||||
|
||||
```
|
||||
CSV: /app/data/apply-plan.csv ← 306 строк
|
||||
mp3 на диске: 7861 пропущено не-mp3: 561
|
||||
пропущено changed=no: 0
|
||||
не найдено на диске: 0
|
||||
к обработке: 306
|
||||
|
||||
=== APPLY: 306 файлов ===
|
||||
... 306/306 (100%) ok=306 err=0
|
||||
|
||||
=== ИТОГ APPLY ===
|
||||
обработано: 306 успешно: 306 ошибок: 0
|
||||
|
||||
изменения по полям:
|
||||
TIT2 (title) 0
|
||||
TPE1 (artist) 0
|
||||
TPE2 (albumartist) 306
|
||||
TALB (album) 306
|
||||
TCON (genre) 264
|
||||
TRCK (track) 0
|
||||
```
|
||||
|
||||
### ✅ ПРИЁМКА — READ-BACK ТЕГОВ С ДИСКА (не отчёт скрипта)
|
||||
|
||||
Скрипт `/tmp/verify_306.py` (в контейнере: `/app/data/verify_306c.py`, пути `PLAN=/app/data/apply-plan.csv`,
|
||||
`MUSIC=/music`). Читает `mutagen.id3.ID3` и сравнивает **значения** `TALB`/`TPE2` с `new_album`/`new_albumartist`.
|
||||
|
||||
```
|
||||
проверено файлов: 306
|
||||
совпало (album + albumartist): 306
|
||||
расхождений: 0
|
||||
осталось album в скобках: 0 ← 🔑 ключевой индикатор
|
||||
файлов меньше 100KB: 0 ← аудио целое, не схлопнулось
|
||||
```
|
||||
|
||||
🔴 **Правило: приёмка = чтение тегов с диска по значению, а не `ok=306` из отчёта скрипта.**
|
||||
Дополнительно проверять **размер файла** (`>100KB`) — он доказывает, что MPEG-поток не тронут (W2).
|
||||
|
||||
### ⏳ ОТКРЫТО: NAVidrome — СТАРЫЕ И НОВЫЕ АЛЬБОМЫ СОСУЩЕСТВУЮТ
|
||||
|
||||
Navidrome смотрит в **ту же** папку (`/mnt/RED_2TB/storage/Music → /music`), данные
|
||||
`/mnt/RED_2TB/docker/navidrome/data`, `ND_SCANSCHEDULE=1h`, порт 4533, `https://music.mallexxx.duckdns.org`.
|
||||
|
||||
**Проверка БД (sqlite3 есть на NAS: `/usr/bin/sqlite3`, 3.40.1):**
|
||||
|
||||
```bash
|
||||
DB=/mnt/RED_2TB/docker/navidrome/data/navidrome.db
|
||||
sqlite3 "file:$DB?mode=ro" "SELECT COUNT(*) FROM album WHERE name LIKE '(%';" # → 14
|
||||
```
|
||||
|
||||
| Что | Значение |
|
||||
|---|---|
|
||||
| альбомов в БД | 967 |
|
||||
| со скобками | **14** |
|
||||
| новые значения (`Философские`, `Морские`, `Москва пьёт пиво`, `Retro`, `Владимир Высоцкий`, …) | ✅ появились |
|
||||
| старые скобочные (`(Философские)`, `(Авария)` ×2, `(Высоцкий)`, …) | ❌ **НЕ удалены** |
|
||||
|
||||
**Диагноз:** watcher/плановый скан **добавил** новые альбомы, но **не вычистил старые записи**,
|
||||
к которым больше нет файлов. Нормальное поведение инкрементального скана — нужен полный rescan.
|
||||
|
||||
**Что нужно (не сделано, ждёт решения Alex):**
|
||||
|
||||
1. **Рестарт контейнера** — `docker restart navidrome` (полный скан на старте, чистит пропавшие) —
|
||||
предпочтительный вариант, без пароля;
|
||||
2. **Плановый скан** — сам раз в час (`ND_SCANSCHEDULE=1h`);
|
||||
3. Rescan через API требует пароль `navi_admin` — **неизвестен, не выдумывать**
|
||||
(`curl …/rest/ping` → `code 40 Wrong username or password`).
|
||||
|
||||
Проверка результата — тот же запрос: `LIKE '(%'` должно стать **0**.
|
||||
|
||||
🔴 **Питфолл-нюанс:** Navidrome при скане **пересчитывает album из тегов**, поэтому у 306 файлов
|
||||
кроме `TALB` сменился и `TPE2` — в БД это **новые** записи альбомов, а не апдейт старых.
|
||||
Пока старые не вычищены, в UI видны оба варианта (со скобками и без).
|
||||
|
||||
### 🔴 ИТОГОВЫЙ ПИТФОЛЛ СЕССИИ 21: ЗАДАЧА БЫЛА НЕ СФОРМУЛИРОВАНА — ЧИТАТЬ «СКОЛЬКО ПРАВОК» БУКВАЛЬНО
|
||||
|
||||
Alex потратил час, повторяя один вопрос. Разбор:
|
||||
|
||||
| Что я говорил | Что было нужно |
|
||||
|---|---|
|
||||
| `7649` (весь план) | **`306`** — сколько правок ЖЕЛАЕМ сделать |
|
||||
| `7963` / `4359` (genre) | не относится к задаче |
|
||||
| «какой план гонять?» — переспрашивал | задача была уже названа: **dry-run должен показать 306** |
|
||||
|
||||
🔴 **ПРАВИЛО: если Alex называет ожидаемое число вывода — это И ЕСТЬ задача.**
|
||||
Не переспрашивать «какой план», не предлагать варианты меню. Собрать артефакт так, чтобы
|
||||
вывод был равен названному числу. Переспрашивание после названного числа читается как саботаж.
|
||||
|
||||
Ср. D32 (дифф завышает — считать по плану), D33 (путь + md5 + промежуточные/финальные значения),
|
||||
D35 (не называть числа двух артефактов в одной фразе), D36 (формулировка счёта одним предложением).
|
||||
|
||||
### 📁 АРТЕФАКТЫ СЕССИИ 21
|
||||
|
||||
```
|
||||
~/Downloads/music-tags/apply-plan-306.csv 306 строк, md5 8bfa52389a80119e713b88d05a91b9ef
|
||||
/tmp/make_plan_306.py сборка плана 306 из APPLY-PLAN.csv + ALBUM-FIX-306.csv
|
||||
/tmp/backup_306.py бэкап 306 файлов + _MANIFEST.tsv (md5, size)
|
||||
/tmp/verify_306.py (→ verify_306c.py в контейнере) read-back TALB/TPE2 с диска + проверка размера
|
||||
/tmp/check_navidrome.py проверка БД Navidrome (sqlite3, read-only)
|
||||
NAS: /mnt/RED_2TB/docker/arr/tagwriter/apply-plan-306.csv
|
||||
NAS: /tmp/tw306/apply-plan.csv 306-план под именем, которое читает скрипт
|
||||
NAS: /mnt/RED_2TB/storage/Music/backup_before_306/20260927-051727/ бэкап + _MANIFEST.tsv
|
||||
```
|
||||
|
||||
## 🟢 СЕССИЯ 20 (2026-09-27, поздний вечер) — ПРОИЗВОДНЫЙ ПЛАН НА 306 СОБРАН, DRY-RUN ЖДЁТ «GO»
|
||||
|
||||
> **ТРИГГЕР:** Alex спросил про diff с 371 правкой → после разбора выяснилось, что **spor идёт
|
||||
|
||||
Reference in new issue
Block a user