feat: document wired sync pipeline, notifier, and web UI in README
This commit is contained in:
51
README.md
51
README.md
@@ -13,7 +13,12 @@ NaviWatcher is an autonomous service daemon that monitors your Navidrome music c
|
||||
1. **Scans** your Navidrome library via Subsonic API to get the list of artists and albums.
|
||||
2. **Fetches** full artist discographies from MusicBrainz (using Release Groups to avoid duplicate editions).
|
||||
3. **Compares** local collection with external data using fuzzy matching (configurable threshold, default 0.85).
|
||||
4. **Notifies** you about missing albums/singles/EPs through daily Telegram digests and a web dashboard *(not yet implemented — see Implementation Status)*.
|
||||
4. **Syncs automatically** on a periodic loop (`sync.interval`, default 6h): Navidrome artist/album pull → lazy MusicBrainz ID resolution → discography cache → re-scan, so the dashboard and digests always reflect current state.
|
||||
5. **Notifies** you about missing albums/singles/EPs through daily Telegram digests and a web dashboard.
|
||||
|
||||
### How It Works Now
|
||||
|
||||
On startup NaviWatcher opens (or auto-migrates) a local SQLite database at `naviwatcher.db` in the working directory, performs one immediate sync+scan, then runs a ticker-driven periodic sync+scan goroutine until SIGTERM. The Web UI serves a basic-auth-protected dashboard; the Notifier runs a cron scheduler emitting a daily digest of newly-found missing releases (tracked via `notifications_sent`). The MusicBrainz ID for each artist is resolved lazily on first sync and cached on the `artist_settings` row.
|
||||
|
||||
### Features
|
||||
|
||||
@@ -21,8 +26,8 @@ NaviWatcher is an autonomous service daemon that monitors your Navidrome music c
|
||||
- **Fuzzy matching** — smart string normalization (ignores remastered/deluxe/anniversary editions, year suffixes, special characters).
|
||||
- **Per-artist filters** — opt out of Singles and Compilations per artist (via `artist_settings`); type filtering includes only Album/Single/EP primary types (plus release groups whose secondary types include Single/EP/Compilation).
|
||||
- **MusicBrainz caching** — 24-hour TTL cache to minimize API calls and respect rate limits (1 req/sec).
|
||||
- **Telegram notifications** — *(not yet implemented)* daily summary messages with links to the web UI.
|
||||
- **Web dashboard** — *(not yet implemented)* browse missing albums, ignore releases, manage artist-specific settings.
|
||||
- **Telegram notifications** — daily summary messages with links to the web UI, sent on the configured `telegram.cron_schedule`.
|
||||
- **Web dashboard** — browse missing albums, ignore releases, manage artist-specific settings, with an archive of ignored releases.
|
||||
- **Single binary deployment** — all HTML templates embedded via `//go:embed`.
|
||||
- **Docker support** — ready for `docker compose` deployment.
|
||||
|
||||
@@ -63,10 +68,11 @@ NaviWatcher is an autonomous service daemon that monitors your Navidrome music c
|
||||
5. **Access the web UI** at `http://localhost:8080`
|
||||
|
||||
> **Note (current status):** On startup the service opens a local SQLite database at
|
||||
> `naviwatcher.db` in the working directory (existing databases are auto-migrated) and
|
||||
> performs a compute-only scan of all monitored artists, logging the count of missing
|
||||
> releases. `musicbrainz.user_agent` is required and validated at startup. The notifier
|
||||
> and Web UI are not yet wired into the running service — scan results are logged only.
|
||||
> `naviwatcher.db` in the working directory (existing databases are auto-migrated), performs
|
||||
> one immediate sync+scan, then runs a periodic sync+scan loop (`sync.interval`, default 6h)
|
||||
> until shutdown. `musicbrainz.user_agent` is required and validated at startup. The Web UI
|
||||
> (basic-auth protected) and Telegram notifier (cron-scheduled) are wired in; set
|
||||
> `telegram.enabled` to activate digests.
|
||||
|
||||
### Configuration
|
||||
|
||||
@@ -94,6 +100,10 @@ telegram:
|
||||
|
||||
scanner:
|
||||
fuzzy_threshold: 0.85
|
||||
|
||||
# Periodic sync+scan loop frequency (Go duration, e.g. "6h", "30m"); defaults to 6h.
|
||||
sync:
|
||||
interval: 6h
|
||||
```
|
||||
|
||||
See [docs/Specification.md](docs/Specification.md) for the full configuration reference and architecture details.
|
||||
@@ -111,8 +121,10 @@ See [docs/Specification.md](docs/Specification.md) for the full configuration re
|
||||
|
||||
### Implementation Status
|
||||
|
||||
- **Scanner Engine** — implemented (compute-only). The missing-release detection core is complete: string normalization lives in `internal/normalize`, similarity scoring and the diff engine (`FindMissingReleases`, `ScanArtist`, `ScanAll`) in `internal/scanner`. It uses the configurable `scanner.fuzzy_threshold` (default 0.85), normalizes titles (ignoring `(Remastered)`/year/special-char variants), and skips releases marked ignored.
|
||||
- **Notifier and Web UI** — not yet implemented (out of scope for the scanner plan). `main.run()` currently performs a compute-only scan and logs missing-release counts; it does not persist results or send notifications.
|
||||
- **Scanner Engine** — implemented. The missing-release detection core is complete: string normalization lives in `internal/normalize`, similarity scoring and the diff engine (`FindMissingReleases`, `ScanArtist`, `ScanAll`) in `internal/scanner`. It uses the configurable `scanner.fuzzy_threshold` (default 0.85), normalizes titles (ignoring `(Remastered)`/year/special-char variants), and skips releases marked ignored.
|
||||
- **Sync pipeline** — implemented. `SyncAll` pulls artists/albums from Navidrome into the DB, resolves each artist's MusicBrainz ID lazily (cached on `artist_settings.mbid`), syncs the MusicBrainz discography, then re-runs the scanner. Wired into `main.run()` as an immediate + periodic (`sync.interval`) loop.
|
||||
- **Notifier** — implemented. A `Sender` interface with a Telegram implementation, `FormatDigest` for daily summaries, and a cron scheduler honoring `telegram.cron_schedule` (no-op when `enabled=false`); sent-tracking via `notifications_sent`.
|
||||
- **Web UI** — implemented. Basic-auth-protected `net/http` server with `//go:embed` templates: dashboard with missing-release counts, artist detail with ignore actions, and an archive of ignored releases with restore.
|
||||
|
||||
### License
|
||||
|
||||
@@ -129,7 +141,12 @@ NaviWatcher — это автономный сервис-демон для мо
|
||||
1. **Сканирует** библиотеку Navidrome через Subsonic API — получает список артистов и альбомов.
|
||||
2. **Загружает** полные дискографии артистов из MusicBrainz (использует Release Groups, чтобы избежать дубликатов изданий).
|
||||
3. **Сравнивает** локальную коллекцию с внешними данными через нечёткое сравнение строк (настраиваемый порог, по умолчанию 0.85).
|
||||
4. **Уведомляет** об отсутствующих альбомах/синглах/EP через ежедневные дайджесты в Telegram и веб-панель *(пока не реализовано — см. раздел «Статус реализации»)*.
|
||||
4. **Синхронизируется автоматически** по периодическому циклу (`sync.interval`, по умолчанию 6h): выгрузка артистов/альбомов из Navidrome → ленивое разрешение MusicBrainz ID → кэш дискографии → повторное сканирование, чтобы панель и дайджесты всегда отражали текущее состояние.
|
||||
5. **Уведомляет** об отсутствующих альбомах/синглах/EP через ежедневные дайджесты в Telegram и веб-панель.
|
||||
|
||||
### Как это работает сейчас
|
||||
|
||||
При запуске NaviWatcher открывает (или автомигрирует) локальную SQLite-БД `naviwatcher.db` в рабочей директории, выполняет одну немедленную синхронизацию+сканирование, затем запускает управляемый тикером периодический цикл до получения SIGTERM. Веб-интерфейс — это панель под basic-auth; нотификатор запускает cron-планировщик, отправляющий ежедневный дайджест новых отсутствующих релизов (отслеживается через `notifications_sent`). MusicBrainz ID каждого артиста разрешается лениво при первой синхронизации и кэшируется в строке `artist_settings`.
|
||||
|
||||
### Возможности
|
||||
|
||||
@@ -137,8 +154,8 @@ NaviWatcher — это автономный сервис-демон для мо
|
||||
- **Нечёткое сравнение** — умная нормализация строк (игнорирует ремастеры, deluxe/anniversary-издания, год в скобках, спецсимволы).
|
||||
- **Фильтры по артистам** — отключение синглов и компиляций для конкретного артиста (через `artist_settings`); фильтрация по типам включает только основные типы Album/Single/EP (а также группы релизов, чьи вторичные типы содержат Single/EP/Compilation).
|
||||
- **Кэширование MusicBrainz** — TTL 24 часа для минимизации запросов и соблюдения лимитов (1 запрос/сек).
|
||||
- **Уведомления в Telegram** — *(пока не реализовано)* ежедневные сводки со ссылками на веб-интерфейс.
|
||||
- **Веб-панель** — *(пока не реализовано)* просмотр отсутствующих альбомов, игнорирование релизов, управление настройками артистов.
|
||||
- **Уведомления в Telegram** — ежедневные сводки со ссылками на веб-интерфейс, отправляемые по расписанию `telegram.cron_schedule`.
|
||||
- **Веб-панель** — просмотр отсутствующих альбомов, игнорирование релизов, управление настройками артистов, архив проигнорированных релизов.
|
||||
- **Один бинарный файл** — все HTML-шаблоны встроены через `//go:embed`.
|
||||
- **Поддержка Docker** — готов к развёртыванию через `docker compose`.
|
||||
|
||||
@@ -204,6 +221,10 @@ telegram:
|
||||
|
||||
scanner:
|
||||
fuzzy_threshold: 0.85
|
||||
|
||||
# Частота периодического цикла синхронизации+сканирования (длительность Go, напр. "6h", "30m"); по умолчанию 6h.
|
||||
sync:
|
||||
interval: 6h
|
||||
```
|
||||
|
||||
Полную справку по конфигурации и архитектуру см. в [docs/Specification.md](docs/Specification.md).
|
||||
@@ -221,8 +242,10 @@ scanner:
|
||||
|
||||
### Статус реализации
|
||||
|
||||
- **Scanner Engine** — реализован (только вычисления). Ядро поиска отсутствующих релизов готово: нормализация строк в `internal/normalize`, оценка схожести и движок сравнения (`FindMissingReleases`, `ScanArtist`, `ScanAll`) в `internal/scanner`. Используется настраиваемый `scanner.fuzzy_threshold` (по умолчанию 0.85), игнорируются варианты `(Remastered)`/год/спецсимволы, пропускаются отмеченные как игнорируемые.
|
||||
- **Notifier и Web UI** — пока не реализованы (вне рамок плана сканера). `main.run()` выполняет только вычислительное сканирование и логирует количество отсутствующих релизов; результаты не сохраняются и уведомления не отправляются.
|
||||
- **Scanner Engine** — реализован. Ядро поиска отсутствующих релизов готово: нормализация строк в `internal/normalize`, оценка схожести и движок сравнения (`FindMissingReleases`, `ScanArtist`, `ScanAll`) в `internal/scanner`. Используется настраиваемый `scanner.fuzzy_threshold` (по умолчанию 0.85), игнорируются варианты `(Remastered)`/год/спецсимволы, пропускаются отмеченные как игнорируемые.
|
||||
- **Sync pipeline** — реализован. `SyncAll` выгружает артистов/альбомы из Navidrome в БД, лениво разрешает MusicBrainz ID каждого артиста (кэшируется в `artist_settings.mbid`), синхронизирует дискографию MusicBrainz, затем повторно запускает сканер. Подключён в `main.run()` как немедленный + периодический (`sync.interval`) цикл.
|
||||
- **Notifier** — реализован. Интерфейс `Sender` с Telegram-реализацией, `FormatDigest` для ежедневных сводок и cron-планировщик по `telegram.cron_schedule` (no-op при `enabled=false`); отслеживание отправок через `notifications_sent`.
|
||||
- **Web UI** — реализован. Защищённый basic-auth `net/http` сервер с `//go:embed` шаблонами: панель со счётчиками отсутствующих релизов, страница артиста с действиями игнорирования и архив проигнорированных релизов с восстановлением.
|
||||
|
||||
### Лицензия
|
||||
|
||||
|
||||
Reference in New Issue
Block a user