Add GetAlbum RPC with track details and persist metadata on discovery
This commit is contained in:
@@ -41,6 +41,7 @@ type MusicAgregatorService struct {
|
||||
torrents *database.TorrentRepository
|
||||
downloads *database.DownloadRepository
|
||||
artists *database.ArtistRepository
|
||||
downloadFiles *database.DownloadFileRepository
|
||||
}
|
||||
|
||||
func NewMusicAgregatorService(cfg config.Config, riverClient *river.Client[pgx.Tx], db *database.DB) (*MusicAgregatorService, error) {
|
||||
@@ -78,6 +79,7 @@ func NewMusicAgregatorService(cfg config.Config, riverClient *river.Client[pgx.T
|
||||
torrents: database.NewTorrentRepository(db.Pool),
|
||||
downloads: database.NewDownloadRepository(db.Pool),
|
||||
artists: database.NewArtistRepository(db.Pool),
|
||||
downloadFiles: database.NewDownloadFileRepository(db.Pool),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -123,6 +125,10 @@ func (service *MusicAgregatorService) buildAlbumsForArtist(ctx context.Context,
|
||||
return nil, fmt.Errorf("fetching metadata albums: %w", err)
|
||||
}
|
||||
|
||||
for _, ma := range metadataAlbums {
|
||||
service.metadata.PersistAlbum(ctx, ma, database.Unmonitored)
|
||||
}
|
||||
|
||||
dbAlbums, err := service.metadata.GetAlbumsByArtistID(ctx, artist.ID)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Str("artist_id", artist.ID).Msg("failed to get local albums")
|
||||
@@ -177,6 +183,113 @@ func (service *MusicAgregatorService) buildAlbumsForArtist(ctx context.Context,
|
||||
return albums, nil
|
||||
}
|
||||
|
||||
func (service *MusicAgregatorService) GetAlbum(ctx context.Context, req *pb.GetAlbumRequest) (*pb.GetAlbumResponse, error) {
|
||||
dbAlbum, err := service.metadata.GetAlbumByID(ctx, req.GetAlbumId())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("album not found: %w", err)
|
||||
}
|
||||
|
||||
metadataAlbum, err := service.metadata.GetAlbum(ctx, dbAlbum.ExternalID)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("album_id", dbAlbum.ExternalID).Msg("failed to get album from metadata")
|
||||
return nil, fmt.Errorf("fetching album: %w", err)
|
||||
}
|
||||
|
||||
metadataTracks, err := service.metadata.GetAlbumTracks(ctx, dbAlbum.ExternalID)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Str("album_id", dbAlbum.ExternalID).Msg("failed to get tracks from metadata")
|
||||
}
|
||||
|
||||
service.metadata.PersistTracks(ctx, dbAlbum.ID, metadataTracks)
|
||||
|
||||
album := &pb.AlbumDetail{
|
||||
Id: dbAlbum.ID,
|
||||
ExternalId: metadataAlbum.GetId(),
|
||||
Title: metadataAlbum.GetTitle(),
|
||||
AlbumType: metadataAlbum.GetAlbumType(),
|
||||
ReleaseDate: metadataAlbum.GetReleaseDate(),
|
||||
TotalTracks: metadataAlbum.GetTotalTracks(),
|
||||
TotalDiscs: metadataAlbum.GetTotalDiscs(),
|
||||
CoverUrl: metadataAlbum.GetCoverUrl(),
|
||||
MonitorState: toProtoMonitorState(dbAlbum.MonitorState),
|
||||
}
|
||||
|
||||
if metadataAlbum.GetLabel() != nil {
|
||||
album.Label = metadataAlbum.GetLabel().GetName()
|
||||
}
|
||||
for _, g := range metadataAlbum.GetGenres() {
|
||||
album.Genres = append(album.Genres, g.GetName())
|
||||
}
|
||||
|
||||
downloads, err := service.downloads.GetByAlbumID(ctx, dbAlbum.ID)
|
||||
if err == nil && len(downloads) > 0 {
|
||||
best := downloads[0]
|
||||
album.Download = &pb.DownloadInfo{
|
||||
State: best.State,
|
||||
Format: best.Format,
|
||||
Quality: best.Quality,
|
||||
SavePath: best.SavePath,
|
||||
}
|
||||
}
|
||||
|
||||
var downloadFilesByTrackID map[string]*database.DownloadFile
|
||||
if album.Download != nil {
|
||||
files, err := service.downloadFiles.GetByDownloadID(ctx, downloads[0].ID)
|
||||
if err == nil {
|
||||
downloadFilesByTrackID = make(map[string]*database.DownloadFile, len(files))
|
||||
for _, f := range files {
|
||||
if f.TrackID != nil {
|
||||
downloadFilesByTrackID[*f.TrackID] = f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbTracks, _ := service.metadata.GetTracksByAlbumID(ctx, dbAlbum.ID)
|
||||
dbTracksByExternalID := make(map[string]*database.Track, len(dbTracks))
|
||||
for _, t := range dbTracks {
|
||||
dbTracksByExternalID[t.ExternalID] = t
|
||||
}
|
||||
|
||||
tracks := make([]*pb.TrackDetail, 0, len(metadataTracks))
|
||||
for _, mt := range metadataTracks {
|
||||
td := &pb.TrackDetail{
|
||||
ExternalId: mt.GetId(),
|
||||
Title: mt.GetTitle(),
|
||||
DurationMs: mt.GetDurationMs(),
|
||||
DiscNumber: mt.GetDiscNumber(),
|
||||
TrackNumber: mt.GetTrackNumber(),
|
||||
Isrc: mt.GetIsrc(),
|
||||
Explicit: mt.GetExplicit(),
|
||||
}
|
||||
|
||||
for _, ac := range mt.GetArtists() {
|
||||
td.Artists = append(td.Artists, &pb.ArtistCredit{
|
||||
Id: ac.GetArtist().GetId(),
|
||||
Name: ac.GetArtist().GetName(),
|
||||
})
|
||||
}
|
||||
|
||||
if dbTrack, ok := dbTracksByExternalID[mt.GetId()]; ok {
|
||||
td.Id = dbTrack.ID
|
||||
if df, ok := downloadFilesByTrackID[dbTrack.ID]; ok {
|
||||
td.File = &pb.TrackFile{
|
||||
Path: df.FilePath,
|
||||
Format: df.FileType,
|
||||
Size: df.FileSize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tracks = append(tracks, td)
|
||||
}
|
||||
|
||||
return &pb.GetAlbumResponse{
|
||||
Album: album,
|
||||
Tracks: tracks,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (service *MusicAgregatorService) MonitorAlbum(ctx context.Context, req *pb.MonitorAlbumRequest) (*pb.MonitorAlbumResponse, error) {
|
||||
album, err := service.metadata.GetAlbum(ctx, req.GetAlbumId())
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user