test one smart default parser
parent
e85fec9bbf
commit
d40a1f8fd4
56
main.go
56
main.go
|
|
@ -133,6 +133,11 @@ func Main(ctx context.Context) error {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
PatternGroupTitleHyphenSE = `^(\[[^\]]*\] )?(?P<title>.*?)( -)?[ \.](S(?P<season>[0-9]{2})E)?(?P<episode>[0-9]{2})[^0-9].*`
|
||||||
|
PatternTitleSE = `^(?P<title>.*) S(?P<season>[0-9]+)E(?P<episode>[0-9]+).*`
|
||||||
|
)
|
||||||
|
|
||||||
func Run(ctx context.Context, outd, ind string, patterns []string, overrides Fields, dry bool) error {
|
func Run(ctx context.Context, outd, ind string, patterns []string, overrides Fields, dry bool) error {
|
||||||
mvNLn := RealMvNLn
|
mvNLn := RealMvNLn
|
||||||
if dry {
|
if dry {
|
||||||
|
|
@ -141,10 +146,7 @@ func Run(ctx context.Context, outd, ind string, patterns []string, overrides Fie
|
||||||
return RunWith(ctx,
|
return RunWith(ctx,
|
||||||
outd,
|
outd,
|
||||||
ind,
|
ind,
|
||||||
append(patterns,
|
append(patterns, PatternGroupTitleHyphenSE, PatternTitleSE),
|
||||||
`^\[[^\]]*\] (?P<title>.*) - (?P<episode>[0-9]+).*`,
|
|
||||||
`^(?P<title>.*) S(?P<season>[0-9]+)E(?P<episode>[0-9]+).*`,
|
|
||||||
),
|
|
||||||
overrides,
|
overrides,
|
||||||
mvNLn,
|
mvNLn,
|
||||||
)
|
)
|
||||||
|
|
@ -171,28 +173,11 @@ func RunWith(ctx context.Context, outd, ind string, patterns []string, overrides
|
||||||
func one(ctx context.Context, outd, inf string, patterns []string, overrides Fields, mvNLn MvNLn) error {
|
func one(ctx context.Context, outd, inf string, patterns []string, overrides Fields, mvNLn MvNLn) error {
|
||||||
f := path.Base(inf)
|
f := path.Base(inf)
|
||||||
for _, pattern := range patterns {
|
for _, pattern := range patterns {
|
||||||
re := regexp.MustCompile(pattern)
|
found, match := Parse(f, pattern)
|
||||||
if !re.MatchString(f) {
|
if !match {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var found Fields
|
|
||||||
groupNames := re.SubexpNames()
|
|
||||||
groups := re.FindStringSubmatch(f)
|
|
||||||
for i := 1; i < len(groupNames); i++ {
|
|
||||||
v := groups[i]
|
|
||||||
switch groupNames[i] {
|
|
||||||
case "title":
|
|
||||||
found.Title = v
|
|
||||||
case "season":
|
|
||||||
found.Season = v
|
|
||||||
case "episode":
|
|
||||||
found.Episode = v
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unexpected capture group %q", groupNames[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, wr := range [][2]*string{
|
for _, wr := range [][2]*string{
|
||||||
[2]*string{&found.Title, &overrides.Title},
|
[2]*string{&found.Title, &overrides.Title},
|
||||||
[2]*string{&found.Season, &overrides.Season},
|
[2]*string{&found.Season, &overrides.Season},
|
||||||
|
|
@ -213,6 +198,31 @@ func one(ctx context.Context, outd, inf string, patterns []string, overrides Fie
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Parse(f string, pattern string) (Fields, bool) {
|
||||||
|
re := regexp.MustCompile(pattern)
|
||||||
|
if !re.MatchString(f) {
|
||||||
|
return Fields{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
var found Fields
|
||||||
|
groupNames := re.SubexpNames()
|
||||||
|
groups := re.FindStringSubmatch(f)
|
||||||
|
for i := 1; i < len(groupNames); i++ {
|
||||||
|
v := groups[i]
|
||||||
|
switch groupNames[i] {
|
||||||
|
case "title":
|
||||||
|
found.Title = v
|
||||||
|
case "season":
|
||||||
|
found.Season = v
|
||||||
|
case "episode":
|
||||||
|
found.Episode = v
|
||||||
|
default:
|
||||||
|
//return fmt.Errorf("unexpected capture group %q", groupNames[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found, true
|
||||||
|
}
|
||||||
|
|
||||||
func foundOne(ctx context.Context, outd, inf string, fields Fields, mvNLn MvNLn) error {
|
func foundOne(ctx context.Context, outd, inf string, fields Fields, mvNLn MvNLn) error {
|
||||||
tmpl, err := template.New(inf).Parse(outd)
|
tmpl, err := template.New(inf).Parse(outd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
98
main_test.go
98
main_test.go
|
|
@ -242,3 +242,101 @@ func ls(d string) []string {
|
||||||
slices.Sort(result)
|
slices.Sort(result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParse(t *testing.T) {
|
||||||
|
cases := map[string]struct {
|
||||||
|
pattern string
|
||||||
|
want main.Fields
|
||||||
|
}{
|
||||||
|
"[SubsPlease] Tokidoki Bosotto Russia-go de Dereru Tonari no Alya-san - 01 (720p) [A12844D5].mkv": {
|
||||||
|
pattern: main.PatternGroupTitleHyphenSE,
|
||||||
|
want: main.Fields{
|
||||||
|
Title: "Tokidoki Bosotto Russia-go de Dereru Tonari no Alya-san",
|
||||||
|
Season: "",
|
||||||
|
Episode: "01",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Survivor.AU.S12E11.1080p.HEVC.x265-MeGusta[EZTVx.to].mkv": {
|
||||||
|
pattern: main.PatternGroupTitleHyphenSE,
|
||||||
|
want: main.Fields{
|
||||||
|
Title: "Survivor.AU",
|
||||||
|
Season: "12",
|
||||||
|
Episode: "11",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"DAN DA DAN (2024) S01E01v2 (1080p WEB-DL H264 AAC DDP 2.0 Dual-Audio) [MALD].mkv": {
|
||||||
|
pattern: main.PatternGroupTitleHyphenSE,
|
||||||
|
want: main.Fields{
|
||||||
|
Title: "DAN DA DAN (2024)",
|
||||||
|
Season: "01",
|
||||||
|
Episode: "01",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ZENSHU.S01E01.1080p.AMZN.WEB-DL.MULTi.DDP2.0.H.264.MSubs-ToonsHub.mkv": {
|
||||||
|
pattern: main.PatternGroupTitleHyphenSE,
|
||||||
|
want: main.Fields{
|
||||||
|
Title: "ZENSHU",
|
||||||
|
Season: "01",
|
||||||
|
Episode: "01",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"[Yameii] My Hero Academia - S07E08 [English Dub] [CR WEB-DL 720p] [DE5FFC3E].mkv": {
|
||||||
|
pattern: main.PatternGroupTitleHyphenSE,
|
||||||
|
want: main.Fields{
|
||||||
|
Title: "My Hero Academia",
|
||||||
|
Season: "07",
|
||||||
|
Episode: "08",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Ranma1-2.2024.S01E03.Because.Theres.Someone.He.Likes.1080p.NF.WEB-DL.AAC2.0.H.264-VARYG.mkv": {
|
||||||
|
pattern: main.PatternGroupTitleHyphenSE,
|
||||||
|
want: main.Fields{
|
||||||
|
Title: "Ranma1-2.2024",
|
||||||
|
Season: "01",
|
||||||
|
Episode: "03",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"[Yameii] The Apothecary Diaries - S02E03 [English Dub] [CR WEB-DL 720p] [FD3E7434].mkv": {
|
||||||
|
pattern: main.PatternGroupTitleHyphenSE,
|
||||||
|
want: main.Fields{
|
||||||
|
Title: "The Apothecary Diaries",
|
||||||
|
Season: "02",
|
||||||
|
Episode: "03",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"The.Dinner.Table.Detective.S01E01.Welcome.to.the.murderous.party.File.1.1080p.AMZN.WEB-DL.DDP2.0.H.264-VARYG.mkv": {
|
||||||
|
pattern: main.PatternGroupTitleHyphenSE,
|
||||||
|
want: main.Fields{
|
||||||
|
Title: "The.Dinner.Table.Detective",
|
||||||
|
Season: "01",
|
||||||
|
Episode: "01",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"[Reza] Wistoria Wand and Sword - S01E01.mkv": {
|
||||||
|
pattern: main.PatternGroupTitleHyphenSE,
|
||||||
|
want: main.Fields{
|
||||||
|
Title: "Wistoria Wand and Sword",
|
||||||
|
Season: "01",
|
||||||
|
Episode: "01",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"[EMBER] Ao no Hako - 01.mkv": {
|
||||||
|
pattern: main.PatternGroupTitleHyphenSE,
|
||||||
|
want: main.Fields{
|
||||||
|
Title: "Ao no Hako",
|
||||||
|
Season: "",
|
||||||
|
Episode: "01",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for f, d := range cases {
|
||||||
|
c := d
|
||||||
|
t.Run(f, func(t *testing.T) {
|
||||||
|
got, _ := main.Parse(f, c.pattern)
|
||||||
|
if got != c.want {
|
||||||
|
t.Errorf("expected \n\t%+v but got \n\t%+v", c.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue