implemented getStarred (just for albums, for now)

This commit is contained in:
Deluan 2016-03-14 11:35:48 -04:00
parent 14934dccf7
commit e36a4201db
9 changed files with 95 additions and 13 deletions

View file

@ -10,7 +10,7 @@ import (
"github.com/deluan/gosonic/utils"
)
type GetAlbumListController struct {
type AlbumListController struct {
BaseAPIController
listGen engine.ListGenerator
types map[string]strategy
@ -18,7 +18,7 @@ type GetAlbumListController struct {
type strategy func(offset int, size int) (*domain.Albums, error)
func (c *GetAlbumListController) Prepare() {
func (c *AlbumListController) Prepare() {
utils.ResolveDependencies(&c.listGen)
c.types = map[string]strategy{
@ -30,12 +30,12 @@ func (c *GetAlbumListController) Prepare() {
}
}
func (c *GetAlbumListController) Get() {
func (c *AlbumListController) GetAlbumList() {
typ := c.RequiredParamString("type", "Required string parameter 'type' is not present")
method, found := c.types[typ]
if !found {
beego.Error("getAlbumList type", typ, "not implemented!")
beego.Error("albumList type", typ, "not implemented!")
c.SendError(responses.ERROR_GENERIC, "Not implemented!")
}
@ -70,3 +70,21 @@ func (c *GetAlbumListController) Get() {
response.AlbumList = &responses.AlbumList{Album: albumList}
c.SendResponse(response)
}
func (c *AlbumListController) GetStarred() {
albums, err := c.listGen.GetStarred()
if err != nil {
beego.Error("Error retrieving starred albums:", err)
c.SendError(responses.ERROR_GENERIC, "Internal Error")
}
response := c.NewEmpty()
response.Starred = &responses.Starred{}
response.Starred.Album = make([]responses.Child, len(*albums))
for i, entry := range *albums {
response.Starred.Album[i] = c.ToChild(entry)
}
c.SendResponse(response)
}

View file

@ -19,6 +19,7 @@ type Subsonic struct {
Playlists *Playlists `xml:"playlists,omitempty" json:"playlists,omitempty"`
Playlist *PlaylistWithSongs `xml:"playlist,omitempty" json:"playlist,omitempty"`
SearchResult2 *SearchResult2 `xml:"searchResult2,omitempty" json:"searchResult2,omitempty"`
Starred *Starred `xml:"starred,omitempty" json:"starred,omitempty"`
}
type JsonWrapper struct {
@ -131,6 +132,12 @@ type SearchResult2 struct {
Song []Child `xml:"song" json:"song,omitempty"`
}
type Starred struct {
Artist []Artist `xml:"artist" json:"artist,omitempty"`
Album []Child `xml:"album" json:"album,omitempty"`
Song []Child `xml:"song" json:"song,omitempty"`
}
type User struct {
Username string `xml:"username,attr" json:"username"`
Email string `xml:"email,attr,omitempty" json:"email,omitempty"`

View file

@ -31,7 +31,8 @@ func mapEndpoints() {
beego.NSRouter("/scrobble.view", &api.MediaAnnotationController{}, "*:Scrobble"),
beego.NSRouter("/getAlbumList.view", &api.GetAlbumListController{}, "*:Get"),
beego.NSRouter("/getAlbumList.view", &api.AlbumListController{}, "*:GetAlbumList"),
beego.NSRouter("/getStarred.view", &api.AlbumListController{}, "*:GetStarred"),
beego.NSRouter("/getPlaylists.view", &api.PlaylistsController{}, "*:GetAll"),
beego.NSRouter("/getPlaylist.view", &api.PlaylistsController{}, "*:Get"),

View file

@ -31,4 +31,5 @@ type AlbumRepository interface {
GetAll(QueryOptions) (*Albums, error)
PurgeInactive(active *Albums) error
GetAllIds() (*[]string, error)
GetStarred(QueryOptions) (*Albums, error)
}

View file

@ -26,6 +26,8 @@ type Entry struct {
ContentType string
}
type Entries []Entry
var (
ErrDataNotFound = errors.New("Data Not Found")
)

View file

@ -14,6 +14,7 @@ type ListGenerator interface {
GetFrequent(offset int, size int) (*domain.Albums, error)
GetHighest(offset int, size int) (*domain.Albums, error)
GetRandom(offset int, size int) (*domain.Albums, error)
GetStarred() (*Entries, error)
}
func NewListGenerator(alr domain.AlbumRepository) ListGenerator {
@ -69,3 +70,17 @@ func (g listGenerator) GetRandom(offset int, size int) (*domain.Albums, error) {
}
return &r, nil
}
func (g listGenerator) GetStarred() (*Entries, error) {
albums, err := g.albumRepo.GetStarred(domain.QueryOptions{})
if err != nil {
return nil, err
}
entries := make(Entries, len(*albums))
for i, al := range *albums {
entries[i] = FromAlbum(&al)
}
return &entries, nil
}

View file

@ -74,4 +74,10 @@ func (r *albumRepository) PurgeInactive(active *domain.Albums) error {
return r.DeleteAll(inactiveIds)
}
func (r *albumRepository) GetStarred(options domain.QueryOptions) (*domain.Albums, error) {
var as = make(domain.Albums, 0)
err := r.loadRange("Starred", true, true, &as, options)
return &as, err
}
var _ domain.AlbumRepository = (*albumRepository)(nil)

View file

@ -167,23 +167,25 @@ func (r *ledisRepository) saveOrUpdate(id string, entity interface{}) error {
}
func calcScore(entity interface{}, fieldName string) int64 {
var score int64
dv := reflect.ValueOf(entity).Elem()
v := dv.FieldByName(fieldName)
switch v.Interface().(type) {
return toScore(v.Interface())
}
func toScore(value interface{}) int64 {
switch v := value.(type) {
case int:
score = v.Int()
return int64(v)
case bool:
if v.Bool() {
score = 1
if v {
return 1
}
case time.Time:
score = utils.ToMillis(v.Interface().(time.Time))
return utils.ToMillis(v)
}
return score
return 0
}
func (r *ledisRepository) getParentRelationKey(entity interface{}) string {
@ -243,6 +245,36 @@ func (r *ledisRepository) toEntity(response [][]byte, entity interface{}) error
return utils.ToStruct(record, entity)
}
func (r *ledisRepository) loadRange(idxName string, min interface{}, max interface{}, entities interface{}, qo ...domain.QueryOptions) error {
o := domain.QueryOptions{}
if len(qo) > 0 {
o = qo[0]
}
if o.Size == 0 {
o.Size = -1
}
minS := toScore(min)
maxS := toScore(max)
idxKey := fmt.Sprintf("%s:idx:%s", r.table, idxName)
resp, err := Db().ZRangeByScore([]byte(idxKey), minS, maxS, o.Offset, o.Size)
if err != nil {
return err
}
reflected := reflect.ValueOf(entities).Elem()
for _, pair := range resp {
e, err := r.readEntity(string(pair.Member))
if err != nil {
return err
}
reflected.Set(reflect.Append(reflected, reflect.ValueOf(e).Elem()))
}
return nil
}
func (r *ledisRepository) loadAll(entities interface{}, qo ...domain.QueryOptions) error {
setName := r.table + "s:all"
return r.loadFromSet(setName, entities, qo...)