-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathoptions.go
214 lines (178 loc) · 5.89 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
package libmangal
import (
"fmt"
"github.com/philippgille/gokv"
"github.com/philippgille/gokv/syncmap"
"github.com/spf13/afero"
"net/http"
)
// DownloadOptions configures Chapter downloading
type DownloadOptions struct {
// Format in which a chapter must be downloaded
Format Format
// Directory is the directory where manga will be downloaded to
Directory string
// CreateMangaDir will create manga directory
CreateMangaDir bool
// CreateVolumeDir will create volume directory.
//
// If CreateMangaDir is also true, volume directory
// will be created under it.
CreateVolumeDir bool
// Strict means that that if during metadata creation
// error occurs downloader will return it immediately and chapter
// won't be downloaded
Strict bool
// SkipIfExists will skip downloading chapter if its already downloaded (exists at path)
//
// However, metadata will still be created if needed.
SkipIfExists bool
// DownloadMangaCover or not. Will not download cover again if its already downloaded.
DownloadMangaCover bool
// DownloadMangaBanner or not. Will not download banner again if its already downloaded.
DownloadMangaBanner bool
// WriteSeriesJson write metadata series.json file in the manga directory
WriteSeriesJson bool
// WriteComicInfoXml write metadata ComicInfo.xml file to the .cbz archive when
// downloading with FormatCBZ
WriteComicInfoXml bool
// ReadAfter will open the chapter for reading after it was downloaded.
// It will use os default app for resulting mimetype.
//
// E.g. `xdg-open` for Linux.
//
// It will also sync read chapter with your Anilist profile
// if it's configured. See also ReadIncognito
//
// Note, that underlying filesystem must be mapped with OsFs
// in order for os to open it.
ReadAfter bool
// ReadIncognito won't sync Anilist reading history if ReadAfter is enabled.
ReadIncognito bool
// ComicInfoXMLOptions options to use for ComicInfo.xml when WriteComicInfoXml is true
ComicInfoXMLOptions ComicInfoXMLOptions
// ImageTransformer is applied for each image for the chapter.
//
// E.g. grayscale effect
ImageTransformer func([]byte) ([]byte, error)
}
// DefaultDownloadOptions constructs default DownloadOptions
func DefaultDownloadOptions() DownloadOptions {
return DownloadOptions{
Format: FormatPDF,
Directory: ".",
CreateMangaDir: true,
CreateVolumeDir: false,
Strict: true,
SkipIfExists: true,
DownloadMangaCover: false,
DownloadMangaBanner: false,
WriteSeriesJson: false,
WriteComicInfoXml: false,
ReadAfter: false,
ReadIncognito: false,
ImageTransformer: func(img []byte) ([]byte, error) {
return img, nil
},
ComicInfoXMLOptions: DefaultComicInfoOptions(),
}
}
// AnilistOptions is options for Anilist client
type AnilistOptions struct {
// HTTPClient is a http client used for Anilist API
HTTPClient *http.Client
// QueryToIDsStore maps query to ids.
// single query to multiple ids.
//
// ["berserk" => [7, 42, 69], "death note" => [887, 3, 134]]
QueryToIDsStore gokv.Store
// TitleToIDStore maps title to id.
// single title to single id.
//
// ["berserk" => 7, "death note" => 3]
TitleToIDStore gokv.Store
// IDToMangaStore maps id to manga.
// single id to single manga.
//
// [7 => "{title: ..., image: ..., ...}"]
IDToMangaStore gokv.Store
AccessTokenStore gokv.Store
// Log logs progress
Log LogFunc
}
// DefaultAnilistOptions constructs default AnilistOptions
func DefaultAnilistOptions() AnilistOptions {
return AnilistOptions{
Log: func(string) {},
HTTPClient: &http.Client{},
QueryToIDsStore: syncmap.NewStore(syncmap.DefaultOptions),
TitleToIDStore: syncmap.NewStore(syncmap.DefaultOptions),
IDToMangaStore: syncmap.NewStore(syncmap.DefaultOptions),
AccessTokenStore: syncmap.NewStore(syncmap.DefaultOptions),
}
}
// ClientOptions is options that client would use during its runtime.
// See DefaultClientOptions
type ClientOptions struct {
// HTTPClient is http client that client would use for requests
HTTPClient *http.Client
// FS is a file system abstraction
// that the client will use.
FS afero.Fs
// ChapterNameTemplate defines how mangas filenames will look when downloaded.
MangaNameTemplate func(
provider string,
manga Manga,
) string
// ChapterNameTemplate defines how volumes filenames will look when downloaded.
// E.g. Vol. 1
VolumeNameTemplate func(
provider string,
volume Volume,
) string
// ChapterNameTemplate defines how chapters filenames will look when downloaded.
// E.g. "[001] chapter 1" or "Chainsaw Man - Ch. 1"
ChapterNameTemplate func(
provider string,
chapter Chapter,
) string
// Log is a function that will be passed to the provider
// to serve as a progress writer
Log LogFunc
// Anilist is the Anilist client to use
Anilist *Anilist
}
// DefaultClientOptions constructs default ClientOptions
func DefaultClientOptions() ClientOptions {
anilist := NewAnilist(DefaultAnilistOptions())
return ClientOptions{
HTTPClient: &http.Client{},
FS: afero.NewOsFs(),
ChapterNameTemplate: func(_ string, chapter Chapter) string {
info := chapter.Info()
number := fmt.Sprintf("%06.1f", info.Number)
return sanitizePath(fmt.Sprintf("[%s] %s", number, info.Title))
},
MangaNameTemplate: func(_ string, manga Manga) string {
return sanitizePath(manga.Info().Title)
},
VolumeNameTemplate: func(_ string, volume Volume) string {
return sanitizePath(fmt.Sprintf("Vol. %d", volume.Info().Number))
},
Log: func(string) {},
Anilist: &anilist,
}
}
// ComicInfoXMLOptions tweaks ComicInfoXML generation
type ComicInfoXMLOptions struct {
// AddDate whether to add series release date or not
AddDate bool
// AlternativeDate use other date
AlternativeDate *Date
}
// DefaultComicInfoOptions constructs default ComicInfoXMLOptions
func DefaultComicInfoOptions() ComicInfoXMLOptions {
return ComicInfoXMLOptions{
AddDate: true,
}
}