| assets | ||
| deploy | ||
| .gitignore | ||
| aoi-avatar.png | ||
| aoi.py | ||
| config.example.json | ||
| README.md | ||
| requirements.txt | ||
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 и не пытается «угадывать» — она опирается на конкретные источники и кеширует увиденное:
- По расписанию опрашивает Navidrome и discovery-playlist (раздельные интервалы для альбомов, плейлистов и релизов).
- Сравнивает с локальным state и забирает только новые сущности.
- Обогащает карточки Last.fm-данными при наличии ключа.
- Шлёт карточку в Matrix-комнату с обложкой, описанием и ссылками.
- Помечает сущность как обработанную в SQLite.
Каждый источник работает независимо, так что падение Navidrome не валит discovery, и наоборот.
Сообщения в Matrix
Карточка нового альбома выглядит примерно так:
🎧 Новый альбом в 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 |
Лог сервиса, не коммитится. |
Конфигурация
Создать конфиг из примера:
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-путь:
/storage/scripts/aoi
Установка
В production Aoi использует виртуальное окружение Watcher (общие зависимости):
cd /storage/scripts/watcher
python3 -m venv .venv
. .venv/bin/activate
pip install -r /storage/scripts/aoi/requirements.txt
Можно завести отдельный venv — тогда обновить deploy/aoi.service.
Запуск
/storage/scripts/watcher/.venv/bin/python /storage/scripts/aoi/aoi.py
Healthcheck:
curl -fsS http://127.0.0.1:18323/healthz
Ожидаемый ответ:
{"ok":true}
systemd
Unit хранится в репозитории:
deploy/aoi.service
Установка или обновление:
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
Операции:
sudo systemctl restart aoi.service
systemctl --no-pager -l status aoi.service
journalctl -u aoi.service -f
tail -f /storage/scripts/aoi/aoi.log
Ручные команды
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__/