package metadata import ( "context" "fmt" "github.com/rs/zerolog/log" metadataPb "homelab.lan/music-agregator/gen/metadata/v1" "homelab.lan/music-agregator/internal/database" ) type MetadataService struct { client metadataPb.MetadataServiceClient artists *database.ArtistRepository albums *database.AlbumRepository } func NewMetadataService(client metadataPb.MetadataServiceClient, db *database.DB) *MetadataService { return &MetadataService{ client: client, artists: database.NewArtistRepository(db.Pool), albums: database.NewAlbumRepository(db.Pool), } } func (s *MetadataService) GetAlbum(ctx context.Context, albumID string) (*metadataPb.Album, error) { resp, err := s.client.GetAlbum(ctx, &metadataPb.GetAlbumRequest{ Identifier: &metadataPb.GetAlbumRequest_Id{Id: albumID}, }) if err != nil { return nil, fmt.Errorf("fetching album: %w", err) } album := resp.GetAlbum() if _, err := s.albums.GetByExternalID(ctx, album.GetId()); err != nil { s.persistArtist(ctx, album) s.persistAlbum(ctx, album) } return album, nil } func (s *MetadataService) GetArtistAlbums(ctx context.Context, artistExternalID string) ([]*metadataPb.Album, error) { resp, err := s.client.GetArtistAlbums(ctx, &metadataPb.GetArtistAlbumsRequest{ ArtistId: artistExternalID, }) if err != nil { return nil, fmt.Errorf("fetching artist albums: %w", err) } return resp.GetAlbums(), nil } func (s *MetadataService) GetArtistByExternalID(ctx context.Context, externalID string) (*database.Artist, error) { return s.artists.GetByExternalID(ctx, externalID) } func (s *MetadataService) GetAlbumByExternalID(ctx context.Context, externalID string) (*database.Album, error) { return s.albums.GetByExternalID(ctx, externalID) } func (s *MetadataService) GetAlbumsByArtistID(ctx context.Context, artistID string) ([]*database.Album, error) { return s.albums.GetByArtistID(ctx, artistID) } func (s *MetadataService) persistArtist(ctx context.Context, album *metadataPb.Album) { if len(album.GetArtists()) == 0 { return } artist := album.GetArtists()[0].GetArtist() var genres []string for _, g := range artist.GetGenres() { genres = append(genres, g.GetName()) } err := s.artists.Create(ctx, &database.Artist{ ExternalID: artist.GetId(), Name: artist.GetName(), ArtistType: artist.GetArtistType(), Country: artist.GetCountry(), Genres: genres, ImageURL: artist.GetImageUrl(), MonitorState: database.Monitored, }) if err != nil { log.Warn().Err(err).Str("name", artist.GetName()).Msg("failed to persist artist") } } func (s *MetadataService) persistAlbum(ctx context.Context, album *metadataPb.Album) { artistID := "" if len(album.GetArtists()) > 0 { a, err := s.artists.GetByExternalID(ctx, album.GetArtists()[0].GetArtist().GetId()) if err == nil { artistID = a.ID } } if artistID == "" { log.Trace().Str("album", album.GetTitle()).Msg("skipping album persist, no artist in DB") return } var genres []string for _, g := range album.GetGenres() { genres = append(genres, g.GetName()) } labelName := "" if album.GetLabel() != nil { labelName = album.GetLabel().GetName() } err := s.albums.Create(ctx, &database.Album{ ExternalID: album.GetId(), ArtistID: artistID, Title: album.GetTitle(), AlbumType: album.GetAlbumType(), TotalTracks: int(album.GetTotalTracks()), TotalDiscs: int(album.GetTotalDiscs()), Label: labelName, Genres: genres, CoverURL: album.GetCoverUrl(), MonitorState: database.Monitored, }) if err != nil { log.Warn().Err(err).Str("title", album.GetTitle()).Msg("failed to persist album") } }