Playlists support (99%) complete!

This commit is contained in:
Deluan 2016-03-24 13:28:20 -04:00
parent a27803a4d1
commit b9952bc3de
7 changed files with 110 additions and 8 deletions

View File

@ -39,6 +39,10 @@ func (c *BaseAPIController) ParamString(param string) string {
return c.Input().Get(param)
}
func (c *BaseAPIController) ParamStrings(param string) []string {
return c.Input()[param]
}
func (c *BaseAPIController) ParamTime(param string, def time.Time) time.Time {
var value int64
if c.Input().Get(param) == "" {
@ -74,6 +78,18 @@ func (c *BaseAPIController) ParamInt(param string, def int) int {
return value
}
func (c *BaseAPIController) ParamInts(param string) []int {
pStr := c.Input()[param]
ints := make([]int, 0, len(pStr))
for _, s := range pStr {
i, err := strconv.ParseInt(s, 10, 32)
if err == nil {
ints = append(ints, int(i))
}
}
return ints
}
func (c *BaseAPIController) ParamBool(param string, def bool) bool {
value := def
if c.Input().Get(param) == "" {

View File

@ -1,6 +1,8 @@
package api
import (
"fmt"
"github.com/astaxie/beego"
"github.com/deluan/gosonic/api/responses"
"github.com/deluan/gosonic/domain"
@ -27,7 +29,7 @@ func (c *PlaylistsController) GetAll() {
for i, p := range allPls {
playlists[i].Id = p.Id
playlists[i].Name = p.Name
playlists[i].Comment = "Original: " + p.FullPath
playlists[i].Comment = p.Comment
playlists[i].SongCount = len(p.Tracks)
playlists[i].Duration = p.Duration
playlists[i].Owner = p.Owner
@ -77,6 +79,32 @@ func (c *PlaylistsController) Delete() {
c.SendEmptyResponse()
}
func (c *PlaylistsController) Update() {
playlistId := c.RequiredParamString("playlistId", "Required parameter playlistId is missing")
songsToAdd := c.ParamStrings("songIdToAdd")
songIndexesToRemove := c.ParamInts("songIndexToRemove")
var pname *string
if len(c.Input()["name"]) > 0 {
s := c.Input()["name"][0]
pname = &s
}
beego.Info(fmt.Sprintf("Updating playlist with id '%s'", playlistId))
if pname != nil {
beego.Debug(fmt.Sprintf(" -- New Name: '%s'", *pname))
}
beego.Debug(fmt.Sprintf(" -- Adding: '%v'", songsToAdd))
beego.Debug(fmt.Sprintf(" -- Removing: '%v'", songIndexesToRemove))
err := c.pls.Update(playlistId, pname, songsToAdd, songIndexesToRemove)
if err != nil {
beego.Error(err)
c.SendError(responses.ErrorGeneric, "Internal Error")
}
c.SendEmptyResponse()
}
func (c *PlaylistsController) buildPlaylist(d *engine.PlaylistInfo) *responses.PlaylistWithSongs {
pls := &responses.PlaylistWithSongs{}
pls.Id = d.Id

View File

@ -42,6 +42,7 @@ func mapEndpoints() {
beego.NSRouter("/getPlaylists.view", &api.PlaylistsController{}, "*:GetAll"),
beego.NSRouter("/getPlaylist.view", &api.PlaylistsController{}, "*:Get"),
beego.NSRouter("/createPlaylist.view", &api.PlaylistsController{}, "*:Create"),
beego.NSRouter("/updatePlaylist.view", &api.PlaylistsController{}, "*:Update"),
beego.NSRouter("/deletePlaylist.view", &api.PlaylistsController{}, "*:Delete"),
beego.NSRouter("/getUser.view", &api.UsersController{}, "*:GetUser"),

View File

@ -3,6 +3,7 @@ package domain
type Playlist struct {
Id string
Name string
Comment string
FullPath string
Duration int
Owner string

View File

@ -2,6 +2,7 @@ package engine
import (
"fmt"
"sort"
"github.com/astaxie/beego"
"github.com/deluan/gosonic/domain"
@ -12,7 +13,8 @@ type Playlists interface {
GetAll() (domain.Playlists, error)
Get(id string) (*PlaylistInfo, error)
Create(name string, ids []string) error
Delete(id string) error
Delete(playlistId string) error
Update(playlistId string, name *string, idsToAdd []string, idxToRemove []int) error
}
func NewPlaylists(itunes itunesbridge.ItunesControl, pr domain.PlaylistRepository, mr domain.MediaFileRepository) Playlists {
@ -37,6 +39,7 @@ type PlaylistInfo struct {
Duration int
Public bool
Owner string
Comment string
}
func (p *playlists) Create(name string, ids []string) error {
@ -48,12 +51,39 @@ func (p *playlists) Create(name string, ids []string) error {
return nil
}
func (p *playlists) Delete(id string) error {
err := p.itunes.DeletePlaylist(id)
func (p *playlists) Delete(playlistId string) error {
err := p.itunes.DeletePlaylist(playlistId)
if err != nil {
return err
}
beego.Info(fmt.Sprintf("Deleted playlist with id '%s'", id))
beego.Info(fmt.Sprintf("Deleted playlist with id '%s'", playlistId))
return nil
}
func (p *playlists) Update(playlistId string, name *string, idsToAdd []string, idxToRemove []int) error {
pl, err := p.plsRepo.Get(playlistId)
if err != nil {
return err
}
if name != nil {
pl.Name = *name
err := p.itunes.RenamePlaylist(pl.Id, pl.Name)
if err != nil {
return err
}
}
if len(idsToAdd) > 0 || len(idxToRemove) > 0 {
sort.Sort(sort.Reverse(sort.IntSlice(idxToRemove)))
for _, i := range idxToRemove {
pl.Tracks, pl.Tracks[len(pl.Tracks)-1] = append(pl.Tracks[:i], pl.Tracks[i+1:]...), ""
}
pl.Tracks = append(pl.Tracks, idsToAdd...)
err := p.itunes.UpdatePlaylist(pl.Id, pl.Tracks)
if err != nil {
return err
}
}
p.plsRepo.Put(pl)
return nil
}
@ -70,6 +100,7 @@ func (p *playlists) Get(id string) (*PlaylistInfo, error) {
Duration: pl.Duration,
Public: pl.Public,
Owner: pl.Owner,
Comment: pl.Comment,
}
pinfo.Entries = make(Entries, len(pl.Tracks))

View File

@ -14,7 +14,9 @@ type ItunesControl interface {
SetTrackRating(trackId string, rating int) error
SetAlbumRating(trackId string, rating int) error
CreatePlaylist(name string, ids []string) (string, error)
DeletePlaylist(id string) error
UpdatePlaylist(playlistId string, ids []string) error
RenamePlaylist(playlistId, name string) error
DeletePlaylist(playlistId string) error
}
func NewItunesControl() ItunesControl {
@ -40,9 +42,31 @@ func (c *itunesControl) CreatePlaylist(name string, ids []string) (string, error
return strings.TrimSuffix(pid, "\n"), nil
}
func (c *itunesControl) DeletePlaylist(id string) error {
func (c *itunesControl) UpdatePlaylist(playlistId string, ids []string) error {
pids := `"` + strings.Join(ids, `","`) + `"`
script := Script{
fmt.Sprintf(`set pls to the first item of (every playlist whose persistent ID is equal to "%s")`, id),
fmt.Sprintf(`set pls to the first item of (every playlist whose persistent ID is equal to "%s")`, playlistId),
`delete every track of pls`,
fmt.Sprintf(`set pids to {%s}`, pids),
`repeat with trackPID in pids`,
` set myTrack to the first item of (every track whose persistent ID is equal to trackPID)`,
` duplicate myTrack to pls`,
`end repeat`}
return script.Run()
}
func (c *itunesControl) RenamePlaylist(playlistId, name string) error {
script := Script{
fmt.Sprintf(`set pls to the first item of (every playlist whose persistent ID is equal to "%s")`, playlistId),
`tell pls`,
fmt.Sprintf(`set name to "%s"`, name),
`end tell`}
return script.Run()
}
func (c *itunesControl) DeletePlaylist(playlistId string) error {
script := Script{
fmt.Sprintf(`set pls to the first item of (every playlist whose persistent ID is equal to "%s")`, playlistId),
`delete pls`,
}
return script.Run()

View File

@ -217,6 +217,7 @@ func (i *Importer) importLibrary() (err error) {
for _, pl := range i.scanner.Playlists() {
pl.Public = true
pl.Owner = beego.AppConfig.String("user")
pl.Comment = "Original: " + pl.FullPath
pls[j] = *pl
j++
if err := i.plsRepo.Put(pl); err != nil {