Initial commit

This commit is contained in:
2026-05-19 17:42:12 +03:00
commit 001f9ce691
4 changed files with 550 additions and 0 deletions

217
README.md Normal file
View File

@@ -0,0 +1,217 @@
# NaviWatcher
> **Language:** [English](#english) | [Русский](#русский)
---
## English
NaviWatcher is an autonomous service daemon that monitors your Navidrome music collection, compares it against artist discographies from MusicBrainz, and notifies you about missing releases via Telegram and a built-in web interface.
### How It Works
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.
### Features
- **Subsonic API compatible** — works with Navidrome, Airsonic, Ampache, and other Subsonic-compatible servers.
- **Fuzzy matching** — smart string normalization (ignores remastered/deluxe/anniversary editions, year suffixes, special characters).
- **Configurable filters** — ignore bootlegs, singles, compilations, live albums, remixes, soundtracks per artist or globally.
- **MusicBrainz caching** — 24-hour TTL cache to minimize API calls and respect rate limits (1 req/sec).
- **Telegram notifications** — daily summary messages with links to the web UI.
- **Web dashboard** — browse missing albums, ignore releases, manage artist-specific settings.
- **Single binary deployment** — all HTML templates embedded via `//go:embed`.
- **Docker support** — ready for `docker compose` deployment.
### Technology Stack
- **Language:** Go 1.21+
- **Database:** SQLite 3
- **HTTP Server:** Go standard library (`net/http` + `html/template`)
- **Key dependencies:**
- `github.com/mattn/go-sqlite3` — SQLite driver
- `github.com/lithammer/fuzzysearch` — fuzzy string matching
- `gopkg.in/yaml.v3` — configuration parsing
### Quick Start
1. **Create a service user in Navidrome:**
- Go to Settings → Users → Add User
- Set a username and password
- Ensure the user has access to your music libraries
2. **Configure NaviWatcher:**
```bash
cp config.yaml.example config.yaml
# Edit config.yaml with your settings
```
3. **Build and run:**
```bash
go build -o naviwatcher
./naviwatcher
```
4. **Or use Docker:**
```bash
docker compose up -d
```
5. **Access the web UI** at `http://localhost:8080`
### Configuration
```yaml
server:
host: "0.0.0.0"
port: 8080
username: "admin"
password: "password123"
navidrome:
url: "http://localhost:4533"
user: "watcher_service"
password: "user_password"
musicbrainz:
user_agent: "NaviWatcher/1.0 ( mail@example.com )"
cache_ttl: 24h
telegram:
enabled: true
token: "bot_token"
chat_id: "your_chat_id"
cron_schedule: "0 10 * * *"
scanner:
fuzzy_threshold: 0.85
ignore_bootlegs: true
include_compilations: true
```
See [docs/Specification.md](docs/Specification.md) for the full configuration reference and architecture details.
### Architecture
| Module | Purpose |
|--------|---------|
| **Navidrome Client** | Subsonic API v1.16.1 communication (token-based auth) |
| **MusicBrainz Provider** | Discography fetching with rate limiting and caching |
| **Scanner Engine** | String normalization and fuzzy comparison |
| **Database Layer** | SQLite persistence for settings, cache, and state |
| **Notifier** | Scheduled Telegram notifications |
| **Web UI** | Dashboard for browsing and managing missing releases |
### License
[WTFPL](License.md) — Do What The Fuck You Want To Public License
---
## Русский
NaviWatcher — это автономный сервис-демон для мониторинга музыкальной коллекции в Navidrome. Он сравнивает вашу медиатеку с полными дискографиями артистов из MusicBrainz и уведомляет об отсутствующих релизах через Telegram и веб-интерфейс.
### Как это работает
1. **Сканирует** библиотеку Navidrome через Subsonic API — получает список артистов и альбомов.
2. **Загружает** полные дискографии артистов из MusicBrainz (использует Release Groups, чтобы избежать дубликатов изданий).
3. **Сравнивает** локальную коллекцию с внешними данными через нечёткое сравнение строк (настраиваемый порог, по умолчанию 0.85).
4. **Уведомляет** об отсутствующих альбомах/синглах/EP через ежедневные дайджесты в Telegram и веб-панель.
### Возможности
- **Совместим с Subsonic API** — работает с Navidrome, Airsonic, Ampache и другими Subsonic-совместимыми серверами.
- **Нечёткое сравнение** — умная нормализация строк (игнорирует ремастеры, deluxe/anniversary-издания, год в скобках, спецсимволы).
- **Гибкие фильтры** — игнорирование бутлегов, синглов, компиляций, лайвов, ремиксаундов — глобально или для конкретного артиста.
- **Кэширование MusicBrainz** — TTL 24 часа для минимизации запросов и соблюдения лимитов (1 запрос/сек).
- **Уведомления в Telegram** — ежедневные сводки со ссылками на веб-интерфейс.
- **Веб-панель** — просмотр отсутствующих альбомов, игнорирование релизов, управление настройками артистов.
- **Один бинарный файл** — все HTML-шаблоны встроены через `//go:embed`.
- **Поддержка Docker** — готов к развёртыванию через `docker compose`.
### Технологический стек
- **Язык:** Go 1.21+
- **База данных:** SQLite 3
- **HTTP-сервер:** стандартная библиотека Go (`net/http` + `html/template`)
- **Ключевые зависимости:**
- `github.com/mattn/go-sqlite3` — драйвер SQLite
- `github.com/lithammer/fuzzysearch` — нечёткое сравнение строк
- `gopkg.in/yaml.v3` — парсинг конфигурации
### Быстрый старт
1. **Создайте сервисного пользователя в Navidrome:**
- Перейдите в Settings → Users → Add User
- Задайте имя пользователя и пароль
- Убедитесь, что у пользователя есть доступ к медиатекам
2. **Настройте NaviWatcher:**
```bash
cp config.yaml.example config.yaml
# Отредактируйте config.yaml
```
3. **Соберите и запустите:**
```bash
go build -o naviwatcher
./naviwatcher
```
4. **Или используйте Docker:**
```bash
docker compose up -d
```
5. **Откройте веб-интерфейс** по адресу `http://localhost:8080`
### Конфигурация
```yaml
server:
host: "0.0.0.0"
port: 8080
username: "admin"
password: "password123"
navidrome:
url: "http://localhost:4533"
user: "watcher_service"
password: "user_password"
musicbrainz:
user_agent: "NaviWatcher/1.0 ( mail@example.com )"
cache_ttl: 24h
telegram:
enabled: true
token: "bot_token"
chat_id: "your_chat_id"
cron_schedule: "0 10 * * *"
scanner:
fuzzy_threshold: 0.85
ignore_bootlegs: true
include_compilations: true
```
Полную справку по конфигурации и архитектуру см. в [docs/Specification.md](docs/Specification.md).
### Архитектура
| Модуль | Назначение |
|--------|------------|
| **Navidrome Client** | Взаимодействие с Subsonic API v1.16.1 (токенная аутентификация) |
| **MusicBrainz Provider** | Загрузка дискографий с кэшированием и rate limiting |
| **Scanner Engine** | Нормализация строк и нечёткое сравнение |
| **Database Layer** | Хранение настроек, кэша и состояния в SQLite |
| **Notifier** | Планировщик уведомлений в Telegram |
| **Web UI** | Панель управления отсутствющими релизами |
### Лицензия
[WTFPL](License.md) — Do What The Fuck You Want To Public License