mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-03 12:37:37 +03:00
Refactor included handling
This commit is contained in:
parent
40f7170930
commit
7cf98af9da
3 changed files with 109 additions and 70 deletions
|
@ -1,7 +1,6 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/navidrome/navidrome/utils/slice"
|
||||
|
@ -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"`
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -73,21 +73,18 @@ 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
|
||||
|
||||
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,
|
||||
}
|
||||
err = resources.AddAlbums(mfs.AlbumIDs()...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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) {
|
||||
|
@ -95,19 +92,16 @@ func (a *Router) GetTrack(ctx context.Context, request GetTrackRequestObject) (G
|
|||
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
|
||||
|
||||
resources := newIncludedResources(ctx, a.ds, request.Params.Include)
|
||||
resources.Artists(mf.ArtistID, mf.AlbumArtistID)
|
||||
resources.Albums(mf.AlbumID)
|
||||
|
||||
response := GetTrack200JSONResponse{
|
||||
Data: toAPITrack(*mf),
|
||||
}
|
||||
err = resources.AddAlbums(mf.AlbumID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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) {
|
||||
|
@ -122,17 +116,17 @@ 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) {
|
||||
|
@ -140,19 +134,16 @@ func (a *Router) GetAlbum(ctx context.Context, request GetAlbumRequestObject) (G
|
|||
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
|
||||
|
||||
resources := newIncludedResources(ctx, a.ds, request.Params.Include)
|
||||
resources.Artists(album.ArtistID, album.AlbumArtistID)
|
||||
resources.Tracks(album.ID)
|
||||
|
||||
response := GetAlbum200JSONResponse{
|
||||
Data: toAPIAlbum(*album),
|
||||
}
|
||||
err = resources.AddTracks(album.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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) {
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue