diff --git a/server/ctrlsubsonic/handlers_by_tags.go b/server/ctrlsubsonic/handlers_by_tags.go index 769d12a..db8bcb3 100644 --- a/server/ctrlsubsonic/handlers_by_tags.go +++ b/server/ctrlsubsonic/handlers_by_tags.go @@ -21,6 +21,7 @@ func (c *Controller) ServeGetArtists(r *http.Request) *spec.Response { params := r.Context().Value(CtxParams).(params.Params) var artists []*db.Artist q := c.DB. + Preload("GuessedFolder"). Select("*, count(sub.id) album_count"). Joins("LEFT JOIN albums sub ON artists.id=sub.tag_artist_id"). Group("artists.id"). @@ -61,6 +62,7 @@ func (c *Controller) ServeGetArtist(r *http.Request) *spec.Response { } artist := &db.Artist{} c.DB. + Preload("GuessedFolder"). Preload("Albums", func(db *gorm.DB) *gorm.DB { return db. Select("*, count(sub.id) child_count, sum(sub.length) duration"). @@ -187,6 +189,7 @@ func (c *Controller) ServeSearchThree(r *http.Request) *spec.Response { // search "artists" var artists []*db.Artist q := c.DB. + Preload("GuessedFolder"). Select("*, count(albums.id) album_count"). Group("artists.id"). Where("name LIKE ? OR name_u_dec LIKE ?", query, query). @@ -254,23 +257,6 @@ func (c *Controller) ServeGetArtistInfoTwo(r *http.Request) *spec.Response { sub := spec.NewResponse() sub.ArtistInfoTwo = &spec.ArtistInfo{} - guessedArtistFolder := &db.Album{} - err = c.DB. - Select("parent.*"). - Joins("JOIN albums parent ON parent.id=albums.parent_id"). - Where("albums.tag_artist_id=?", id.Value). - Find(&guessedArtistFolder). - Error - if err != nil { - return spec.NewError(0, "finding artist folder: %v", err) - } - - if guessedArtistFolder.Cover != "" { - sub.ArtistInfoTwo.SmallImageURL = c.genAlbumCoverURL(r, guessedArtistFolder, 64) - sub.ArtistInfoTwo.MediumImageURL = c.genAlbumCoverURL(r, guessedArtistFolder, 126) - sub.ArtistInfoTwo.LargeImageURL = c.genAlbumCoverURL(r, guessedArtistFolder, 256) - } - apiKey, _ := c.DB.GetSetting("lastfm_api_key") if apiKey == "" { return sub @@ -278,6 +264,7 @@ func (c *Controller) ServeGetArtistInfoTwo(r *http.Request) *spec.Response { artist := &db.Artist{} err = c.DB. + Preload("GuessedFolder"). Where("id=?", id.Value). Find(artist). Error @@ -285,6 +272,12 @@ func (c *Controller) ServeGetArtistInfoTwo(r *http.Request) *spec.Response { return spec.NewError(70, "artist with id `%s` not found", id) } + if artist.GuessedFolder != nil && artist.GuessedFolder.Cover != "" { + sub.ArtistInfoTwo.SmallImageURL = c.genAlbumCoverURL(r, artist.GuessedFolder, 64) + sub.ArtistInfoTwo.MediumImageURL = c.genAlbumCoverURL(r, artist.GuessedFolder, 126) + sub.ArtistInfoTwo.LargeImageURL = c.genAlbumCoverURL(r, artist.GuessedFolder, 256) + } + info, err := lastfm.ArtistGetInfo(apiKey, artist) if err != nil { return spec.NewError(0, "fetching artist info: %v", err) @@ -294,7 +287,7 @@ func (c *Controller) ServeGetArtistInfoTwo(r *http.Request) *spec.Response { sub.ArtistInfoTwo.MusicBrainzID = info.MBID sub.ArtistInfoTwo.LastFMURL = info.URL - if guessedArtistFolder.Cover == "" { + if !(artist.GuessedFolder != nil && artist.GuessedFolder.Cover != "") { for _, image := range info.Image { switch image.Size { case "small": diff --git a/server/ctrlsubsonic/spec/construct_by_tags.go b/server/ctrlsubsonic/spec/construct_by_tags.go index 3250995..4475f85 100644 --- a/server/ctrlsubsonic/spec/construct_by_tags.go +++ b/server/ctrlsubsonic/spec/construct_by_tags.go @@ -72,11 +72,15 @@ func NewTrackByTags(t *db.Track, album *db.Album) *TrackChild { } func NewArtistByTags(a *db.Artist) *Artist { - return &Artist{ + ret := &Artist{ ID: a.SID(), Name: a.Name, AlbumCount: a.AlbumCount, } + if a.GuessedFolder != nil && a.GuessedFolder.Cover != "" { + ret.CoverID = a.GuessedFolder.SID() + } + return ret } func NewGenre(g *db.Genre) *Genre { diff --git a/server/db/migrations.go b/server/db/migrations.go index 7a515ac..77df72a 100644 --- a/server/db/migrations.go +++ b/server/db/migrations.go @@ -37,6 +37,7 @@ func (db *DB) Migrate(ctx MigrationContext) error { construct(ctx, "202102191448", migratePodcastAutoDownload), construct(ctx, "202110041330", migrateAlbumCreatedAt), construct(ctx, "202111021951", migrateAlbumRootDir), + construct(ctx, "202201042236", migrateArtistGuessedFolder), } return gormigrate. @@ -306,3 +307,7 @@ func migrateAlbumRootDir(tx *gorm.DB, ctx MigrationContext) error { } return nil } + +func migrateArtistGuessedFolder(tx *gorm.DB, ctx MigrationContext) error { + return tx.AutoMigrate(Artist{}).Error +} diff --git a/server/db/model.go b/server/db/model.go index 1580192..41aa85d 100644 --- a/server/db/model.go +++ b/server/db/model.go @@ -43,11 +43,13 @@ func joinInt(in []int, sep string) string { } type Artist struct { - ID int `gorm:"primary_key"` - Name string `gorm:"not null; unique_index"` - NameUDec string `sql:"default: null"` - Albums []*Album `gorm:"foreignkey:TagArtistID"` - AlbumCount int `sql:"-"` + ID int `gorm:"primary_key"` + Name string `gorm:"not null; unique_index"` + NameUDec string `sql:"default: null"` + Albums []*Album `gorm:"foreignkey:TagArtistID"` + AlbumCount int `sql:"-"` + GuessedFolder *Album + GuessedFolderID int `sql:"default: null; type:int REFERENCES albums(id)"` } func (a *Artist) SID() *specid.ID { diff --git a/server/scanner/scanner.go b/server/scanner/scanner.go index ce5af91..e9031fb 100644 --- a/server/scanner/scanner.go +++ b/server/scanner/scanner.go @@ -216,7 +216,7 @@ func (s *Scanner) populateTrackAndAlbumArtists(tx *db.DB, c *ctx, i int, album * } artistName := trags.SomeAlbumArtist() - albumArtist, err := s.populateAlbumArtist(tx, artistName) + albumArtist, err := s.populateAlbumArtist(tx, album, artistName) if err != nil { return fmt.Errorf("populate artist: %w", err) } @@ -310,12 +310,15 @@ func populateTrack(tx *db.DB, album *db.Album, albumArtist *db.Artist, track *db return nil } -func (s *Scanner) populateAlbumArtist(tx *db.DB, artistName string) (*db.Artist, error) { +func (s *Scanner) populateAlbumArtist(tx *db.DB, guessedArtistFolder *db.Album, artistName string) (*db.Artist, error) { var artist db.Artist update := db.Artist{ Name: artistName, NameUDec: decoded(artistName), } + if guessedArtistFolder != nil { + update.GuessedFolderID = guessedArtistFolder.ParentID + } if err := tx.Where("name=?", artistName).Assign(update).FirstOrCreate(&artist).Error; err != nil { return nil, fmt.Errorf("find or create artist: %w", err) }