Comment blocks in cmd/minstrel and 30 smaller internal packages, rewritten
to rule 32's standard with each citation read in context: task, milestone
and rule ids go, and so do the stories they were attached to ("used to",
"Before #N", measurements from one install, quotes, pointers to Fabled
Librarian's records and to docs/superpowers files that are not in the
repo). Where a story wrapped a real constraint, the constraint stays as a
present-tense fact.
Comments that had gone stale are corrected:
- taste.Config: the tuned values are overlaid by internal/recsettings;
it is no longer "a later follow-up".
- StorageConfig: the data dir holds art, caches and the stream secret,
not only playlist covers.
- the Subsonic album list and getUser comments describe what they do
today rather than a milestone that would change it.
Checked: the non-comment token stream of every changed file matches
HEAD, and gofmt -l is empty.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
80 lines
2.5 KiB
Go
80 lines
2.5 KiB
Go
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. 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
|
||
}
|