mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-03 20:47:35 +03:00
refactor: move request param extractors to utils
This commit is contained in:
parent
d9dd9fe587
commit
8673533cd4
11 changed files with 129 additions and 116 deletions
|
@ -47,8 +47,8 @@ func (c *AlbumListController) getAlbumList(r *http.Request) (engine.Entries, err
|
|||
return nil, errors.New("Not implemented!")
|
||||
}
|
||||
|
||||
offset := ParamInt(r, "offset", 0)
|
||||
size := utils.MinInt(ParamInt(r, "size", 10), 500)
|
||||
offset := utils.ParamInt(r, "offset", 0)
|
||||
size := utils.MinInt(utils.ParamInt(r, "size", 10), 500)
|
||||
|
||||
albums, err := listFunc(r.Context(), offset, size)
|
||||
if err != nil {
|
||||
|
@ -132,8 +132,8 @@ func (c *AlbumListController) GetNowPlaying(w http.ResponseWriter, r *http.Reque
|
|||
}
|
||||
|
||||
func (c *AlbumListController) GetRandomSongs(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
size := utils.MinInt(ParamInt(r, "size", 10), 500)
|
||||
genre := ParamString(r, "genre")
|
||||
size := utils.MinInt(utils.ParamInt(r, "size", 10), 500)
|
||||
genre := utils.ParamString(r, "genre")
|
||||
|
||||
songs, err := c.listGen.GetRandomSongs(r.Context(), size, genre)
|
||||
if err != nil {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/deluan/navidrome/engine"
|
||||
"github.com/deluan/navidrome/log"
|
||||
"github.com/deluan/navidrome/server/subsonic/responses"
|
||||
"github.com/deluan/navidrome/utils"
|
||||
"github.com/go-chi/chi"
|
||||
)
|
||||
|
||||
|
@ -163,7 +164,7 @@ func SendError(w http.ResponseWriter, r *http.Request, err error) {
|
|||
}
|
||||
|
||||
func SendResponse(w http.ResponseWriter, r *http.Request, payload *responses.Subsonic) {
|
||||
f := ParamString(r, "f")
|
||||
f := utils.ParamString(r, "f")
|
||||
var response []byte
|
||||
switch f {
|
||||
case "json":
|
||||
|
@ -172,7 +173,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 := ParamString(r, "callback")
|
||||
callback := utils.ParamString(r, "callback")
|
||||
wrapper := &responses.JsonWrapper{Subsonic: *payload}
|
||||
data, _ := json.Marshal(wrapper)
|
||||
response = []byte(fmt.Sprintf("%s(%s)", callback, data))
|
||||
|
|
|
@ -59,8 +59,8 @@ func (c *BrowsingController) getArtistIndex(r *http.Request, musicFolderId strin
|
|||
}
|
||||
|
||||
func (c *BrowsingController) GetIndexes(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
musicFolderId := ParamString(r, "musicFolderId")
|
||||
ifModifiedSince := ParamTime(r, "ifModifiedSince", time.Time{})
|
||||
musicFolderId := utils.ParamString(r, "musicFolderId")
|
||||
ifModifiedSince := utils.ParamTime(r, "ifModifiedSince", time.Time{})
|
||||
|
||||
res, err := c.getArtistIndex(r, musicFolderId, ifModifiedSince)
|
||||
if err != nil {
|
||||
|
@ -73,7 +73,7 @@ func (c *BrowsingController) GetIndexes(w http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
|
||||
func (c *BrowsingController) GetArtists(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
musicFolderId := ParamString(r, "musicFolderId")
|
||||
musicFolderId := utils.ParamString(r, "musicFolderId")
|
||||
res, err := c.getArtistIndex(r, musicFolderId, time.Time{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -85,7 +85,7 @@ func (c *BrowsingController) GetArtists(w http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
|
||||
func (c *BrowsingController) GetMusicDirectory(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
id := ParamString(r, "id")
|
||||
id := utils.ParamString(r, "id")
|
||||
dir, err := c.browser.Directory(r.Context(), id)
|
||||
switch {
|
||||
case err == model.ErrNotFound:
|
||||
|
@ -102,7 +102,7 @@ func (c *BrowsingController) GetMusicDirectory(w http.ResponseWriter, r *http.Re
|
|||
}
|
||||
|
||||
func (c *BrowsingController) GetArtist(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
id := ParamString(r, "id")
|
||||
id := utils.ParamString(r, "id")
|
||||
dir, err := c.browser.Artist(r.Context(), id)
|
||||
switch {
|
||||
case err == model.ErrNotFound:
|
||||
|
@ -119,7 +119,7 @@ func (c *BrowsingController) GetArtist(w http.ResponseWriter, r *http.Request) (
|
|||
}
|
||||
|
||||
func (c *BrowsingController) GetAlbum(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
id := ParamString(r, "id")
|
||||
id := utils.ParamString(r, "id")
|
||||
dir, err := c.browser.Album(r.Context(), id)
|
||||
switch {
|
||||
case err == model.ErrNotFound:
|
||||
|
@ -136,7 +136,7 @@ func (c *BrowsingController) GetAlbum(w http.ResponseWriter, r *http.Request) (*
|
|||
}
|
||||
|
||||
func (c *BrowsingController) GetSong(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
id := ParamString(r, "id")
|
||||
id := utils.ParamString(r, "id")
|
||||
song, err := c.browser.GetSong(r.Context(), id)
|
||||
switch {
|
||||
case err == model.ErrNotFound:
|
||||
|
|
|
@ -5,8 +5,6 @@ import (
|
|||
"mime"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/deluan/navidrome/consts"
|
||||
"github.com/deluan/navidrome/engine"
|
||||
|
@ -20,7 +18,7 @@ func NewResponse() *responses.Subsonic {
|
|||
}
|
||||
|
||||
func RequiredParamString(r *http.Request, param string, msg string) (string, error) {
|
||||
p := ParamString(r, param)
|
||||
p := utils.ParamString(r, param)
|
||||
if p == "" {
|
||||
return "", NewError(responses.ErrorMissingParameter, msg)
|
||||
}
|
||||
|
@ -28,83 +26,19 @@ func RequiredParamString(r *http.Request, param string, msg string) (string, err
|
|||
}
|
||||
|
||||
func RequiredParamStrings(r *http.Request, param string, msg string) ([]string, error) {
|
||||
ps := ParamStrings(r, param)
|
||||
ps := utils.ParamStrings(r, param)
|
||||
if len(ps) == 0 {
|
||||
return nil, NewError(responses.ErrorMissingParameter, msg)
|
||||
}
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
func ParamString(r *http.Request, param string) string {
|
||||
return r.URL.Query().Get(param)
|
||||
}
|
||||
|
||||
func ParamStrings(r *http.Request, param string) []string {
|
||||
return r.URL.Query()[param]
|
||||
}
|
||||
|
||||
func ParamTimes(r *http.Request, param string) []time.Time {
|
||||
pStr := ParamStrings(r, param)
|
||||
times := make([]time.Time, len(pStr))
|
||||
for i, t := range pStr {
|
||||
ti, err := strconv.ParseInt(t, 10, 64)
|
||||
if err == nil {
|
||||
times[i] = utils.ToTime(ti)
|
||||
}
|
||||
}
|
||||
return times
|
||||
}
|
||||
|
||||
func ParamTime(r *http.Request, param string, def time.Time) time.Time {
|
||||
v := ParamString(r, param)
|
||||
if v == "" {
|
||||
return def
|
||||
}
|
||||
value, err := strconv.ParseInt(v, 10, 64)
|
||||
if err != nil {
|
||||
return def
|
||||
}
|
||||
return utils.ToTime(value)
|
||||
}
|
||||
|
||||
func RequiredParamInt(r *http.Request, param string, msg string) (int, error) {
|
||||
p := ParamString(r, param)
|
||||
p := utils.ParamString(r, param)
|
||||
if p == "" {
|
||||
return 0, NewError(responses.ErrorMissingParameter, msg)
|
||||
}
|
||||
return ParamInt(r, param, 0), nil
|
||||
}
|
||||
|
||||
func ParamInt(r *http.Request, param string, def int) int {
|
||||
v := ParamString(r, param)
|
||||
if v == "" {
|
||||
return def
|
||||
}
|
||||
value, err := strconv.ParseInt(v, 10, 32)
|
||||
if err != nil {
|
||||
return def
|
||||
}
|
||||
return int(value)
|
||||
}
|
||||
|
||||
func ParamInts(r *http.Request, param string) []int {
|
||||
pStr := ParamStrings(r, param)
|
||||
ints := make([]int, 0, len(pStr))
|
||||
for _, s := range pStr {
|
||||
i, err := strconv.ParseInt(s, 10, 32)
|
||||
if err == nil {
|
||||
ints = append(ints, int(i))
|
||||
}
|
||||
}
|
||||
return ints
|
||||
}
|
||||
|
||||
func ParamBool(r *http.Request, param string, def bool) bool {
|
||||
p := ParamString(r, param)
|
||||
if p == "" {
|
||||
return def
|
||||
}
|
||||
return strings.Index("/true/on/1/", "/"+p+"/") != -1
|
||||
return utils.ParamInt(r, param, 0), nil
|
||||
}
|
||||
|
||||
type SubsonicError struct {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/deluan/navidrome/log"
|
||||
"github.com/deluan/navidrome/model"
|
||||
"github.com/deluan/navidrome/server/subsonic/responses"
|
||||
"github.com/deluan/navidrome/utils"
|
||||
)
|
||||
|
||||
type MediaAnnotationController struct {
|
||||
|
@ -49,9 +50,9 @@ func (c *MediaAnnotationController) SetRating(w http.ResponseWriter, r *http.Req
|
|||
}
|
||||
|
||||
func (c *MediaAnnotationController) Star(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
ids := ParamStrings(r, "id")
|
||||
albumIds := ParamStrings(r, "albumId")
|
||||
artistIds := ParamStrings(r, "artistId")
|
||||
ids := utils.ParamStrings(r, "id")
|
||||
albumIds := utils.ParamStrings(r, "albumId")
|
||||
artistIds := utils.ParamStrings(r, "artistId")
|
||||
if len(ids)+len(albumIds)+len(artistIds) == 0 {
|
||||
return nil, NewError(responses.ErrorMissingParameter, "Required id parameter is missing")
|
||||
}
|
||||
|
@ -84,9 +85,9 @@ func (c *MediaAnnotationController) star(ctx context.Context, starred bool, ids
|
|||
}
|
||||
|
||||
func (c *MediaAnnotationController) Unstar(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
ids := ParamStrings(r, "id")
|
||||
albumIds := ParamStrings(r, "albumId")
|
||||
artistIds := ParamStrings(r, "artistId")
|
||||
ids := utils.ParamStrings(r, "id")
|
||||
albumIds := utils.ParamStrings(r, "albumId")
|
||||
artistIds := utils.ParamStrings(r, "artistId")
|
||||
if len(ids)+len(albumIds)+len(artistIds) == 0 {
|
||||
return nil, NewError(responses.ErrorMissingParameter, "Required id parameter is missing")
|
||||
}
|
||||
|
@ -106,14 +107,14 @@ func (c *MediaAnnotationController) Scrobble(w http.ResponseWriter, r *http.Requ
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
times := ParamTimes(r, "time")
|
||||
times := utils.ParamTimes(r, "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))
|
||||
}
|
||||
submission := ParamBool(r, "submission", true)
|
||||
submission := utils.ParamBool(r, "submission", true)
|
||||
playerId := 1 // TODO Multiple players, based on playerName/username/clientIP(?)
|
||||
playerName := ParamString(r, "c")
|
||||
username := ParamString(r, "u")
|
||||
playerName := utils.ParamString(r, "c")
|
||||
username := utils.ParamString(r, "u")
|
||||
|
||||
log.Debug(r, "Scrobbling tracks", "ids", ids, "times", times, "submission", submission)
|
||||
for i, id := range ids {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/deluan/navidrome/model"
|
||||
"github.com/deluan/navidrome/server/subsonic/responses"
|
||||
"github.com/deluan/navidrome/static"
|
||||
"github.com/deluan/navidrome/utils"
|
||||
)
|
||||
|
||||
type MediaRetrievalController struct {
|
||||
|
@ -36,7 +37,7 @@ func (c *MediaRetrievalController) GetCoverArt(w http.ResponseWriter, r *http.Re
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
size := ParamInt(r, "size", 0)
|
||||
size := utils.ParamInt(r, "size", 0)
|
||||
|
||||
err = c.cover.Get(r.Context(), id, size, w)
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/deluan/navidrome/log"
|
||||
"github.com/deluan/navidrome/model"
|
||||
"github.com/deluan/navidrome/server/subsonic/responses"
|
||||
"github.com/deluan/navidrome/utils"
|
||||
)
|
||||
|
||||
func postFormToQueryParams(next http.Handler) http.Handler {
|
||||
|
@ -36,7 +37,7 @@ func checkRequiredParameters(next http.Handler) http.Handler {
|
|||
requiredParameters := []string{"u", "v", "c"}
|
||||
|
||||
for _, p := range requiredParameters {
|
||||
if ParamString(r, p) == "" {
|
||||
if utils.ParamString(r, p) == "" {
|
||||
msg := fmt.Sprintf(`Missing required parameter "%s"`, p)
|
||||
log.Warn(r, msg)
|
||||
SendError(w, r, NewError(responses.ErrorMissingParameter, msg))
|
||||
|
@ -44,9 +45,9 @@ func checkRequiredParameters(next http.Handler) http.Handler {
|
|||
}
|
||||
}
|
||||
|
||||
user := ParamString(r, "u")
|
||||
client := ParamString(r, "c")
|
||||
version := ParamString(r, "v")
|
||||
user := utils.ParamString(r, "u")
|
||||
client := utils.ParamString(r, "c")
|
||||
version := utils.ParamString(r, "v")
|
||||
ctx := r.Context()
|
||||
ctx = context.WithValue(ctx, "username", user)
|
||||
ctx = context.WithValue(ctx, "client", client)
|
||||
|
@ -61,11 +62,11 @@ func checkRequiredParameters(next http.Handler) http.Handler {
|
|||
func authenticate(users engine.Users) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
username := ParamString(r, "u")
|
||||
pass := ParamString(r, "p")
|
||||
token := ParamString(r, "t")
|
||||
salt := ParamString(r, "s")
|
||||
jwt := ParamString(r, "jwt")
|
||||
username := utils.ParamString(r, "u")
|
||||
pass := utils.ParamString(r, "p")
|
||||
token := utils.ParamString(r, "t")
|
||||
salt := utils.ParamString(r, "s")
|
||||
jwt := utils.ParamString(r, "jwt")
|
||||
|
||||
usr, err := users.Authenticate(r.Context(), username, pass, token, salt, jwt)
|
||||
if err == model.ErrInvalidAuth {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/deluan/navidrome/log"
|
||||
"github.com/deluan/navidrome/model"
|
||||
"github.com/deluan/navidrome/server/subsonic/responses"
|
||||
"github.com/deluan/navidrome/utils"
|
||||
)
|
||||
|
||||
type PlaylistsController struct {
|
||||
|
@ -61,9 +62,9 @@ func (c *PlaylistsController) GetPlaylist(w http.ResponseWriter, r *http.Request
|
|||
}
|
||||
|
||||
func (c *PlaylistsController) CreatePlaylist(w http.ResponseWriter, r *http.Request) (*responses.Subsonic, error) {
|
||||
songIds := ParamStrings(r, "songId")
|
||||
playlistId := ParamString(r, "playlistId")
|
||||
name := ParamString(r, "name")
|
||||
songIds := utils.ParamStrings(r, "songId")
|
||||
playlistId := utils.ParamString(r, "playlistId")
|
||||
name := utils.ParamString(r, "name")
|
||||
if playlistId == "" && name == "" {
|
||||
return nil, errors.New("Required parameter name is missing")
|
||||
}
|
||||
|
@ -96,8 +97,8 @@ func (c *PlaylistsController) UpdatePlaylist(w http.ResponseWriter, r *http.Requ
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
songsToAdd := ParamStrings(r, "songIdToAdd")
|
||||
songIndexesToRemove := ParamInts(r, "songIndexToRemove")
|
||||
songsToAdd := utils.ParamStrings(r, "songIdToAdd")
|
||||
songIndexesToRemove := utils.ParamInts(r, "songIndexToRemove")
|
||||
|
||||
var pname *string
|
||||
if len(r.URL.Query()["name"]) > 0 {
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/deluan/navidrome/engine"
|
||||
"github.com/deluan/navidrome/log"
|
||||
"github.com/deluan/navidrome/server/subsonic/responses"
|
||||
"github.com/deluan/navidrome/utils"
|
||||
)
|
||||
|
||||
type SearchingController struct {
|
||||
|
@ -34,12 +35,12 @@ func (c *SearchingController) getParams(r *http.Request) (*searchParams, error)
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sp.artistCount = ParamInt(r, "artistCount", 20)
|
||||
sp.artistOffset = ParamInt(r, "artistOffset", 0)
|
||||
sp.albumCount = ParamInt(r, "albumCount", 20)
|
||||
sp.albumOffset = ParamInt(r, "albumOffset", 0)
|
||||
sp.songCount = ParamInt(r, "songCount", 20)
|
||||
sp.songOffset = ParamInt(r, "songOffset", 0)
|
||||
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)
|
||||
return sp, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/deluan/navidrome/engine"
|
||||
"github.com/deluan/navidrome/server/subsonic/responses"
|
||||
"github.com/deluan/navidrome/utils"
|
||||
)
|
||||
|
||||
type StreamController struct {
|
||||
|
@ -20,8 +21,8 @@ func (c *StreamController) Stream(w http.ResponseWriter, r *http.Request) (*resp
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
maxBitRate := ParamInt(r, "maxBitRate", 0)
|
||||
format := ParamString(r, "format")
|
||||
maxBitRate := utils.ParamInt(r, "maxBitRate", 0)
|
||||
format := utils.ParamString(r, "format")
|
||||
|
||||
ms, err := c.streamer.NewStream(r.Context(), id, maxBitRate, format)
|
||||
if err != nil {
|
||||
|
|
72
utils/request_helpers.go
Normal file
72
utils/request_helpers.go
Normal file
|
@ -0,0 +1,72 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ParamString(r *http.Request, param string) string {
|
||||
return r.URL.Query().Get(param)
|
||||
}
|
||||
|
||||
func ParamStrings(r *http.Request, param string) []string {
|
||||
return r.URL.Query()[param]
|
||||
}
|
||||
|
||||
func ParamTimes(r *http.Request, param string) []time.Time {
|
||||
pStr := ParamStrings(r, param)
|
||||
times := make([]time.Time, len(pStr))
|
||||
for i, t := range pStr {
|
||||
ti, err := strconv.ParseInt(t, 10, 64)
|
||||
if err == nil {
|
||||
times[i] = ToTime(ti)
|
||||
}
|
||||
}
|
||||
return times
|
||||
}
|
||||
|
||||
func ParamTime(r *http.Request, param string, def time.Time) time.Time {
|
||||
v := ParamString(r, param)
|
||||
if v == "" {
|
||||
return def
|
||||
}
|
||||
value, err := strconv.ParseInt(v, 10, 64)
|
||||
if err != nil {
|
||||
return def
|
||||
}
|
||||
return ToTime(value)
|
||||
}
|
||||
|
||||
func ParamInt(r *http.Request, param string, def int) int {
|
||||
v := ParamString(r, param)
|
||||
if v == "" {
|
||||
return def
|
||||
}
|
||||
value, err := strconv.ParseInt(v, 10, 32)
|
||||
if err != nil {
|
||||
return def
|
||||
}
|
||||
return int(value)
|
||||
}
|
||||
|
||||
func ParamInts(r *http.Request, param string) []int {
|
||||
pStr := ParamStrings(r, param)
|
||||
ints := make([]int, 0, len(pStr))
|
||||
for _, s := range pStr {
|
||||
i, err := strconv.ParseInt(s, 10, 32)
|
||||
if err == nil {
|
||||
ints = append(ints, int(i))
|
||||
}
|
||||
}
|
||||
return ints
|
||||
}
|
||||
|
||||
func ParamBool(r *http.Request, param string, def bool) bool {
|
||||
p := ParamString(r, param)
|
||||
if p == "" {
|
||||
return def
|
||||
}
|
||||
return strings.Index("/true/on/1/", "/"+p+"/") != -1
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue