Subsonic: browsing endpoints (getMusicFolders, getIndexes, getMusicDirectory, getGenres, getArtists/Artist, getAlbum, getSong, getVideos/VideoInfo, getArtistInfo/2, getAlbumInfo/2, getSimilarSongs/2, getTopSongs)

This commit is contained in:
2026-08-23 00:06:08 -05:00
parent b5e2bf01e2
commit f40a011c46
9 changed files with 1732 additions and 4 deletions
+10 -4
View File
@@ -3,6 +3,7 @@ package database
import (
"database/sql"
"errors"
"time"
"git.noroutes.net/NoRoutes/vibetunes/internal/idgen"
)
@@ -128,6 +129,7 @@ type Album struct {
MusicBrainzID string
PrimaryAlbumArtistID sql.NullString
CoverArtID sql.NullString
CreatedAt time.Time
}
// FindOrCreateAlbum resolves an album by (title, primary album artist),
@@ -167,7 +169,7 @@ func FindOrCreateAlbum(db *sql.DB, title string, primaryArtistID sql.NullString,
return GetAlbum(db, id)
}
const albumSelect = `SELECT id, title, sort_title, year, original_year, record_label, musicbrainz_id, primary_album_artist_id, cover_art_id FROM albums`
const albumSelect = `SELECT id, title, sort_title, year, original_year, record_label, musicbrainz_id, primary_album_artist_id, cover_art_id, created_at FROM albums`
func GetAlbum(db *sql.DB, id string) (*Album, error) {
return scanAlbum(db.QueryRow(albumSelect+` WHERE id = ?`, id))
@@ -175,13 +177,15 @@ func GetAlbum(db *sql.DB, id string) (*Album, error) {
func scanAlbum(row *sql.Row) (*Album, error) {
var a Album
err := row.Scan(&a.ID, &a.Title, &a.SortTitle, &a.Year, &a.OriginalYear, &a.RecordLabel, &a.MusicBrainzID, &a.PrimaryAlbumArtistID, &a.CoverArtID)
var createdAt string
err := row.Scan(&a.ID, &a.Title, &a.SortTitle, &a.Year, &a.OriginalYear, &a.RecordLabel, &a.MusicBrainzID, &a.PrimaryAlbumArtistID, &a.CoverArtID, &createdAt)
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrNotFound
}
if err != nil {
return nil, err
}
a.CreatedAt, _ = parseTime(createdAt)
return &a, nil
}
@@ -195,7 +199,7 @@ func ListAlbums(db *sql.DB, limit, offset int) ([]*Album, error) {
}
func ListAlbumsByArtist(db *sql.DB, artistID string) ([]*Album, error) {
rows, err := db.Query(`SELECT DISTINCT al.id, al.title, al.sort_title, al.year, al.original_year, al.record_label, al.musicbrainz_id, al.primary_album_artist_id, al.cover_art_id
rows, err := db.Query(`SELECT DISTINCT al.id, al.title, al.sort_title, al.year, al.original_year, al.record_label, al.musicbrainz_id, al.primary_album_artist_id, al.cover_art_id, al.created_at
FROM albums al JOIN album_artists aa ON aa.album_id = al.id
WHERE aa.artist_id = ? ORDER BY al.year, al.sort_title COLLATE NOCASE`, artistID)
if err != nil {
@@ -209,9 +213,11 @@ func scanAlbums(rows *sql.Rows) ([]*Album, error) {
var out []*Album
for rows.Next() {
var a Album
if err := rows.Scan(&a.ID, &a.Title, &a.SortTitle, &a.Year, &a.OriginalYear, &a.RecordLabel, &a.MusicBrainzID, &a.PrimaryAlbumArtistID, &a.CoverArtID); err != nil {
var createdAt string
if err := rows.Scan(&a.ID, &a.Title, &a.SortTitle, &a.Year, &a.OriginalYear, &a.RecordLabel, &a.MusicBrainzID, &a.PrimaryAlbumArtistID, &a.CoverArtID, &createdAt); err != nil {
return nil, err
}
a.CreatedAt, _ = parseTime(createdAt)
out = append(out, &a)
}
return out, rows.Err()