feat: fetch all artist albums with caching, filter by type in handler
- Provider fetches all release groups via paginated browse, no type filter - Service caches all albums in DB, ensures referenced artists exist first - Server handler filters by album_types (default: album|ep|single), excludes secondary types - Add secondary_types to domain, DB schema, and MB types - Add ErrBadRequest handling for MusicBrainz 400 errors - Replace migrations with single schema.sql - Add GetAllByArtistID and SaveAll to album repository
This commit is contained in:
+35
-13
@@ -3,11 +3,13 @@ package server
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/metadata-agregator/internal/domain"
|
||||
"github.com/metadata-agregator/internal/provider/musicbrainz"
|
||||
"github.com/metadata-agregator/internal/repository"
|
||||
"github.com/metadata-agregator/internal/service"
|
||||
@@ -114,10 +116,9 @@ func (s *MetadataServer) SearchAlbums(ctx context.Context, req *metadatav1.Searc
|
||||
limit = 25
|
||||
}
|
||||
|
||||
albumTypes := defaultAlbumTypes(req.AlbumTypes)
|
||||
log.Debug().Str("query", req.Query).Str("artist", req.Artist).Int("limit", limit).Int("offset", int(req.Offset)).Strs("album_types", albumTypes).Msg("searching albums")
|
||||
log.Debug().Str("query", req.Query).Str("artist", req.Artist).Int("limit", limit).Int("offset", int(req.Offset)).Msg("searching albums")
|
||||
|
||||
result, err := svc.SearchAlbums(ctx, req.Query, req.Artist, limit, int(req.Offset), albumTypes)
|
||||
result, err := svc.SearchAlbums(ctx, req.Query, req.Artist, limit, int(req.Offset))
|
||||
if err != nil {
|
||||
return nil, toGRPCError(ctx, err)
|
||||
}
|
||||
@@ -172,28 +173,25 @@ func (s *MetadataServer) GetArtistAlbums(ctx context.Context, req *metadatav1.Ge
|
||||
return nil, err
|
||||
}
|
||||
|
||||
limit := int(req.Limit)
|
||||
if limit <= 0 {
|
||||
limit = 25
|
||||
}
|
||||
|
||||
albumTypes := defaultAlbumTypes(req.AlbumTypes)
|
||||
log.Debug().Str("artist_id", req.ArtistId).Int("limit", limit).Int("offset", int(req.Offset)).Strs("album_types", albumTypes).Msg("getting artist albums")
|
||||
log.Debug().Str("artist_id", req.ArtistId).Strs("album_types", albumTypes).Msg("getting artist albums")
|
||||
|
||||
result, err := svc.GetArtistAlbums(ctx, req.ArtistId, limit, int(req.Offset), albumTypes)
|
||||
allAlbums, err := svc.GetArtistAlbums(ctx, req.ArtistId)
|
||||
if err != nil {
|
||||
return nil, toGRPCError(ctx, err)
|
||||
}
|
||||
|
||||
filtered := filterAlbums(allAlbums, albumTypes)
|
||||
|
||||
resp := &metadatav1.GetArtistAlbumsResponse{
|
||||
Total: int32(result.Total),
|
||||
Total: int32(len(filtered)),
|
||||
}
|
||||
|
||||
for _, a := range result.Items {
|
||||
for _, a := range filtered {
|
||||
resp.Albums = append(resp.Albums, toProtoAlbum(&a))
|
||||
}
|
||||
|
||||
log.Trace().Int("total", result.Total).Int("returned", len(resp.Albums)).Msg("artist albums retrieved")
|
||||
log.Trace().Int("total_fetched", len(allAlbums)).Int("filtered", len(filtered)).Strs("album_types", albumTypes).Msg("artist albums retrieved")
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@@ -279,6 +277,25 @@ func defaultAlbumTypes(types []string) []string {
|
||||
return defaultTypes
|
||||
}
|
||||
|
||||
func filterAlbums(albums []domain.Album, types []string) []domain.Album {
|
||||
allowed := make(map[string]bool, len(types))
|
||||
for _, t := range types {
|
||||
allowed[strings.ToLower(t)] = true
|
||||
}
|
||||
|
||||
var result []domain.Album
|
||||
for _, a := range albums {
|
||||
if len(a.SecondaryTypes) > 0 {
|
||||
continue
|
||||
}
|
||||
if !allowed[strings.ToLower(a.Type)] {
|
||||
continue
|
||||
}
|
||||
result = append(result, a)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func toGRPCError(ctx context.Context, err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
@@ -286,6 +303,11 @@ func toGRPCError(ctx context.Context, err error) error {
|
||||
|
||||
log := zerolog.Ctx(ctx)
|
||||
|
||||
if errors.Is(err, musicbrainz.ErrBadRequest) {
|
||||
log.Debug().Err(err).Msg("bad request")
|
||||
return status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
if errors.Is(err, repository.ErrNotFound) {
|
||||
log.Debug().Msg("entity not found")
|
||||
return status.Error(codes.NotFound, "not found")
|
||||
|
||||
Reference in New Issue
Block a user