feat(subsonic): add getOpenSubsonicExtensions endpoint and openSubsonic response key

This commit is contained in:
sentriz
2023-09-28 21:11:15 +01:00
parent e0b1603c00
commit 2caee441ca
30 changed files with 158 additions and 118 deletions

View File

@@ -35,6 +35,12 @@ func (c *Controller) ServePing(_ *http.Request) *spec.Response {
return spec.NewResponse() return spec.NewResponse()
} }
func (c *Controller) ServeGetOpenSubsonicExtensions(_ *http.Request) *spec.Response {
sub := spec.NewResponse()
sub.OpenSubsonicExtensions = spec.OpenSubsonicExtensions{}
return sub
}
func (c *Controller) ServeScrobble(r *http.Request) *spec.Response { func (c *Controller) ServeScrobble(r *http.Request) *spec.Response {
user := r.Context().Value(CtxUser).(*db.User) user := r.Context().Value(CtxUser).(*db.User)
params := r.Context().Value(CtxParams).(params.Params) params := r.Context().Value(CtxParams).(params.Params)

View File

@@ -9,9 +9,11 @@ func AddRoutes(c *Controller, r *mux.Router) {
// common // common
r.Handle("/getLicense{_:(?:\\.view)?}", c.H(c.ServeGetLicence)) r.Handle("/getLicense{_:(?:\\.view)?}", c.H(c.ServeGetLicence))
r.Handle("/ping{_:(?:\\.view)?}", c.H(c.ServePing))
r.Handle("/getOpenSubsonicExtensions{_:(?:\\.view)?}", c.H(c.ServeGetOpenSubsonicExtensions))
r.Handle("/getMusicFolders{_:(?:\\.view)?}", c.H(c.ServeGetMusicFolders)) r.Handle("/getMusicFolders{_:(?:\\.view)?}", c.H(c.ServeGetMusicFolders))
r.Handle("/getScanStatus{_:(?:\\.view)?}", c.H(c.ServeGetScanStatus)) r.Handle("/getScanStatus{_:(?:\\.view)?}", c.H(c.ServeGetScanStatus))
r.Handle("/ping{_:(?:\\.view)?}", c.H(c.ServePing))
r.Handle("/scrobble{_:(?:\\.view)?}", c.H(c.ServeScrobble)) r.Handle("/scrobble{_:(?:\\.view)?}", c.H(c.ServeScrobble))
r.Handle("/startScan{_:(?:\\.view)?}", c.H(c.ServeStartScan)) r.Handle("/startScan{_:(?:\\.view)?}", c.H(c.ServeStartScan))
r.Handle("/getUser{_:(?:\\.view)?}", c.H(c.ServeGetUser)) r.Handle("/getUser{_:(?:\\.view)?}", c.H(c.ServeGetUser))

View File

@@ -26,8 +26,10 @@ type Response struct {
XMLNS string `xml:"xmlns,attr" json:"-"` XMLNS string `xml:"xmlns,attr" json:"-"`
// https://opensubsonic.netlify.app/docs/responses/subsonic-response/ // https://opensubsonic.netlify.app/docs/responses/subsonic-response/
Type string `xml:"type,attr" json:"type"` Type string `xml:"type,attr" json:"type"`
ServerVersion string `xml:"serverVersion,attr" json:"serverVersion"` ServerVersion string `xml:"serverVersion,attr" json:"serverVersion"`
OpenSubsonic bool `xml:"openSubsonic,attr" json:"openSubsonic"`
OpenSubsonicExtensions OpenSubsonicExtensions `xml:"openSubsonicExtensions" json:"openSubsonicExtensions,omitempty"`
Error *Error `xml:"error" json:"error,omitempty"` Error *Error `xml:"error" json:"error,omitempty"`
Albums *Albums `xml:"albumList" json:"albumList,omitempty"` Albums *Albums `xml:"albumList" json:"albumList,omitempty"`
@@ -73,6 +75,7 @@ func NewResponse() *Response {
Version: apiVersion, Version: apiVersion,
Type: gonic.Name, Type: gonic.Name,
ServerVersion: gonic.Version, ServerVersion: gonic.Version,
OpenSubsonic: true,
} }
} }
@@ -429,6 +432,8 @@ type Lyrics struct {
Title string `xml:"title,attr,omitempty" json:"title,omitempty"` Title string `xml:"title,attr,omitempty" json:"title,omitempty"`
} }
type OpenSubsonicExtensions map[string][]int
func formatRating(rating float64) string { func formatRating(rating float64) string {
if rating == 0 { if rating == 0 {
return "" return ""

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"albumList": { "albumList": {
"album": [ "album": [
{ {

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"albumList": { "albumList": {
"album": [ "album": [
{ {

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"albumList": { "albumList": {
"album": [ "album": [
{ {

View File

@@ -4,16 +4,30 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"albumList": { "albumList": {
"album": [ "album": [
{ {
"id": "al-3", "id": "al-12",
"coverArt": "al-3", "coverArt": "al-12",
"artist": "artist-0", "artist": "artist-2",
"created": "2019-11-30T00:00:00Z", "created": "2019-11-30T00:00:00Z",
"title": "album-0", "title": "album-1",
"album": "", "album": "",
"parent": "al-2", "parent": "al-10",
"isDir": true,
"name": "",
"songCount": 3,
"duration": 300
},
{
"id": "al-9",
"coverArt": "al-9",
"artist": "artist-1",
"created": "2019-11-30T00:00:00Z",
"title": "album-2",
"album": "",
"parent": "al-6",
"isDir": true, "isDir": true,
"name": "", "name": "",
"songCount": 3, "songCount": 3,
@@ -33,12 +47,25 @@
"duration": 300 "duration": 300
}, },
{ {
"id": "al-7", "id": "al-3",
"coverArt": "al-7", "coverArt": "al-3",
"artist": "artist-1", "artist": "artist-0",
"created": "2019-11-30T00:00:00Z", "created": "2019-11-30T00:00:00Z",
"title": "album-0", "title": "album-0",
"album": "", "album": "",
"parent": "al-2",
"isDir": true,
"name": "",
"songCount": 3,
"duration": 300
},
{
"id": "al-8",
"coverArt": "al-8",
"artist": "artist-1",
"created": "2019-11-30T00:00:00Z",
"title": "album-1",
"album": "",
"parent": "al-6", "parent": "al-6",
"isDir": true, "isDir": true,
"name": "", "name": "",
@@ -59,37 +86,24 @@
"duration": 300 "duration": 300
}, },
{ {
"id": "al-12", "id": "al-4",
"coverArt": "al-12", "coverArt": "al-4",
"artist": "artist-2", "artist": "artist-0",
"created": "2019-11-30T00:00:00Z", "created": "2019-11-30T00:00:00Z",
"title": "album-1", "title": "album-1",
"album": "", "album": "",
"parent": "al-10", "parent": "al-2",
"isDir": true, "isDir": true,
"name": "", "name": "",
"songCount": 3, "songCount": 3,
"duration": 300 "duration": 300
}, },
{ {
"id": "al-8", "id": "al-7",
"coverArt": "al-8", "coverArt": "al-7",
"artist": "artist-1", "artist": "artist-1",
"created": "2019-11-30T00:00:00Z", "created": "2019-11-30T00:00:00Z",
"title": "album-1", "title": "album-0",
"album": "",
"parent": "al-6",
"isDir": true,
"name": "",
"songCount": 3,
"duration": 300
},
{
"id": "al-9",
"coverArt": "al-9",
"artist": "artist-1",
"created": "2019-11-30T00:00:00Z",
"title": "album-2",
"album": "", "album": "",
"parent": "al-6", "parent": "al-6",
"isDir": true, "isDir": true,
@@ -109,19 +123,6 @@
"name": "", "name": "",
"songCount": 3, "songCount": 3,
"duration": 300 "duration": 300
},
{
"id": "al-4",
"coverArt": "al-4",
"artist": "artist-0",
"created": "2019-11-30T00:00:00Z",
"title": "album-1",
"album": "",
"parent": "al-2",
"isDir": true,
"name": "",
"songCount": 3,
"duration": 300
} }
] ]
} }

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"albumList2": { "albumList2": {
"album": [ "album": [
{ {

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"albumList2": { "albumList2": {
"album": [ "album": [
{ {

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"albumList2": { "albumList2": {
"album": [ "album": [
{ {

View File

@@ -4,17 +4,88 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"albumList2": { "albumList2": {
"album": [ "album": [
{ {
"id": "al-8", "id": "al-3",
"coverArt": "al-8", "coverArt": "al-3",
"artistId": "ar-1",
"artist": "artist-0",
"artists": [{ "id": "ar-1", "name": "artist-0" }],
"created": "2019-11-30T00:00:00Z",
"title": "",
"album": "",
"name": "album-0",
"songCount": 3,
"duration": 300,
"year": 2021
},
{
"id": "al-7",
"coverArt": "al-7",
"artistId": "ar-2", "artistId": "ar-2",
"artist": "artist-1", "artist": "artist-1",
"artists": [{ "id": "ar-2", "name": "artist-1" }], "artists": [{ "id": "ar-2", "name": "artist-1" }],
"created": "2019-11-30T00:00:00Z", "created": "2019-11-30T00:00:00Z",
"title": "", "title": "",
"album": "", "album": "",
"name": "album-0",
"songCount": 3,
"duration": 300,
"year": 2021
},
{
"id": "al-12",
"coverArt": "al-12",
"artistId": "ar-3",
"artist": "artist-2",
"artists": [{ "id": "ar-3", "name": "artist-2" }],
"created": "2019-11-30T00:00:00Z",
"title": "",
"album": "",
"name": "album-1",
"songCount": 3,
"duration": 300,
"year": 2021
},
{
"id": "al-13",
"coverArt": "al-13",
"artistId": "ar-3",
"artist": "artist-2",
"artists": [{ "id": "ar-3", "name": "artist-2" }],
"created": "2019-11-30T00:00:00Z",
"title": "",
"album": "",
"name": "album-2",
"songCount": 3,
"duration": 300,
"year": 2021
},
{
"id": "al-9",
"coverArt": "al-9",
"artistId": "ar-2",
"artist": "artist-1",
"artists": [{ "id": "ar-2", "name": "artist-1" }],
"created": "2019-11-30T00:00:00Z",
"title": "",
"album": "",
"name": "album-2",
"songCount": 3,
"duration": 300,
"year": 2021
},
{
"id": "al-4",
"coverArt": "al-4",
"artistId": "ar-1",
"artist": "artist-0",
"artists": [{ "id": "ar-1", "name": "artist-0" }],
"created": "2019-11-30T00:00:00Z",
"title": "",
"album": "",
"name": "album-1", "name": "album-1",
"songCount": 3, "songCount": 3,
"duration": 300, "duration": 300,
@@ -49,84 +120,14 @@
"year": 2021 "year": 2021
}, },
{ {
"id": "al-3", "id": "al-8",
"coverArt": "al-3", "coverArt": "al-8",
"artistId": "ar-1",
"artist": "artist-0",
"artists": [{ "id": "ar-1", "name": "artist-0" }],
"created": "2019-11-30T00:00:00Z",
"title": "",
"album": "",
"name": "album-0",
"songCount": 3,
"duration": 300,
"year": 2021
},
{
"id": "al-9",
"coverArt": "al-9",
"artistId": "ar-2", "artistId": "ar-2",
"artist": "artist-1", "artist": "artist-1",
"artists": [{ "id": "ar-2", "name": "artist-1" }], "artists": [{ "id": "ar-2", "name": "artist-1" }],
"created": "2019-11-30T00:00:00Z", "created": "2019-11-30T00:00:00Z",
"title": "", "title": "",
"album": "", "album": "",
"name": "album-2",
"songCount": 3,
"duration": 300,
"year": 2021
},
{
"id": "al-7",
"coverArt": "al-7",
"artistId": "ar-2",
"artist": "artist-1",
"artists": [{ "id": "ar-2", "name": "artist-1" }],
"created": "2019-11-30T00:00:00Z",
"title": "",
"album": "",
"name": "album-0",
"songCount": 3,
"duration": 300,
"year": 2021
},
{
"id": "al-13",
"coverArt": "al-13",
"artistId": "ar-3",
"artist": "artist-2",
"artists": [{ "id": "ar-3", "name": "artist-2" }],
"created": "2019-11-30T00:00:00Z",
"title": "",
"album": "",
"name": "album-2",
"songCount": 3,
"duration": 300,
"year": 2021
},
{
"id": "al-4",
"coverArt": "al-4",
"artistId": "ar-1",
"artist": "artist-0",
"artists": [{ "id": "ar-1", "name": "artist-0" }],
"created": "2019-11-30T00:00:00Z",
"title": "",
"album": "",
"name": "album-1",
"songCount": 3,
"duration": 300,
"year": 2021
},
{
"id": "al-12",
"coverArt": "al-12",
"artistId": "ar-3",
"artist": "artist-2",
"artists": [{ "id": "ar-3", "name": "artist-2" }],
"created": "2019-11-30T00:00:00Z",
"title": "",
"album": "",
"name": "album-1", "name": "album-1",
"songCount": 3, "songCount": 3,
"duration": 300, "duration": 300,

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"album": { "album": {
"id": "al-3", "id": "al-3",
"coverArt": "al-3", "coverArt": "al-3",

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"album": { "album": {
"id": "al-2", "id": "al-2",
"created": "2019-11-30T00:00:00Z", "created": "2019-11-30T00:00:00Z",

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"artist": { "artist": {
"id": "ar-1", "id": "ar-1",
"name": "artist-0", "name": "artist-0",

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"artist": { "artist": {
"id": "ar-3", "id": "ar-3",
"name": "artist-2", "name": "artist-2",

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"artist": { "artist": {
"id": "ar-2", "id": "ar-2",
"name": "artist-1", "name": "artist-1",

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"artists": { "artists": {
"ignoredArticles": "", "ignoredArticles": "",
"index": [ "index": [

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"artists": { "artists": {
"ignoredArticles": "", "ignoredArticles": "",
"index": [ "index": [

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"artists": { "artists": {
"ignoredArticles": "", "ignoredArticles": "",
"index": [ "index": [

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"indexes": { "indexes": {
"lastModified": 0, "lastModified": 0,
"ignoredArticles": "", "ignoredArticles": "",

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"indexes": { "indexes": {
"lastModified": 0, "lastModified": 0,
"ignoredArticles": "", "ignoredArticles": "",

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"indexes": { "indexes": {
"lastModified": 0, "lastModified": 0,
"ignoredArticles": "", "ignoredArticles": "",

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"directory": { "directory": {
"id": "al-3", "id": "al-3",
"parent": "al-2", "parent": "al-2",

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"directory": { "directory": {
"id": "al-2", "id": "al-2",
"parent": "al-1", "parent": "al-1",

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"searchResult3": { "searchResult3": {
"album": [ "album": [
{ {

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"searchResult3": { "searchResult3": {
"artist": [ "artist": [
{ "id": "ar-1", "name": "artist-0", "albumCount": 3 }, { "id": "ar-1", "name": "artist-0", "albumCount": 3 },

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"searchResult3": { "searchResult3": {
"song": [ "song": [
{ {

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"searchResult2": { "searchResult2": {
"album": [ "album": [
{ {

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"searchResult2": { "searchResult2": {
"artist": [ "artist": [
{ "id": "al-2", "parent": "al-1", "name": "artist-0" }, { "id": "al-2", "parent": "al-1", "name": "artist-0" },

View File

@@ -4,6 +4,7 @@
"version": "1.15.0", "version": "1.15.0",
"type": "gonic", "type": "gonic",
"serverVersion": "", "serverVersion": "",
"openSubsonic": true,
"searchResult2": { "searchResult2": {
"song": [ "song": [
{ {