METANOIA/handler/metadata.go

176 lines
4.5 KiB
Go

package handler
import (
"git.gammaspectra.live/S.O.N.G/METANOIA/metadata"
accuraterip_com "git.gammaspectra.live/S.O.N.G/METANOIA/metadata/accuraterip.com"
cuetools_net "git.gammaspectra.live/S.O.N.G/METANOIA/metadata/cuetools.net"
en_touhouwiki_net "git.gammaspectra.live/S.O.N.G/METANOIA/metadata/en.touhouwiki.net"
musicbrainz_org "git.gammaspectra.live/S.O.N.G/METANOIA/metadata/musicbrainz.org"
thwiki_cc "git.gammaspectra.live/S.O.N.G/METANOIA/metadata/thwiki.cc"
vgmdb_net "git.gammaspectra.live/S.O.N.G/METANOIA/metadata/vgmdb.net"
"time"
)
var metadataSources = []metadata.SourceMetadata{
accuraterip_com.NewSource(),
cuetools_net.NewSource(),
musicbrainz_org.NewSource(),
vgmdb_net.NewSource(),
thwiki_cc.NewSource(),
en_touhouwiki_net.NewSource(),
}
func SearchMetadata(disc *DiscHandlerResult, fuzzy bool) (albums []*metadata.Album) {
for _, source := range metadataSources {
var foundAlbums []*metadata.Album
if tocSource, ok := source.(metadata.TOCSource); ok {
foundAlbums = tocSource.FindByTOC(disc.TOC)
if fuzzy || len(foundAlbums) == 0 {
for _, toc := range disc.Identifiers.GetKind("toc") {
foundAlbums = append(foundAlbums, tocSource.FindByTOC(metadata.NewTOCFromString(toc))...)
}
}
}
if cddb1Source, ok := source.(metadata.CDDB1Source); fuzzy && ok {
foundAlbums = cddb1Source.FindByCDDB1(disc.TOC.GetCDDB1())
if fuzzy || len(foundAlbums) == 0 {
for _, id := range disc.Identifiers.GetKind("cddb1") {
foundAlbums = append(foundAlbums, cddb1Source.FindByCDDB1(metadata.NewCDDB1FromString(id))...)
}
}
}
if catalogSource, ok := source.(metadata.CatalogSource); (fuzzy || len(foundAlbums) == 0) && ok {
var catalogNumbers []metadata.CatalogNumber
for _, catno := range disc.Identifiers.GetKind("catalog") {
catalogNumbers = append(catalogNumbers, metadata.CatalogNumber(catno))
}
//TODO: also search combined number (aka EX-1000~11 or EX-1234~6)
for _, catno := range catalogNumbers {
foundAlbums = append(foundAlbums, catalogSource.FindByCatalogNumber(catno)...)
}
}
if nameSource, ok := source.(metadata.AlbumNameSource); (fuzzy || len(foundAlbums) == 0) && ok && len(disc.Album) > 0 {
nameSource.FindByAlbumNames([]metadata.Name{
{Kind: "original", Name: disc.Album},
})
}
albums = append(albums, foundAlbums...)
}
return
}
func MergeAlbums(albums ...*metadata.Album) (result []*metadata.Album) {
//normalize?
//make a copy to process
a := make([]*metadata.Album, 0, len(albums))
for _, e := range albums {
e = e.Copy()
e.Normalize()
a = append(a, e)
}
for len(a) > 0 {
album := a[0]
catalogNumbers := album.Identifiers.GetKind("catalog")
urls := album.Identifiers.GetKind("url")
var duration time.Duration
var tracks = 0
for _, d := range album.Discs {
tracks += len(d.Tracks)
for _, t := range d.Tracks {
duration += t.Duration
}
}
for i, other := range a[1:] {
if other == nil {
continue
}
sameIdentifier := album.SourceUniqueIdentifier == other.SourceUniqueIdentifier
sameUrls := false
sameTitle := false
sameCatalog := false
sameRelease := album.ReleaseDate.Sub(other.ReleaseDate).Hours() <= 24*2 //within 2 days, todo: maybe just check same year?
var otherDuration time.Duration
var otherTracks = 0
for _, d := range other.Discs {
otherTracks += len(d.Tracks)
for _, t := range d.Tracks {
otherDuration += t.Duration
}
}
sameDiscs := len(album.Discs) == len(other.Discs)
sameTrackCount := tracks == otherTracks
durationDiff := duration - otherDuration
if durationDiff < 0 {
durationDiff = -durationDiff
}
sameDuration := durationDiff < time.Second*10
for _, n := range other.Name {
if album.Name.Exists(n) != -1 {
sameTitle = true
break
}
}
for _, n := range other.Identifiers.GetKind("catalog") {
for _, s := range catalogNumbers {
if n == s {
sameCatalog = true
break
}
}
}
for _, n := range other.Identifiers.GetKind("url") {
for _, s := range urls {
if n == s {
sameUrls = true
break
}
}
}
if sameIdentifier ||
(sameTitle && sameRelease) ||
(sameTitle && sameDiscs && sameTrackCount) ||
(sameTitle && sameDiscs && sameDuration) ||
(sameTitle && sameUrls) ||
sameCatalog {
//merge
album = album.Merge(other)
//remove old
a[i+1] = nil
}
}
//remove, append to result
for {
a = a[1:]
if len(a) == 0 || a[0] != nil {
break
}
}
result = append(result, album)
}
return
}