mirror of
https://github.com/navidrome/navidrome.git
synced 2025-08-10 00:52:20 +00:00
Replace all utils.Param* with req.Params
This commit is contained in:
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/navidrome/navidrome/core"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
type restHandler = func(rest.RepositoryConstructor, ...rest.Logger) http.HandlerFunc
|
||||
@@ -95,8 +95,9 @@ func handleExportPlaylist(ds model.DataStore) http.HandlerFunc {
|
||||
|
||||
func deleteFromPlaylist(ds model.DataStore) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
playlistId := utils.ParamString(r, ":playlistId")
|
||||
ids := r.URL.Query()["id"]
|
||||
p := req.Params(r)
|
||||
playlistId, _ := p.String(":playlistId")
|
||||
ids, _ := p.Strings("id")
|
||||
err := ds.WithTx(func(tx model.DataStore) error {
|
||||
tracksRepo := tx.Playlist(r.Context()).Tracks(playlistId, true)
|
||||
return tracksRepo.Delete(ids...)
|
||||
@@ -139,7 +140,8 @@ func addToPlaylist(ds model.DataStore) http.HandlerFunc {
|
||||
}
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
playlistId := utils.ParamString(r, ":playlistId")
|
||||
p := req.Params(r)
|
||||
playlistId, _ := p.String(":playlistId")
|
||||
var payload addTracksPayload
|
||||
err := json.NewDecoder(r.Body).Decode(&payload)
|
||||
if err != nil {
|
||||
@@ -183,8 +185,9 @@ func reorderItem(ds model.DataStore) http.HandlerFunc {
|
||||
}
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
playlistId := utils.ParamString(r, ":playlistId")
|
||||
id := utils.ParamInt(r, ":id", 0)
|
||||
p := req.Params(r)
|
||||
playlistId, _ := p.String(":playlistId")
|
||||
id := p.IntOr(":id", 0)
|
||||
if id == 0 {
|
||||
http.Error(w, "invalid id", http.StatusBadRequest)
|
||||
return
|
||||
|
||||
@@ -2,15 +2,17 @@ package public
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (p *Router) handleDownloads(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.URL.Query().Get(":id")
|
||||
if id == "" {
|
||||
http.Error(w, "invalid id", http.StatusBadRequest)
|
||||
func (pub *Router) handleDownloads(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := req.Params(r).String(":id")
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err := p.archiver.ZipShare(r.Context(), id, w)
|
||||
err = pub.archiver.ZipShare(r.Context(), id, w)
|
||||
checkShareError(r.Context(), w, err, id)
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
"github.com/navidrome/navidrome/core/artwork"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (p *Router) handleImages(w http.ResponseWriter, r *http.Request) {
|
||||
func (pub *Router) handleImages(w http.ResponseWriter, r *http.Request) {
|
||||
// If context is already canceled, discard request without further processing
|
||||
if r.Context().Err() != nil {
|
||||
return
|
||||
@@ -21,7 +21,9 @@ func (p *Router) handleImages(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||
defer cancel()
|
||||
id := r.URL.Query().Get(":id")
|
||||
|
||||
p := req.Params(r)
|
||||
id, _ := p.String(":id")
|
||||
if id == "" {
|
||||
http.Error(w, "invalid id", http.StatusBadRequest)
|
||||
return
|
||||
@@ -32,9 +34,9 @@ func (p *Router) handleImages(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
size := utils.ParamInt(r, "size", 0)
|
||||
size := p.IntOr("size", 0)
|
||||
|
||||
imgReader, lastUpdate, err := p.artwork.Get(ctx, artId, size)
|
||||
imgReader, lastUpdate, err := pub.artwork.Get(ctx, artId, size)
|
||||
switch {
|
||||
case errors.Is(err, context.Canceled):
|
||||
return
|
||||
|
||||
@@ -10,31 +10,32 @@ import (
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/server"
|
||||
"github.com/navidrome/navidrome/ui"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (p *Router) handleShares(w http.ResponseWriter, r *http.Request) {
|
||||
id := r.URL.Query().Get(":id")
|
||||
if id == "" {
|
||||
http.Error(w, "invalid id", http.StatusBadRequest)
|
||||
func (pub *Router) handleShares(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := req.Params(r).String(":id")
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// If requested file is a UI asset, just serve it
|
||||
_, err := ui.BuildAssets().Open(id)
|
||||
_, err = ui.BuildAssets().Open(id)
|
||||
if err == nil {
|
||||
p.assetsHandler.ServeHTTP(w, r)
|
||||
pub.assetsHandler.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// If it is not, consider it a share ID
|
||||
s, err := p.share.Load(r.Context(), id)
|
||||
s, err := pub.share.Load(r.Context(), id)
|
||||
if err != nil {
|
||||
checkShareError(r.Context(), w, err, id)
|
||||
return
|
||||
}
|
||||
|
||||
s = p.mapShareInfo(r, *s)
|
||||
server.IndexWithShare(p.ds, ui.BuildAssets(), s)(w, r)
|
||||
s = pub.mapShareInfo(r, *s)
|
||||
server.IndexWithShare(pub.ds, ui.BuildAssets(), s)(w, r)
|
||||
}
|
||||
|
||||
func checkShareError(ctx context.Context, w http.ResponseWriter, err error, id string) {
|
||||
@@ -54,7 +55,7 @@ func checkShareError(ctx context.Context, w http.ResponseWriter, err error, id s
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Router) mapShareInfo(r *http.Request, s model.Share) *model.Share {
|
||||
func (pub *Router) mapShareInfo(r *http.Request, s model.Share) *model.Share {
|
||||
s.URL = ShareURL(r, s.ID)
|
||||
s.ImageURL = ImageURL(r, s.CoverArtID(), consts.UICoverArtSize)
|
||||
for i := range s.Tracks {
|
||||
|
||||
@@ -10,12 +10,13 @@ import (
|
||||
"github.com/lestrrat-go/jwx/v2/jwt"
|
||||
"github.com/navidrome/navidrome/core/auth"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (p *Router) handleStream(w http.ResponseWriter, r *http.Request) {
|
||||
func (pub *Router) handleStream(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
tokenId := r.URL.Query().Get(":id")
|
||||
p := req.Params(r)
|
||||
tokenId, _ := p.String(":id")
|
||||
info, err := decodeStreamInfo(tokenId)
|
||||
if err != nil {
|
||||
log.Error(ctx, "Error parsing shared stream info", err)
|
||||
@@ -23,7 +24,7 @@ func (p *Router) handleStream(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
stream, err := p.streamer.NewStream(ctx, info.id, info.format, info.bitrate, 0)
|
||||
stream, err := pub.streamer.NewStream(ctx, info.id, info.format, info.bitrate, 0)
|
||||
if err != nil {
|
||||
log.Error(ctx, "Error starting shared stream", err)
|
||||
http.Error(w, "invalid request", http.StatusInternalServerError)
|
||||
@@ -46,7 +47,7 @@ func (p *Router) handleStream(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Accept-Ranges", "none")
|
||||
w.Header().Set("Content-Type", stream.ContentType())
|
||||
|
||||
estimateContentLength := utils.ParamBool(r, "estimateContentLength", false)
|
||||
estimateContentLength := p.BoolOr("estimateContentLength", false)
|
||||
|
||||
// if Client requests the estimated content-length, send it
|
||||
if estimateContentLength {
|
||||
|
||||
@@ -35,7 +35,7 @@ func New(ds model.DataStore, artwork artwork.Artwork, streamer core.MediaStreame
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Router) routes() http.Handler {
|
||||
func (pub *Router) routes() http.Handler {
|
||||
r := chi.NewRouter()
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
@@ -48,16 +48,16 @@ func (p *Router) routes() http.Handler {
|
||||
r.Use(middleware.ThrottleBacklog(conf.Server.DevArtworkMaxRequests, conf.Server.DevArtworkThrottleBacklogLimit,
|
||||
conf.Server.DevArtworkThrottleBacklogTimeout))
|
||||
}
|
||||
r.HandleFunc("/img/{id}", p.handleImages)
|
||||
r.HandleFunc("/img/{id}", pub.handleImages)
|
||||
})
|
||||
if conf.Server.EnableSharing {
|
||||
r.HandleFunc("/s/{id}", p.handleStream)
|
||||
r.HandleFunc("/s/{id}", pub.handleStream)
|
||||
if conf.Server.EnableDownloads {
|
||||
r.HandleFunc("/d/{id}", p.handleDownloads)
|
||||
r.HandleFunc("/d/{id}", pub.handleDownloads)
|
||||
}
|
||||
r.HandleFunc("/{id}", p.handleShares)
|
||||
r.HandleFunc("/", p.handleShares)
|
||||
r.Handle("/*", p.assetsHandler)
|
||||
r.HandleFunc("/{id}", pub.handleShares)
|
||||
r.HandleFunc("/", pub.handleShares)
|
||||
r.Handle("/*", pub.assetsHandler)
|
||||
}
|
||||
})
|
||||
return r
|
||||
|
||||
@@ -10,12 +10,13 @@ import (
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/server/subsonic/filter"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/number"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (api *Router) getAlbumList(r *http.Request) (model.Albums, int64, error) {
|
||||
typ, err := requiredParamString(r, "type")
|
||||
p := req.Params(r)
|
||||
typ, err := p.String("type")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
@@ -39,17 +40,17 @@ func (api *Router) getAlbumList(r *http.Request) (model.Albums, int64, error) {
|
||||
case "highest":
|
||||
opts = filter.AlbumsByRating()
|
||||
case "byGenre":
|
||||
genre, err := requiredParamString(r, "genre")
|
||||
genre, err := p.String("genre")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
opts = filter.AlbumsByGenre(genre)
|
||||
case "byYear":
|
||||
fromYear, err := requiredParamInt(r, "fromYear")
|
||||
fromYear, err := p.Int("fromYear")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
toYear, err := requiredParamInt(r, "toYear")
|
||||
toYear, err := p.Int("toYear")
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
@@ -59,8 +60,8 @@ func (api *Router) getAlbumList(r *http.Request) (model.Albums, int64, error) {
|
||||
return nil, 0, newError(responses.ErrorGeneric, "type '%s' not implemented", typ)
|
||||
}
|
||||
|
||||
opts.Offset = utils.ParamInt(r, "offset", 0)
|
||||
opts.Max = number.Min(utils.ParamInt(r, "size", 10), 500)
|
||||
opts.Offset = p.IntOr("offset", 0)
|
||||
opts.Max = number.Min(p.IntOr("size", 10), 500)
|
||||
albums, err := api.ds.Album(r.Context()).GetAllWithoutGenres(opts)
|
||||
|
||||
if err != nil {
|
||||
@@ -163,10 +164,11 @@ func (api *Router) GetNowPlaying(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
|
||||
func (api *Router) GetRandomSongs(r *http.Request) (*responses.Subsonic, error) {
|
||||
size := number.Min(utils.ParamInt(r, "size", 10), 500)
|
||||
genre := utils.ParamString(r, "genre")
|
||||
fromYear := utils.ParamInt(r, "fromYear", 0)
|
||||
toYear := utils.ParamInt(r, "toYear", 0)
|
||||
p := req.Params(r)
|
||||
size := number.Min(p.IntOr("size", 10), 500)
|
||||
genre, _ := p.String("genre")
|
||||
fromYear := p.IntOr("fromYear", 0)
|
||||
toYear := p.IntOr("toYear", 0)
|
||||
|
||||
songs, err := api.getSongs(r.Context(), 0, size, filter.SongsByRandom(genre, fromYear, toYear))
|
||||
if err != nil {
|
||||
@@ -181,9 +183,10 @@ func (api *Router) GetRandomSongs(r *http.Request) (*responses.Subsonic, error)
|
||||
}
|
||||
|
||||
func (api *Router) GetSongsByGenre(r *http.Request) (*responses.Subsonic, error) {
|
||||
count := number.Min(utils.ParamInt(r, "count", 10), 500)
|
||||
offset := utils.ParamInt(r, "offset", 0)
|
||||
genre := utils.ParamString(r, "genre")
|
||||
p := req.Params(r)
|
||||
count := number.Min(p.IntOr("count", 10), 500)
|
||||
offset := p.IntOr("offset", 0)
|
||||
genre, _ := p.String("genre")
|
||||
|
||||
songs, err := api.getSongs(r.Context(), offset, count, filter.SongsByGenre(genre))
|
||||
if err != nil {
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net/http/httptest"
|
||||
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
@@ -36,7 +37,7 @@ var _ = Describe("Album Lists", func() {
|
||||
})
|
||||
resp, err := router.GetAlbumList(w, r)
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(resp.AlbumList.Album[0].Id).To(Equal("1"))
|
||||
Expect(resp.AlbumList.Album[1].Id).To(Equal("2"))
|
||||
Expect(w.Header().Get("x-total-count")).To(Equal("2"))
|
||||
@@ -47,12 +48,8 @@ var _ = Describe("Album Lists", func() {
|
||||
It("should fail if missing type parameter", func() {
|
||||
r := newGetRequest()
|
||||
_, err := router.GetAlbumList(w, r)
|
||||
var subErr subError
|
||||
isSubError := errors.As(err, &subErr)
|
||||
|
||||
Expect(isSubError).To(BeTrue())
|
||||
Expect(subErr).To(MatchError("required 'type' parameter is missing"))
|
||||
Expect(subErr.code).To(Equal(responses.ErrorMissingParameter))
|
||||
Expect(err).To(MatchError(req.ErrMissingParam))
|
||||
})
|
||||
|
||||
It("should return error if call fails", func() {
|
||||
@@ -61,7 +58,7 @@ var _ = Describe("Album Lists", func() {
|
||||
|
||||
_, err := router.GetAlbumList(w, r)
|
||||
|
||||
Expect(err).ToNot(BeNil())
|
||||
Expect(err).To(MatchError(errSubsonic))
|
||||
var subErr subError
|
||||
errors.As(err, &subErr)
|
||||
Expect(subErr.code).To(Equal(responses.ErrorGeneric))
|
||||
@@ -76,7 +73,7 @@ var _ = Describe("Album Lists", func() {
|
||||
})
|
||||
resp, err := router.GetAlbumList2(w, r)
|
||||
|
||||
Expect(err).To(BeNil())
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(resp.AlbumList2.Album[0].Id).To(Equal("1"))
|
||||
Expect(resp.AlbumList2.Album[1].Id).To(Equal("2"))
|
||||
Expect(w.Header().Get("x-total-count")).To(Equal("2"))
|
||||
@@ -86,13 +83,10 @@ var _ = Describe("Album Lists", func() {
|
||||
|
||||
It("should fail if missing type parameter", func() {
|
||||
r := newGetRequest()
|
||||
|
||||
_, err := router.GetAlbumList2(w, r)
|
||||
|
||||
var subErr subError
|
||||
errors.As(err, &subErr)
|
||||
|
||||
Expect(subErr).To(MatchError("required 'type' parameter is missing"))
|
||||
Expect(subErr.code).To(Equal(responses.ErrorMissingParameter))
|
||||
Expect(err).To(MatchError(req.ErrMissingParam))
|
||||
})
|
||||
|
||||
It("should return error if call fails", func() {
|
||||
@@ -101,9 +95,9 @@ var _ = Describe("Album Lists", func() {
|
||||
|
||||
_, err := router.GetAlbumList2(w, r)
|
||||
|
||||
Expect(err).To(MatchError(errSubsonic))
|
||||
var subErr subError
|
||||
errors.As(err, &subErr)
|
||||
Expect(subErr).ToNot(BeNil())
|
||||
Expect(subErr.code).To(Equal(responses.ErrorGeneric))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/navidrome/navidrome/scanner"
|
||||
"github.com/navidrome/navidrome/server/events"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
@@ -283,7 +282,8 @@ func sendError(w http.ResponseWriter, r *http.Request, err error) {
|
||||
}
|
||||
|
||||
func sendResponse(w http.ResponseWriter, r *http.Request, payload *responses.Subsonic) {
|
||||
f := utils.ParamString(r, "f")
|
||||
p := req.Params(r)
|
||||
f, _ := p.String("f")
|
||||
var response []byte
|
||||
switch f {
|
||||
case "json":
|
||||
@@ -292,7 +292,7 @@ func sendResponse(w http.ResponseWriter, r *http.Request, payload *responses.Sub
|
||||
response, _ = json.Marshal(wrapper)
|
||||
case "jsonp":
|
||||
w.Header().Set("Content-Type", "application/javascript")
|
||||
callback := utils.ParamString(r, "callback")
|
||||
callback, _ := p.String("callback")
|
||||
wrapper := &responses.JsonWrapper{Subsonic: *payload}
|
||||
data, _ := json.Marshal(wrapper)
|
||||
response = []byte(fmt.Sprintf("%s(%s)", callback, data))
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/model/request"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (api *Router) GetBookmarks(r *http.Request) (*responses.Subsonic, error) {
|
||||
@@ -36,13 +36,14 @@ func (api *Router) GetBookmarks(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
|
||||
func (api *Router) CreateBookmark(r *http.Request) (*responses.Subsonic, error) {
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
comment := utils.ParamString(r, "comment")
|
||||
position := utils.ParamInt(r, "position", int64(0))
|
||||
comment, _ := p.String("comment")
|
||||
position := p.Int64Or("position", 0)
|
||||
|
||||
repo := api.ds.MediaFile(r.Context())
|
||||
err = repo.AddBookmark(id, comment, position)
|
||||
@@ -53,7 +54,8 @@ func (api *Router) CreateBookmark(r *http.Request) (*responses.Subsonic, error)
|
||||
}
|
||||
|
||||
func (api *Router) DeleteBookmark(r *http.Request) (*responses.Subsonic, error) {
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -88,13 +90,14 @@ func (api *Router) GetPlayQueue(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
|
||||
func (api *Router) SavePlayQueue(r *http.Request) (*responses.Subsonic, error) {
|
||||
ids, err := requiredParamStrings(r, "id")
|
||||
p := req.Params(r)
|
||||
ids, err := p.Strings("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
current := utils.ParamString(r, "current")
|
||||
position := utils.ParamInt(r, "position", int64(0))
|
||||
current, _ := p.String("current")
|
||||
position := p.Int64Or("position", 0)
|
||||
|
||||
user, _ := request.UserFrom(r.Context())
|
||||
client, _ := request.ClientFrom(r.Context())
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/navidrome/navidrome/server/subsonic/filter"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (api *Router) GetMusicFolders(r *http.Request) (*responses.Subsonic, error) {
|
||||
@@ -67,8 +68,9 @@ func (api *Router) getArtistIndex(r *http.Request, mediaFolderId int, ifModified
|
||||
}
|
||||
|
||||
func (api *Router) GetIndexes(r *http.Request) (*responses.Subsonic, error) {
|
||||
musicFolderId := utils.ParamInt(r, "musicFolderId", 0)
|
||||
ifModifiedSince := utils.ParamTime(r, "ifModifiedSince", time.Time{})
|
||||
p := req.Params(r)
|
||||
musicFolderId := p.IntOr("musicFolderId", 0)
|
||||
ifModifiedSince := p.TimeOr("ifModifiedSince", time.Time{})
|
||||
|
||||
res, err := api.getArtistIndex(r, musicFolderId, ifModifiedSince)
|
||||
if err != nil {
|
||||
@@ -81,7 +83,8 @@ func (api *Router) GetIndexes(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
|
||||
func (api *Router) GetArtists(r *http.Request) (*responses.Subsonic, error) {
|
||||
musicFolderId := utils.ParamInt(r, "musicFolderId", 0)
|
||||
p := req.Params(r)
|
||||
musicFolderId := p.IntOr("musicFolderId", 0)
|
||||
res, err := api.getArtistIndex(r, musicFolderId, time.Time{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -93,7 +96,8 @@ func (api *Router) GetArtists(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
|
||||
func (api *Router) GetMusicDirectory(r *http.Request) (*responses.Subsonic, error) {
|
||||
id := utils.ParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, _ := p.String("id")
|
||||
ctx := r.Context()
|
||||
|
||||
entity, err := model.GetEntityByID(ctx, api.ds, id)
|
||||
@@ -129,7 +133,8 @@ func (api *Router) GetMusicDirectory(r *http.Request) (*responses.Subsonic, erro
|
||||
}
|
||||
|
||||
func (api *Router) GetArtist(r *http.Request) (*responses.Subsonic, error) {
|
||||
id := utils.ParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, _ := p.String("id")
|
||||
ctx := r.Context()
|
||||
|
||||
artist, err := api.ds.Artist(ctx).Get(id)
|
||||
@@ -151,7 +156,8 @@ func (api *Router) GetArtist(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
|
||||
func (api *Router) GetAlbum(r *http.Request) (*responses.Subsonic, error) {
|
||||
id := utils.ParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, _ := p.String("id")
|
||||
|
||||
ctx := r.Context()
|
||||
|
||||
@@ -177,7 +183,8 @@ func (api *Router) GetAlbum(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
|
||||
func (api *Router) GetAlbumInfo(r *http.Request) (*responses.Subsonic, error) {
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
ctx := r.Context()
|
||||
|
||||
if err != nil {
|
||||
@@ -204,7 +211,8 @@ func (api *Router) GetAlbumInfo(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
|
||||
func (api *Router) GetSong(r *http.Request) (*responses.Subsonic, error) {
|
||||
id := utils.ParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, _ := p.String("id")
|
||||
ctx := r.Context()
|
||||
|
||||
mf, err := api.ds.MediaFile(ctx).Get(id)
|
||||
@@ -243,12 +251,13 @@ func (api *Router) GetGenres(r *http.Request) (*responses.Subsonic, error) {
|
||||
|
||||
func (api *Router) GetArtistInfo(r *http.Request) (*responses.Subsonic, error) {
|
||||
ctx := r.Context()
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
count := utils.ParamInt(r, "count", 20)
|
||||
includeNotPresent := utils.ParamBool(r, "includeNotPresent", false)
|
||||
count := p.IntOr("count", 20)
|
||||
includeNotPresent := p.BoolOr("includeNotPresent", false)
|
||||
|
||||
artist, err := api.externalMetadata.UpdateArtistInfo(ctx, id, count, includeNotPresent)
|
||||
if err != nil {
|
||||
@@ -295,11 +304,12 @@ func (api *Router) GetArtistInfo2(r *http.Request) (*responses.Subsonic, error)
|
||||
|
||||
func (api *Router) GetSimilarSongs(r *http.Request) (*responses.Subsonic, error) {
|
||||
ctx := r.Context()
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
count := utils.ParamInt(r, "count", 50)
|
||||
count := p.IntOr("count", 50)
|
||||
|
||||
songs, err := api.externalMetadata.SimilarSongs(ctx, id, count)
|
||||
if err != nil {
|
||||
@@ -328,11 +338,12 @@ func (api *Router) GetSimilarSongs2(r *http.Request) (*responses.Subsonic, error
|
||||
|
||||
func (api *Router) GetTopSongs(r *http.Request) (*responses.Subsonic, error) {
|
||||
ctx := r.Context()
|
||||
artist, err := requiredParamString(r, "artist")
|
||||
p := req.Params(r)
|
||||
artist, err := p.String("artist")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
count := utils.ParamInt(r, "count", 50)
|
||||
count := p.IntOr("count", 50)
|
||||
|
||||
songs, err := api.externalMetadata.TopSongs(ctx, artist, count)
|
||||
if err != nil {
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/navidrome/navidrome/model/request"
|
||||
"github.com/navidrome/navidrome/server/public"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
)
|
||||
|
||||
func newResponse() *responses.Subsonic {
|
||||
@@ -27,30 +26,6 @@ func newResponse() *responses.Subsonic {
|
||||
}
|
||||
}
|
||||
|
||||
func requiredParamString(r *http.Request, param string) (string, error) {
|
||||
p := utils.ParamString(r, param)
|
||||
if p == "" {
|
||||
return "", newError(responses.ErrorMissingParameter, "required '%s' parameter is missing", param)
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func requiredParamStrings(r *http.Request, param string) ([]string, error) {
|
||||
ps := utils.ParamStrings(r, param)
|
||||
if len(ps) == 0 {
|
||||
return nil, newError(responses.ErrorMissingParameter, "required '%s' parameter is missing", param)
|
||||
}
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
func requiredParamInt(r *http.Request, param string) (int, error) {
|
||||
p := utils.ParamString(r, param)
|
||||
if p == "" {
|
||||
return 0, newError(responses.ErrorMissingParameter, "required '%s' parameter is missing", param)
|
||||
}
|
||||
return utils.ParamInt(r, param, 0), nil
|
||||
}
|
||||
|
||||
type subError struct {
|
||||
code int
|
||||
messages []interface{}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/navidrome/navidrome/core/playback"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -27,8 +27,9 @@ const (
|
||||
func (api *Router) JukeboxControl(r *http.Request) (*responses.Subsonic, error) {
|
||||
ctx := r.Context()
|
||||
user := getUser(ctx)
|
||||
p := req.Params(r)
|
||||
|
||||
actionString, err := requiredParamString(r, "action")
|
||||
actionString, err := p.String("action")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -58,31 +59,31 @@ func (api *Router) JukeboxControl(r *http.Request) (*responses.Subsonic, error)
|
||||
case ActionStatus:
|
||||
return createResponse(pb.Status(ctx))
|
||||
case ActionSet:
|
||||
ids := utils.ParamStrings(r, "id")
|
||||
ids, _ := p.Strings("id")
|
||||
return createResponse(pb.Set(ctx, ids))
|
||||
case ActionStart:
|
||||
return createResponse(pb.Start(ctx))
|
||||
case ActionStop:
|
||||
return createResponse(pb.Stop(ctx))
|
||||
case ActionSkip:
|
||||
index, err := requiredParamInt(r, "index")
|
||||
index, err := p.Int("index")
|
||||
if err != nil {
|
||||
return nil, newError(responses.ErrorMissingParameter, "missing parameter index, err: %s", err)
|
||||
}
|
||||
|
||||
offset := utils.ParamInt(r, "offset", 0)
|
||||
offset := p.IntOr("offset", 0)
|
||||
if err != nil {
|
||||
offset = 0
|
||||
}
|
||||
|
||||
return createResponse(pb.Skip(ctx, index, offset))
|
||||
case ActionAdd:
|
||||
ids := utils.ParamStrings(r, "id")
|
||||
ids, _ := p.Strings("id")
|
||||
return createResponse(pb.Add(ctx, ids))
|
||||
case ActionClear:
|
||||
return createResponse(pb.Clear(ctx))
|
||||
case ActionRemove:
|
||||
index, err := requiredParamInt(r, "index")
|
||||
index, err := p.Int("index")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -91,7 +92,7 @@ func (api *Router) JukeboxControl(r *http.Request) (*responses.Subsonic, error)
|
||||
case ActionShuffle:
|
||||
return createResponse(pb.Shuffle(ctx))
|
||||
case ActionSetGain:
|
||||
gainStr, err := requiredParamString(r, "gain")
|
||||
gainStr, err := p.String("gain")
|
||||
if err != nil {
|
||||
return nil, newError(responses.ErrorMissingParameter, "missing parameter gain, err: %s", err)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model/request"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (api *Router) GetScanStatus(r *http.Request) (*responses.Subsonic, error) {
|
||||
@@ -41,7 +41,8 @@ func (api *Router) StartScan(r *http.Request) (*responses.Subsonic, error) {
|
||||
return nil, newError(responses.ErrorAuthorizationFail)
|
||||
}
|
||||
|
||||
fullScan := utils.ParamBool(r, "fullScan", false)
|
||||
p := req.Params(r)
|
||||
fullScan := p.BoolOr("fullScan", false)
|
||||
|
||||
go func() {
|
||||
start := time.Now()
|
||||
|
||||
@@ -160,7 +160,7 @@ func (api *Router) Scrobble(r *http.Request) (*responses.Subsonic, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
times := p.Times("time")
|
||||
times, _ := p.Times("time")
|
||||
if len(times) > 0 && len(times) != len(ids) {
|
||||
return nil, newError(responses.ErrorGeneric, "Wrong number of timestamps: %d, should be %d", len(times), len(ids))
|
||||
}
|
||||
|
||||
@@ -15,15 +15,16 @@ import (
|
||||
"github.com/navidrome/navidrome/resources"
|
||||
"github.com/navidrome/navidrome/server/subsonic/filter"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/gravatar"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (api *Router) GetAvatar(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
if !conf.Server.EnableGravatar {
|
||||
return api.getPlaceHolderAvatar(w, r)
|
||||
}
|
||||
username, err := requiredParamString(r, "username")
|
||||
p := req.Params(r)
|
||||
username, err := p.String("username")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -61,8 +62,9 @@ func (api *Router) GetCoverArt(w http.ResponseWriter, r *http.Request) (*respons
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
id := utils.ParamString(r, "id")
|
||||
size := utils.ParamInt(r, "size", 0)
|
||||
p := req.Params(r)
|
||||
id, _ := p.String("id")
|
||||
size := p.IntOr("size", 0)
|
||||
|
||||
imgReader, lastUpdate, err := api.artwork.GetOrPlaceholder(ctx, id, size)
|
||||
w.Header().Set("cache-control", "public, max-age=315360000")
|
||||
@@ -99,8 +101,9 @@ func isSynced(rawLyrics string) bool {
|
||||
}
|
||||
|
||||
func (api *Router) GetLyrics(r *http.Request) (*responses.Subsonic, error) {
|
||||
artist := utils.ParamString(r, "artist")
|
||||
title := utils.ParamString(r, "title")
|
||||
p := req.Params(r)
|
||||
artist, _ := p.String("artist")
|
||||
title, _ := p.String("title")
|
||||
response := newResponse()
|
||||
lyrics := responses.Lyrics{}
|
||||
response.Lyrics = &lyrics
|
||||
|
||||
@@ -20,8 +20,8 @@ import (
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/model/request"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
. "github.com/navidrome/navidrome/utils/gg"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func postFormToQueryParams(next http.Handler) http.Handler {
|
||||
@@ -45,19 +45,18 @@ func postFormToQueryParams(next http.Handler) http.Handler {
|
||||
func checkRequiredParameters(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
requiredParameters := []string{"u", "v", "c"}
|
||||
|
||||
for _, p := range requiredParameters {
|
||||
if utils.ParamString(r, p) == "" {
|
||||
msg := fmt.Sprintf(`Missing required parameter "%s"`, p)
|
||||
log.Warn(r, msg)
|
||||
sendError(w, r, newError(responses.ErrorMissingParameter, msg))
|
||||
p := req.Params(r)
|
||||
for _, param := range requiredParameters {
|
||||
if _, err := p.String(param); err != nil {
|
||||
log.Warn(r, err)
|
||||
sendError(w, r, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
username := utils.ParamString(r, "u")
|
||||
client := utils.ParamString(r, "c")
|
||||
version := utils.ParamString(r, "v")
|
||||
username, _ := p.String("u")
|
||||
client, _ := p.String("c")
|
||||
version, _ := p.String("v")
|
||||
ctx := r.Context()
|
||||
ctx = request.WithUsername(ctx, username)
|
||||
ctx = request.WithClient(ctx, client)
|
||||
@@ -73,12 +72,13 @@ func authenticate(ds model.DataStore) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
username := utils.ParamString(r, "u")
|
||||
p := req.Params(r)
|
||||
username, _ := p.String("u")
|
||||
|
||||
pass := utils.ParamString(r, "p")
|
||||
token := utils.ParamString(r, "t")
|
||||
salt := utils.ParamString(r, "s")
|
||||
jwt := utils.ParamString(r, "jwt")
|
||||
pass, _ := p.String("p")
|
||||
token, _ := p.String("t")
|
||||
salt, _ := p.String("s")
|
||||
jwt, _ := p.String("jwt")
|
||||
|
||||
usr, err := validateUser(ctx, ds, username, pass, token, salt, jwt)
|
||||
if errors.Is(err, model.ErrInvalidAuth) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (api *Router) GetPlaylists(r *http.Request) (*responses.Subsonic, error) {
|
||||
@@ -31,7 +31,8 @@ func (api *Router) GetPlaylists(r *http.Request) (*responses.Subsonic, error) {
|
||||
|
||||
func (api *Router) GetPlaylist(r *http.Request) (*responses.Subsonic, error) {
|
||||
ctx := r.Context()
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -84,9 +85,10 @@ func (api *Router) create(ctx context.Context, playlistId, name string, ids []st
|
||||
|
||||
func (api *Router) CreatePlaylist(r *http.Request) (*responses.Subsonic, error) {
|
||||
ctx := r.Context()
|
||||
songIds := utils.ParamStrings(r, "songId")
|
||||
playlistId := utils.ParamString(r, "playlistId")
|
||||
name := utils.ParamString(r, "name")
|
||||
p := req.Params(r)
|
||||
songIds, _ := p.Strings("songId")
|
||||
playlistId, _ := p.String("playlistId")
|
||||
name, _ := p.String("name")
|
||||
if playlistId == "" && name == "" {
|
||||
return nil, errors.New("required parameter name is missing")
|
||||
}
|
||||
@@ -99,7 +101,8 @@ func (api *Router) CreatePlaylist(r *http.Request) (*responses.Subsonic, error)
|
||||
}
|
||||
|
||||
func (api *Router) DeletePlaylist(r *http.Request) (*responses.Subsonic, error) {
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -115,23 +118,23 @@ func (api *Router) DeletePlaylist(r *http.Request) (*responses.Subsonic, error)
|
||||
}
|
||||
|
||||
func (api *Router) UpdatePlaylist(r *http.Request) (*responses.Subsonic, error) {
|
||||
playlistId, err := requiredParamString(r, "playlistId")
|
||||
p := req.Params(r)
|
||||
playlistId, err := p.String("playlistId")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
songsToAdd := utils.ParamStrings(r, "songIdToAdd")
|
||||
songIndexesToRemove := utils.ParamInts(r, "songIndexToRemove")
|
||||
songsToAdd, _ := p.Strings("songIdToAdd")
|
||||
songIndexesToRemove, _ := p.Ints("songIndexToRemove")
|
||||
var plsName *string
|
||||
if s, ok := r.URL.Query()["name"]; ok {
|
||||
plsName = &s[0]
|
||||
if s, err := p.String("name"); err == nil {
|
||||
plsName = &s
|
||||
}
|
||||
var comment *string
|
||||
if c, ok := r.URL.Query()["comment"]; ok {
|
||||
comment = &c[0]
|
||||
if s, err := p.String("comment"); err == nil {
|
||||
comment = &s
|
||||
}
|
||||
var public *bool
|
||||
if _, ok := r.URL.Query()["public"]; ok {
|
||||
p := utils.ParamBool(r, "public", false)
|
||||
if p, err := p.Bool("public"); err == nil {
|
||||
public = &p
|
||||
}
|
||||
|
||||
|
||||
@@ -5,21 +5,22 @@ import (
|
||||
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (api *Router) CreateInternetRadio(r *http.Request) (*responses.Subsonic, error) {
|
||||
streamUrl, err := requiredParamString(r, "streamUrl")
|
||||
p := req.Params(r)
|
||||
streamUrl, err := p.String("streamUrl")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name, err := requiredParamString(r, "name")
|
||||
name, err := p.String("name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
homepageUrl := utils.ParamString(r, "homepageUrl")
|
||||
homepageUrl, _ := p.String("homepageUrl")
|
||||
ctx := r.Context()
|
||||
|
||||
radio := &model.Radio{
|
||||
@@ -36,7 +37,8 @@ func (api *Router) CreateInternetRadio(r *http.Request) (*responses.Subsonic, er
|
||||
}
|
||||
|
||||
func (api *Router) DeleteInternetRadio(r *http.Request) (*responses.Subsonic, error) {
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -75,22 +77,23 @@ func (api *Router) GetInternetRadios(r *http.Request) (*responses.Subsonic, erro
|
||||
}
|
||||
|
||||
func (api *Router) UpdateInternetRadio(r *http.Request) (*responses.Subsonic, error) {
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
streamUrl, err := requiredParamString(r, "streamUrl")
|
||||
streamUrl, err := p.String("streamUrl")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name, err := requiredParamString(r, "name")
|
||||
name, err := p.String("name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
homepageUrl := utils.ParamString(r, "homepageUrl")
|
||||
homepageUrl, _ := p.String("homepageUrl")
|
||||
ctx := r.Context()
|
||||
|
||||
radio := &model.Radio{
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/server/public"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
type searchParams struct {
|
||||
@@ -28,18 +28,19 @@ type searchParams struct {
|
||||
}
|
||||
|
||||
func (api *Router) getParams(r *http.Request) (*searchParams, error) {
|
||||
p := req.Params(r)
|
||||
var err error
|
||||
sp := &searchParams{}
|
||||
sp.query, err = requiredParamString(r, "query")
|
||||
sp.query, err = p.String("query")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.artistCount = utils.ParamInt(r, "artistCount", 20)
|
||||
sp.artistOffset = utils.ParamInt(r, "artistOffset", 0)
|
||||
sp.albumCount = utils.ParamInt(r, "albumCount", 20)
|
||||
sp.albumOffset = utils.ParamInt(r, "albumOffset", 0)
|
||||
sp.songCount = utils.ParamInt(r, "songCount", 20)
|
||||
sp.songOffset = utils.ParamInt(r, "songOffset", 0)
|
||||
sp.artistCount = p.IntOr("artistCount", 20)
|
||||
sp.artistOffset = p.IntOr("artistOffset", 0)
|
||||
sp.albumCount = p.IntOr("albumCount", 20)
|
||||
sp.albumOffset = p.IntOr("albumOffset", 0)
|
||||
sp.songCount = p.IntOr("songCount", 20)
|
||||
sp.songOffset = p.IntOr("songOffset", 0)
|
||||
return sp, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/server/public"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (api *Router) GetShares(r *http.Request) (*responses.Subsonic, error) {
|
||||
@@ -50,13 +50,14 @@ func (api *Router) buildShare(r *http.Request, share model.Share) responses.Shar
|
||||
}
|
||||
|
||||
func (api *Router) CreateShare(r *http.Request) (*responses.Subsonic, error) {
|
||||
ids := utils.ParamStrings(r, "id")
|
||||
if len(ids) == 0 {
|
||||
return nil, newError(responses.ErrorMissingParameter, "Required id parameter is missing")
|
||||
p := req.Params(r)
|
||||
ids, err := p.Strings("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
description := utils.ParamString(r, "description")
|
||||
expires := utils.ParamTime(r, "expires", time.Time{})
|
||||
description, _ := p.String("description")
|
||||
expires := p.TimeOr("expires", time.Time{})
|
||||
|
||||
repo := api.share.NewRepository(r.Context())
|
||||
share := &model.Share{
|
||||
@@ -81,13 +82,14 @@ func (api *Router) CreateShare(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
|
||||
func (api *Router) UpdateShare(r *http.Request) (*responses.Subsonic, error) {
|
||||
id := utils.ParamString(r, "id")
|
||||
if id == "" {
|
||||
return nil, newError(responses.ErrorMissingParameter, "Required id parameter is missing")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
description := utils.ParamString(r, "description")
|
||||
expires := utils.ParamTime(r, "expires", time.Time{})
|
||||
description, _ := p.String("description")
|
||||
expires := p.TimeOr("expires", time.Time{})
|
||||
|
||||
repo := api.share.NewRepository(r.Context())
|
||||
share := &model.Share{
|
||||
@@ -96,7 +98,7 @@ func (api *Router) UpdateShare(r *http.Request) (*responses.Subsonic, error) {
|
||||
ExpiresAt: expires,
|
||||
}
|
||||
|
||||
err := repo.(rest.Persistable).Update(id, share)
|
||||
err = repo.(rest.Persistable).Update(id, share)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -105,13 +107,14 @@ func (api *Router) UpdateShare(r *http.Request) (*responses.Subsonic, error) {
|
||||
}
|
||||
|
||||
func (api *Router) DeleteShare(r *http.Request) (*responses.Subsonic, error) {
|
||||
id := utils.ParamString(r, "id")
|
||||
if id == "" {
|
||||
return nil, newError(responses.ErrorMissingParameter, "Required id parameter is missing")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repo := api.share.NewRepository(r.Context())
|
||||
err := repo.(rest.Persistable).Delete(id)
|
||||
err = repo.(rest.Persistable).Delete(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/model/request"
|
||||
"github.com/navidrome/navidrome/server/subsonic/responses"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
"github.com/navidrome/navidrome/utils/req"
|
||||
)
|
||||
|
||||
func (api *Router) serveStream(ctx context.Context, w http.ResponseWriter, r *http.Request, stream *core.Stream, id string) {
|
||||
@@ -25,7 +25,7 @@ func (api *Router) serveStream(ctx context.Context, w http.ResponseWriter, r *ht
|
||||
w.Header().Set("Accept-Ranges", "none")
|
||||
w.Header().Set("Content-Type", stream.ContentType())
|
||||
|
||||
estimateContentLength := utils.ParamBool(r, "estimateContentLength", false)
|
||||
estimateContentLength := req.Params(r).BoolOr("estimateContentLength", false)
|
||||
|
||||
// if Client requests the estimated content-length, send it
|
||||
if estimateContentLength {
|
||||
@@ -51,13 +51,14 @@ func (api *Router) serveStream(ctx context.Context, w http.ResponseWriter, r *ht
|
||||
|
||||
func (api *Router) Stream(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
ctx := r.Context()
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
maxBitRate := utils.ParamInt(r, "maxBitRate", 0)
|
||||
format := utils.ParamString(r, "format")
|
||||
timeOffset := utils.ParamInt(r, "timeOffset", 0)
|
||||
maxBitRate := p.IntOr("maxBitRate", 0)
|
||||
format, _ := p.String("format")
|
||||
timeOffset := p.IntOr("timeOffset", 0)
|
||||
|
||||
stream, err := api.streamer.NewStream(ctx, id, format, maxBitRate, timeOffset)
|
||||
if err != nil {
|
||||
@@ -82,7 +83,8 @@ func (api *Router) Stream(w http.ResponseWriter, r *http.Request) (*responses.Su
|
||||
func (api *Router) Download(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
ctx := r.Context()
|
||||
username, _ := request.UsernameFrom(ctx)
|
||||
id, err := requiredParamString(r, "id")
|
||||
p := req.Params(r)
|
||||
id, err := p.String("id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -97,8 +99,8 @@ func (api *Router) Download(w http.ResponseWriter, r *http.Request) (*responses.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
maxBitRate := utils.ParamInt(r, "bitrate", 0)
|
||||
format := utils.ParamString(r, "format")
|
||||
maxBitRate := p.IntOr("bitrate", 0)
|
||||
format, _ := p.String("format")
|
||||
|
||||
if format == "" {
|
||||
if conf.Server.AutoTranscodeDownload {
|
||||
|
||||
Reference in New Issue
Block a user