Implement new Artist refresh
This commit is contained in:
@@ -176,65 +176,6 @@ func (r *artistRepository) GetIndex() (model.ArtistIndexes, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (r *artistRepository) Refresh(ids ...string) error {
|
||||
chunks := utils.BreakUpStringSlice(ids, 100)
|
||||
for _, chunk := range chunks {
|
||||
err := r.refresh(chunk...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *artistRepository) refresh(ids ...string) error {
|
||||
type refreshArtist struct {
|
||||
model.Artist
|
||||
CurrentId string
|
||||
GenreIds string
|
||||
}
|
||||
var artists []refreshArtist
|
||||
sel := Select("f.album_artist_id as id", "f.album_artist as name", "count(*) as album_count", "a.id as current_id",
|
||||
"group_concat(f.mbz_album_artist_id , ' ') as mbz_artist_id",
|
||||
"f.sort_album_artist_name as sort_artist_name", "f.order_album_artist_name as order_artist_name",
|
||||
"sum(f.song_count) as song_count", "sum(f.size) as size",
|
||||
"alg.genre_ids").
|
||||
From("album f").
|
||||
LeftJoin("artist a on f.album_artist_id = a.id").
|
||||
LeftJoin(`(select al.album_artist_id, group_concat(ag.genre_id, ' ') as genre_ids from album_genres ag
|
||||
left join album al on al.id = ag.album_id where al.album_artist_id in ('` +
|
||||
strings.Join(ids, "','") + `') group by al.album_artist_id) alg on alg.album_artist_id = f.album_artist_id`).
|
||||
Where(Eq{"f.album_artist_id": ids}).
|
||||
GroupBy("f.album_artist_id").OrderBy("f.id")
|
||||
err := r.queryAll(sel, &artists)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
toInsert := 0
|
||||
toUpdate := 0
|
||||
for _, ar := range artists {
|
||||
if ar.CurrentId != "" {
|
||||
toUpdate++
|
||||
} else {
|
||||
toInsert++
|
||||
}
|
||||
ar.MbzArtistID = getMostFrequentMbzID(r.ctx, ar.MbzArtistID, r.tableName, ar.Name)
|
||||
ar.Genres = getGenres(ar.GenreIds)
|
||||
err := r.Put(&ar.Artist)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if toInsert > 0 {
|
||||
log.Debug(r.ctx, "Inserted new artists", "totalInserted", toInsert)
|
||||
}
|
||||
if toUpdate > 0 {
|
||||
log.Debug(r.ctx, "Updated artists", "totalUpdated", toUpdate)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *artistRepository) purgeEmpty() error {
|
||||
del := Delete(r.tableName).Where("id not in (select distinct(album_artist_id) from album)")
|
||||
c, err := r.executeSQL(del)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package persistence
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -9,9 +8,6 @@ import (
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/fatih/structs"
|
||||
"github.com/navidrome/navidrome/consts"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
)
|
||||
|
||||
func toSqlArgs(rec interface{}) (map[string]interface{}, error) {
|
||||
@@ -58,49 +54,3 @@ func (e existsCond) ToSql() (string, []interface{}, error) {
|
||||
}
|
||||
return sql, args, err
|
||||
}
|
||||
|
||||
func getMostFrequentMbzID(ctx context.Context, mbzIDs, entityName, name string) string {
|
||||
ids := strings.Fields(mbzIDs)
|
||||
if len(ids) == 0 {
|
||||
return ""
|
||||
}
|
||||
var topId string
|
||||
var topCount int
|
||||
idCounts := map[string]int{}
|
||||
|
||||
if len(ids) == 1 {
|
||||
topId = ids[0]
|
||||
} else {
|
||||
for _, id := range ids {
|
||||
c := idCounts[id] + 1
|
||||
idCounts[id] = c
|
||||
if c > topCount {
|
||||
topId = id
|
||||
topCount = c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(idCounts) > 1 && name != consts.VariousArtists {
|
||||
log.Warn(ctx, "Multiple MBIDs found for "+entityName, "name", name, "mbids", idCounts, "selectedId", topId)
|
||||
}
|
||||
if topId == consts.VariousArtistsMbzId && name != consts.VariousArtists {
|
||||
log.Warn(ctx, "Artist with mbid of 'Various Artists'", "name", name, "mbid", topId)
|
||||
}
|
||||
|
||||
return topId
|
||||
}
|
||||
|
||||
func getGenres(genreIds string) model.Genres {
|
||||
ids := strings.Fields(genreIds)
|
||||
var genres model.Genres
|
||||
unique := map[string]struct{}{}
|
||||
for _, id := range ids {
|
||||
if _, ok := unique[id]; ok {
|
||||
continue
|
||||
}
|
||||
genres = append(genres, model.Genre{ID: id})
|
||||
unique[id] = struct{}{}
|
||||
}
|
||||
return genres
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package persistence
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
@@ -68,26 +66,4 @@ var _ = Describe("Helpers", func() {
|
||||
Expect(err).To(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
Describe("getMostFrequentMbzID", func() {
|
||||
It(`returns "" when no ids are passed`, func() {
|
||||
Expect(getMostFrequentMbzID(context.TODO(), " ", "", "")).To(Equal(""))
|
||||
})
|
||||
It(`returns the only id passed`, func() {
|
||||
Expect(getMostFrequentMbzID(context.TODO(), "111 ", "", "")).To(Equal("111"))
|
||||
})
|
||||
It(`returns the id with higher frequency`, func() {
|
||||
Expect(getMostFrequentMbzID(context.TODO(), "1 2 3 4 2", "", "")).To(Equal("2"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("getGenres", func() {
|
||||
It("returns unique genres", func() {
|
||||
expected := model.Genres{{ID: "1"}, {ID: "2"}, {ID: "3"}, {ID: "5"}, {ID: "4"}}
|
||||
Expect(getGenres("1 2 3 5 3 2 4 ")).To(Equal(expected))
|
||||
})
|
||||
It("returns empty list when there are no genres", func() {
|
||||
Expect(getGenres("")).To(BeEmpty())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user