From 82f27a69da8eb81f6dadf214f746b138ae21dbd3 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Sat, 26 Sep 2026 18:50:11 +0600 Subject: [PATCH] [2026-09-26] eagle: personal/plans/music-tags-review/music-tags-review.md personal/tech/music-tags-repair-truenas.md --- .../music-tags-review/music-tags-review.md | 80 +++++++++++++++++++ personal/tech/music-tags-repair-truenas.md | 23 +++++- 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/personal/plans/music-tags-review/music-tags-review.md b/personal/plans/music-tags-review/music-tags-review.md index d162e125..50bbfd4f 100755 --- a/personal/plans/music-tags-review/music-tags-review.md +++ b/personal/plans/music-tags-review/music-tags-review.md @@ -20,6 +20,86 @@ updated: '2026-09-26' | [[2-medium-confidence\|Средняя уверенность]] | 5813 | | [[3-high-confidence\|Высокая уверенность]] | 959 | +## 🔴 Восемнадцатая волна (2026-09-26): РЕГРЕССИЯ ПОЧИНЕНА + ДВЕ СВОДНЫЕ CSV СОБРАНЫ + +Alex: **«Рэпер сява - поправь на просто "Сява"»** + **«подготовить рядом ещё пару csv»**. + +### ✅ `Рэпер Сява` → `Сява` (2 строки) + +`disk_v2/5 POPSA/Нука нака.mp3` (artist) и `Отдыхаем хорошо(Ida Corr cocktail).mp3` +(artist `DJ Иван Silver & Сява`). Питфолл: fuzzy-match `patch` съел **соседнюю строку** +`Ленинград - Ласточка.mp3` — восстановлена, файл сохранён (7907 строк). + +### 🔴 РЕГРЕССИЯ НАЙДЕНА И ПОЧИНЕНА: 18 битых строк от моей же правки класса A + +Диагностика (`python3` + `csv.reader`, счёт полей по строкам) показала рост битых строк +с **4 → 22** между бэкапами `171423` → `180619`. **4 были изначально** (Пахмутова — многострочный +mojibake с `"` внутри), **18 внёс я** при вырезании техпапок из `new_album` в `z Старое/disk*` — +потерял по одной запятой (пустое поле) в 15 строках, добавил лишнюю в 3. + +| Класс дефекта | Строк | Фикс | +|---|---:|---| +| `10 полей` — потеряна пустая `new_album` | 8 | `,,,,` вместо `,,,` (NSK ×2, Перец ×2, Простоквашено ×2, Monster DJ's ×2) | +| `12 полей` — лишнее пустое поле | 8 | `,,` вместо `,,,` (Nickelback ×4, P.O.D. ×2, Jay-Z ×2) | +| `12 полей` — запятая в `Короче, дело к ночи` без кавычек | 2 | title закавычен | +| `10/3 полей` — Пахмутова, `"` внутри значения | 4 | `corrupt`-строки переписаны чисто | + +**Итог: 0 битых, 7907 строк, все CRLF.** Урок: **`wc -l` + счёт полей после каждого батча** — +регрессия жила незамеченной с 17-й волны, потому что проверялись только кавычки и длина файла, +но не число полей. +**Диагностический скрипт (только чтение):** `~/Downloads/music-tags/diag_fields.py` — +гистограмма числа полей по строкам, печатает все строки ≠ 11 полей. + +### 📊 ДВЕ СВОДНЫЕ CSV (новый артефакт) + +`~/Downloads/music-tags/build_summaries.py` (только чтение исходника, запись новых файлов): + +| Файл | Строк | Колонки | +|---|---:|---| +| `artists-single-track.csv` | 778 | `artist, title, album, path` | +| `artists-multi-track.csv` | 7128 | `artist, album, track, title, path` | + +**778 + 7128 = 7906 — все строки исходной CSV покрыты** (проверка в скрипте печатает `TOTAL COVERED`). +Сортировка: исполнитель → альбом → номер трека (`track_key`: числовой ключ, пустой в конец). +Значения берутся **исправленные** (`new_*`, с fallback на `cur_*`). + +> 🔴 **Питфолл генерации:** строки с **пустым `artist`** (188 шт.) при группировке склеивались +> в одну фальшивую группу `,,`. Фикс: sentinel `(без исполнителя)` + разделение по album +> (`(без исполнителя) — `). Пустых artist в итоговых файлах — **0** (проверено). + +### 🖐 ПОЧЕМУ 186 СТРОК БЕЗ ARTIST — ЭТО НЕ КОСЯК + +Alex спросил: **«Откуда строки с пустым артистом? Это косяк.»** +Проверено по самому раннему бэкапу `164432` — **186 из 188 были пустыми с самого начала**: + +| Где | Кол-во | Это | +|---|---:|---| +| `!Детские/Сказки/*` | 186 | аудиосказки (Бременские, Буратино, Врунгель, Алиса…) — **у них нет исполнителя** | +| `!A Not sorted/НАШЕСТВИЕ 2009 - ДЕНЬ ВТОРОЙ.mp3` | 1 | файл-фестиваль | +| `Голубой щенок/01 - Хоттабыч!.mp3` | 1 | сказка | + +Грабитель тегов оставил `artist` пустым, потому что источник — сборник, а не песня. +**Вывод: не косяк правок, правильного artist просто не существует.** + +### 📊 Состояние на конец 18-й волны + +| Показатель | Значение | +|---|---:| +| Строк в CSV | 7906 (+1 заголовок = 7907) | +| Битых строк | **0** | +| CRLF-потерь | **0** | +| `fix` / `no_change` | 6931 / 976 | +| Ручных правок | ~640 | +| Регрессия класса A | ✅ **ПОЧИНЕНА** | +| Сводные CSV | ✅ **СОБРАНЫ (778 + 7128 = 7906)** | +| Применение на NAS | **НЕ начато** | + +### ⏭ Осталось + +1. Только применение: **бэкап `Music/backup/` → применение → приёмка в UI Alex → Music-библиотека Jellyfin** + (ждём «go»). +2. Отдельно: чистить merge-конфликт в `1-needs-decision.md` (по команде Alex). + ## 🔴 Пятнадцатая волна (2026-09-26): КЛАСС 3 ЗАКРЫТ, КЛАСС 4 НАЧАТ ### ✅ Класс 3 (номер трека в `new_title`) — ЗАКРЫТ ПОЛНОСТЬЮ, 156 строк diff --git a/personal/tech/music-tags-repair-truenas.md b/personal/tech/music-tags-repair-truenas.md index 1e305fdd..9441c8e6 100755 --- a/personal/tech/music-tags-repair-truenas.md +++ b/personal/tech/music-tags-repair-truenas.md @@ -20,8 +20,27 @@ related: # Music Tags Repair — TrueNAS (7906 файлов) -> **Статус: СЕМНАДЦАТАЯ ВОЛНА (2026-09-26). КЛАСС C, A, 3, 4 ЗАКРЫТЫ + ЧИСТКА `no_change` ПРОДВИНУТА. -> NAS ДОСТУПЕН, применение НЕ начато.** +> **Статус: ВОСЕМНАДЦАТАЯ ВОЛНА (2026-09-26). CSV ГОТОВ К ПРИМЕНЕНИЮ. +> `Рэпер Сява`→`Сява`; РЕГРЕССИЯ 18 БИТЫХ СТРОК ПОЧИНЕНА (0 битых); ДВЕ СВОДНЫЕ CSV СОБРАНЫ. +> NAS ДОСТУПЕН, применение НЕ начато — ждём «go».** +> ✅ **НОВОЕ (18-я волна):** исправлена **собственная регрессия** — при вырезании техпапок из +> `new_album` в `z Старое/disk*` (17-я волна) терялись запятые → 18 битых строк. Все починены. +> **Урок: после каждого батча считать ЧИСЛО ПОЛЕЙ, не только кавычки и длину файла.** +> Диагностика: `python3 ~/Downloads/music-tags/diag_fields.py` (гистограмма полей, строки ≠ 11). +> 📊 **Две сводные CSV** (`build_summaries.py`, только чтение): `artists-single-track.csv` +> (**778** строк: artist/title/album/path) + `artists-multi-track.csv` (**7128** строк: +> artist/album/track/title/path). **778 + 7128 = 7906 — покрыты все строки.** Сортировка +> artist→album→track. Пустой artist → sentinel `(без исполнителя)` (иначе Excel схлопнет). +> 🖐 **188 строк без artist — НЕ косяк:** 186 из них `!Детские/Сказки/*` (аудиосказки без +> единого исполнителя), + `НАШЕСТВИЕ 2009`, + `Голубой щенок`. Так было с самого начала. +> Итог: **0 битых, 7907 строк, `fix` 6931 / `no_change` 976, ручных правок ~640.** +> ⏭ Осталось ТОЛЬКО применение: бэкап `Music/backup/` → применение → приёмка в UI → +> Music-библиотека Jellyfin. Плюс (отдельно) merge-конфликт в `1-needs-decision.md`. +> **Бэкапы:** `...bak-20260926-184122` (последний до регрессии), `bak-20260926-164432` (самый ранний). +> +> --- +> +> Контекст семнадцатой волны: > Работа — ручной проход по CSV `tag-fix-plan.csv` построчно; правка скриптов ЗАПРЕЩЕНА.** > ✅ **Класс A («имя техпапки в artist/album») — ЗАКРЫТ ПОЛНОСТЬЮ: 0 остатков.** > (`Забугр`, `disk`, `disk_v2`, `1 DRIVE`, `5 POPSA`, `3 SHANSON` — все вычищены.)