feat: add transcodedSuffix to Subsonic API responses

This commit is contained in:
Deluan
2020-03-16 12:56:15 -04:00
committed by Deluan Quintão
parent 45180115a6
commit 39993810b3
12 changed files with 136 additions and 61 deletions
+10 -3
View File
@@ -12,7 +12,7 @@ import (
type Players interface { type Players interface {
Get(ctx context.Context, playerId string) (*model.Player, error) Get(ctx context.Context, playerId string) (*model.Player, error)
Register(ctx context.Context, id, client, typ, ip string) (*model.Player, error) Register(ctx context.Context, id, client, typ, ip string) (*model.Player, *model.Transcoding, error)
} }
func NewPlayers(ds model.DataStore) Players { func NewPlayers(ds model.DataStore) Players {
@@ -23,8 +23,9 @@ type players struct {
ds model.DataStore ds model.DataStore
} }
func (p *players) Register(ctx context.Context, id, client, typ, ip string) (*model.Player, error) { func (p *players) Register(ctx context.Context, id, client, typ, ip string) (*model.Player, *model.Transcoding, error) {
var plr *model.Player var plr *model.Player
var trc *model.Transcoding
var err error var err error
userName := ctx.Value("username").(string) userName := ctx.Value("username").(string)
if id != "" { if id != "" {
@@ -49,7 +50,13 @@ func (p *players) Register(ctx context.Context, id, client, typ, ip string) (*mo
plr.Type = typ plr.Type = typ
plr.IPAddress = ip plr.IPAddress = ip
err = p.ds.Player(ctx).Put(plr) err = p.ds.Player(ctx).Put(plr)
return plr, err if err != nil {
return nil, nil, err
}
if plr.TranscodingId != "" {
trc, err = p.ds.Transcoding(ctx).Get(plr.TranscodingId)
}
return plr, trc, err
} }
func (p *players) Get(ctx context.Context, playerId string) (*model.Player, error) { func (p *players) Get(ctx context.Context, playerId string) (*model.Player, error) {
+28 -6
View File
@@ -20,14 +20,14 @@ var _ = Describe("Players", func() {
BeforeEach(func() { BeforeEach(func() {
repo = &mockPlayerRepository{} repo = &mockPlayerRepository{}
ds := &persistence.MockDataStore{MockedPlayer: repo} ds := &persistence.MockDataStore{MockedPlayer: repo, MockedTranscoding: &mockTranscodingRepository{}}
players = NewPlayers(ds) players = NewPlayers(ds)
beforeRegister = time.Now() beforeRegister = time.Now()
}) })
Describe("Register", func() { Describe("Register", func() {
It("creates a new player when no ID is specified", func() { It("creates a new player when no ID is specified", func() {
p, err := players.Register(ctx, "", "client", "chrome", "1.2.3.4") p, trc, err := players.Register(ctx, "", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p.ID).ToNot(BeEmpty()) Expect(p.ID).ToNot(BeEmpty())
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister)) Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
@@ -35,30 +35,33 @@ var _ = Describe("Players", func() {
Expect(p.UserName).To(Equal("johndoe")) Expect(p.UserName).To(Equal("johndoe"))
Expect(p.Type).To(Equal("chrome")) Expect(p.Type).To(Equal("chrome"))
Expect(repo.lastSaved).To(Equal(p)) Expect(repo.lastSaved).To(Equal(p))
Expect(trc).To(BeNil())
}) })
It("creates a new player if it cannot find any matching player", func() { It("creates a new player if it cannot find any matching player", func() {
p, err := players.Register(ctx, "123", "client", "chrome", "1.2.3.4") p, trc, err := players.Register(ctx, "123", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p.ID).ToNot(BeEmpty()) Expect(p.ID).ToNot(BeEmpty())
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister)) Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(repo.lastSaved).To(Equal(p)) Expect(repo.lastSaved).To(Equal(p))
Expect(trc).To(BeNil())
}) })
It("finds players by ID", func() { It("finds players by ID", func() {
plr := &model.Player{ID: "123", Name: "A Player", LastSeen: time.Time{}} plr := &model.Player{ID: "123", Name: "A Player", LastSeen: time.Time{}}
repo.add(plr) repo.add(plr)
p, err := players.Register(ctx, "123", "client", "chrome", "1.2.3.4") p, trc, err := players.Register(ctx, "123", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p.ID).To(Equal("123")) Expect(p.ID).To(Equal("123"))
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister)) Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(repo.lastSaved).To(Equal(p)) Expect(repo.lastSaved).To(Equal(p))
Expect(trc).To(BeNil())
}) })
It("finds player by client and user names when ID is not found", func() { It("finds player by client and user names when ID is not found", func() {
plr := &model.Player{ID: "123", Name: "A Player", Client: "client", UserName: "johndoe", LastSeen: time.Time{}} plr := &model.Player{ID: "123", Name: "A Player", Client: "client", UserName: "johndoe", LastSeen: time.Time{}}
repo.add(plr) repo.add(plr)
p, err := players.Register(ctx, "999", "client", "chrome", "1.2.3.4") p, _, err := players.Register(ctx, "999", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p.ID).To(Equal("123")) Expect(p.ID).To(Equal("123"))
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister)) Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
@@ -68,15 +71,34 @@ var _ = Describe("Players", func() {
It("finds player by client and user names when not ID is provided", func() { It("finds player by client and user names when not ID is provided", func() {
plr := &model.Player{ID: "123", Name: "A Player", Client: "client", UserName: "johndoe", LastSeen: time.Time{}} plr := &model.Player{ID: "123", Name: "A Player", Client: "client", UserName: "johndoe", LastSeen: time.Time{}}
repo.add(plr) repo.add(plr)
p, err := players.Register(ctx, "", "client", "chrome", "1.2.3.4") p, _, err := players.Register(ctx, "", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(p.ID).To(Equal("123")) Expect(p.ID).To(Equal("123"))
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister)) Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(repo.lastSaved).To(Equal(p)) Expect(repo.lastSaved).To(Equal(p))
}) })
It("finds player by ID and return its transcoding", func() {
plr := &model.Player{ID: "123", Name: "A Player", LastSeen: time.Time{}, TranscodingId: "1"}
repo.add(plr)
p, trc, err := players.Register(ctx, "123", "client", "chrome", "1.2.3.4")
Expect(err).ToNot(HaveOccurred())
Expect(p.ID).To(Equal("123"))
Expect(p.LastSeen).To(BeTemporally(">=", beforeRegister))
Expect(repo.lastSaved).To(Equal(p))
Expect(trc.ID).To(Equal("1"))
})
}) })
}) })
type mockTranscodingRepository struct {
model.TranscodingRepository
}
func (m *mockTranscodingRepository) Get(id string) (*model.Transcoding, error) {
return &model.Transcoding{ID: id, TargetFormat: "mp3"}, nil
}
type mockPlayerRepository struct { type mockPlayerRepository struct {
model.PlayerRepository model.PlayerRepository
lastSaved *model.Player lastSaved *model.Player
+1
View File
@@ -11,5 +11,6 @@ type Transcoding struct {
type Transcodings []Transcoding type Transcodings []Transcoding
type TranscodingRepository interface { type TranscodingRepository interface {
Get(id string) (*Transcoding, error)
Put(*Transcoding) error Put(*Transcoding) error
} }
+10 -6
View File
@@ -7,12 +7,13 @@ import (
) )
type MockDataStore struct { type MockDataStore struct {
MockedGenre model.GenreRepository MockedGenre model.GenreRepository
MockedAlbum model.AlbumRepository MockedAlbum model.AlbumRepository
MockedArtist model.ArtistRepository MockedArtist model.ArtistRepository
MockedMediaFile model.MediaFileRepository MockedMediaFile model.MediaFileRepository
MockedUser model.UserRepository MockedUser model.UserRepository
MockedPlayer model.PlayerRepository MockedPlayer model.PlayerRepository
MockedTranscoding model.TranscodingRepository
} }
func (db *MockDataStore) Album(context.Context) model.AlbumRepository { func (db *MockDataStore) Album(context.Context) model.AlbumRepository {
@@ -63,6 +64,9 @@ func (db *MockDataStore) User(context.Context) model.UserRepository {
} }
func (db *MockDataStore) Transcoding(context.Context) model.TranscodingRepository { func (db *MockDataStore) Transcoding(context.Context) model.TranscodingRepository {
if db.MockedTranscoding != nil {
return db.MockedTranscoding
}
return struct{ model.TranscodingRepository }{} return struct{ model.TranscodingRepository }{}
} }
+8 -5
View File
@@ -21,6 +21,13 @@ func NewTranscodingRepository(ctx context.Context, o orm.Ormer) model.Transcodin
return r return r
} }
func (r *transcodingRepository) Get(id string) (*model.Transcoding, error) {
sel := r.newSelect().Columns("*").Where(Eq{"id": id})
var res model.Transcoding
err := r.queryOne(sel, &res)
return &res, err
}
func (r *transcodingRepository) Put(t *model.Transcoding) error { func (r *transcodingRepository) Put(t *model.Transcoding) error {
_, err := r.put(t.ID, t) _, err := r.put(t.ID, t)
return err return err
@@ -31,11 +38,7 @@ func (r *transcodingRepository) Count(options ...rest.QueryOptions) (int64, erro
} }
func (r *transcodingRepository) Read(id string) (interface{}, error) { func (r *transcodingRepository) Read(id string) (interface{}, error) {
sel := r.newSelect().Columns("*").Where(Eq{"id": id}) return r.Get(id)
var res model.Transcoding
err := r.queryOne(sel, &res)
return &res, err
} }
func (r *transcodingRepository) ReadAll(options ...rest.QueryOptions) (interface{}, error) { func (r *transcodingRepository) ReadAll(options ...rest.QueryOptions) (interface{}, error) {
+8 -11
View File
@@ -66,7 +66,7 @@ func (c *AlbumListController) GetAlbumList(w http.ResponseWriter, r *http.Reques
} }
response := NewResponse() response := NewResponse()
response.AlbumList = &responses.AlbumList{Album: ToChildren(albums)} response.AlbumList = &responses.AlbumList{Album: ToChildren(r.Context(), albums)}
return response, nil return response, nil
} }
@@ -77,7 +77,7 @@ func (c *AlbumListController) GetAlbumList2(w http.ResponseWriter, r *http.Reque
} }
response := NewResponse() response := NewResponse()
response.AlbumList2 = &responses.AlbumList{Album: ToAlbums(albums)} response.AlbumList2 = &responses.AlbumList{Album: ToAlbums(r.Context(), albums)}
return response, nil return response, nil
} }
@@ -91,8 +91,8 @@ func (c *AlbumListController) GetStarred(w http.ResponseWriter, r *http.Request)
response := NewResponse() response := NewResponse()
response.Starred = &responses.Starred{} response.Starred = &responses.Starred{}
response.Starred.Artist = ToArtists(artists) response.Starred.Artist = ToArtists(artists)
response.Starred.Album = ToChildren(albums) response.Starred.Album = ToChildren(r.Context(), albums)
response.Starred.Song = ToChildren(mediaFiles) response.Starred.Song = ToChildren(r.Context(), mediaFiles)
return response, nil return response, nil
} }
@@ -106,8 +106,8 @@ func (c *AlbumListController) GetStarred2(w http.ResponseWriter, r *http.Request
response := NewResponse() response := NewResponse()
response.Starred2 = &responses.Starred{} response.Starred2 = &responses.Starred{}
response.Starred2.Artist = ToArtists(artists) response.Starred2.Artist = ToArtists(artists)
response.Starred2.Album = ToAlbums(albums) response.Starred2.Album = ToAlbums(r.Context(), albums)
response.Starred2.Song = ToChildren(mediaFiles) response.Starred2.Song = ToChildren(r.Context(), mediaFiles)
return response, nil return response, nil
} }
@@ -122,7 +122,7 @@ func (c *AlbumListController) GetNowPlaying(w http.ResponseWriter, r *http.Reque
response.NowPlaying = &responses.NowPlaying{} response.NowPlaying = &responses.NowPlaying{}
response.NowPlaying.Entry = make([]responses.NowPlayingEntry, len(npInfos)) response.NowPlaying.Entry = make([]responses.NowPlayingEntry, len(npInfos))
for i, entry := range npInfos { for i, entry := range npInfos {
response.NowPlaying.Entry[i].Child = ToChild(entry) response.NowPlaying.Entry[i].Child = ToChild(r.Context(), entry)
response.NowPlaying.Entry[i].UserName = entry.UserName response.NowPlaying.Entry[i].UserName = entry.UserName
response.NowPlaying.Entry[i].MinutesAgo = entry.MinutesAgo response.NowPlaying.Entry[i].MinutesAgo = entry.MinutesAgo
response.NowPlaying.Entry[i].PlayerId = entry.PlayerId response.NowPlaying.Entry[i].PlayerId = entry.PlayerId
@@ -143,9 +143,6 @@ func (c *AlbumListController) GetRandomSongs(w http.ResponseWriter, r *http.Requ
response := NewResponse() response := NewResponse()
response.RandomSongs = &responses.Songs{} response.RandomSongs = &responses.Songs{}
response.RandomSongs.Songs = make([]responses.Child, len(songs)) response.RandomSongs.Songs = ToChildren(r.Context(), songs)
for i, entry := range songs {
response.RandomSongs.Songs[i] = ToChild(entry)
}
return response, nil return response, nil
} }
+11 -10
View File
@@ -1,6 +1,7 @@
package subsonic package subsonic
import ( import (
"context"
"fmt" "fmt"
"net/http" "net/http"
"time" "time"
@@ -97,7 +98,7 @@ func (c *BrowsingController) GetMusicDirectory(w http.ResponseWriter, r *http.Re
} }
response := NewResponse() response := NewResponse()
response.Directory = c.buildDirectory(dir) response.Directory = c.buildDirectory(r.Context(), dir)
return response, nil return response, nil
} }
@@ -114,7 +115,7 @@ func (c *BrowsingController) GetArtist(w http.ResponseWriter, r *http.Request) (
} }
response := NewResponse() response := NewResponse()
response.ArtistWithAlbumsID3 = c.buildArtist(dir) response.ArtistWithAlbumsID3 = c.buildArtist(r.Context(), dir)
return response, nil return response, nil
} }
@@ -131,7 +132,7 @@ func (c *BrowsingController) GetAlbum(w http.ResponseWriter, r *http.Request) (*
} }
response := NewResponse() response := NewResponse()
response.AlbumWithSongsID3 = c.buildAlbum(dir) response.AlbumWithSongsID3 = c.buildAlbum(r.Context(), dir)
return response, nil return response, nil
} }
@@ -148,7 +149,7 @@ func (c *BrowsingController) GetSong(w http.ResponseWriter, r *http.Request) (*r
} }
response := NewResponse() response := NewResponse()
child := ToChild(*song) child := ToChild(r.Context(), *song)
response.Song = &child response.Song = &child
return response, nil return response, nil
} }
@@ -189,7 +190,7 @@ func (c *BrowsingController) GetArtistInfo2(w http.ResponseWriter, r *http.Reque
return response, nil return response, nil
} }
func (c *BrowsingController) buildDirectory(d *engine.DirectoryInfo) *responses.Directory { func (c *BrowsingController) buildDirectory(ctx context.Context, d *engine.DirectoryInfo) *responses.Directory {
dir := &responses.Directory{ dir := &responses.Directory{
Id: d.Id, Id: d.Id,
Name: d.Name, Name: d.Name,
@@ -202,11 +203,11 @@ func (c *BrowsingController) buildDirectory(d *engine.DirectoryInfo) *responses.
dir.Starred = &d.Starred dir.Starred = &d.Starred
} }
dir.Child = ToChildren(d.Entries) dir.Child = ToChildren(ctx, d.Entries)
return dir return dir
} }
func (c *BrowsingController) buildArtist(d *engine.DirectoryInfo) *responses.ArtistWithAlbumsID3 { func (c *BrowsingController) buildArtist(ctx context.Context, d *engine.DirectoryInfo) *responses.ArtistWithAlbumsID3 {
dir := &responses.ArtistWithAlbumsID3{} dir := &responses.ArtistWithAlbumsID3{}
dir.Id = d.Id dir.Id = d.Id
dir.Name = d.Name dir.Name = d.Name
@@ -216,11 +217,11 @@ func (c *BrowsingController) buildArtist(d *engine.DirectoryInfo) *responses.Art
dir.Starred = &d.Starred dir.Starred = &d.Starred
} }
dir.Album = ToAlbums(d.Entries) dir.Album = ToAlbums(ctx, d.Entries)
return dir return dir
} }
func (c *BrowsingController) buildAlbum(d *engine.DirectoryInfo) *responses.AlbumWithSongsID3 { func (c *BrowsingController) buildAlbum(ctx context.Context, d *engine.DirectoryInfo) *responses.AlbumWithSongsID3 {
dir := &responses.AlbumWithSongsID3{} dir := &responses.AlbumWithSongsID3{}
dir.Id = d.Id dir.Id = d.Id
dir.Name = d.Name dir.Name = d.Name
@@ -239,6 +240,6 @@ func (c *BrowsingController) buildAlbum(d *engine.DirectoryInfo) *responses.Albu
dir.Starred = &d.Starred dir.Starred = &d.Starred
} }
dir.Song = ToChildren(d.Entries) dir.Song = ToChildren(ctx, d.Entries)
return dir return dir
} }
+23 -10
View File
@@ -1,6 +1,7 @@
package subsonic package subsonic
import ( import (
"context"
"fmt" "fmt"
"mime" "mime"
"net/http" "net/http"
@@ -63,16 +64,16 @@ func (e SubsonicError) Error() string {
return msg return msg
} }
func ToAlbums(entries engine.Entries) []responses.Child { func ToAlbums(ctx context.Context, entries engine.Entries) []responses.Child {
children := make([]responses.Child, len(entries)) children := make([]responses.Child, len(entries))
for i, entry := range entries { for i, entry := range entries {
children[i] = ToAlbum(entry) children[i] = ToAlbum(ctx, entry)
} }
return children return children
} }
func ToAlbum(entry engine.Entry) responses.Child { func ToAlbum(ctx context.Context, entry engine.Entry) responses.Child {
album := ToChild(entry) album := ToChild(ctx, entry)
album.Name = album.Title album.Name = album.Title
album.Title = "" album.Title = ""
album.Parent = "" album.Parent = ""
@@ -96,15 +97,15 @@ func ToArtists(entries engine.Entries) []responses.Artist {
return artists return artists
} }
func ToChildren(entries engine.Entries) []responses.Child { func ToChildren(ctx context.Context, entries engine.Entries) []responses.Child {
children := make([]responses.Child, len(entries)) children := make([]responses.Child, len(entries))
for i, entry := range entries { for i, entry := range entries {
children[i] = ToChild(entry) children[i] = ToChild(ctx, entry)
} }
return children return children
} }
func ToChild(entry engine.Entry) responses.Child { func ToChild(ctx context.Context, entry engine.Entry) responses.Child {
child := responses.Child{} child := responses.Child{}
child.Id = entry.Id child.Id = entry.Id
child.Title = entry.Title child.Title = entry.Title
@@ -136,9 +137,11 @@ func ToChild(entry engine.Entry) responses.Child {
child.IsVideo = false child.IsVideo = false
child.UserRating = entry.UserRating child.UserRating = entry.UserRating
child.SongCount = entry.SongCount child.SongCount = entry.SongCount
// TODO Must be dynamic, based on player/transcoding config format, _ := getTranscoding(ctx)
child.TranscodedSuffix = "mp3" if entry.Suffix != "" && format != "" && entry.Suffix != format {
child.TranscodedContentType = mime.TypeByExtension(".mp3") child.TranscodedSuffix = format
child.TranscodedContentType = mime.TypeByExtension("." + format)
}
return child return child
} }
@@ -149,3 +152,13 @@ func ToGenres(genres model.Genres) *responses.Genres {
} }
return &responses.Genres{Genre: response} return &responses.Genres{Genre: response}
} }
func getTranscoding(ctx context.Context) (format string, bitRate int) {
if trc, ok := ctx.Value("transcoding").(model.Transcoding); ok {
format = trc.TargetFormat
}
if plr, ok := ctx.Value("player").(model.Player); ok {
bitRate = plr.MaxBitRate
}
return
}
+4 -1
View File
@@ -103,11 +103,14 @@ func getPlayer(players engine.Players) func(next http.Handler) http.Handler {
client := ctx.Value("client").(string) client := ctx.Value("client").(string)
playerId := playerIDFromCookie(r, userName) playerId := playerIDFromCookie(r, userName)
ip, _, _ := net.SplitHostPort(r.RemoteAddr) ip, _, _ := net.SplitHostPort(r.RemoteAddr)
player, err := players.Register(ctx, playerId, client, r.Header.Get("user-agent"), ip) player, trc, err := players.Register(ctx, playerId, client, r.Header.Get("user-agent"), ip)
if err != nil { if err != nil {
log.Error("Could not register player", "userName", userName, "client", client) log.Error("Could not register player", "userName", userName, "client", client)
} else { } else {
ctx = context.WithValue(ctx, "player", *player) ctx = context.WithValue(ctx, "player", *player)
if trc != nil {
ctx = context.WithValue(ctx, "transcoding", *trc)
}
r = r.WithContext(ctx) r = r.WithContext(ctx)
} }
+25 -2
View File
@@ -173,6 +173,7 @@ var _ = Describe("Middlewares", func() {
Expect(next.called).To(BeTrue()) Expect(next.called).To(BeTrue())
player := next.req.Context().Value("player").(model.Player) player := next.req.Context().Value("player").(model.Player)
Expect(player.ID).To(Equal("123")) Expect(player.ID).To(Equal("123"))
Expect(next.req.Context().Value("transcoding")).To(BeNil())
}) })
It("returns the playerId in the cookie", func() { It("returns the playerId in the cookie", func() {
@@ -180,6 +181,27 @@ var _ = Describe("Middlewares", func() {
Expect(cookieStr).To(ContainSubstring(playerIDCookieName("someone") + "=123")) Expect(cookieStr).To(ContainSubstring(playerIDCookieName("someone") + "=123"))
}) })
}) })
Context("Player has transcoding configured", func() {
BeforeEach(func() {
cookie := &http.Cookie{
Name: playerIDCookieName("someone"),
Value: "123",
MaxAge: cookieExpiry,
}
r.AddCookie(cookie)
mockedPlayers.transcoding = &model.Transcoding{ID: "12"}
gp := getPlayer(mockedPlayers)(next)
gp.ServeHTTP(w, r)
})
It("stores the player in the context", func() {
player := next.req.Context().Value("player").(model.Player)
Expect(player.ID).To(Equal("123"))
transcoding := next.req.Context().Value("transcoding").(model.Transcoding)
Expect(transcoding.ID).To(Equal("12"))
})
})
}) })
}) })
@@ -212,12 +234,13 @@ func (m *mockUsers) Authenticate(ctx context.Context, username, password, token,
type mockPlayers struct { type mockPlayers struct {
engine.Players engine.Players
transcoding *model.Transcoding
} }
func (mp *mockPlayers) Get(ctx context.Context, playerId string) (*model.Player, error) { func (mp *mockPlayers) Get(ctx context.Context, playerId string) (*model.Player, error) {
return &model.Player{ID: playerId}, nil return &model.Player{ID: playerId}, nil
} }
func (mp *mockPlayers) Register(ctx context.Context, id, client, typ, ip string) (*model.Player, error) { func (mp *mockPlayers) Register(ctx context.Context, id, client, typ, ip string) (*model.Player, *model.Transcoding, error) {
return &model.Player{ID: id}, nil return &model.Player{ID: id}, mp.transcoding, nil
} }
+4 -3
View File
@@ -1,6 +1,7 @@
package subsonic package subsonic
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
@@ -57,7 +58,7 @@ func (c *PlaylistsController) GetPlaylist(w http.ResponseWriter, r *http.Request
} }
response := NewResponse() response := NewResponse()
response.Playlist = c.buildPlaylist(pinfo) response.Playlist = c.buildPlaylist(r.Context(), pinfo)
return response, nil return response, nil
} }
@@ -124,7 +125,7 @@ func (c *PlaylistsController) UpdatePlaylist(w http.ResponseWriter, r *http.Requ
return NewResponse(), nil return NewResponse(), nil
} }
func (c *PlaylistsController) buildPlaylist(d *engine.PlaylistInfo) *responses.PlaylistWithSongs { func (c *PlaylistsController) buildPlaylist(ctx context.Context, d *engine.PlaylistInfo) *responses.PlaylistWithSongs {
pls := &responses.PlaylistWithSongs{} pls := &responses.PlaylistWithSongs{}
pls.Id = d.Id pls.Id = d.Id
pls.Name = d.Name pls.Name = d.Name
@@ -133,6 +134,6 @@ func (c *PlaylistsController) buildPlaylist(d *engine.PlaylistInfo) *responses.P
pls.Duration = d.Duration pls.Duration = d.Duration
pls.Public = d.Public pls.Public = d.Public
pls.Entry = ToChildren(d.Entries) pls.Entry = ToChildren(ctx, d.Entries)
return pls return pls
} }
+4 -4
View File
@@ -72,8 +72,8 @@ func (c *SearchingController) Search2(w http.ResponseWriter, r *http.Request) (*
response := NewResponse() response := NewResponse()
searchResult2 := &responses.SearchResult2{} searchResult2 := &responses.SearchResult2{}
searchResult2.Artist = ToArtists(as) searchResult2.Artist = ToArtists(as)
searchResult2.Album = ToChildren(als) searchResult2.Album = ToChildren(r.Context(), als)
searchResult2.Song = ToChildren(mfs) searchResult2.Song = ToChildren(r.Context(), mfs)
response.SearchResult2 = searchResult2 response.SearchResult2 = searchResult2
return response, nil return response, nil
} }
@@ -99,8 +99,8 @@ func (c *SearchingController) Search3(w http.ResponseWriter, r *http.Request) (*
searchResult3.Artist[i].Starred = &e.Starred searchResult3.Artist[i].Starred = &e.Starred
} }
} }
searchResult3.Album = ToAlbums(als) searchResult3.Album = ToAlbums(r.Context(), als)
searchResult3.Song = ToChildren(mfs) searchResult3.Song = ToChildren(r.Context(), mfs)
response.SearchResult3 = searchResult3 response.SearchResult3 = searchResult3
return response, nil return response, nil
} }