Создана структура документации, описывающая функциональность, установку, использование CLI, архитектуру и интеграции с TorrAPI и OpenRouter. Добавлены примеры конфигурации и метаданных, а также описание структуры выходных данных.
117 lines
6.1 KiB
Markdown
117 lines
6.1 KiB
Markdown
# Архитектура
|
||
|
||
GenAudioBookInfo построен по принципам **Чистой архитектуры** (Clean Architecture / Hexagonal Architecture).
|
||
Бизнес-логика не зависит от внешних библиотек, баз данных или UI-фреймворков.
|
||
|
||
---
|
||
|
||
## Слои
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────┐
|
||
│ cmd/genaudiobookinfo/main.go (Composition Root / DI) │
|
||
├──────────────────────────────────────────────────────────┤
|
||
│ presentation/ TUI, ConsoleLogger, Presenter │
|
||
├──────────────────────────────────────────────────────────┤
|
||
│ usecase/ Бизнес-логика. Нет зависимостей │
|
||
│ от infra, только интерфейсы │
|
||
├──────────────────────────────────────────────────────────┤
|
||
│ domain/ Сущности + интерфейсы (порты) │
|
||
├──────────────────────────────────────────────────────────┤
|
||
│ infrastructure/ Адаптеры: FS, HTTP, теги, YAML │
|
||
└──────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
Зависимости направлены **внутрь**: `main → usecase → domain ← infrastructure`.
|
||
|
||
---
|
||
|
||
## Структура папок
|
||
|
||
```
|
||
genaudiobookinfo/
|
||
├── cmd/
|
||
│ └── genaudiobookinfo/
|
||
│ └── main.go # Точка входа, DI, TUI запуск
|
||
├── internal/
|
||
│ ├── domain/
|
||
│ │ ├── audiobook.go # Агрегат AudioBookInfo, EnrichedBookInfo
|
||
│ │ ├── llm.go # Интерфейс LLMClient
|
||
│ │ ├── ports.go # Все порты: FolderLister, MetadataExtractor,
|
||
│ │ │ # TorrentSearcher, ResultWriter, CoverDownloader,
|
||
│ │ │ # ProcessLogger, ProcessResult
|
||
│ │ └── torrent.go # Сущности TorrentInfo, TorrentDetail
|
||
│ ├── usecase/
|
||
│ │ └── scan_audiobooks.go # Конвейер (Pipeline + Fan-Out/Fan-In)
|
||
│ ├── infrastructure/ # Адаптеры (реализации портов)
|
||
│ │ ├── folder_lister.go # FSFolderLister
|
||
│ │ ├── metadata_extractor.go # TagMetadataExtractor (dhowden/tag)
|
||
│ │ ├── torrapi_client.go # TorrAPIClient (HTTP)
|
||
│ │ ├── result_writer.go # FSResultWriter (создание папок, JSON, копирование)
|
||
│ │ ├── cover_downloader.go # HTTPCoverDownloader
|
||
│ │ ├── openrouter_client.go # OpenRouterClient (LLM через REST)
|
||
│ │ ├── audio_utils.go # Утилиты: длительность, формат, список файлов
|
||
│ │ ├── console_windows.go # SetConsoleUTF8 для Windows
|
||
│ │ └── console_other.go # Заглушка для non-Windows
|
||
│ ├── nameparser/
|
||
│ │ └── parser.go # Разбор "Автор - Название" из имени папки
|
||
│ └── presentation/
|
||
│ ├── tui_logger.go # TUILogger (Bubbletea, Dracula)
|
||
│ ├── console_logger.go # ConsoleLogger (fallback без TUI)
|
||
│ └── console_presenter.go # Финальная сводка в stdout
|
||
├── config.yaml
|
||
├── go.mod
|
||
├── go.sum
|
||
├── Makefile
|
||
└── README.md
|
||
```
|
||
|
||
---
|
||
|
||
## Интерфейсы (порты)
|
||
|
||
Определены в `internal/domain/ports.go`:
|
||
|
||
| Интерфейс | Назначение | Адаптер |
|
||
|---|---|---|
|
||
| `FolderLister` | Перечислить подпапки | `FSFolderLister` |
|
||
| `MetadataExtractor` | Извлечь теги из аудиофайла | `TagMetadataExtractor` |
|
||
| `TorrentSearcher` | Поиск + детали раздачи | `TorrAPIClient` |
|
||
| `ResultWriter` | Записать результат на диск | `FSResultWriter` |
|
||
| `CoverDownloader` | Скачать обложку | `HTTPCoverDownloader` |
|
||
| `LLMClient` | Нормализовать автора/название | `OpenRouterClient` |
|
||
| `ProcessLogger` | Отчитываться о прогрессе | `TUILogger` / `ConsoleLogger` |
|
||
|
||
---
|
||
|
||
## Паттерны
|
||
|
||
| Паттерн | Где применён |
|
||
|---|---|
|
||
| Pipeline | `ExecuteForFolders` → `processOneBook` → writer |
|
||
| Fan-Out / Fan-In | Worker Pool в `ExecuteForFolders` |
|
||
| Semaphore | `searchSem` — ограничение параллелизма к TorrAPI |
|
||
| Dependency Injection | `main.go` — Composition Root без фреймворка |
|
||
| Repository / Port-Adapter | Все `infrastructure/` адаптеры |
|
||
| Strategy | `ProcessLogger` — TUI или Console выбирается в `main.go` |
|
||
| Graceful Shutdown | `context.WithTimeout` + `signal.Notify` (SIGINT, SIGTERM) |
|
||
|
||
---
|
||
|
||
## TUI (Bubbletea)
|
||
|
||
`presentation/tui_logger.go` реализует полноэкранный интерфейс:
|
||
|
||
- **Верхняя панель**: текущая книга, статус, прогресс-бар `N / Total`, спиннер, последние 5 событий
|
||
- **Нижняя панель**: полный лог с цветами (Dracula palette)
|
||
|
||
Цветовая схема:
|
||
|
||
| Тип | Цвет |
|
||
|---|---|
|
||
| INFO | `#00FFFF` cyan |
|
||
| WARN | `#FFFF00` yellow |
|
||
| ERROR | `#FF5555` red |
|
||
| OK | `#50FA7B` green |
|
||
| DEBUG | `#6272A4` gray |
|