Initial commit: Aoi (Аой-тян) — Matrix notifier for Navidrome and discovery-playlist
- aoi.py: poller for Navidrome (main + anime libraries), discovery playlists, release watch for liked/rated artists - Last.fm enrichment (bio, tags); Bandcamp search links - config.example.json: safe template; config.json gitignored - deploy/aoi.service: systemd unit (production) - assets/banner.png + aoi-avatar.png: persona banner + bot avatar - Russian README in line with sibling bots (rada/watcher)
This commit is contained in:
commit
5fa857b9cc
8 changed files with 1155 additions and 0 deletions
160
README.md
Normal file
160
README.md
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<p align="center">
|
||||
<img src="assets/banner.png" alt="Aoi banner" width="40%">
|
||||
</p>
|
||||
|
||||
# Aoi
|
||||
|
||||
**Aoi** (Аой-тян) — домашний Matrix-бот для музыкальной библиотеки. Она следит за Navidrome и discovery-playlist, аккуратно докладывает о новых альбомах, свежих Discovery-плейлистах и предстоящих релизах любимых артистов, обогащая карточки данными Last.fm и ссылками на внешние источники.
|
||||
|
||||
## Что умеет
|
||||
|
||||
| Блок | Что происходит |
|
||||
| --- | --- |
|
||||
| Navidrome albums | Поллинг библиотек `main` и `anime` — новые альбомы превращаются в карточки с обложкой, описанием, тегами и рейтингом. |
|
||||
| Discovery playlists | Свежесгенерированные плейлисты discovery-playlist (имя содержит «Discovery») приходят в Matrix отдельным постом. |
|
||||
| Release watch | Аналитика по любимым/высоко оцененным артистам: анонсы и фактические релизы из дискографии, отслеживаемой discovery-playlist. |
|
||||
| Rich-описания | Last.fm-биография, теги, обложка из `album.getInfo`, ссылки на Last.fm и поиск Bandcamp. |
|
||||
| Baseline | На первом запуске можно зафиксировать всё уже существующее как «уже видела», чтобы не получить спам с историей. |
|
||||
| State & dedupe | SQLite хранит увиденные альбомы, плейлисты и релизы — повторов не будет. |
|
||||
|
||||
## Как устроена логика
|
||||
|
||||
Aoi не делает запросов к LLM и не пытается «угадывать» — она опирается на конкретные источники и кеширует увиденное:
|
||||
|
||||
1. По расписанию опрашивает Navidrome и discovery-playlist (раздельные интервалы для альбомов, плейлистов и релизов).
|
||||
2. Сравнивает с локальным state и забирает только новые сущности.
|
||||
3. Обогащает карточки Last.fm-данными при наличии ключа.
|
||||
4. Шлёт карточку в Matrix-комнату с обложкой, описанием и ссылками.
|
||||
5. Помечает сущность как обработанную в SQLite.
|
||||
|
||||
Каждый источник работает независимо, так что падение Navidrome не валит discovery, и наоборот.
|
||||
|
||||
## Сообщения в Matrix
|
||||
|
||||
Карточка нового альбома выглядит примерно так:
|
||||
|
||||
```text
|
||||
🎧 Новый альбом в Navidrome
|
||||
Artist — Album Title (2026)
|
||||
|
||||
━━ ОПИСАНИЕ ━━
|
||||
Краткая биография/описание альбома из Last.fm…
|
||||
|
||||
━━ ТЕГИ ━━
|
||||
shoegaze · indie · dream-pop
|
||||
|
||||
🔗 Last.fm: https://www.last.fm/music/Artist/Album
|
||||
🔗 Bandcamp: https://bandcamp.com/search?q=Artist+Album
|
||||
```
|
||||
|
||||
Discovery-плейлисты приходят отдельной карточкой со списком треков, release watch — отдельной с пометкой типа релиза (`announced`, `released`).
|
||||
|
||||
## Файлы проекта
|
||||
|
||||
| Файл | Назначение |
|
||||
| --- | --- |
|
||||
| `aoi.py` | Основной сервис. |
|
||||
| `config.example.json` | Безопасный пример конфигурации. |
|
||||
| `config.json` | Локальная конфигурация с секретами, не коммитится. |
|
||||
| `requirements.txt` | Python-зависимости. |
|
||||
| `deploy/aoi.service` | systemd unit для production. |
|
||||
| `assets/banner.png` | Баннер README. |
|
||||
| `aoi.db` | SQLite-состояние, не коммитится. |
|
||||
| `aoi.log` | Лог сервиса, не коммитится. |
|
||||
|
||||
## Конфигурация
|
||||
|
||||
Создать конфиг из примера:
|
||||
|
||||
```bash
|
||||
cp config.example.json config.json
|
||||
```
|
||||
|
||||
Заполнить:
|
||||
|
||||
- `matrix.homeserver`, `matrix.room_id`, `matrix.access_token`, `matrix.user_id`;
|
||||
- `bot.name` (по умолчанию `Аой-тян`) и `bot.avatar_path` для Matrix-профиля;
|
||||
- `navidrome.url`, `navidrome.username`, `navidrome.password`, идентификаторы библиотек;
|
||||
- `discovery.db_path` — путь к SQLite базе discovery-playlist;
|
||||
- `metadata.lastfm_api_key` — ключ Last.fm для био и тегов;
|
||||
- `polling.*` — интервалы опроса источников;
|
||||
- `polling.baseline_existing_on_first_run` — `true` на первом запуске, чтобы не спамить историей.
|
||||
|
||||
Production-путь:
|
||||
|
||||
```text
|
||||
/storage/scripts/aoi
|
||||
```
|
||||
|
||||
## Установка
|
||||
|
||||
В production Aoi использует виртуальное окружение Watcher (общие зависимости):
|
||||
|
||||
```bash
|
||||
cd /storage/scripts/watcher
|
||||
python3 -m venv .venv
|
||||
. .venv/bin/activate
|
||||
pip install -r /storage/scripts/aoi/requirements.txt
|
||||
```
|
||||
|
||||
Можно завести отдельный venv — тогда обновить `deploy/aoi.service`.
|
||||
|
||||
## Запуск
|
||||
|
||||
```bash
|
||||
/storage/scripts/watcher/.venv/bin/python /storage/scripts/aoi/aoi.py
|
||||
```
|
||||
|
||||
Healthcheck:
|
||||
|
||||
```bash
|
||||
curl -fsS http://127.0.0.1:18323/healthz
|
||||
```
|
||||
|
||||
Ожидаемый ответ:
|
||||
|
||||
```json
|
||||
{"ok":true}
|
||||
```
|
||||
|
||||
## systemd
|
||||
|
||||
Unit хранится в репозитории:
|
||||
|
||||
```text
|
||||
deploy/aoi.service
|
||||
```
|
||||
|
||||
Установка или обновление:
|
||||
|
||||
```bash
|
||||
sudo cp /storage/scripts/aoi/deploy/aoi.service /etc/systemd/system/aoi.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable aoi.service
|
||||
sudo systemctl restart aoi.service
|
||||
```
|
||||
|
||||
Операции:
|
||||
|
||||
```bash
|
||||
sudo systemctl restart aoi.service
|
||||
systemctl --no-pager -l status aoi.service
|
||||
journalctl -u aoi.service -f
|
||||
tail -f /storage/scripts/aoi/aoi.log
|
||||
```
|
||||
|
||||
## Ручные команды
|
||||
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:18323/run/navidrome-albums
|
||||
curl -X POST http://127.0.0.1:18323/run/discovery-playlists
|
||||
curl -X POST http://127.0.0.1:18323/run/release-watch
|
||||
```
|
||||
|
||||
## Что не коммитить
|
||||
|
||||
- `config.json`
|
||||
- `*.db`
|
||||
- `*.log`
|
||||
- `.venv/`
|
||||
- `__pycache__/`
|
||||
Loading…
Add table
Add a link
Reference in a new issue