31febb9f56
Parse releases with an explicit fixed positional model and document the whole logic in British English doc-blocks. Model: - [0]=Artist, [1]=Title are fixed and never matched against dictionaries, so titles like "Split"/"Demo"/"De" are never eaten. - [len-1]=Group is always read from the line, not from the query key. - [len-2]=Year when it is a 4-digit 19xx|20xx token; otherwise the slot is resolved as a middle-zone token (e.g. FLAC still picked up as format). - The middle zone is resolved via case-insensitive dictionaries in the order format -> source -> bit-depth -> resolution -> edition -> language -> catalogue number. Position within the zone is irrelevant. Catalogue numbers: - Any "(...)" token in the middle zone is a catalogue number regardless of content (digits, roman numerals, dots, underscores, mixed case). Removed the hasDigit requirement and character whitelist that rejected real catalogues like (DYN.3140-2) and (GOWP_DCCCLXXXIX). - Splitting never breaks tokens inside parentheses. Case handling: lookups are case-insensitive; stored values keep their original case from the line. Documentation: replaced Ukrainian comments in parser.go and analyzer.go with British-English doc-blocks describing the model, tail resolution order, catalogue rule and confidence scoring. Tests: - Add TestParseCatalogNumberWithDotAndRoman for (DYN.3140-2)/(GOWP_DCCCLXXXIX). - Update case-insensitive, split-title, no-year and language expectations. - go build, go vet and go test all pass.
43 lines
1.3 KiB
Go
43 lines
1.3 KiB
Go
package moonblood
|
|
|
|
import (
|
|
"embed"
|
|
"strings"
|
|
|
|
"git.kplus.net.ua/yevhen/resource-scraper/internal/releaseparser"
|
|
)
|
|
|
|
// Словники токенів лежать у dicts/*.txt — один токен на рядок.
|
|
// Їх можна редагувати без перекомпіляції логіки (embed тягне їх у бінарник на збірці).
|
|
|
|
//go:embed dicts/*.txt
|
|
var dictFS embed.FS
|
|
|
|
func loadDict(name string) map[string]bool {
|
|
data, err := dictFS.ReadFile("dicts/" + name + ".txt")
|
|
if err != nil {
|
|
panic("moonblood: cannot load dictionary " + name + ": " + err.Error())
|
|
}
|
|
out := make(map[string]bool)
|
|
for _, line := range strings.Split(string(data), "\n") {
|
|
line = strings.ToUpper(strings.TrimSpace(line))
|
|
if line == "" || strings.HasPrefix(line, "#") {
|
|
continue
|
|
}
|
|
out[line] = true
|
|
}
|
|
return out
|
|
}
|
|
|
|
var Profile = releaseparser.GroupProfile{
|
|
Name: "MOONBLOOD",
|
|
ExpectedTailOrder: []string{"bit_depth", "resolution", "source", "format", "year", "group"},
|
|
FormatTokens: loadDict("format"),
|
|
SourceTokens: loadDict("source"),
|
|
BitDepthTokens: loadDict("bitdepth"),
|
|
ResolutionTokens: loadDict("resolution"),
|
|
LanguageMarkers: loadDict("language"),
|
|
EditionTokens: loadDict("edition"),
|
|
CommentTokens: loadDict("comment"),
|
|
}
|