forked from metafates/mangal
-
Notifications
You must be signed in to change notification settings - Fork 1
/
options.go
128 lines (108 loc) 路 2.82 KB
/
options.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package inline
import (
"fmt"
"github.com/belphemur/mangal/source"
"github.com/belphemur/mangal/util"
"github.com/samber/lo"
"github.com/samber/mo"
"io"
"regexp"
"strconv"
"strings"
)
type (
MangaPicker func([]*source.Manga) *source.Manga
ChaptersFilter func([]*source.Chapter) ([]*source.Chapter, error)
)
type Options struct {
Out io.Writer
Sources []source.Source
IncludeAnilistManga bool
Download bool
Json bool
PopulatePages bool
Query string
MangaPicker mo.Option[MangaPicker]
ChaptersFilter mo.Option[ChaptersFilter]
}
func ParseMangaPicker(query, description string) (MangaPicker, error) {
const (
first = "first"
last = "last"
exact = "exact"
)
pattern := fmt.Sprintf(`^(%s|%s|%s|\d+)$`, first, last, exact)
mangaPickerRegex := regexp.MustCompile(pattern)
if !mangaPickerRegex.MatchString(description) {
return nil, fmt.Errorf("invalid manga picker pattern: %s", description)
}
return func(mangas []*source.Manga) *source.Manga {
if len(mangas) == 0 {
return nil
}
switch description {
case first:
return mangas[0]
case last:
return mangas[len(mangas)-1]
case exact:
for _, manga := range mangas {
if manga.Name == query {
return manga
}
}
return nil
default:
index := lo.Must(strconv.ParseUint(description, 10, 16))
return mangas[util.Min(index, uint64(len(mangas)-1))]
}
}, nil
}
func ParseChaptersFilter(description string) (ChaptersFilter, error) {
const (
first = "first"
last = "last"
all = "all"
from = "From"
to = "To"
sub = "Sub"
)
pattern := fmt.Sprintf(`^(%s|%s|%s|(?P<%s>\d+)(-(?P<%s>\d+))?|@(?P<%s>.+)@)$`, first, last, all, from, to, sub)
mangaPickerRegex := regexp.MustCompile(pattern)
if !mangaPickerRegex.MatchString(description) {
return nil, fmt.Errorf("invalid chapter filter pattern: %s", description)
}
return func(chapters []*source.Chapter) ([]*source.Chapter, error) {
maxIndex := len(chapters) - 1
if maxIndex == 0 {
return chapters, nil
}
switch description {
case first:
return chapters[0:1], nil
case last:
return chapters[maxIndex:], nil
case all:
return chapters, nil
default:
groups := util.ReGroups(mangaPickerRegex, description)
if sub, ok := groups[sub]; ok && sub != "" {
return lo.Filter(chapters, func(a *source.Chapter, _ int) bool {
return strings.Contains(a.Name, sub)
}), nil
}
from := lo.Must(strconv.ParseUint(groups[from], 10, 16))
from = util.Min(from, uint64(maxIndex))
n := groups[to]
if n == "" {
return []*source.Chapter{chapters[from]}, nil
}
to := lo.Must(strconv.ParseUint(n, 10, 16))
to = util.Min(to, uint64(maxIndex))
if from > to {
from, to = to, from
}
return chapters[from : to+1], nil
}
}, nil
}