mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-20 22:07:43 +03:00
feat(scanner): enhance album artist mapping logic for better display name handling
Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
58367afaea
commit
8464e8c8e5
@ -224,13 +224,38 @@ func (md Metadata) mapDisplayArtist() string {
|
||||
}
|
||||
|
||||
func (md Metadata) mapDisplayAlbumArtist(mf model.MediaFile) string {
|
||||
// 1. Check for explicit album artist tags first
|
||||
albumArtistDisplay := md.mapDisplayName(model.TagAlbumArtist, model.TagAlbumArtists)
|
||||
if albumArtistDisplay != "" {
|
||||
return albumArtistDisplay
|
||||
}
|
||||
|
||||
// 2. No explicit album artist, check for track artist tags
|
||||
artistTag := model.TagTrackArtist
|
||||
artistsTag := model.TagTrackArtists
|
||||
hasMultiValuedArtistTag := len(md.tags[artistTag]) > 1 || len(md.tags[artistsTag]) > 1
|
||||
hasSingleValuedArtistTag := len(md.tags[artistTag]) == 1 || len(md.tags[artistsTag]) == 1
|
||||
|
||||
if hasMultiValuedArtistTag {
|
||||
// Special case from tests: Use only the first artist if ARTIST/ARTISTS tag is multi-valued
|
||||
if len(md.tags[artistTag]) > 1 {
|
||||
return md.tags[artistTag][0]
|
||||
}
|
||||
// We know artistsTag must have > 1 here
|
||||
return md.tags[artistsTag][0]
|
||||
}
|
||||
// If execution reaches here, hasMultiValuedArtistTag is false
|
||||
if hasSingleValuedArtistTag {
|
||||
// For single artist values (including those with separators like ';'), use the artist display name
|
||||
return md.mapDisplayArtist()
|
||||
}
|
||||
|
||||
// 3. Neither album artist nor track artist tags found. Fallback logic:
|
||||
fallbackName := consts.UnknownArtist
|
||||
if md.Bool(model.TagCompilation) {
|
||||
fallbackName = consts.VariousArtists
|
||||
}
|
||||
return cmp.Or(
|
||||
md.mapDisplayName(model.TagAlbumArtist, model.TagAlbumArtists),
|
||||
mf.Participants.First(model.RoleAlbumArtist).Name,
|
||||
fallbackName,
|
||||
)
|
||||
|
||||
// Use the name from the first participant found for RoleAlbumArtist, or the default fallback
|
||||
return cmp.Or(mf.Participants.First(model.RoleAlbumArtist).Name, fallbackName)
|
||||
}
|
||||
|
@ -370,6 +370,49 @@ var _ = Describe("Participants", func() {
|
||||
Expect(artist1.MbzArtistID).To(Equal(mbid2))
|
||||
})
|
||||
})
|
||||
|
||||
Context("Single-valued ARTIST tag with semicolon, no ARTISTS tags", func() {
|
||||
BeforeEach(func() {
|
||||
mf = toMediaFile(model.RawTags{
|
||||
"ARTIST": {"hey; ho"},
|
||||
})
|
||||
})
|
||||
|
||||
It("should use the full string as display name", func() {
|
||||
Expect(mf.Artist).To(Equal("hey; ho"))
|
||||
})
|
||||
|
||||
It("should split the artist by semicolon", func() {
|
||||
participants := mf.Participants
|
||||
Expect(participants).To(SatisfyAll(
|
||||
HaveKeyWithValue(model.RoleArtist, HaveLen(2)),
|
||||
))
|
||||
|
||||
By("adding the first artist to the participants")
|
||||
artist0 := participants[model.RoleArtist][0]
|
||||
Expect(artist0.ID).ToNot(BeEmpty())
|
||||
Expect(artist0.Name).To(Equal("hey"))
|
||||
Expect(artist0.OrderArtistName).To(Equal("hey"))
|
||||
|
||||
By("adding the second artist to the participants")
|
||||
artist1 := participants[model.RoleArtist][1]
|
||||
Expect(artist1.ID).ToNot(BeEmpty())
|
||||
Expect(artist1.Name).To(Equal("ho"))
|
||||
Expect(artist1.OrderArtistName).To(Equal("ho"))
|
||||
})
|
||||
|
||||
It("should use the full artist name as albumArtist when no ALBUMARTIST is provided", func() {
|
||||
Expect(mf.AlbumArtist).To(Equal("hey; ho"))
|
||||
|
||||
participants := mf.Participants
|
||||
Expect(participants).To(SatisfyAll(
|
||||
HaveKeyWithValue(model.RoleAlbumArtist, HaveLen(2)),
|
||||
))
|
||||
|
||||
albumArtist := participants[model.RoleAlbumArtist][0]
|
||||
Expect(albumArtist.Name).To(Equal("hey"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("ALBUMARTIST(S) tags", func() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user