feat: add server name and version to all responses

This is inline with other Subsonic compatible servers, like funkwhale, madsonic, ampache...
This commit is contained in:
Deluan 2020-01-30 14:43:24 -05:00
parent 482350c076
commit 90a1e6d213
47 changed files with 76 additions and 71 deletions

View File

@ -19,7 +19,7 @@ builds:
flags:
- -tags=embed
ldflags:
- -X main.gitSha={{.ShortCommit}} -X main.gitTag={{.Tag}}
- -X github.com/deluan/navidrome/consts.gitSha={{.ShortCommit}} -X github.com/deluan/navidrome/consts.gitTag={{.Tag}}
- id: navidrome_linux
env:
@ -32,7 +32,7 @@ builds:
- -tags=embed
ldflags:
- "-extldflags '-static'"
- -X main.gitSha={{.ShortCommit}} -X main.gitTag={{.Tag}}
- -X github.com/deluan/navidrome/consts.gitSha={{.ShortCommit}} -X github.com/deluan/navidrome/consts.gitTag={{.Tag}}
- id: navidrome_windows_i686
env:
@ -47,7 +47,7 @@ builds:
- -tags=embed
ldflags:
- "-extldflags '-static'"
- -X main.gitSha={{.ShortCommit}} -X main.gitTag={{.Tag}}
- -X github.com/deluan/navidrome/consts.gitSha={{.ShortCommit}} -X github.com/deluan/navidrome/consts.gitTag={{.Tag}}
- id: navidrome_windows_x64
env:
@ -62,7 +62,7 @@ builds:
- -tags=embed
ldflags:
- "-extldflags '-static'"
- -X main.gitSha={{.ShortCommit}} -X main.gitTag={{.Tag}}
- -X github.com/deluan/navidrome/consts.gitSha={{.ShortCommit}} -X github.com/deluan/navidrome/consts.gitTag={{.Tag}}
archives:
-

View File

@ -41,7 +41,7 @@ RUN GIT_TAG=$(git name-rev --name-only HEAD) && \
GIT_SHA=$(git rev-parse --short HEAD) && \
echo "Building version: ${GIT_TAG} (${GIT_SHA})" && \
go-bindata -fs -prefix ui/build -tags embed -nocompress -pkg assets -o assets/embedded_gen.go ui/build/... && \
go build -ldflags="-X main.gitSha=${GIT_SHA} -X main.gitTag=${GIT_TAG}" -tags=embed
go build -ldflags="-X github.com/deluan/navidrome/consts.gitSha=${GIT_SHA} -X github.com/deluan/navidrome/consts.gitTag=${GIT_TAG}" -tags=embed
#####################################################
### Build Final Image

View File

@ -69,8 +69,8 @@ assets/embedded_gen.go: ui/build
.PHONY: build
build: check_go_env
go build -ldflags="-X main.gitSha=$(GIT_SHA) -X main.gitTag=master"
go build -ldflags="-X github.com/deluan/navidrome/consts.gitSha=$(GIT_SHA) -X github.com/deluan/navidrome/consts.gitTag=master"
.PHONY: buildall
buildall: check_go_env assets/embedded_gen.go
go build -ldflags="-X main.gitSha=$(GIT_SHA) -X main.gitTag=master" -tags=embed
go build -ldflags="-X github.com/deluan/navidrome/consts.gitSha=$(GIT_SHA) -X github.com/deluan/navidrome/consts.gitTag=master" -tags=embed

View File

@ -4,33 +4,17 @@ import (
"fmt"
"strings"
"github.com/deluan/navidrome/consts"
"github.com/deluan/navidrome/static"
)
var (
// This will be set in build time. If not, version will be set to "dev"
gitTag string
gitSha string
)
// Formats:
// dev
// v0.2.0 (5b84188)
// master (9ed35cb)
func getVersion() string {
if gitSha == "" {
return "dev"
}
return fmt.Sprintf("%s (%s)", gitTag, gitSha)
}
func getBanner() string {
data, _ := static.Asset("banner.txt")
return strings.TrimSuffix(string(data), "\n")
}
func ShowBanner() {
version := "Version: " + getVersion()
version := "Version: " + consts.Version()
padding := strings.Repeat(" ", 52-len(version))
fmt.Printf("%s%s%s\n\n", getBanner(), padding, version)
}

View File

@ -52,8 +52,6 @@ func newWithPath(path string, skipFlags ...bool) *multiconfig.DefaultLoader {
if strings.HasSuffix(path, "yml") || strings.HasSuffix(path, "yaml") {
loaders = append(loaders, &multiconfig.YAMLLoader{Path: path})
}
} else {
println("Skipping config file not found: ", path)
}
e := &multiconfig.EnvironmentLoader{}

View File

@ -3,6 +3,8 @@ package consts
import "time"
const (
AppName = "navidrome"
LocalConfigFile = "./navidrome.toml"
InitialSetupFlagKey = "InitialSetup"
@ -10,7 +12,5 @@ const (
JWTIssuer = "ND"
JWTTokenExpiration = 30 * time.Minute
InitialUserName = "admin"
UIAssetsLocalPath = "ui/build"
)

20
consts/version.go Normal file
View File

@ -0,0 +1,20 @@
package consts
import "fmt"
var (
// This will be set in build time. If not, version will be set to "dev"
gitTag string
gitSha string
)
// Formats:
// dev
// v0.2.0 (5b84188)
// master (9ed35cb)
func Version() string {
if gitSha == "" {
return "dev"
}
return fmt.Sprintf("%s (%s)", gitTag, gitSha)
}

View File

@ -3,7 +3,6 @@ package engine
import (
"context"
"github.com/deluan/navidrome/consts"
"github.com/deluan/navidrome/model"
"github.com/deluan/navidrome/utils"
)
@ -52,12 +51,11 @@ func (p *playlists) Create(ctx context.Context, playlistId, name string, ids []s
}
func (p *playlists) getUser(ctx context.Context) string {
owner := consts.InitialUserName
user, ok := ctx.Value("user").(*model.User)
if ok {
owner = user.UserName
return user.UserName
}
return owner
return ""
}
func (p *playlists) Delete(ctx context.Context, playlistId string) error {

View File

@ -109,7 +109,7 @@ func CreateAdmin(ds model.DataStore) func(w http.ResponseWriter, r *http.Request
func createDefaultUser(ctx context.Context, ds model.DataStore, username, password string) error {
id, _ := uuid.NewRandom()
log.Warn("Creating initial user", "user", consts.InitialUserName)
log.Warn("Creating initial user", "user", username)
initialUser := model.User{
ID: id.String(),
UserName: username,

View File

@ -151,11 +151,12 @@ func HGone(r chi.Router, path string) {
}
func SendError(w http.ResponseWriter, r *http.Request, err error) {
response := &responses.Subsonic{Version: Version, Status: "fail"}
response := NewResponse()
code := responses.ErrorGeneric
if e, ok := err.(SubsonicError); ok {
code = e.code
}
response.Status = "fail"
response.Error = &responses.Error{Code: code, Message: err.Error()}
SendResponse(w, r, response)

View File

@ -7,6 +7,7 @@ import (
"strings"
"time"
"github.com/deluan/navidrome/consts"
"github.com/deluan/navidrome/engine"
"github.com/deluan/navidrome/model"
"github.com/deluan/navidrome/server/subsonic/responses"
@ -14,7 +15,7 @@ import (
)
func NewResponse() *responses.Subsonic {
return &responses.Subsonic{Status: "ok", Version: Version}
return &responses.Subsonic{Status: "ok", Version: Version, Type: consts.AppName, ServerVersion: consts.Version()}
}
func RequiredParamString(r *http.Request, param string, msg string) (string, error) {

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","albumList":{"album":[{"id":"1","isDir":false,"title":"title"}]}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","albumList":{"album":[{"id":"1","isDir":false,"title":"title"}]}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><albumList><album id="1" isDir="false" title="title"></album></albumList></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><albumList><album id="1" isDir="false" title="title"></album></albumList></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","albumList":{}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","albumList":{}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><albumList></albumList></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><albumList></albumList></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","directory":{"child":[{"id":"1","isDir":true,"title":"title","album":"album","artist":"artist","track":1,"year":1985,"genre":"Rock","coverArt":"1","size":"8421341","contentType":"audio/flac","suffix":"flac","starred":"2016-03-02T20:30:00Z","transcodedContentType":"audio/mpeg","transcodedSuffix":"mp3","duration":146,"bitRate":320}],"id":"1","name":"N"}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","directory":{"child":[{"id":"1","isDir":true,"title":"title","album":"album","artist":"artist","track":1,"year":1985,"genre":"Rock","coverArt":"1","size":"8421341","contentType":"audio/flac","suffix":"flac","starred":"2016-03-02T20:30:00Z","transcodedContentType":"audio/mpeg","transcodedSuffix":"mp3","duration":146,"bitRate":320}],"id":"1","name":"N"}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><directory id="1" name="N"><child id="1" isDir="true" title="title" album="album" artist="artist" track="1" year="1985" genre="Rock" coverArt="1" size="8421341" contentType="audio/flac" suffix="flac" starred="2016-03-02T20:30:00Z" transcodedContentType="audio/mpeg" transcodedSuffix="mp3" duration="146" bitRate="320"></child></directory></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><directory id="1" name="N"><child id="1" isDir="true" title="title" album="album" artist="artist" track="1" year="1985" genre="Rock" coverArt="1" size="8421341" contentType="audio/flac" suffix="flac" starred="2016-03-02T20:30:00Z" transcodedContentType="audio/mpeg" transcodedSuffix="mp3" duration="146" bitRate="320"></child></directory></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","directory":{"child":[{"id":"1","isDir":false,"title":"title"}],"id":"1","name":"N"}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","directory":{"child":[{"id":"1","isDir":false,"title":"title"}],"id":"1","name":"N"}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><directory id="1" name="N"><child id="1" isDir="false" title="title"></child></directory></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><directory id="1" name="N"><child id="1" isDir="false" title="title"></child></directory></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","directory":{"id":"1","name":"N"}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","directory":{"id":"1","name":"N"}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><directory id="1" name="N"></directory></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><directory id="1" name="N"></directory></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0"}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0"}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","genres":{"genre":[{"value":"Rock","songCount":1000,"albumCount":100},{"value":"Reggae","songCount":500,"albumCount":50},{"value":"Pop","songCount":0,"albumCount":0}]}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","genres":{"genre":[{"value":"Rock","songCount":1000,"albumCount":100},{"value":"Reggae","songCount":500,"albumCount":50},{"value":"Pop","songCount":0,"albumCount":0}]}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><genres><genre songCount="1000" albumCount="100">Rock</genre><genre songCount="500" albumCount="50">Reggae</genre><genre songCount="0" albumCount="0">Pop</genre></genres></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><genres><genre songCount="1000" albumCount="100">Rock</genre><genre songCount="500" albumCount="50">Reggae</genre><genre songCount="0" albumCount="0">Pop</genre></genres></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","genres":{}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","genres":{}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><genres></genres></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><genres></genres></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","indexes":{"index":[{"name":"A","artist":[{"id":"111","name":"aaa","starred":"2016-03-02T20:30:00Z"}]}],"lastModified":"1","ignoredArticles":"A"}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","indexes":{"index":[{"name":"A","artist":[{"id":"111","name":"aaa","starred":"2016-03-02T20:30:00Z"}]}],"lastModified":"1","ignoredArticles":"A"}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><indexes lastModified="1" ignoredArticles="A"><index name="A"><artist id="111" name="aaa" starred="2016-03-02T20:30:00Z"></artist></index></indexes></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><indexes lastModified="1" ignoredArticles="A"><index name="A"><artist id="111" name="aaa" starred="2016-03-02T20:30:00Z"></artist></index></indexes></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","indexes":{"lastModified":"1","ignoredArticles":"A"}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","indexes":{"lastModified":"1","ignoredArticles":"A"}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><indexes lastModified="1" ignoredArticles="A"></indexes></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><indexes lastModified="1" ignoredArticles="A"></indexes></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","license":{"valid":true}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","license":{"valid":true}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><license valid="true"></license></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><license valid="true"></license></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","musicFolders":{"musicFolder":[{"id":"111","name":"aaa"},{"id":"222","name":"bbb"}]}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","musicFolders":{"musicFolder":[{"id":"111","name":"aaa"},{"id":"222","name":"bbb"}]}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><musicFolders><musicFolder id="111" name="aaa"></musicFolder><musicFolder id="222" name="bbb"></musicFolder></musicFolders></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><musicFolders><musicFolder id="111" name="aaa"></musicFolder><musicFolder id="222" name="bbb"></musicFolder></musicFolders></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","musicFolders":{}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","musicFolders":{}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><musicFolders></musicFolders></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><musicFolders></musicFolders></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","playlists":{"playlist":[{"id":"111","name":"aaa"},{"id":"222","name":"bbb"}]}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","playlists":{"playlist":[{"id":"111","name":"aaa"},{"id":"222","name":"bbb"}]}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><playlists><playlist id="111" name="aaa"></playlist><playlist id="222" name="bbb"></playlist></playlists></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><playlists><playlist id="111" name="aaa"></playlist><playlist id="222" name="bbb"></playlist></playlists></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","playlists":{}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","playlists":{}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><playlists></playlists></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><playlists></playlists></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","user":{"username":"deluan","email":"navidrome@deluan.com","scrobblingEnabled":false,"adminRole":false,"settingsRole":false,"downloadRole":false,"uploadRole":false,"playlistRole":false,"coverArtRole":false,"commentRole":false,"podcastRole":false,"streamRole":false,"jukeboxRole":false,"shareRole":false,"videoConversionRole":false,"folder":[1]}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","user":{"username":"deluan","email":"navidrome@deluan.com","scrobblingEnabled":false,"adminRole":false,"settingsRole":false,"downloadRole":false,"uploadRole":false,"playlistRole":false,"coverArtRole":false,"commentRole":false,"podcastRole":false,"streamRole":false,"jukeboxRole":false,"shareRole":false,"videoConversionRole":false,"folder":[1]}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><user username="deluan" email="navidrome@deluan.com" scrobblingEnabled="false" adminRole="false" settingsRole="false" downloadRole="false" uploadRole="false" playlistRole="false" coverArtRole="false" commentRole="false" podcastRole="false" streamRole="false" jukeboxRole="false" shareRole="false" videoConversionRole="false"><folder>1</folder></user></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><user username="deluan" email="navidrome@deluan.com" scrobblingEnabled="false" adminRole="false" settingsRole="false" downloadRole="false" uploadRole="false" playlistRole="false" coverArtRole="false" commentRole="false" podcastRole="false" streamRole="false" jukeboxRole="false" shareRole="false" videoConversionRole="false"><folder>1</folder></user></subsonic-response>

View File

@ -1 +1 @@
{"status":"ok","version":"1.8.0","user":{"username":"deluan","scrobblingEnabled":false,"adminRole":false,"settingsRole":false,"downloadRole":false,"uploadRole":false,"playlistRole":false,"coverArtRole":false,"commentRole":false,"podcastRole":false,"streamRole":false,"jukeboxRole":false,"shareRole":false,"videoConversionRole":false}}
{"status":"ok","version":"1.8.0","type":"navidrome","serverVersion":"v0.0.0","user":{"username":"deluan","scrobblingEnabled":false,"adminRole":false,"settingsRole":false,"downloadRole":false,"uploadRole":false,"playlistRole":false,"coverArtRole":false,"commentRole":false,"podcastRole":false,"streamRole":false,"jukeboxRole":false,"shareRole":false,"videoConversionRole":false}}

View File

@ -1 +1 @@
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0"><user username="deluan" scrobblingEnabled="false" adminRole="false" settingsRole="false" downloadRole="false" uploadRole="false" playlistRole="false" coverArtRole="false" commentRole="false" podcastRole="false" streamRole="false" jukeboxRole="false" shareRole="false" videoConversionRole="false"></user></subsonic-response>
<subsonic-response xmlns="http://subsonic.org/restapi" status="ok" version="1.8.0" type="navidrome" serverVersion="v0.0.0"><user username="deluan" scrobblingEnabled="false" adminRole="false" settingsRole="false" downloadRole="false" uploadRole="false" playlistRole="false" coverArtRole="false" commentRole="false" podcastRole="false" streamRole="false" jukeboxRole="false" shareRole="false" videoConversionRole="false"></user></subsonic-response>

View File

@ -9,6 +9,8 @@ type Subsonic struct {
XMLName xml.Name `xml:"http://subsonic.org/restapi subsonic-response" json:"-"`
Status string `xml:"status,attr" json:"status"`
Version string `xml:"version,attr" json:"version"`
Type string `xml:"type,attr" json:"type"`
ServerVersion string `xml:"serverVersion,attr" json:"serverVersion"`
Error *Error `xml:"error,omitempty" json:"error,omitempty"`
License *License `xml:"license,omitempty" json:"license,omitempty"`
MusicFolders *MusicFolders `xml:"musicFolders,omitempty" json:"musicFolders,omitempty"`

View File

@ -10,6 +10,7 @@ import (
"encoding/xml"
"time"
"github.com/deluan/navidrome/consts"
. "github.com/deluan/navidrome/server/subsonic/responses"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@ -18,7 +19,7 @@ import (
var _ = Describe("Responses", func() {
var response *Subsonic
BeforeEach(func() {
response = &Subsonic{Status: "ok", Version: "1.8.0"}
response = &Subsonic{Status: "ok", Version: "1.8.0", Type: consts.AppName, ServerVersion: "v0.0.0"}
})
Describe("EmptyResponse", func() {