mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-04 21:17: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
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/navidrome/navidrome/utils/slice"
|
"github.com/navidrome/navidrome/utils/slice"
|
||||||
|
@ -61,6 +60,10 @@ func (a Album) CoverArtID() ArtworkID {
|
||||||
return artworkIDFromAlbum(a)
|
return artworkIDFromAlbum(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a Album) ArtistIDs() []string {
|
||||||
|
return []string{a.ArtistID, a.AlbumArtistID}
|
||||||
|
}
|
||||||
|
|
||||||
type DiscID struct {
|
type DiscID struct {
|
||||||
AlbumID string `json:"albumId"`
|
AlbumID string `json:"albumId"`
|
||||||
ReleaseDate string `json:"releaseDate"`
|
ReleaseDate string `json:"releaseDate"`
|
||||||
|
@ -95,7 +98,7 @@ func (als Albums) ToAlbumArtist() Artist {
|
||||||
func (als Albums) ArtistIDs() []string {
|
func (als Albums) ArtistIDs() []string {
|
||||||
var ids []string
|
var ids []string
|
||||||
for _, al := range als {
|
for _, al := range als {
|
||||||
ids = append(ids, strings.Split(al.AllArtistIDs, " ")...)
|
ids = append(ids, al.ArtistIDs()...)
|
||||||
}
|
}
|
||||||
return ids
|
return ids
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,21 +73,18 @@ func (a *Router) GetTracks(ctx context.Context, request GetTracksRequestObject)
|
||||||
}
|
}
|
||||||
baseUrl := baseResourceUrl(ctx, "tracks")
|
baseUrl := baseResourceUrl(ctx, "tracks")
|
||||||
links, meta := buildPaginationLinksAndMeta(int32(cnt), request.Params, baseUrl)
|
links, meta := buildPaginationLinksAndMeta(int32(cnt), request.Params, baseUrl)
|
||||||
resources := includedResources{ctx: ctx, ds: a.ds, includes: request.Params.Include}
|
|
||||||
err = resources.AddArtists(mfs.ArtistIDs()...)
|
resources := newIncludedResources(ctx, a.ds, request.Params.Include)
|
||||||
if err != nil {
|
resources.Artists(mfs.ArtistIDs()...)
|
||||||
return nil, err
|
resources.Albums(mfs.AlbumIDs()...)
|
||||||
}
|
|
||||||
err = resources.AddAlbums(mfs.AlbumIDs()...)
|
response := GetTracks200JSONResponse{
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return GetTracks200JSONResponse{
|
|
||||||
Data: toAPITracks(mfs),
|
Data: toAPITracks(mfs),
|
||||||
Links: links,
|
Links: links,
|
||||||
Meta: &meta,
|
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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resources := includedResources{ctx: ctx, ds: a.ds, includes: request.Params.Include}
|
|
||||||
err = resources.AddArtists(mf.ArtistID, mf.AlbumArtistID)
|
resources := newIncludedResources(ctx, a.ds, request.Params.Include)
|
||||||
if err != nil {
|
resources.Artists(mf.ArtistID, mf.AlbumArtistID)
|
||||||
return nil, err
|
resources.Albums(mf.AlbumID)
|
||||||
}
|
|
||||||
err = resources.AddAlbums(mf.AlbumID)
|
response := GetTrack200JSONResponse{
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return GetTrack200JSONResponse{
|
|
||||||
Data: toAPITrack(*mf),
|
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) {
|
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")
|
baseUrl := baseResourceUrl(ctx, "albums")
|
||||||
links, meta := buildPaginationLinksAndMeta(int32(cnt), request.Params, baseUrl)
|
links, meta := buildPaginationLinksAndMeta(int32(cnt), request.Params, baseUrl)
|
||||||
resources := includedResources{ctx: ctx, ds: a.ds, includes: request.Params.Include}
|
|
||||||
err = resources.AddArtists(albums.ArtistIDs()...)
|
resources := newIncludedResources(ctx, a.ds, request.Params.Include)
|
||||||
if err != nil {
|
resources.Artists(albums.ArtistIDs()...)
|
||||||
return nil, err
|
|
||||||
}
|
response := GetAlbums200JSONResponse{
|
||||||
return GetAlbums200JSONResponse{
|
|
||||||
Data: toAPIAlbums(albums),
|
Data: toAPIAlbums(albums),
|
||||||
Links: links,
|
Links: links,
|
||||||
Meta: &meta,
|
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) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
resources := includedResources{ctx: ctx, ds: a.ds, includes: request.Params.Include}
|
|
||||||
err = resources.AddArtists(album.ArtistID, album.AlbumArtistID)
|
resources := newIncludedResources(ctx, a.ds, request.Params.Include)
|
||||||
if err != nil {
|
resources.Artists(album.ArtistID, album.AlbumArtistID)
|
||||||
return nil, err
|
resources.Tracks(album.ID)
|
||||||
}
|
|
||||||
err = resources.AddTracks(album.ID)
|
response := GetAlbum200JSONResponse{
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return GetAlbum200JSONResponse{
|
|
||||||
Data: toAPIAlbum(*album),
|
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) {
|
func (a *Router) GetArtists(ctx context.Context, request GetArtistsRequestObject) (GetArtistsResponseObject, error) {
|
||||||
|
|
|
@ -14,14 +14,46 @@ type includedResources struct {
|
||||||
ds model.DataStore
|
ds model.DataStore
|
||||||
includes *includeSlice
|
includes *includeSlice
|
||||||
resources []IncludedResource
|
resources []IncludedResource
|
||||||
|
ids map[ResourceType][]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *includedResources) AddTracks(albumIds ...string) error {
|
func newIncludedResources(ctx context.Context, ds model.DataStore, includes *includeSlice) *includedResources {
|
||||||
if i.includes == nil || !slices.Contains(*i.includes, string(ResourceTypeTrack)) {
|
i := &includedResources{
|
||||||
return nil
|
ctx: ctx,
|
||||||
|
ds: ds,
|
||||||
|
includes: includes,
|
||||||
}
|
}
|
||||||
sort.Strings(albumIds)
|
if includes != nil {
|
||||||
slices.Compact(albumIds)
|
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}})
|
tracks, err := i.ds.MediaFile(i.ctx).GetAll(model.QueryOptions{Filters: squirrel.Eq{"album_id": albumIds}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -34,12 +66,7 @@ func (i *includedResources) AddTracks(albumIds ...string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *includedResources) AddAlbums(albumIds ...string) error {
|
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)
|
|
||||||
albums, err := i.ds.Album(i.ctx).GetAll(model.QueryOptions{Filters: squirrel.Eq{"id": albumIds}})
|
albums, err := i.ds.Album(i.ctx).GetAll(model.QueryOptions{Filters: squirrel.Eq{"id": albumIds}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -52,12 +79,7 @@ func (i *includedResources) AddAlbums(albumIds ...string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *includedResources) AddArtists(artistIds ...string) error {
|
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)
|
|
||||||
artists, err := i.ds.Artist(i.ctx).GetAll(model.QueryOptions{Filters: squirrel.Eq{"artist.id": artistIds}})
|
artists, err := i.ds.Artist(i.ctx).GetAll(model.QueryOptions{Filters: squirrel.Eq{"artist.id": artistIds}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -70,9 +92,32 @@ func (i *includedResources) AddArtists(artistIds ...string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *includedResources) Build() *[]IncludedResource {
|
func (i *includedResources) Build() (*[]IncludedResource, error) {
|
||||||
if i.includes == nil {
|
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