[2026-09-27] eagle: family/how-to/navidrome-truenas-android.md personal/plans/music-artist-albumartist-repair.md personal/plans/tagwriter-container.md
This commit is contained in:
1 parent
54adfa9a5a
commit
41ae82ab3c
3 files changed
+173
-38
No files matched your search
@@ -1,9 +1,10 @@
|
||||
# Музыкальный плеер с TrueNAS на Android
|
||||
|
||||
**Статус:** ✅ **РАЗВЁРНУТ 2026-09-27** — Navidrome на TrueNAS, работает, скан завершён (8043 трека).
|
||||
🔴 **2026-09-27 (сессия 22):** теги 306 исправлены ✅, но **rescan НЕ помог** — в БД остались **14 сирот** `album` в скобках. `restart` и **пересоздание контейнера** дают `fullScan=false`, теги не перечитываются. Следующий шаг: **`touch` 306 файлов** (mtime) → полный скан.
|
||||
**Статус:** ✅ **РАЗВЁРНУТ 2026-09-27** — Navidrome на TrueNAS, работает.
|
||||
✅ **2026-09-27 (сессия 22):** теги 306 исправлены, **БД Navidrome снесена и построена заново**, скобочных сирот **0**, треков **8167**.
|
||||
🔴 **Ни `restart`, ни пересоздание контейнера НЕ дают полного скана** (`fullScan=false`) — теги не перечитываются. Рабочий способ: **снести `navidrome.db`** (тогда старт → `fullScan=true`).
|
||||
**Дата:** 2026-05-10
|
||||
**Обновлено:** 2026-09-27 (v6 — rescan не помог, 14 сирот, путь через mtime)
|
||||
**Обновлено:** 2026-09-27 (v7 — БД пересоздана, 0 сирот, треков 8167)
|
||||
|
||||
---
|
||||
|
||||
@@ -321,23 +322,17 @@ folder="!Pop, Club, Любэ/Дискотека Авария/Москва пьё
|
||||
**Артефакт для просмотра (запрошен у Alex, ещё не выгружен):** CSV `путь + текущий album + title`
|
||||
по **306** файлам со «скобочным» album, топ-20 для глазной вычитки.
|
||||
|
||||
## 🔴 АКТИВНО (2026-09-27, сессия 22): RESCAN НЕ ПОМОГ — 14 СИРОТ ОСТАЛИСЬ
|
||||
## ✅ РЕШЕНО (2026-09-27, сессия 22): СНОС БД → ПОЛНЫЙ СКАН → 0 СИРОТ
|
||||
|
||||
> **Alex: «Navidrome rescan теперь надо»** → затем **«Просто контейнер пересоздай»**
|
||||
> **Alex: «Navidrome rescan теперь надо»** → **«Просто контейнер пересоздай»** → **«Сука базу блядь снеси руками!!!»**
|
||||
|
||||
**Факт: теги на диске исправлены, но БД Navidrome содержит И СТАРЫЕ, И НОВЫЕ альбомы.**
|
||||
**Проблема:** теги на диске исправлены, но БД Navidrome содержала И СТАРЫЕ, И НОВЫЕ альбомы — **14 сирот**.
|
||||
|
||||
```bash
|
||||
DB=/mnt/RED_2TB/docker/navidrome/data/navidrome.db
|
||||
sqlite3 "file:$DB?mode=ro" "SELECT COUNT(*) FROM album WHERE name LIKE '(%';" # → 14 (до и после)
|
||||
sqlite3 "file:$DB?mode=ro" "SELECT COUNT(*) FROM album WHERE name LIKE '(%';" # → 14 (до и после попыток rescan)
|
||||
```
|
||||
|
||||
| Что | Значение |
|
||||
|---|---|
|
||||
| альбомов в БД | 967 |
|
||||
| `album` целиком в скобках | **14** ← не вычищены (число НЕ изменилось от rescan) |
|
||||
| новые значения (`Философские`, `Морские`, `Москва пьёт пиво`, `Старые хиты`, `Дискотека Авария`, `Retro`, `Владимир Высоцкий`, `Несчастный Случай`, `zvezda`) | ✅ присутствуют |
|
||||
|
||||
### ❌ ЧТО ПРОБОВАЛОСЬ И НЕ ПОМОГЛО (факт)
|
||||
|
||||
| # | Способ | Результат |
|
||||
@@ -354,27 +349,47 @@ sqlite3 "file:$DB?mode=ro" "SELECT COUNT(*) FROM album WHERE name LIKE '(%';"
|
||||
(скан их не помечает missing). Причина: album = пара `(name, album_artist)`; теги сменились →
|
||||
Navidrome **создал новые** альбомы, **старые не удалил** (быстрый скан файлы не перечитывает).
|
||||
|
||||
### 🔑 СЛЕДУЮЩИЙ ШАГ (не сделан): перечитать `mtime` файлов → полный скан
|
||||
### ✅ СНОС БД — РАБОЧИЙ СПОСОБ (выполнен)
|
||||
|
||||
Единственный надёжный путь без пароля: **`touch` 306 файлов** (меняет только `mtime`, содержимое
|
||||
и аудио не трогает) → Navidrome увидит «изменённые» файлы → перечитает теги → сироты уйдут.
|
||||
Либо через UI Navidrome: `Скан` с галкой **«Full scan»** (пароль `navi_admin` неизвестен —
|
||||
спрашивать у Alex, не выдумывать; `curl /rest/ping` → `code 40 Wrong username or password`).
|
||||
```bash
|
||||
D=/mnt/RED_2TB/docker/navidrome/data
|
||||
mkdir -p "$D/navidrome.db.bak-$(date +%Y%m%d-%H%M%S)" # копия ПЕРЕД сносом (обязательно)
|
||||
cp "$D"/navidrome.db* "$D/navidrome.db.bak-<ts>"/
|
||||
cd /mnt/RED_2TB/docker/navidrome && docker compose stop
|
||||
rm -v "$D/navidrome.db" "$D/navidrome.db-shm" "$D/navidrome.db-wal"
|
||||
docker compose up -d # старт → Full scan required after migration
|
||||
```
|
||||
|
||||
**Проверка после:** тот же запрос `LIKE '(%'` → должно стать **0**, в UI не должно быть дублей
|
||||
«альбом со скобками» + «альбом без скобок».
|
||||
**Лог на старте:** `Full scan required after migration` → `Scanner: Starting scan fullScan=true` ✅
|
||||
|
||||
> 🔴 **ПИТФОЛЛ (важно на будущее): `docker restart` и `docker compose down/up` для Navidrome
|
||||
> НЕ вызывают полный скан.** В логе всегда `fullScan=false`. Navidrome читает только новые/изменённые
|
||||
> файлы. Для принудительного перечитывания тегов нужно менять `mtime` файлов или использовать
|
||||
> UI-скан с `Full scan`. Полный скан на старте — `ND_SCANONSTARTUP` + `ND_SCANONSTARTUP` force
|
||||
> (**не проверено**, в ENV отсутствует; проверять, если `touch` не поможет).
|
||||
**Результат (факт по `sqlite3`):**
|
||||
|
||||
| Метрика | До сноса | После |
|
||||
|---|---:|---:|
|
||||
| `album` целиком в скобках | **14** | **0** ✅ |
|
||||
| треков (`media_file`) | 7861 | **8167** |
|
||||
| альбомов (`album`) | 967 | **837** |
|
||||
|
||||
Все целевые значения присутствуют по одному разу: `Философские` · `Морские` · `Блатные` ·
|
||||
`Спортивные` · `Из Сказок` · `Разное` · `Москва пьёт пиво` · `Старые хиты` · `Дискотека Авария`(2) ·
|
||||
`Красивые, богатые` · `Retro` · `Вилли Токарев` · `Владимир Высоцкий` · `Несчастный Случай` · `zvezda`.
|
||||
|
||||
**Проверка после:** `sqlite3 "file:$DB?mode=ro" "SELECT COUNT(*) FROM album WHERE name LIKE '(%';"` → **0**.
|
||||
|
||||
⚠️ **Что теряется при сносе БД:** плейлисты, избранное, счётчики проигрываний, оценки, пользователи
|
||||
Navidrome (пароль задаётся заново в UI). **Что НЕ теряется:** музыка и теги — они на диске.
|
||||
**Бэкап `navidrome.db.bak-<ts>/` обязателен** — единственный путь к откату метаданных Navidrome.
|
||||
|
||||
> 🔴 **ПИТФОЛЛ (главный, метод): НИ `docker restart`, НИ `docker compose down/up` не дают полного
|
||||
> скана Navidrome** — в логе всегда `fullScan=false` (`duration≈3s`). Массовая смена тегов без смены
|
||||
> `mtime` не подхватывается: Navidrome **добавляет** новые альбомы и **не удаляет** старые → дубли
|
||||
> «скобочный + чистый». `ND_SCANSCHEDULE=1h` тоже не помогает. **Единственный проверенный способ —
|
||||
> снести `navidrome.db`** (старт форсирует `fullScan=true`). Альтернатива без сноса — `touch` файлов
|
||||
> (меняет `mtime`, не содержимое) + полный скан; в этой сессии не применялась.
|
||||
|
||||
> 🔴 **ВАЖНО на будущее: `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`).
|
||||
> не нужно `docker exec`. Быстрее и не требует запуска контейнера. В контейнере `tagwriter:v2`
|
||||
> `sqlite3` **нет** (только `mutagen`).
|
||||
|
||||
Боевой прогон и приёмка — [[personal/plans/tagwriter-container]] §СЕССИЯ 21.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ created: '2026-09-27'
|
||||
updated: '2026-09-27'
|
||||
type: plan
|
||||
namespace: personal
|
||||
status: session20-dry-run-306-verified-awaiting-apply-go
|
||||
status: session20-APPLY-306-done-nav.md-REBUILT
|
||||
tags:
|
||||
- music
|
||||
- metadata
|
||||
@@ -363,6 +363,89 @@ Alex: «**это 4359 правки?**» про таблицу из 16 пар. **
|
||||
> 🔴 Ловушка: `/mnt/RED_2TB/Music` **пуста** — первый прогон смонтировал её и дал `к правке: 0`.
|
||||
> Подробности и два питфолла — `[[personal/plans/tagwriter-container]]` §СЕССИЯ 20.
|
||||
|
||||
### ✅ БОЕВОЙ ПРОГОН 306 — ВЫПОЛНЕН И ПРИНЯТ ПО ДИСКУ (сессия 20, вечер)
|
||||
|
||||
Alex: «**Гони боевой**» → «**Navidrome rescan теперь надо**» → «**Просто контейнер пересоздай**»
|
||||
→ «**Сука базу блядь снеси руками!!!**»
|
||||
|
||||
| Шаг | Факт |
|
||||
|---|---|
|
||||
| Бэкап ДО правки | `/mnt/RED_2TB/storage/Music/backup_before_306/20260927-051727` — **306 файлов + `_MANIFEST.tsv`** (md5 каждого до/после копии, расхождений 0). Скрипт `/tmp/backup_306.py` |
|
||||
| План на NAS | `/tmp/tw306/apply-plan.csv`, md5 `8bfa52389a80119e713b88d05a91b9ef` = локальному ✅ |
|
||||
| **APPLY** | ✅ **306/306, ошибок 0** |
|
||||
| Изменения по полям | `TALB` 306 · `TPE2` 306 · `TCON` 264 · `TIT2`/`TPE1`/`TRCK` **0** (не тронуты) |
|
||||
| **READ-BACK с диска** (не отчёт скрипта) | ✅ проверено 306 · **совпало 306** · расхождений **0** · **album в скобках — 0** · файлов < 100 КБ — **0** (аудио целое). Скрипт `/tmp/verify_306c.py` (пути внутри контейнера: `/app/data`, `/music`) |
|
||||
|
||||
> 🔴 **МЕТОД-УРОК (приёмка):** `--apply` печатает «306/306, 0 ошибок» — это **не приёмка**
|
||||
> (ср. W2: «40/40 записано» при уничтоженном аудио). Приёмка = **перечитать теги с диска**
|
||||
> своим скриптом и проверить ЗНАЧЕНИЕ + размер файла. Здесь это дало `совпало 306 / расхождений 0`.
|
||||
|
||||
### 🔴 NAVIDROME: СКАН НЕ ПЕРЕЧИТЫВАЕТ ТЕГИ — ЛЕЧИТСЯ ТОЛЬКО СНОСОМ БД
|
||||
|
||||
Хронология (каждый шаг **проверен запросом к БД**, а не на словах):
|
||||
|
||||
| Действие | Результат |
|
||||
|---|---|
|
||||
| `docker restart navidrome` | `fullScan=false`, `Scan completed` за 3 с → **в БД те же 14 альбомов со скобками** |
|
||||
| `docker compose down && up -d` (пересоздание) | снова `fullScan=false` → **те же 14**. БД лежит на диске (том `/data`), пересоздание контейнера её не трогает |
|
||||
| ✅ **Снос БД руками** | бэкап `data/navidrome.db.bak-20260927-053238/` → `rm navidrome.db{,-shm,-wal}` → старт → `Full scan required after migration`, **`fullScan=true`** |
|
||||
|
||||
**Финал (факт по `sqlite3`):**
|
||||
|
||||
```
|
||||
БЫЛО: album со скобками 14 | треков 7861
|
||||
СТАЛО: album со скобками 0 | альбомов 837 | треков 8167
|
||||
```
|
||||
|
||||
Целевые значения в БД: `Философские` 1 · `Морские` 1 · `Блатные` 1 · `Спортивные` 1 ·
|
||||
`Из Сказок` 1 · `Разное` 1 · `Москва пьёт пиво` 1 · `Старые хиты` 1 · `Дискотека Авария` 2 ·
|
||||
`Красивые, богатые` 1 · `Retro` 1 · `Вилли Токарев` 1 · `Володимир Высоцкий`→`Владимир Высоцкий` 1 ·
|
||||
`Несчастный Случай` 1 · `zvezda` 1. **Скобочных дублей — 0.**
|
||||
|
||||
> 🔴 **МЕТОД-УРОК (Navidrome):** обычный скан (`fullScan=false`) сверяет **`mtime`/путь**, а не теги.
|
||||
> Массовая правка тегов **не видна** быстрому скану: Navidrome добавляет **новые** альбомы,
|
||||
> старые **не удаляет** → дубли «скобочный + чистый». Рестарт и пересоздание контейнера
|
||||
> **не помогают** (`ND_SCANSCHEDULE=1h` тоже). Рабочий способ — **снести `navidrome.db`**,
|
||||
> тогда старт даёт `fullScan=true` и база строится заново. Перед сносом — копия `navidrome.db*`.
|
||||
> **Теряется:** плейлисты/избранное/счётчики Navidrome. **Не теряется:** музыка и теги (на диске).
|
||||
> Проверочные запросы: `sqlite3 "file:.../navidrome.db?mode=ro" "SELECT COUNT(*) FROM album WHERE name LIKE \"(%\";"`.
|
||||
|
||||
### 🗄 ИНФРАСТРУКТУРА (уточнения сессии 20)
|
||||
|
||||
| Факт | Значение |
|
||||
|---|---|
|
||||
| **Библиотека музыки на NAS** | **`/mnt/RED_2TB/storage/Music`** (100 ГБ, 15 929 mp3). `/mnt/RED_2TB/Music` — **пустая обманка** |
|
||||
| Карта путей | план хранит `/storage/Music/...`; в контейнере это `/music`; на хосте `/mnt/RED_2TB/storage/Music` |
|
||||
| Navidrome | контейнер `navidrome`, образ `deluan/navidrome:latest` (0.64.2), порт 4533, `ND_SCANSCHEDULE=1h` |
|
||||
| Compose Navidrome | `/mnt/RED_2TB/docker/navidrome/docker-compose.yml` (бэкап `.bak-20260927-052857`), том `/mnt/RED_2TB/storage/Music:/music:rw` |
|
||||
| `tagwriter:v2` | `CSV_IN = "/app/data/apply-plan.csv"` — путь **зашит константой**, CLI-флага для плана нет. Свой план подкладывать под этим именем в отдельную папку |
|
||||
| Вариант запуска без approval | `docker run --rm -v …:/app/data:ro -v …/Music:/music:rw tagwriter:v2 --dry-run` |
|
||||
| `/mnt/RED_2TB/IRONWOLF` | пустой второй пул (не библиотека) |
|
||||
|
||||
### ❓ ОТКРЫТЫЙ ВОПРОС ALEX (сессия 20, конец)
|
||||
|
||||
Alex про песни из `!Детские` — «**А нам все равно, если б я был султан, платы паровоз — какой
|
||||
albumartist и album? Они же в песнях для детей лежат? Почему они не в одном альбоме для детей
|
||||
оказались?**»
|
||||
|
||||
**Факт:** этих песен в `!Детские` **нет**. Все три — в **`!Retro/Юрий Никулин`** (3 файла):
|
||||
|
||||
```
|
||||
!Retro/Юрий Никулин/Если бы я был султан.mp3
|
||||
!Retro/Юрий Никулин/Постой паровоз.mp3
|
||||
!Retro/Юрий Никулин/А нам все равно.mp3
|
||||
folder = !Retro/Юрий Никулин class = АЛЬБОМ
|
||||
album = Песни albumartist = Юрий Никулин artist = Юрий Никулин
|
||||
```
|
||||
|
||||
Причина: правило **D21** (файл в папке артиста = один альбом) смотрит только на **путь** и не
|
||||
учитывает, что песня «детская». `!Детские` (570 файлов) содержит свои альбомы
|
||||
(`Сборка Песни для детей` 165 · `Детский Хит Сезона` 156), эти три — не там.
|
||||
|
||||
**«Храбрый зайчик»** — поиск по плану и по диску (`*зайчик*`, `*заяц*`, `*храбр*`) дал **0**.
|
||||
Найденные «зайчики» — другие песни (`Мартовский заяц`, `Хор мальчиков-зайчиков`, `Солнечный зайчик` ×2).
|
||||
⏭ Ждём от Alex точное имя/исполнителя.
|
||||
|
||||
---
|
||||
|
||||
## 🟣 СЕССИЯ 18 (2026-09-27) — NAVIDROME РАЗВЁРНУТ, ДЕФЕКТ-КЛАСС ВСКРЫТ, ПРАВИЛА ВОССТАНОВЛЕНЫ ИЗ ZULIP, 306 СТРОК ИСПРАВЛЕНЫ, НОВЫЙ ДИФФ ГОТОВ
|
||||
|
||||
@@ -4,7 +4,7 @@ created: '2026-09-26'
|
||||
updated: '2026-09-27'
|
||||
type: plan
|
||||
namespace: personal
|
||||
status: session22-apply-306-done-navidrome-rescan-failed-14-orphans
|
||||
status: session22-apply-306-done-navidrome-db-rebuilt-0-orphans
|
||||
tags:
|
||||
- music
|
||||
- truenas
|
||||
@@ -118,15 +118,52 @@ sqlite3 "file:$DB?mode=ro" "SELECT COUNT(*) FROM album WHERE name LIKE '(%';"
|
||||
Compose не менялся (бэкап `docker-compose.yml.bak-20260927-052857`), данные/музыка целы.
|
||||
⚠️ Сироты: `updated_at` 10:09–10:23 UTC, `missing=0` — скан их живыми считает.
|
||||
|
||||
**🔑 СЛЕДУЮЩИЙ ШАГ (не сделан): `touch` 306 файлов → полный скан.** `touch` меняет только `mtime`,
|
||||
содержимое/аудио не трогает; Navidrome увидит «изменённые» файлы и перечитает теги. Альтернатива —
|
||||
UI-скан с галкой **Full scan** (пароль `navi_admin` неизвестен — **не выдумывать**,
|
||||
`curl …/rest/ping` → `code 40 Wrong username or password`).
|
||||
🔑 **РЕШЕНИЕ НАЙДЕНО (Alex): «Сука базу блядь снеси руками!!!» → снос `navidrome.db`.**
|
||||
|
||||
Проверка результата — тот же запрос: `LIKE '(%'` должно стать **0**.
|
||||
| # | Способ | Результат |
|
||||
|---|---|---|
|
||||
| 1 | `docker restart navidrome` | ❌ `fullScan=false` → те же **14** |
|
||||
| 2 | `docker compose down` + `up -d` | ❌ `fullScan=false`, `duration=3.12s` → снова **14** |
|
||||
| 3 | ✅ **снести `navidrome.db*` → старт** | ✅ `Full scan required after migration`, **`fullScan=true`** → **скобок 0** |
|
||||
|
||||
🔴 **ПИТФОЛЛ: `docker restart` и `docker compose down/up` для Navidrome НЕ дают полного скана** —
|
||||
в логе всегда `fullScan=false`. Смена тегов без смены `mtime` не подхватывается.
|
||||
**Порядок (выполнен и подтверждён):**
|
||||
|
||||
```bash
|
||||
D=/mnt/RED_2TB/docker/navidrome/data
|
||||
mkdir -p "$D/navidrome.db.bak-$(date +%Y%m%d-%H%M%S)" # копия ПЕРЕД сносом
|
||||
cp "$D"/navidrome.db* "$D/navidrome.db.bak-<ts>"/
|
||||
cd /mnt/RED_2TB/docker/navidrome && docker compose stop
|
||||
rm -v "$D/navidrome.db" "$D/navidrome.db-shm" "$D/navidrome.db-wal"
|
||||
docker compose up -d # построит БД заново
|
||||
```
|
||||
|
||||
**Результат (факт по `sqlite3`):**
|
||||
|
||||
| Метрика | До сноса | После |
|
||||
|---|---:|---:|
|
||||
| `album` со скобками | 14 | **0** |
|
||||
| треков (`media_file`) | 7861 | **8167** |
|
||||
| альбомов (`album`) | 967 | **837** |
|
||||
|
||||
Все целевые значения присутствуют по одному разу: `Философские` · `Морские` · `Блатные` ·
|
||||
`Спортивные` · `Из Сказок` · `Разное` · `Москва пьёт пиво` · `Старые хиты` · `Дискотека Авария`(2) ·
|
||||
`Красивые, богатые` · `Retro` · `Вилли Токарев` · `Владимир Высоцкий` · `Несчастный Случай` · `zvezda`.
|
||||
|
||||
⚠️ **Что теряется при сносе БД:** плейлисты, избранное, счётчики проигрываний, оценки, пользователи
|
||||
Navidrome (пароль задаётся заново в UI). **Что НЕ теряется:** музыка и теги — они на диске.
|
||||
Поэтому бэкап `navidrome.db.bak-<ts>/` обязателен — единственный путь к откату метаданных Navidrome.
|
||||
|
||||
**Проверка после:** `sqlite3 "file:$DB?mode=ro" "SELECT COUNT(*) FROM album WHERE name LIKE '(%';"` → **0**.
|
||||
|
||||
⚠️ Сироты: `updated_at` 10:09–10:23 UTC, `missing=0` — скан их живыми считает.
|
||||
|
||||
🔴 **ПИТФОЛЛ (главный, метод): НИ `docker restart`, НИ `docker compose down/up` не дают полного
|
||||
скана Navidrome — в логе всегда `fullScan=false`.** Массовая смена тегов без смены `mtime` не
|
||||
подхватывается: Navidrome **добавляет** новые альбомы и **не удаляет** старые → дубли
|
||||
«скобочный + чистый». `ND_SCANSCHEDULE=1h` тоже не помогает. **Единственный рабочий способ —
|
||||
снести `navidrome.db`** (тогда старт форсирует `fullScan=true`). Альтернатива без сноса —
|
||||
`touch` 306 файлов (меняет `mtime`, не содержимое) + полный скан; в этой сессии не применялась,
|
||||
сработал снос БД.
|
||||
|
||||
🔴 **Питфолл-нюанс:** Navidrome при скане **пересчитывает album из тегов**, поэтому у 306 файлов
|
||||
кроме `TALB` сменился и `TPE2` — в БД это **новые** записи альбомов, а не апдейт старых.
|
||||
|
||||
Reference in new issue
Block a user