mirror of
https://github.com/navidrome/navidrome.git
synced 2025-05-10 07:11:07 +03:00
Add user filter for deleting songs. Add get beets id endpoint. (#1)
* add get beets id from navidrome song id endpoint * add getBeetTrack api * fix delete song api
This commit is contained in:
parent
aebb823948
commit
bfd9449494
@ -54,6 +54,7 @@ func (n *Router) routes() http.Handler {
|
|||||||
n.addPlaylistRoute(r)
|
n.addPlaylistRoute(r)
|
||||||
n.addPlaylistTrackRoute(r)
|
n.addPlaylistTrackRoute(r)
|
||||||
n.addDeleteSongRoute(r)
|
n.addDeleteSongRoute(r)
|
||||||
|
n.addGetBeetsTrackRoute(r)
|
||||||
|
|
||||||
// Keepalive endpoint to be used to keep the session valid (ex: while playing songs)
|
// Keepalive endpoint to be used to keep the session valid (ex: while playing songs)
|
||||||
r.Get("/keepalive/*", func(w http.ResponseWriter, r *http.Request) {
|
r.Get("/keepalive/*", func(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -148,10 +149,19 @@ func (n *Router) addPlaylistTrackRoute(r chi.Router) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *Router) addDeleteSongRoute(r chi.Router) {
|
func (n *Router) addDeleteSongRoute(r chi.Router) {
|
||||||
r.Route("/deleteSong", func(r chi.Router) {
|
r.Route("/delete", func(r chi.Router) {
|
||||||
r.Use(server.URLParamsMiddleware)
|
r.Use(server.URLParamsMiddleware)
|
||||||
r.Delete("/", func(w http.ResponseWriter, r *http.Request) {
|
r.Delete("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
deleteSong(n.ds)(w, r)
|
deleteSong(n.ds)(w, r)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Router) addGetBeetsTrackRoute(r chi.Router) {
|
||||||
|
r.Route("/getBeetTrack", func(r chi.Router) {
|
||||||
|
r.Use(server.URLParamsMiddleware)
|
||||||
|
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
getBeetTrack(n.ds)(w, r)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/navidrome/navidrome/log"
|
"github.com/navidrome/navidrome/log"
|
||||||
"github.com/navidrome/navidrome/model"
|
"github.com/navidrome/navidrome/model"
|
||||||
|
"github.com/navidrome/navidrome/utils/req"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BeetsItem struct {
|
type BeetsItem struct {
|
||||||
@ -70,7 +71,7 @@ type BeetsItem struct {
|
|||||||
Disctitle string `json:"disctitle"`
|
Disctitle string `json:"disctitle"`
|
||||||
Lyrics string `json:"lyrics"`
|
Lyrics string `json:"lyrics"`
|
||||||
Albumstatus string `json:"albumstatus"`
|
Albumstatus string `json:"albumstatus"`
|
||||||
Albumtypes string `json:"albumtypes"`
|
Albumtypes any `json:"albumtypes"`
|
||||||
Releasegroupdisambig string `json:"releasegroupdisambig"`
|
Releasegroupdisambig string `json:"releasegroupdisambig"`
|
||||||
Comments string `json:"comments"`
|
Comments string `json:"comments"`
|
||||||
Encoder string `json:"encoder"`
|
Encoder string `json:"encoder"`
|
||||||
@ -98,6 +99,7 @@ type BeetsItem struct {
|
|||||||
func deleteSong(ds model.DataStore) http.HandlerFunc {
|
func deleteSong(ds model.DataStore) http.HandlerFunc {
|
||||||
type deleteSongPayload struct {
|
type deleteSongPayload struct {
|
||||||
Ids []string `json:"ids"`
|
Ids []string `json:"ids"`
|
||||||
|
User string `json:"user"`
|
||||||
}
|
}
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
// todo: tests, use proper url parsing lib
|
// todo: tests, use proper url parsing lib
|
||||||
@ -118,19 +120,22 @@ func deleteSong(ds model.DataStore) http.HandlerFunc {
|
|||||||
println(mf.Title)
|
println(mf.Title)
|
||||||
// todo set this base from env variable
|
// todo set this base from env variable
|
||||||
//baseUrl := "http://127.0.0.1:8337"
|
//baseUrl := "http://127.0.0.1:8337"
|
||||||
baseUrl := "http://host.docker.internal:8337"
|
// get docker port
|
||||||
|
baseUrl := fmt.Sprintf("http://beets%s:8337", payload.User)
|
||||||
queryEndPoint := "/item/query/"
|
queryEndPoint := "/item/query/"
|
||||||
queryStr := fmt.Sprintf("artist:%s/title:%s/album:%s", mf.Artist, mf.Title, mf.Album)
|
queryStr := fmt.Sprintf("artist:%s/title:%s/album:%s/user:%s", mf.Artist, mf.Title, mf.Album, payload.User)
|
||||||
url := baseUrl + queryEndPoint + queryStr
|
url := baseUrl + queryEndPoint + queryStr
|
||||||
fmt.Printf("query url: %s\n", url)
|
fmt.Printf("query url: %s\n", url)
|
||||||
resp, err := http.Get(url) // nolint
|
resp, err := http.Get(url) // nolint
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sb := string(body)
|
sb := string(body)
|
||||||
@ -138,14 +143,12 @@ func deleteSong(ds model.DataStore) http.HandlerFunc {
|
|||||||
err = json.Unmarshal([]byte(sb), &beetsItem)
|
err = json.Unmarshal([]byte(sb), &beetsItem)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
length := len(beetsItem.Results)
|
length := len(beetsItem.Results)
|
||||||
if length != 1 {
|
log.Info("following query string matched ", length, "entries: ", queryStr)
|
||||||
log.Error("following query string matched n entries", "n", length, "queryStr", queryStr)
|
for _, item := range beetsItem.Results {
|
||||||
return
|
|
||||||
}
|
|
||||||
item := beetsItem.Results[0]
|
|
||||||
log.Info("deleting: ", item.Artist, " : ", item.Title, " id: ", item.ID)
|
log.Info("deleting: ", item.Artist, " : ", item.Title, " id: ", item.ID)
|
||||||
|
|
||||||
deleteStr := fmt.Sprintf("/item/%d", item.ID)
|
deleteStr := fmt.Sprintf("/item/%d", item.ID)
|
||||||
@ -158,13 +161,15 @@ func deleteSong(ds model.DataStore) http.HandlerFunc {
|
|||||||
log.Info("delete request: ", req)
|
log.Info("delete request: ", req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Fetch Request
|
// Fetch Request
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
del_resp, del_err := client.Do(req)
|
del_resp, del_err := client.Do(req)
|
||||||
if del_err != nil {
|
if del_err != nil {
|
||||||
log.Error(err)
|
log.Error(del_err)
|
||||||
|
http.Error(w, del_err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer del_resp.Body.Close()
|
defer del_resp.Body.Close()
|
||||||
@ -173,6 +178,7 @@ func deleteSong(ds model.DataStore) http.HandlerFunc {
|
|||||||
del_body, err := io.ReadAll(del_resp.Body)
|
del_body, err := io.ReadAll(del_resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,4 +187,55 @@ func deleteSong(ds model.DataStore) http.HandlerFunc {
|
|||||||
log.Info("del body: ", del_body)
|
log.Info("del body: ", del_body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBeetTrack(ds model.DataStore) http.HandlerFunc {
|
||||||
|
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// todo: tests, use proper url parsing lib
|
||||||
|
p := req.Params(r)
|
||||||
|
id, _ := p.String("id")
|
||||||
|
user, _ := p.String("user")
|
||||||
|
|
||||||
|
log.Info("got parameters", "id", id, "user", user)
|
||||||
|
ctx := r.Context()
|
||||||
|
mf, err := ds.MediaFile(ctx).Get(id)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
|
if mf == nil {
|
||||||
|
log.Error("no mediafile for id", "id", id)
|
||||||
|
}
|
||||||
|
log.Info("mediafile", "mf", mf)
|
||||||
|
// todo set this base from env variable
|
||||||
|
//baseUrl := "http://127.0.0.1:8337"
|
||||||
|
baseUrl := fmt.Sprintf("http://beets%s:8337", user)
|
||||||
|
queryEndPoint := "/item/query/"
|
||||||
|
queryStr := fmt.Sprintf("artist:%s/title:%s/user:%s", mf.Artist, mf.Title, user)
|
||||||
|
url := baseUrl + queryEndPoint + queryStr
|
||||||
|
fmt.Printf("query url: %s\n", url)
|
||||||
|
resp, err := http.Get(url) // nolint
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
body, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sb := string(body)
|
||||||
|
var beetsItem BeetsItem
|
||||||
|
err = json.Unmarshal([]byte(sb), &beetsItem)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(beetsItem)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user