Fix release matching for featured artists and credit annotations
ci / module boundaries / boundaries (push) Successful in 1m11s
ci / api / api (push) Successful in 1m54s
ci / mobile / mobile (Metro-бандл Android) (push) Failing after 6m50s
ci / ts / ts (packages + web) (push) Failing after 6m19s
ci / db / db (push) Failing after 11s
ci / module boundaries / boundaries (push) Successful in 1m11s
ci / api / api (push) Successful in 1m54s
ci / mobile / mobile (Metro-бандл Android) (push) Failing after 6m50s
ci / ts / ts (packages + web) (push) Failing after 6m19s
ci / db / db (push) Failing after 11s
This commit is contained in:
1 parent
f4681da876
commit
fd17c06397
7 files changed
+146
-12
No files matched your search
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -70,7 +71,11 @@ func releaseHash(files []File) string {
|
||||
entries = append(entries, entry{f.ID, f.Meta, f.DurationMs, f.Tags})
|
||||
}
|
||||
sort.Slice(entries, func(i, j int) bool { return entries[i].ID.String() < entries[j].ID.String() })
|
||||
b, _ := json.Marshal(entries)
|
||||
// Invalidate persisted reports when matching rules change, as well as tags.
|
||||
b, _ := json.Marshal(struct {
|
||||
Version int
|
||||
Files []entry
|
||||
}{2, entries})
|
||||
h := sha256.Sum256(b)
|
||||
return hex.EncodeToString(h[:])
|
||||
}
|
||||
@@ -111,6 +116,39 @@ func batchReleaseQuery(files []File) (musicbrainz.Query, bool) {
|
||||
}
|
||||
return q, q.Artist != ""
|
||||
}
|
||||
|
||||
// Only credit annotations are removed for tentative matching. Version labels
|
||||
// such as live, remix or instrumental remain significant.
|
||||
var releaseTitleCredits = regexp.MustCompile(`(?i)\s*[\(\[]\s*(?:feat\.?|ft\.?|featuring|prod\.?|produced by)\s+[^()\[\]]+[\)\]]\s*$`)
|
||||
|
||||
func releaseTitleKey(title string) string {
|
||||
for {
|
||||
cleaned := releaseTitleCredits.ReplaceAllString(title, "")
|
||||
if cleaned == title {
|
||||
return meta.Key(title)
|
||||
}
|
||||
title = cleaned
|
||||
}
|
||||
}
|
||||
|
||||
func sameReleaseArtists(a, b string) bool {
|
||||
left := meta.SplitArtists(strings.ToLower(a), nil)
|
||||
right := meta.SplitArtists(strings.ToLower(b), nil)
|
||||
if len(left) == 0 || len(left) != len(right) {
|
||||
return false
|
||||
}
|
||||
credits := make(map[string]bool, len(left))
|
||||
for _, artist := range left {
|
||||
credits[meta.Key(artist.Name)] = true
|
||||
}
|
||||
for _, artist := range right {
|
||||
if !credits[meta.Key(artist.Name)] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func trackScore(f File, t musicbrainz.Track, albumArtist string) int {
|
||||
if f.Meta == nil {
|
||||
return 0
|
||||
@@ -137,8 +175,9 @@ func trackScore(f File, t musicbrainz.Track, albumArtist string) int {
|
||||
if title && (t.DurationMs == 0 || f.DurationMs == nil) {
|
||||
return 70
|
||||
}
|
||||
if delta <= 2000 && m.Track != nil && *m.Track == t.Position && (m.Disc == nil && t.Disc == 1 || m.Disc != nil && *m.Disc == t.Disc) && meta.Key(m.Artist) == meta.Key(t.Artist) {
|
||||
return 60
|
||||
if delta <= 2000 && m.Track != nil && *m.Track == t.Position && (m.Disc == nil && t.Disc == 1 || m.Disc != nil && *m.Disc == t.Disc) &&
|
||||
releaseTitleKey(m.Title) != "" && releaseTitleKey(m.Title) == releaseTitleKey(t.Title) && sameReleaseArtists(m.Artist, t.Artist) {
|
||||
return 75
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user