* wip: API endpoint for creating playlists from m3u files * wip: get user id from context * temporarily disable failing test * custom logic for playlist route to accomodate m3u content type * incorporate playlist parsing into existing logic in core * re-enable test * fix locally failing test * Address requested changes. * Improve ImportFile tests. * Remove ownerID as a parameter of ImportM3U. * Write tests for ImportM3U. * Separate ImportM3U test into two. * Test OwnerID and playlist Name. --------- Co-authored-by: Sam Watson <SwatsonCodes@users.noreply.github.com> Co-authored-by: caiocotts <caio@cotts.com.br>
This commit is contained in:
@@ -14,12 +14,13 @@ import (
|
||||
|
||||
type Router struct {
|
||||
http.Handler
|
||||
ds model.DataStore
|
||||
share core.Share
|
||||
ds model.DataStore
|
||||
share core.Share
|
||||
playlists core.Playlists
|
||||
}
|
||||
|
||||
func New(ds model.DataStore, share core.Share) *Router {
|
||||
r := &Router{ds: ds, share: share}
|
||||
func New(ds model.DataStore, share core.Share, playlists core.Playlists) *Router {
|
||||
r := &Router{ds: ds, share: share, playlists: playlists}
|
||||
r.Handler = r.routes()
|
||||
return r
|
||||
}
|
||||
@@ -40,13 +41,13 @@ func (n *Router) routes() http.Handler {
|
||||
n.R(r, "/artist", model.Artist{}, false)
|
||||
n.R(r, "/genre", model.Genre{}, false)
|
||||
n.R(r, "/player", model.Player{}, true)
|
||||
n.R(r, "/playlist", model.Playlist{}, true)
|
||||
n.R(r, "/transcoding", model.Transcoding{}, conf.Server.EnableTranscodingConfig)
|
||||
n.R(r, "/radio", model.Radio{}, true)
|
||||
if conf.Server.EnableSharing {
|
||||
n.RX(r, "/share", n.share.NewRepository, true)
|
||||
}
|
||||
|
||||
n.addPlaylistRoute(r)
|
||||
n.addPlaylistTrackRoute(r)
|
||||
|
||||
// Keepalive endpoint to be used to keep the session valid (ex: while playing songs)
|
||||
@@ -82,6 +83,30 @@ func (n *Router) RX(r chi.Router, pathPrefix string, constructor rest.Repository
|
||||
})
|
||||
}
|
||||
|
||||
func (n *Router) addPlaylistRoute(r chi.Router) {
|
||||
constructor := func(ctx context.Context) rest.Repository {
|
||||
return n.ds.Resource(ctx, model.Playlist{})
|
||||
}
|
||||
|
||||
r.Route("/playlist", func(r chi.Router) {
|
||||
r.Get("/", rest.GetAll(constructor))
|
||||
r.Post("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("Content-type") == "application/json" {
|
||||
rest.Post(constructor)(w, r)
|
||||
return
|
||||
}
|
||||
createPlaylistFromM3U(n.playlists)(w, r)
|
||||
})
|
||||
|
||||
r.Route("/{id}", func(r chi.Router) {
|
||||
r.Use(server.URLParamsMiddleware)
|
||||
r.Get("/", rest.Get(constructor))
|
||||
r.Put("/", rest.Put(constructor))
|
||||
r.Delete("/", rest.Delete(constructor))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func (n *Router) addPlaylistTrackRoute(r chi.Router) {
|
||||
r.Route("/playlist/{playlistId}/tracks", func(r chi.Router) {
|
||||
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/deluan/rest"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/navidrome/navidrome/core"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
@@ -42,6 +43,26 @@ func getPlaylist(ds model.DataStore) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func createPlaylistFromM3U(playlists core.Playlists) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
pls, err := playlists.ImportM3U(ctx, r.Body)
|
||||
if err != nil {
|
||||
log.Error(r.Context(), "Error parsing playlist", err)
|
||||
// TODO: consider returning StatusBadRequest for playlists that are malformed
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
_, err = w.Write([]byte(pls.ToM3U8()))
|
||||
if err != nil {
|
||||
log.Error(ctx, "Error sending m3u contents", err)
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleExportPlaylist(ds model.DataStore) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
@@ -625,7 +625,8 @@ var _ = Describe("Responses", func() {
|
||||
|
||||
Context("with data", func() {
|
||||
BeforeEach(func() {
|
||||
t, _ := time.Parse(time.RFC822, time.RFC822)
|
||||
timeFmt := "2006-01-02 15:04:00"
|
||||
t, _ := time.Parse(timeFmt, timeFmt)
|
||||
response.ScanStatus = &ScanStatus{
|
||||
Scanning: true,
|
||||
FolderCount: 123,
|
||||
|
||||
Reference in New Issue
Block a user