mirror of
https://github.com/gabehf/Koito.git
synced 2026-03-17 03:06:42 -07:00
feat: v0.0.5
This commit is contained in:
parent
4c4ebc593d
commit
242a82ad8c
36 changed files with 694 additions and 174 deletions
|
|
@ -3,6 +3,7 @@ package catalog
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
|
|
@ -17,11 +18,12 @@ import (
|
|||
)
|
||||
|
||||
type AssociateArtistsOpts struct {
|
||||
ArtistMbzIDs []uuid.UUID
|
||||
ArtistNames []string
|
||||
ArtistName string
|
||||
TrackTitle string
|
||||
Mbzc mbz.MusicBrainzCaller
|
||||
ArtistMbzIDs []uuid.UUID
|
||||
ArtistNames []string
|
||||
ArtistMbidMap []ArtistMbidMap
|
||||
ArtistName string
|
||||
TrackTitle string
|
||||
Mbzc mbz.MusicBrainzCaller
|
||||
}
|
||||
|
||||
func AssociateArtists(ctx context.Context, d db.DB, opts AssociateArtistsOpts) ([]*models.Artist, error) {
|
||||
|
|
@ -29,9 +31,19 @@ func AssociateArtists(ctx context.Context, d db.DB, opts AssociateArtistsOpts) (
|
|||
|
||||
var result []*models.Artist
|
||||
|
||||
if len(opts.ArtistMbzIDs) > 0 {
|
||||
l.Debug().Msg("Associating artists by MusicBrainz ID(s)")
|
||||
mbzMatches, err := matchArtistsByMBID(ctx, d, opts)
|
||||
// use mbid map first, as it is the most reliable way to get mbid for artists
|
||||
if len(opts.ArtistMbidMap) > 0 {
|
||||
l.Debug().Msg("Associating artists by MusicBrainz ID(s) mappings")
|
||||
mbzMatches, err := matchArtistsByMBIDMappings(ctx, d, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, mbzMatches...)
|
||||
}
|
||||
|
||||
if len(opts.ArtistMbzIDs) > len(result) {
|
||||
l.Debug().Msg("Associating artists by list of MusicBrainz ID(s)")
|
||||
mbzMatches, err := matchArtistsByMBID(ctx, d, opts, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -60,11 +72,82 @@ func AssociateArtists(ctx context.Context, d db.DB, opts AssociateArtistsOpts) (
|
|||
return result, nil
|
||||
}
|
||||
|
||||
func matchArtistsByMBID(ctx context.Context, d db.DB, opts AssociateArtistsOpts) ([]*models.Artist, error) {
|
||||
func matchArtistsByMBIDMappings(ctx context.Context, d db.DB, opts AssociateArtistsOpts) ([]*models.Artist, error) {
|
||||
l := logger.FromContext(ctx)
|
||||
var result []*models.Artist
|
||||
|
||||
for _, a := range opts.ArtistMbidMap {
|
||||
// first, try to get by mbid
|
||||
artist, err := d.GetArtist(ctx, db.GetArtistOpts{
|
||||
MusicBrainzID: a.Mbid,
|
||||
})
|
||||
if err == nil {
|
||||
l.Debug().Msgf("Artist '%s' found by MusicBrainz ID", artist.Name)
|
||||
result = append(result, artist)
|
||||
continue
|
||||
}
|
||||
if !errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, fmt.Errorf("matchArtistsBYMBIDMappings: %w", err)
|
||||
}
|
||||
// then, try to get by mbz name
|
||||
artist, err = d.GetArtist(ctx, db.GetArtistOpts{
|
||||
Name: a.Artist,
|
||||
})
|
||||
if err == nil {
|
||||
l.Debug().Msgf("Artist '%s' found by Name", a.Artist)
|
||||
// ...associate with mbzid if found
|
||||
err = d.UpdateArtist(ctx, db.UpdateArtistOpts{ID: artist.ID, MusicBrainzID: a.Mbid})
|
||||
if err != nil {
|
||||
l.Err(fmt.Errorf("matchArtistsBYMBIDMappings: %w", err)).Msgf("Failed to associate artist '%s' with MusicBrainz ID", artist.Name)
|
||||
} else {
|
||||
artist.MbzID = &a.Mbid
|
||||
}
|
||||
result = append(result, artist)
|
||||
continue
|
||||
}
|
||||
if !errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, fmt.Errorf("matchArtistsBYMBIDMappings: %w", err)
|
||||
}
|
||||
|
||||
// then, try to get by aliases, or create
|
||||
artist, err = resolveAliasOrCreateArtist(ctx, a.Mbid, opts.ArtistNames, d, opts.Mbzc)
|
||||
if err != nil {
|
||||
// if mbz unreachable, just create a new artist with provided name and mbid
|
||||
l.Warn().Msg("MusicBrainz unreachable, creating new artist with provided MusicBrainz ID mapping")
|
||||
var imgid uuid.UUID
|
||||
imgUrl, err := images.GetArtistImage(ctx, images.ArtistImageOpts{
|
||||
Aliases: []string{a.Artist},
|
||||
})
|
||||
if err == nil {
|
||||
imgid = uuid.New()
|
||||
err = DownloadAndCacheImage(ctx, imgid, imgUrl, ImageSourceSize())
|
||||
if err != nil {
|
||||
l.Err(fmt.Errorf("matchArtistsByMBIDMappings: %w", err)).Msgf("Failed to download artist image for artist '%s'", a.Artist)
|
||||
imgid = uuid.Nil
|
||||
}
|
||||
} else {
|
||||
l.Err(fmt.Errorf("matchArtistsByMBIDMappings: %w", err)).Msgf("Failed to get artist image for artist '%s'", a.Artist)
|
||||
}
|
||||
artist, err = d.SaveArtist(ctx, db.SaveArtistOpts{Name: a.Artist, MusicBrainzID: a.Mbid, Image: imgid, ImageSrc: imgUrl})
|
||||
if err != nil {
|
||||
l.Err(fmt.Errorf("matchArtistsByMBIDMappings: %w", err)).Msgf("Failed to create artist '%s' in database", a.Artist)
|
||||
return nil, fmt.Errorf("matchArtistsByMBIDMappings: %w", err)
|
||||
}
|
||||
}
|
||||
result = append(result, artist)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func matchArtistsByMBID(ctx context.Context, d db.DB, opts AssociateArtistsOpts, existing []*models.Artist) ([]*models.Artist, error) {
|
||||
l := logger.FromContext(ctx)
|
||||
var result []*models.Artist
|
||||
|
||||
for _, id := range opts.ArtistMbzIDs {
|
||||
if artistExistsByMbzID(id, existing) || artistExistsByMbzID(id, result) {
|
||||
l.Debug().Msgf("Artist with MusicBrainz ID %s already found, skipping...", id)
|
||||
continue
|
||||
}
|
||||
if id == uuid.Nil {
|
||||
l.Warn().Msg("Provided artist has uuid.Nil MusicBrainzID")
|
||||
return matchArtistsByNames(ctx, opts.ArtistNames, result, d)
|
||||
|
|
@ -229,3 +312,11 @@ func artistExists(name string, artists []*models.Artist) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
func artistExistsByMbzID(id uuid.UUID, artists []*models.Artist) bool {
|
||||
for _, a := range artists {
|
||||
if a.MbzID != nil && *a.MbzID == id {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue