navidrome/api/base_api_controller.go

198 lines
4.7 KiB
Go

package api
import (
"encoding/xml"
"fmt"
"strconv"
"time"
"github.com/astaxie/beego"
"github.com/cloudsonic/sonic-server/api/responses"
"github.com/cloudsonic/sonic-server/engine"
"github.com/cloudsonic/sonic-server/utils"
)
type BaseAPIController struct{ beego.Controller }
func (c *BaseAPIController) NewEmpty() responses.Subsonic {
return responses.Subsonic{Status: "ok", Version: beego.AppConfig.String("apiVersion")}
}
func (c *BaseAPIController) RequiredParamString(param string, msg string) string {
p := c.Input().Get(param)
if p == "" {
c.SendError(responses.ErrorMissingParameter, msg)
}
return p
}
func (c *BaseAPIController) RequiredParamStrings(param string, msg string) []string {
ps := c.Input()[param]
if len(ps) == 0 {
c.SendError(responses.ErrorMissingParameter, msg)
}
return ps
}
func (c *BaseAPIController) ParamString(param string) string {
return c.Input().Get(param)
}
func (c *BaseAPIController) ParamStrings(param string) []string {
return c.Input()[param]
}
func (c *BaseAPIController) ParamTime(param string, def time.Time) time.Time {
if c.Input().Get(param) == "" {
return def
}
var value int64
c.Ctx.Input.Bind(&value, param)
return utils.ToTime(value)
}
func (c *BaseAPIController) ParamTimes(param string) []time.Time {
pStr := c.Input()[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 (c *BaseAPIController) RequiredParamInt(param string, msg string) int {
p := c.Input().Get(param)
if p == "" {
c.SendError(responses.ErrorMissingParameter, msg)
}
return c.ParamInt(param, 0)
}
func (c *BaseAPIController) ParamInt(param string, def int) int {
if c.Input().Get(param) == "" {
return def
}
var value int
c.Ctx.Input.Bind(&value, param)
return value
}
func (c *BaseAPIController) ParamInts(param string) []int {
pStr := c.Input()[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 (c *BaseAPIController) ParamBool(param string, def bool) bool {
if c.Input().Get(param) == "" {
return def
}
var value bool
c.Ctx.Input.Bind(&value, param)
return value
}
func (c *BaseAPIController) SendError(errorCode int, message ...interface{}) {
response := responses.Subsonic{Version: beego.AppConfig.String("apiVersion"), Status: "fail"}
var msg string
if len(message) == 0 {
msg = responses.ErrorMsg(errorCode)
} else {
msg = fmt.Sprintf(message[0].(string), message[1:]...)
}
response.Error = &responses.Error{Code: errorCode, Message: msg}
xmlBody, _ := xml.Marshal(&response)
c.CustomAbort(200, xml.Header+string(xmlBody))
}
func (c *BaseAPIController) SendEmptyResponse() {
c.SendResponse(c.NewEmpty())
}
func (c *BaseAPIController) SendResponse(response responses.Subsonic) {
f := c.GetString("f")
switch f {
case "json":
w := &responses.JsonWrapper{Subsonic: response}
c.Data["json"] = &w
c.ServeJSON()
case "jsonp":
w := &responses.JsonWrapper{Subsonic: response}
c.Data["jsonp"] = &w
c.ServeJSONP()
default:
c.Data["xml"] = &response
c.ServeXML()
}
}
func (c *BaseAPIController) ToChildren(entries engine.Entries) []responses.Child {
children := make([]responses.Child, len(entries))
for i, entry := range entries {
children[i] = c.ToChild(entry)
}
return children
}
func (c *BaseAPIController) ToAlbums(entries engine.Entries) []responses.Child {
children := make([]responses.Child, len(entries))
for i, entry := range entries {
children[i] = c.ToAlbum(entry)
}
return children
}
func (c *BaseAPIController) ToAlbum(entry engine.Entry) responses.Child {
album := c.ToChild(entry)
album.Name = album.Title
album.Title = ""
album.Parent = ""
album.Album = ""
album.AlbumId = ""
return album
}
func (c *BaseAPIController) ToChild(entry engine.Entry) responses.Child {
child := responses.Child{}
child.Id = entry.Id
child.Title = entry.Title
child.IsDir = entry.IsDir
child.Parent = entry.Parent
child.Album = entry.Album
child.Year = entry.Year
child.Artist = entry.Artist
child.Genre = entry.Genre
child.CoverArt = entry.CoverArt
child.Track = entry.Track
child.Duration = entry.Duration
child.Size = entry.Size
child.Suffix = entry.Suffix
child.BitRate = entry.BitRate
child.ContentType = entry.ContentType
if !entry.Starred.IsZero() {
child.Starred = &entry.Starred
}
child.Path = entry.Path
child.PlayCount = entry.PlayCount
child.DiscNumber = entry.DiscNumber
if !entry.Created.IsZero() {
child.Created = &entry.Created
}
child.AlbumId = entry.AlbumId
child.ArtistId = entry.ArtistId
child.Type = entry.Type
child.UserRating = entry.UserRating
child.SongCount = entry.SongCount
return child
}