feat(genius): load song metadata, lyrics, and artwork
ci / ts / ts (packages + web) (push) Canceled after 1m0s
ci / api / api (push) Successful in 46s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 56s
ci / db / db (push) Successful in 1m32s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m27s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m31s

Search hits omit album covers and artist images. The worker now reads the full song and artist, stores the description, and leaves Genius image URLs unchanged on mobile.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
mrleo1nidandCursor committed 2026-10-22 08:23:54 +03:00
1 parent fb20258489
commit 73ad61e7a5
34 files changed
+2214 -303

No files matched your search

+1
View File
@@ -15,6 +15,7 @@ Pipu Music — self-hosted музыкальный сервис (веб + Android
| [library-and-storage.md](library-and-storage.md) | Хранилища (NFS), шаблоны путей, сканер, метаданные, поиск |
| [uploads.md](uploads.md) | Предложение треков модераторами: очередь, квота, дубли, одобрение, раскладка в хранилище |
| [playback.md](playback.md) | Стриминг, транскодинг, состояние плеера, офлайн |
| [genius.md](genius.md) | Genius: токен, поиск метаданных, парсинг текстов и проверочная команда |
| [playlists.md](playlists.md) | Личные плейлисты: API, веб и Android |
| [recommendations.md](recommendations.md) | Рекомендательная система и «Моя волна» |
| [web.md](web.md) | Веб-клиент |
+83
View File
@@ -0,0 +1,83 @@
# Genius: поиск метаданных и получение текста
Реализован Go-провайдер `services/api/internal/genius` и отдельная команда
`services/api/cmd/genius`. Поиск через API возвращает кандидатов, ссылки на изображения
и исполнителя. Текст выбранной песни извлекается из HTML страницы: из контейнеров
`data-lyrics-container` либо из `songPage.lyricsData.body.html` во встроенном состоянии.
JavaScript не исполняется. Используется HTML-парсер `golang.org/x/net/html`.
Это проверяемый первый этап: команда работает отдельно от сервера. Автоматическое
дополнение каталога, хранение текстов в БД, аннотации и отображение в плеере пока
не подключены. Поэтому переменная ниже пока нужна именно процессу команды,
а не Docker Compose или веб-клиенту.
## Почему Go
Основной API Pipu написан на Go. Небольшой провайдер можно подключить к нему без
отдельного Python-сервиса. LyricsGenius удобен для Python, но собственный адаптер
позволяет явно контролировать выбор версии песни, сетевые ограничения и ошибки.
HTML Genius не является стабильным API: при изменении разметки парсер потребует обновления.
## Получение токена
1. Войти или зарегистрироваться на https://genius.com.
2. Открыть https://genius.com/api-clients и создать новый API Client.
3. Указать название, например `Pipu Music`, и URL своего приложения. Если форма
требует Redirect URI, указать URL под своим контролем; для чтения с Client Access
Token OAuth-переходы и обработчик callback в Pipu не нужны.
4. В созданном клиенте нажать **Generate Access Token**.
5. Сохранить **Client Access Token** в переменной `GENIUS_ACCESS_TOKEN` процесса.
Client ID и Client Secret вместо него не подходят.
Токен нужен для поиска через `api.genius.com`. Получение HTML по уже известному
URL не требует токена и не отправляет заголовок Authorization. Не помещать токен
в git, клиентские переменные `VITE_*`, логи или переписку.
Источник: https://lyricsgenius.readthedocs.io/en/master/setup.html.
## Проверка в PowerShell 7
Из корня репозитория:
```powershell
Set-Location services/api
$env:GENIUS_ACCESS_TOKEN = Read-Host 'Genius Client Access Token' -MaskInput
go run ./cmd/genius -search 'Исполнитель Название песни'
```
Выбрать нужного исполнителя и версию песни из результатов. Команда намеренно
не считает первый результат правильным. Затем подставить возвращённый `url`:
```powershell
go run ./cmd/genius -url 'https://genius.com/Artist-song-lyrics'
Remove-Item Env:GENIUS_ACCESS_TOKEN
```
URL во втором примере — шаблон. Результат — JSON с `text`, `source_url` и временем
получения `fetched_at`. Это обычный текст без временной синхронизации.
## Ограничения и дальнейшее подключение
- HTTP 401, 403, 404, 429 и другие ошибки возвращаются явно; `HTTPError` сохраняет
`Retry-After`. Автоматических повторов и обхода блокировок нет.
- Таймаут запроса — 15 секунд, предел ответа — 8 MiB. Разрешён только HTTPS
на Genius; перенаправления на другой хост запрещены.
- Отсутствие распознаваемого текста возвращает `ErrLyricsUnavailable`; HTML
блокировки или навигация не становятся текстом песни.
- Перед интеграцией в каталог нужны кэш результатов, лимит частоты запросов,
сохранение выбранного Genius ID и обработка временных ошибок без потери старого текста.
- Токен API не предоставляет лицензию на тексты. Документация LyricsGenius
предупреждает, что парсинг противоречит условиям Genius; отображление и хранение
в публичном сервисе требуют отдельной проверки разрешений:
https://lyricsgenius.readthedocs.io/en/latest/how_it_works.html.
## Тесты
```powershell
go test ./internal/genius ./cmd/genius
```
Тесты используют синтетические тексты и подмену HTTP: переносы, HTML-сущности,
служебные элементы, встроенное состояние, ошибки HTTP, проверка URL и
отсутствие токена при запросе страницы. Реальный доступ к Genius проверяется
отдельно из сети сервера с собственным токеном.