diff --git a/internal/metadata/service.go b/internal/metadata/service.go index bda0381..f805d91 100644 --- a/internal/metadata/service.go +++ b/internal/metadata/service.go @@ -54,6 +54,30 @@ func (s *MetadataService) GetArtistAlbums(ctx context.Context, artistExternalID return resp.GetAlbums(), nil } +func (s *MetadataService) SearchArtists(ctx context.Context, query string, limit, offset int32) (*metadataPb.SearchArtistsResponse, error) { + resp, err := s.client.SearchArtists(ctx, &metadataPb.SearchArtistsRequest{ + Query: query, + Limit: limit, + Offset: offset, + }) + if err != nil { + return nil, fmt.Errorf("searching artists: %w", err) + } + return resp, nil +} + +func (s *MetadataService) GetArtistAlbumsWithPagination(ctx context.Context, artistID string, limit, offset int32) (*metadataPb.GetArtistAlbumsResponse, error) { + resp, err := s.client.GetArtistAlbums(ctx, &metadataPb.GetArtistAlbumsRequest{ + ArtistId: artistID, + Limit: limit, + Offset: offset, + }) + if err != nil { + return nil, fmt.Errorf("fetching artist albums: %w", err) + } + return resp, nil +} + func (s *MetadataService) GetAlbumTracks(ctx context.Context, albumExternalID string) ([]*metadataPb.Track, error) { resp, err := s.client.GetAlbumTracks(ctx, &metadataPb.GetAlbumTracksRequest{ AlbumId: albumExternalID, diff --git a/internal/server.go b/internal/server.go index c9bddd3..aeea240 100644 --- a/internal/server.go +++ b/internal/server.go @@ -75,6 +75,14 @@ func (s *MusicAgregatorServer) AnalyzeAlbumRelease(ctx context.Context, req *pb. return s.service.AnalyzeAlbumRelease(ctx, req) } +func (s *MusicAgregatorServer) SearchArtists(ctx context.Context, req *pb.SearchArtistsRequest) (*pb.SearchArtistsResponse, error) { + return s.service.SearchArtists(ctx, req) +} + +func (s *MusicAgregatorServer) GetArtistAlbums(ctx context.Context, req *pb.GetArtistAlbumsRequest) (*pb.GetArtistAlbumsResponse, error) { + return s.service.GetArtistAlbums(ctx, req) +} + func (s *MusicAgregatorServer) Register(server *grpc.Server) { pb.RegisterMusicAgregatorServiceServer(server, s) } diff --git a/internal/service.go b/internal/service.go index 71ba522..0f1ddb9 100644 --- a/internal/service.go +++ b/internal/service.go @@ -869,3 +869,106 @@ func downloadTorrentData(url string) ([]byte, error) { return data, nil } + +func (service *MusicAgregatorService) SearchArtists(ctx context.Context, req *pb.SearchArtistsRequest) (*pb.SearchArtistsResponse, error) { + resp, err := service.metadata.SearchArtists(ctx, req.GetQuery(), req.GetLimit(), req.GetOffset()) + if err != nil { + return nil, err + } + + artists := make([]*pb.SearchArtistResult, len(resp.GetArtists())) + for i, a := range resp.GetArtists() { + genres := make([]string, len(a.GetGenres())) + for j, g := range a.GetGenres() { + genres[j] = g.GetName() + } + + extIDs := make([]*pb.ExternalId, len(a.GetExternalIds())) + for j, e := range a.GetExternalIds() { + extIDs[j] = &pb.ExternalId{ + Provider: e.GetSource(), + Id: e.GetSourceId(), + } + } + + artists[i] = &pb.SearchArtistResult{ + Id: a.GetId(), + Name: a.GetName(), + SortName: a.GetSortName(), + ArtistType: a.GetArtistType(), + Country: a.GetCountry(), + FormedDate: a.GetFormedDate(), + DisbandedDate: a.GetDisbandedDate(), + Description: a.GetDescription(), + ImageUrl: a.GetImageUrl(), + Genres: genres, + ExternalIds: extIDs, + } + } + + return &pb.SearchArtistsResponse{ + Artists: artists, + Total: resp.GetTotal(), + }, nil +} + +func (service *MusicAgregatorService) GetArtistAlbums(ctx context.Context, req *pb.GetArtistAlbumsRequest) (*pb.GetArtistAlbumsResponse, error) { + resp, err := service.metadata.GetArtistAlbumsWithPagination(ctx, req.GetArtistId(), req.GetLimit(), req.GetOffset()) + if err != nil { + return nil, err + } + + albums := make([]*pb.AlbumResult, len(resp.GetAlbums())) + for i, a := range resp.GetAlbums() { + genres := make([]string, len(a.GetGenres())) + for j, g := range a.GetGenres() { + genres[j] = g.GetName() + } + + extIDs := make([]*pb.ExternalId, len(a.GetExternalIds())) + for j, e := range a.GetExternalIds() { + extIDs[j] = &pb.ExternalId{ + Provider: e.GetSource(), + Id: e.GetSourceId(), + } + } + + artists := make([]*pb.AlbumArtistCredit, len(a.GetArtists())) + for j, ac := range a.GetArtists() { + artists[j] = &pb.AlbumArtistCredit{ + Id: ac.GetArtist().GetId(), + Name: ac.GetArtist().GetName(), + Role: ac.GetRole(), + } + } + + var label *pb.AlbumLabel + if a.GetLabel() != nil { + label = &pb.AlbumLabel{ + Id: a.GetLabel().GetId(), + Name: a.GetLabel().GetName(), + Country: a.GetLabel().GetCountry(), + } + } + + albums[i] = &pb.AlbumResult{ + Id: a.GetId(), + Title: a.GetTitle(), + AlbumType: a.GetAlbumType(), + ReleaseDate: a.GetReleaseDate(), + Upc: a.GetUpc(), + TotalTracks: a.GetTotalTracks(), + TotalDiscs: a.GetTotalDiscs(), + CoverUrl: a.GetCoverUrl(), + Artists: artists, + Label: label, + Genres: genres, + ExternalIds: extIDs, + } + } + + return &pb.GetArtistAlbumsResponse{ + Albums: albums, + Total: resp.GetTotal(), + }, nil +} diff --git a/proto/music_agregator/v1/music_agregator.proto b/proto/music_agregator/v1/music_agregator.proto index afaca6b..c628153 100644 --- a/proto/music_agregator/v1/music_agregator.proto +++ b/proto/music_agregator/v1/music_agregator.proto @@ -8,6 +8,8 @@ service MusicAgregatorService { rpc GetArtists(GetArtistsRequest) returns (GetArtistsResponse) {} rpc GetAlbum(GetAlbumRequest) returns (GetAlbumResponse) {} rpc AnalyzeAlbumRelease(AnalyzeAlbumReleaseRequest) returns (AnalyzeAlbumReleaseResponse) {} + rpc SearchArtists(SearchArtistsRequest) returns (SearchArtistsResponse) {} + rpc GetArtistAlbums(GetArtistAlbumsRequest) returns (GetArtistAlbumsResponse) {} } message MonitorAlbumRequest { @@ -163,6 +165,74 @@ message MonitoredRelease { string tracker = 18; } +message SearchArtistsRequest { + string query = 1; + int32 limit = 2; + int32 offset = 3; +} + +message SearchArtistsResponse { + repeated SearchArtistResult artists = 1; + int32 total = 2; +} + +message SearchArtistResult { + string id = 1; + string name = 2; + string sort_name = 3; + string artist_type = 4; + string country = 5; + string formed_date = 6; + string disbanded_date = 7; + string description = 8; + string image_url = 9; + repeated string genres = 10; + repeated ExternalId external_ids = 11; +} + +message ExternalId { + string provider = 1; + string id = 2; +} + +message GetArtistAlbumsRequest { + string artist_id = 1; + int32 limit = 2; + int32 offset = 3; +} + +message GetArtistAlbumsResponse { + repeated AlbumResult albums = 1; + int32 total = 2; +} + +message AlbumResult { + string id = 1; + string title = 2; + string album_type = 3; + string release_date = 4; + string upc = 5; + int32 total_tracks = 6; + int32 total_discs = 7; + string cover_url = 8; + repeated AlbumArtistCredit artists = 9; + AlbumLabel label = 10; + repeated string genres = 11; + repeated ExternalId external_ids = 12; +} + +message AlbumArtistCredit { + string id = 1; + string name = 2; + string role = 3; +} + +message AlbumLabel { + string id = 1; + string name = 2; + string country = 3; +} + enum InteractionMode { INTERACTION_MODE_AUTOMATIC = 0; INTERACTION_MODE_MANUAL = 1;