Skip to content

Commit

Permalink
Refactor included handling
Browse files Browse the repository at this point in the history
  • Loading branch information
deluan committed Jun 2, 2023
1 parent dbbf61d commit 0caef92
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 70 deletions.
7 changes: 5 additions & 2 deletions model/album.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package model

import (
"strings"
"time"

"github.com/navidrome/navidrome/utils/slice"
Expand Down Expand Up @@ -61,6 +60,10 @@ func (a Album) CoverArtID() ArtworkID {
return artworkIDFromAlbum(a)
}

func (a Album) ArtistIDs() []string {
return []string{a.ArtistID, a.AlbumArtistID}
}

type DiscID struct {
AlbumID string `json:"albumId"`
ReleaseDate string `json:"releaseDate"`
Expand Down Expand Up @@ -95,7 +98,7 @@ func (als Albums) ToAlbumArtist() Artist {
func (als Albums) ArtistIDs() []string {
var ids []string
for _, al := range als {
ids = append(ids, strings.Split(al.AllArtistIDs, " ")...)
ids = append(ids, al.ArtistIDs()...)
}
return ids
}
Expand Down
87 changes: 39 additions & 48 deletions server/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,41 +73,35 @@ func (a *Router) GetTracks(ctx context.Context, request GetTracksRequestObject)
}
baseUrl := baseResourceUrl(ctx, "tracks")
links, meta := buildPaginationLinksAndMeta(int32(cnt), request.Params, baseUrl)
resources := includedResources{ctx: ctx, ds: a.ds, includes: request.Params.Include}
err = resources.AddArtists(mfs.ArtistIDs()...)
if err != nil {
return nil, err
}
err = resources.AddAlbums(mfs.AlbumIDs()...)
if err != nil {
return nil, err

resources := newIncludedResources(ctx, a.ds, request.Params.Include)
resources.Artists(mfs.ArtistIDs()...)
resources.Albums(mfs.AlbumIDs()...)

response := GetTracks200JSONResponse{
Data: toAPITracks(mfs),
Links: links,
Meta: &meta,
}
return GetTracks200JSONResponse{
Data: toAPITracks(mfs),
Links: links,
Meta: &meta,
Included: resources.Build(),
}, nil
response.Included, err = resources.Build()
return response, err
}

func (a *Router) GetTrack(ctx context.Context, request GetTrackRequestObject) (GetTrackResponseObject, error) {
mf, err := a.ds.MediaFile(ctx).Get(request.TrackId)
if err != nil {
return nil, err
}
resources := includedResources{ctx: ctx, ds: a.ds, includes: request.Params.Include}
err = resources.AddArtists(mf.ArtistID, mf.AlbumArtistID)
if err != nil {
return nil, err
}
err = resources.AddAlbums(mf.AlbumID)
if err != nil {
return nil, err

resources := newIncludedResources(ctx, a.ds, request.Params.Include)
resources.Artists(mf.ArtistID, mf.AlbumArtistID)
resources.Albums(mf.AlbumID)

response := GetTrack200JSONResponse{
Data: toAPITrack(*mf),
}
return GetTrack200JSONResponse{
Data: toAPITrack(*mf),
Included: resources.Build(),
}, nil
response.Included, err = resources.Build()
return response, err
}

func (a *Router) GetAlbums(ctx context.Context, request GetAlbumsRequestObject) (GetAlbumsResponseObject, error) {
Expand All @@ -122,37 +116,34 @@ func (a *Router) GetAlbums(ctx context.Context, request GetAlbumsRequestObject)
}
baseUrl := baseResourceUrl(ctx, "albums")
links, meta := buildPaginationLinksAndMeta(int32(cnt), request.Params, baseUrl)
resources := includedResources{ctx: ctx, ds: a.ds, includes: request.Params.Include}
err = resources.AddArtists(albums.ArtistIDs()...)
if err != nil {
return nil, err

resources := newIncludedResources(ctx, a.ds, request.Params.Include)
resources.Artists(albums.ArtistIDs()...)

response := GetAlbums200JSONResponse{
Data: toAPIAlbums(albums),
Links: links,
Meta: &meta,
}
return GetAlbums200JSONResponse{
Data: toAPIAlbums(albums),
Links: links,
Meta: &meta,
Included: resources.Build(),
}, nil
response.Included, err = resources.Build()
return response, err
}

func (a *Router) GetAlbum(ctx context.Context, request GetAlbumRequestObject) (GetAlbumResponseObject, error) {
album, err := a.ds.Album(ctx).Get(request.AlbumId)
if err != nil {
return nil, err
}
resources := includedResources{ctx: ctx, ds: a.ds, includes: request.Params.Include}
err = resources.AddArtists(album.ArtistID, album.AlbumArtistID)
if err != nil {
return nil, err
}
err = resources.AddTracks(album.ID)
if err != nil {
return nil, err

resources := newIncludedResources(ctx, a.ds, request.Params.Include)
resources.Artists(album.ArtistID, album.AlbumArtistID)
resources.Tracks(album.ID)

response := GetAlbum200JSONResponse{
Data: toAPIAlbum(*album),
}
return GetAlbum200JSONResponse{
Data: toAPIAlbum(*album),
Included: resources.Build(),
}, nil
response.Included, err = resources.Build()
return response, err
}

func (a *Router) GetArtists(ctx context.Context, request GetArtistsRequestObject) (GetArtistsResponseObject, error) {
Expand Down
85 changes: 65 additions & 20 deletions server/api/includes.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,46 @@ type includedResources struct {
ds model.DataStore
includes *includeSlice
resources []IncludedResource
ids map[ResourceType][]string
}

func (i *includedResources) AddTracks(albumIds ...string) error {
if i.includes == nil || !slices.Contains(*i.includes, string(ResourceTypeTrack)) {
return nil
func newIncludedResources(ctx context.Context, ds model.DataStore, includes *includeSlice) *includedResources {
i := &includedResources{
ctx: ctx,
ds: ds,
includes: includes,
}
sort.Strings(albumIds)
slices.Compact(albumIds)
if includes != nil {
i.ids = make(map[ResourceType][]string)
for _, inc := range *includes {
i.ids[ResourceType(inc)] = []string{}
}
}
return i
}

func (i *includedResources) Tracks(trackIds ...string) {
if i.ids == nil || i.ids[ResourceTypeTrack] == nil {
return
}
i.ids[ResourceTypeTrack] = append(i.ids[ResourceTypeTrack], trackIds...)
}

func (i *includedResources) Albums(albumIds ...string) {
if i.ids == nil || i.ids[ResourceTypeAlbum] == nil {
return
}
i.ids[ResourceTypeAlbum] = append(i.ids[ResourceTypeAlbum], albumIds...)
}

func (i *includedResources) Artists(artistIds ...string) {
if i.ids == nil || i.ids[ResourceTypeArtist] == nil {
return
}
i.ids[ResourceTypeArtist] = append(i.ids[ResourceTypeArtist], artistIds...)
}

func (i *includedResources) addTracks(albumIds []string) error {
tracks, err := i.ds.MediaFile(i.ctx).GetAll(model.QueryOptions{Filters: squirrel.Eq{"album_id": albumIds}})
if err != nil {
return err
Expand All @@ -34,12 +66,7 @@ func (i *includedResources) AddTracks(albumIds ...string) error {
return nil
}

func (i *includedResources) AddAlbums(albumIds ...string) error {
if i.includes == nil || !slices.Contains(*i.includes, string(ResourceTypeAlbum)) {
return nil
}
sort.Strings(albumIds)
slices.Compact(albumIds)
func (i *includedResources) addAlbums(albumIds []string) error {
albums, err := i.ds.Album(i.ctx).GetAll(model.QueryOptions{Filters: squirrel.Eq{"id": albumIds}})
if err != nil {
return err
Expand All @@ -52,12 +79,7 @@ func (i *includedResources) AddAlbums(albumIds ...string) error {
return nil
}

func (i *includedResources) AddArtists(artistIds ...string) error {
if i.includes == nil || !slices.Contains(*i.includes, string(ResourceTypeArtist)) {
return nil
}
sort.Strings(artistIds)
slices.Compact(artistIds)
func (i *includedResources) addArtists(artistIds []string) error {
artists, err := i.ds.Artist(i.ctx).GetAll(model.QueryOptions{Filters: squirrel.Eq{"artist.id": artistIds}})
if err != nil {
return err
Expand All @@ -70,9 +92,32 @@ func (i *includedResources) AddArtists(artistIds ...string) error {
return nil
}

func (i *includedResources) Build() *[]IncludedResource {
func (i *includedResources) Build() (*[]IncludedResource, error) {
if i.includes == nil {
return nil
return nil, nil
}
return &i.resources
for _, typ := range *i.includes {
ids := i.ids[ResourceType(typ)]
sort.Strings(ids)
slices.Compact(ids)
if len(ids) == 0 {
continue
}
switch ResourceType(typ) {
case ResourceTypeAlbum:
if err := i.addAlbums(ids); err != nil {
return nil, err
}
case ResourceTypeArtist:
if err := i.addArtists(ids); err != nil {
return nil, err
}
case ResourceTypeTrack:
if err := i.addTracks(ids); err != nil {
return nil, err
}
}
}

return &i.resources, nil
}

0 comments on commit 0caef92

Please sign in to comment.