# Структура результатов После обработки все аудиокниги раскладываются по структурированным папкам. Корневая папка результатов — `result/` (или `dir.out` из `config.yaml`, или флаг `-result`). --- ## Основная структура ``` result/ ├── А/ │ └── Акунин Борис/ │ ├── Акунин Борис — Азазель [2003]/ │ │ ├── metadata.json │ │ ├── cover.jpg │ │ ├── 001.mp3 │ │ └── 002.mp3 │ └── Акунин Борис — Турецкий гамбит [2003]/ │ ├── metadata.json │ └── ... ├── Д/ │ └── Достоевский Федор/ │ └── ... ├── ERROR/ │ ├── Неизвестная_книга_123/ │ │ ├── _error.txt │ │ └── <аудиофайлы...> │ └── ... └── DUPLICATE/ └── А/ └── Акунин Борис/ ├── Акунин Борис — Азазель [2003]/ │ ├── metadata.json │ └── ... └── Акунин Борис — Азазель [2003]_2/ └── ... ``` ### Правила формирования имён 1. Первый уровень — первая буква фамилии автора (кириллица/латиница). 2. Второй уровень — `Фамилия Имя` автора. 3. Третий уровень — `Автор — Название [Год]/` (год добавляется только если известен). Специальные символы (`/`, `\`, `:`, `*`, `?`, `"`, `<`, `>`, `|`) в именах папок заменяются безопасными аналогами. --- ## `metadata.json` Создаётся в каждой папке с книгой. Пример: ```json { "title": "Азазель", "authors": ["Акунин Борис"], "year": 2003, "genre": "Детектив", "comment": "Первый роман серии «Приключения Эраста Фандорина»...", "duration": "8h23m", "format": "mp3", "files_count": 24, "cover_found": true, "source": { "folder": "Акунин - Азазель", "file": "001.mp3" }, "torrent": { "id": "123456", "tracker": "rutracker", "title": "Акунин Б. — Азазель (Б. Дьяченко) [2003, MP3, 96 kbps]", "seeds": 42, "size": "198 MB", "url": "https://rutracker.org/forum/viewtopic.php?t=123456" } } ``` ### Поля metadata.json | Поле | Тип | Описание | |---|---|---| | `title` | string | Нормализованное название книги | | `authors` | []string | Список авторов | | `year` | int | Год издания (0 если неизвестен) | | `genre` | string | Жанр | | `comment` | string | Описание из тегов / трекера | | `duration` | string | Длительность первого трека | | `format` | string | Формат аудиофайлов | | `files_count` | int | Кол-во аудиофайлов в папке | | `cover_found` | bool | Найдена ли обложка | | `source.folder` | string | Исходное имя папки | | `source.file` | string | Файл, из которого читались теги | | `torrent.*` | object | Данные с трекера (если найдено) | --- ## Папка `ERROR/` Книги, которые не удалось найти ни на одном трекере после всех попыток. ``` result/ERROR/ └── Исходное_имя_папки/ ├── _error.txt ← причина (не найдено / таймаут / API недоступен) ├── 001.mp3 └── 002.mp3 ``` ### Файл `_error.txt` ``` Ошибка обработки: aудиокнига не найдена на трекерах Папка: Автор - Название Попыток: 3 Последняя ошибка: no results found for query "Название" Время: 2024-01-15 14:23:45 ``` --- ## Папка `DUPLICATE/` Книга с таким же именем целевой папки уже существует в `result/`. ``` result/DUPLICATE/ └── А/ └── Акунин Борис/ ├── Акунин Борис — Азазель [2003]/ ← первый дубликат ├── Акунин Борис — Азазель [2003]_2/ ← второй └── Акунин Борис — Азазель [2003]_3/ ← третий ``` Суффиксы `_2`, `_3`, ... добавляются итеративно до первого свободного имени. --- ## Обложка (`cover.jpg`) Загружается из URL обложки в данных раздачи с трекера. Если URL недоступен или скачивание завершилось ошибкой — книга сохраняется без `cover.jpg`, в лог пишется `WARN`. --- ## Аудиофайлы Аудиофайлы **перемещаются** (не копируются) из исходной папки в папку результата. Исходная папка после успешного переноса становится пустой (или удаляется, в зависимости от ОС). Поддерживаемые расширения: `mp3`, `m4b`, `m4a`, `ogg`, `opus`, `flac`, `aac`, `wma`, `wav`, `aiff`.