package release import "strings" // TitleVersion is the version of a recording a release group's title names // in its qualifier: the words in brackets, or after a dash. MusicBrainz // does not always type such a group: My Chemical Romance's "Common People // (Recorded For BBC Radio 1)" is a plain Single (#5573). Typ is the // MusicBrainz secondary type the version is, or "" for one no type names // (an acoustic or instrumental version); Word is the word that said so. type TitleVersion struct { Word string What string Typ string } // titleVersions are the qualifier words that name a version, in the order // they are looked for: "rough mix" is a demo before "mix" is a remix. var titleVersions = []struct { words []string what string typ string }{ {[]string{"demo", "demos", "outtake", "outtakes", "rehearsal", "rough mix"}, "demo recordings", "Demo"}, {[]string{"live", "bootleg", "bbc", "session", "sessions", "unplugged", "recorded for", "in concert"}, "a live recording", "Live"}, {[]string{"remix", "remixes", "remixed", "rmx", "mix", "mixes"}, "a remix", "Remix"}, {[]string{"instrumental", "instrumentals", "acoustic", "karaoke", "acapella", "acappella", "a cappella", "drumless", "nightcore", "slowed", "sped up"}, "another version", ""}, {[]string{"commentary", "interview", "interviews"}, "commentary or interviews", "Interview"}, } // VersionInTitle reads a release group's title for the version it names, // if any. Only the qualifier counts, so "Live Through This" and "Live // Forever" name no version. func VersionInTitle(title string) (TitleVersion, bool) { for _, q := range qualifiers(title) { tokens := Tokens(q) for _, v := range titleVersions { for _, w := range v.words { if contains(tokens, strings.Fields(w)) { return TitleVersion{Word: w, What: v.what, Typ: v.typ}, true } } } } return TitleVersion{}, false } // qualifiers are the parts of a title in brackets, and what follows a // spaced dash. func qualifiers(title string) []string { var out []string depth, start := 0, 0 for i, c := range title { switch c { case '(', '[', '{': if depth == 0 { start = i + 1 } depth++ case ')', ']', '}': if depth > 0 { depth-- if depth == 0 { out = append(out, title[start:i]) } } } } if depth > 0 { out = append(out, title[start:]) } for _, dash := range []string{" - ", " – ", " — "} { if i := strings.Index(title, dash); i >= 0 { out = append(out, title[i+len(dash):]) } } return out }