Как это устроено

API демона

Как устроен локальный API, его транспорт, аутентификация, структура и группы маршрутов.

nuvo-core - HTTP-сервер (axum) на unix-сокете. Это внутренний интерфейс между окном Nuvo и его службой. Публичным API он не является и может меняться между версиями.

Транспорт

  • Сокет находится по адресу $XDG_RUNTIME_DIR/nuvo/core.sock, в каталоге с правами 0700, сам сокет с правами 0600. Путь можно переопределить переменной NUVO_CORE_SOCKET.
  • Каждому запросу нужен заголовок Authorization: Bearer <token>. Токен случайный, не короче 32 символов, создаётся при запуске и известен только основному процессу Electron и демону. /health тоже требует его. Неверный токен даёт 401.
  • Второй демон не может занять сокет, пока на нём кто-то отвечает.
  • Размер тела запроса ограничен. Загрузки в кэш ограничены 512 МиБ.

Состояние и проверка работоспособности

GET /health возвращает статус: starting, пока демон открывает медиатеку, затем ok. Пока медиатека заблокирована, её маршруты отвечают 423 с кодом LOCKED.

Ошибки

У каждой ошибки тело одной и той же формы:

{ "message": "...", "code": "NOT_FOUND", "reqId": "a1b2c3d4e5f6", "reason": "..." }

reason появляется только для невоспроизводимых треков SoundCloud. Коды: NOT_FOUND, INVALID_INPUT, FORBIDDEN_HOST, CONFLICT, LOCKED, CORE_STARTING, UNAUTHORIZED, UPSTREAM, UPSTREAM_TIMEOUT, RATE_LIMITED, SC_UNAVAILABLE, SC_UNPLAYABLE, UNSUPPORTED_FORMAT, INTERNAL. Внутренние ошибки возвращают короткое сообщение, а подробности пишутся в лог под reqId.

Логирование

В лог попадают метод, шаблон маршрута, статус и время. Сырые пути в нём не записываются, поэтому идентификаторы треков не превращаются в историю прослушиваний.

Группы маршрутов

Префикс Что делает
/v1/me, /v1/users/me Профиль, любимые треки, сохранённые альбомы и исполнители, плейлисты и их элементы, флаги и порядок закрепления, история, события воспроизведения и «сейчас играет», история поиска, обрезки, ежедневные миксы
/v1/cache Зашифрованное аудио: чтение с Range, запись, удаление, статус, настройки лимита, список недостающего, фоновые задачи загрузки
/v1/covers Обложки в размере для показа
/v1/tracks/{id}/lyrics Поток текста, собственные тексты пользователя, сдвиг времени
/v1/lyrics Сдвиги, настройки переводчика и перевод
/v1/recs Опорные треки, пул, ранжирование, стартовые исполнители, скрытие, «Не интересно», исключённые элементы
/v1/tracks/{id}/radio, /alternative Радио и альтернативные источники
/v1/match Сопоставление каталожных треков для импорта и ссылок
/v1/imports Задачи импорта, строки, кандидаты, массовые действия, отчёты CSV
/v1/sc Поиск SoundCloud, треки, наборы, пользователи, потоки
/v1/youtube Состояние аккаунта и настройки
/v1/links Разбор ссылок
/v1/recognize Распознавание песен, история, состояние инструментов
/v1/local Папки с музыкой, треки, статус, повторное сканирование, аудио, обложки
/v1/downloads Очередь сохранения файлами
/v1/fs Маршруты, которые вызывает только основной процесс Electron: они называют папки или возвращают документы для диалогов сохранения (сохранённые файлы, экспорт, локальные папки)
/v1/recovery Фраза восстановления, подтверждение, восстановление
/v1/appearance, /v1/shortcuts Сохранённые настройки
/v1/system Проверка зависимостей, проверка сети, прокси, отчёт для поддержки, завершение работы
/v1/lastfm Сессия Last.fm и скробблы (в приложении для этого пока нет экрана)
/v1/explore Списки популярного и самого сохраняемого

Аудио через сокет

GET /v1/cache/audio/{id} и GET /v1/local/tracks/{id}/audio обслуживают запросы Range. Демон расшифровывает только те части, которые нужны для диапазона. Рендерер обращается к ним через протокол nuvo-core://, который перенаправляет основной процесс.

Стабильность

Маршруты начинаются с /v1. Считайте API закрытым для Nuvo.