fix: improve subsonic client compatibility

This commit is contained in:
2026-04-03 21:16:40 +03:00
parent a054192e45
commit 0b10dfe055
3 changed files with 166 additions and 23 deletions

View File

@@ -5,9 +5,11 @@ import (
"encoding/json"
"errors"
"log"
"math/rand"
"net/http"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"time"
@@ -98,8 +100,10 @@ func NewRouter(cfg config.Config, database *sql.DB, scanService *scanner.Service
restGet(authed, "getSong", application.subsonicSongByID)
restGet(authed, "getRandomSongs", application.subsonicRandomSongs)
restGet(authed, "getAlbumList2", application.subsonicAlbumList2)
restGet(authed, "getSongsByGenre", application.subsonicSongsByGenre)
restGet(authed, "getMusicFolders", application.subsonicMusicFolders)
restGet(authed, "getGenres", application.subsonicGenres)
restGet(authed, "getOpenSubsonicExtensions", application.subsonicOpenSubsonicExtensions)
restGet(authed, "getPodcasts", application.subsonicPodcasts)
restGet(authed, "getNewestPodcasts", application.subsonicNewestPodcasts)
restGet(authed, "getInternetRadioStations", application.subsonicInternetRadioStations)
@@ -469,14 +473,63 @@ func (a app) subsonicAlbumList2(w http.ResponseWriter, r *http.Request) {
size = parsed
}
}
albums, err := a.library.Albums(r.Context(), size)
offset := parsePositiveInt(r.URL.Query().Get("offset"))
albums, err := a.library.Albums(r.Context(), 5000)
if err != nil {
writeJSON(w, http.StatusInternalServerError, subsonic.ErrorResponse(0, "failed to load albums"))
return
}
if genre := strings.TrimSpace(r.URL.Query().Get("genre")); genre != "" {
filtered := make([]library.Album, 0, len(albums))
for _, album := range albums {
if strings.EqualFold(strings.TrimSpace(album.Genre), genre) {
filtered = append(filtered, album)
}
}
albums = filtered
}
typeName := strings.ToLower(strings.TrimSpace(r.URL.Query().Get("type")))
switch typeName {
case "alphabeticalbyname":
sort.SliceStable(albums, func(i, j int) bool {
return strings.ToLower(albums[i].Title) < strings.ToLower(albums[j].Title)
})
case "random":
rand.Shuffle(len(albums), func(i, j int) {
albums[i], albums[j] = albums[j], albums[i]
})
default:
sort.SliceStable(albums, func(i, j int) bool {
return albums[i].Year > albums[j].Year
})
}
if offset > len(albums) {
albums = []library.Album{}
} else if offset > 0 {
albums = albums[offset:]
}
if size < len(albums) {
albums = albums[:size]
}
writeJSON(w, http.StatusOK, subsonic.AlbumList2Response(albums))
}
func (a app) subsonicSongsByGenre(w http.ResponseWriter, r *http.Request) {
genre := strings.TrimSpace(r.URL.Query().Get("genre"))
if genre == "" {
writeJSON(w, http.StatusBadRequest, subsonic.ErrorResponse(10, "missing genre"))
return
}
count := parsePositiveInt(r.URL.Query().Get("count"))
offset := parsePositiveInt(r.URL.Query().Get("offset"))
tracks, err := a.library.SongsByGenre(r.Context(), genre, count, offset)
if err != nil {
writeJSON(w, http.StatusInternalServerError, subsonic.ErrorResponse(0, "failed to load songs by genre"))
return
}
writeJSON(w, http.StatusOK, subsonic.SongsByGenreResponse(tracks))
}
func (a app) subsonicMusicFolders(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, subsonic.MusicFoldersResponse())
}
@@ -502,6 +555,10 @@ func (a app) subsonicInternetRadioStations(w http.ResponseWriter, r *http.Reques
writeJSON(w, http.StatusOK, subsonic.InternetRadioStationsResponse())
}
func (a app) subsonicOpenSubsonicExtensions(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, subsonic.OpenSubsonicExtensionsResponse())
}
func (a app) subsonicSearch3(w http.ResponseWriter, r *http.Request) {
query := strings.TrimSpace(r.URL.Query().Get("query"))
if query == "" {