fix(library): always split comma-separated artists even if glued name exists
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
75f9c57eca
commit
17c85493b7
2 files changed
+24
-6
No files matched your search
@@ -33,6 +33,8 @@ func TestSplitArtists(t *testing.T) {
|
|||||||
assert.Equal(t, []string{"main:Tom", "main:Jerry"}, names(SplitArtists("Tom & Jerry", known)))
|
assert.Equal(t, []string{"main:Tom", "main:Jerry"}, names(SplitArtists("Tom & Jerry", known)))
|
||||||
assert.Equal(t, []string{"main:A", "main:B"}, names(SplitArtists("A; B", nil)))
|
assert.Equal(t, []string{"main:A", "main:B"}, names(SplitArtists("A; B", nil)))
|
||||||
assert.Equal(t, []string{"main:A", "main:B", "main:C"}, names(SplitArtists("A, B, C", nil)))
|
assert.Equal(t, []string{"main:A", "main:B", "main:C"}, names(SplitArtists("A, B, C", nil)))
|
||||||
|
assert.Equal(t, []string{"main:A", "main:B"}, names(SplitArtists("A, B", func(string) bool { return true })), "already glued name is still split")
|
||||||
|
assert.Equal(t, []string{"main:Tyler, the Creator"}, names(SplitArtists("Tyler, the Creator", nil)))
|
||||||
assert.Equal(t, []string{"main:A", "feat:B", "feat:C"}, names(SplitArtists("A feat. B & C", nil)))
|
assert.Equal(t, []string{"main:A", "feat:B", "feat:C"}, names(SplitArtists("A feat. B & C", nil)))
|
||||||
assert.Equal(t, []string{"main:A"}, names(SplitArtists("A / a", nil)), "duplicates by key are dropped")
|
assert.Equal(t, []string{"main:A"}, names(SplitArtists("A / a", nil)), "duplicates by key are dropped")
|
||||||
assert.Empty(t, SplitArtists(" ", nil))
|
assert.Empty(t, SplitArtists(" ", nil))
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ type ArtistCredit struct {
|
|||||||
Role string // main | feat
|
Role string // main | feat
|
||||||
}
|
}
|
||||||
|
|
||||||
// SplitArtists разбирает поле исполнителя на отдельных. « & » и «, » делят имя, только если составного
|
// SplitArtists разбирает поле исполнителя на отдельных. « & » делит имя, только если составного
|
||||||
// исполнителя нет в библиотеке (known), — иначе «Simon & Garfunkel» распался бы на двоих.
|
// исполнителя нет в библиотеке (known), — иначе «Simon & Garfunkel» распался бы на двоих.
|
||||||
// Всё после feat./ft. — приглашённые исполнители.
|
// Всё после feat./ft. — приглашённые исполнители.
|
||||||
func SplitArtists(s string, known func(key string) bool) []ArtistCredit {
|
func SplitArtists(s string, known func(key string) bool) []ArtistCredit {
|
||||||
@@ -85,13 +85,15 @@ func SplitArtists(s string, known func(key string) bool) []ArtistCredit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, part := range splitAny(main, artistSeparators) {
|
for _, part := range splitAny(main, artistSeparators) {
|
||||||
if (strings.Contains(part, " & ") || strings.Contains(part, ", ")) && (known == nil || !known(Key(part))) {
|
for _, seg := range splitComma(part) {
|
||||||
for _, p := range splitAny(part, []string{" & ", ", "}) {
|
if strings.Contains(seg, " & ") && (known == nil || !known(Key(seg))) {
|
||||||
add(p, "main")
|
for _, p := range strings.Split(seg, " & ") {
|
||||||
|
add(p, "main")
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
continue
|
add(seg, "main")
|
||||||
}
|
}
|
||||||
add(part, "main")
|
|
||||||
}
|
}
|
||||||
for _, part := range splitAny(feat, append(artistSeparators, " & ", ", ")) {
|
for _, part := range splitAny(feat, append(artistSeparators, " & ", ", ")) {
|
||||||
add(part, "feat")
|
add(part, "feat")
|
||||||
@@ -99,6 +101,20 @@ func SplitArtists(s string, known func(key string) bool) []ArtistCredit {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// splitComma делит по «, » без оглядки на библиотеку: иначе уже склеенное имя («A, B») навсегда
|
||||||
|
// остаётся «известным». Продолжение «the …» — часть имени («Tyler, the Creator»).
|
||||||
|
func splitComma(s string) []string {
|
||||||
|
var out []string
|
||||||
|
for _, p := range strings.Split(s, ", ") {
|
||||||
|
if n := len(out); n > 0 && strings.HasPrefix(strings.ToLower(p), "the ") {
|
||||||
|
out[n-1] += ", " + p
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out = append(out, p)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
func splitAny(s string, seps []string) []string {
|
func splitAny(s string, seps []string) []string {
|
||||||
parts := []string{s}
|
parts := []string{s}
|
||||||
for _, sep := range seps {
|
for _, sep := range seps {
|
||||||
|
|||||||
Reference in new issue
Block a user