1
+ import {
2
+ Chapter ,
3
+ ChapterDetails ,
4
+ HomeSection ,
5
+ Manga ,
6
+ MangaUpdates ,
7
+ PagedResults ,
8
+ Request ,
9
+ SearchRequest ,
10
+ Source ,
11
+ SourceInfo ,
12
+ TagSection ,
13
+ } from "paperback-extensions-common"
14
+ import { NovelCoolParser } from "./NovelCoolParser" ;
15
+
16
+ const BASE = "https://www.novelcool.com"
17
+
18
+ export const NovelCoolInfo : SourceInfo = {
19
+ icon : "icon.png" ,
20
+ version : "1.0.1" ,
21
+ name : "NovelCool" ,
22
+ author : "PythonCoderAS" ,
23
+ authorWebsite : "https://github.com/PythonCoderAS" ,
24
+ description : "Extension that pulls manga from NovelCool" ,
25
+ language : "en" ,
26
+ hentaiSource : false ,
27
+ websiteBaseURL : BASE
28
+ }
29
+
30
+ export class NovelCool extends Source {
31
+
32
+ private readonly parser : NovelCoolParser = new NovelCoolParser ( ) ;
33
+
34
+ getMangaShareUrl ( mangaId : string ) : string {
35
+ return `${ BASE } /novel/${ mangaId } .html` ;
36
+ }
37
+
38
+ async getTags ( ) : Promise < TagSection [ ] | null > {
39
+ const options : Request = createRequestObject ( {
40
+ url : `${ BASE } /search?name=awdasdsadsa` ,
41
+ method : 'GET'
42
+ } ) ;
43
+ let response = await this . requestManager . schedule ( options , 1 ) ;
44
+ let $ = this . cheerio . load ( response . data ) ;
45
+ return this . parser . parseGlobalTagList ( $ ) ;
46
+ }
47
+
48
+ async getHomePageSections ( sectionCallback : ( section : HomeSection ) => void ) : Promise < void > {
49
+ const options : Request = createRequestObject ( {
50
+ url : `${ BASE } ` ,
51
+ method : 'GET'
52
+ } ) ;
53
+ let response = await this . requestManager . schedule ( options , 1 ) ;
54
+ let $ = this . cheerio . load ( response . data ) ;
55
+ let carouselItems = this . parser . parseCarousel ( $ , BASE ) ;
56
+ sectionCallback ( createHomeSection ( {
57
+ id : "carousel" ,
58
+ title : "Popular" ,
59
+ items : carouselItems
60
+ } ) )
61
+ const sections = this . parser . parseHomepage ( $ , BASE ) ;
62
+ for ( let i = 0 ; i < sections . length ; i ++ ) {
63
+ const section = sections [ i ] ;
64
+ sectionCallback ( createHomeSection ( {
65
+ id : section . name . toLowerCase ( ) ,
66
+ title : section . name ,
67
+ items : section . items ,
68
+ view_more : true
69
+ } ) ) ;
70
+ }
71
+ }
72
+
73
+ async doGetWebsiteMangaDirectory ( page : number = 1 , end : number | null = null ) {
74
+ const options : Request = createRequestObject ( {
75
+ url : `${ BASE } /category/index_${ page } .html` ,
76
+ method : 'GET'
77
+ } ) ;
78
+ let response = await this . requestManager . schedule ( options , 1 ) ;
79
+ let $ = this . cheerio . load ( response . data ) ;
80
+ let results = this . parser . parseMangaListingPage ( $ , BASE ) ;
81
+ if ( ! end ) {
82
+ end = Number ( $ ( "div.dis-inline-block.para-h8" ) . first ( ) . text ( ) . trim ( ) )
83
+ for ( let i = 2 ; i <= end ; i ++ ) {
84
+ results = results . concat ( await this . doGetWebsiteMangaDirectory ( i , end ) )
85
+ }
86
+ }
87
+ return results ;
88
+ }
89
+
90
+ async getWebsiteMangaDirectory ( metadata : any ) : Promise < PagedResults > {
91
+ return createPagedResults ( {
92
+ results : await this . doGetWebsiteMangaDirectory ( )
93
+ } ) ;
94
+ }
95
+
96
+ async doGetPages ( chapterId : string , page : number = 1 , end : number | null = null ) : Promise < string [ ] > {
97
+ const options : Request = createRequestObject ( {
98
+ url : `${ BASE } /chapter/${ chapterId } -10-${ page } .html` ,
99
+ method : 'GET'
100
+ } ) ;
101
+ let response = await this . requestManager . schedule ( options , 1 ) ;
102
+ let $ : CheerioStatic = this . cheerio . load ( response . data ) ;
103
+ let pages : string [ ] = this . parser . parsePages ( $ ) ;
104
+ if ( end === null ) {
105
+ end = $ ( "select.sl-page option" ) . length
106
+ for ( let i = 2 ; i < end ; i ++ ) {
107
+ pages = pages . concat ( await this . doGetPages ( chapterId , page + 1 , end ) ) ;
108
+ }
109
+ }
110
+ return pages ;
111
+ }
112
+
113
+ async getChapterDetails ( mangaId : string , chapterId : string ) : Promise < ChapterDetails > {
114
+ return createChapterDetails ( {
115
+ id : chapterId ,
116
+ mangaId : mangaId ,
117
+ longStrip : false ,
118
+ pages : await this . doGetPages ( chapterId )
119
+ } ) ;
120
+ }
121
+
122
+ async getChapters ( mangaId : string ) : Promise < Chapter [ ] > {
123
+ const options : Request = createRequestObject ( {
124
+ url : this . getMangaShareUrl ( mangaId ) ,
125
+ method : 'GET'
126
+ } ) ;
127
+ let response = await this . requestManager . schedule ( options , 1 ) ;
128
+ let $ = this . cheerio . load ( response . data ) ;
129
+ return this . parser . parseChapterList ( $ , mangaId , BASE , this . convertTime ) ;
130
+ }
131
+
132
+ async getMangaDetails ( mangaId : string ) : Promise < Manga > {
133
+ const options : Request = createRequestObject ( {
134
+ url : this . getMangaShareUrl ( mangaId ) ,
135
+ method : 'GET'
136
+ } ) ;
137
+ let response = await this . requestManager . schedule ( options , 1 ) ;
138
+ let $ = this . cheerio . load ( response . data ) ;
139
+ return this . parser . parseManga ( $ , mangaId , BASE , this . convertTime ) ;
140
+ }
141
+
142
+ async doSearchRequest ( url : string , page : number = 1 , end : number | null = null ) {
143
+ const original_url = url ;
144
+ url += `&page=${ page } .html`
145
+ const options : Request = createRequestObject ( {
146
+ url : url ,
147
+ method : 'GET'
148
+ } ) ;
149
+ let response = await this . requestManager . schedule ( options , 1 ) ;
150
+ let $ = this . cheerio . load ( response . data ) ;
151
+ if ( $ ( "div.search-nores-hint" ) . length !== 0 ) {
152
+ return [ ] ;
153
+ } else {
154
+ let results = this . parser . parseMangaListingPage ( $ , BASE ) ;
155
+ if ( ! end ) {
156
+ end = Number ( $ ( "div.dis-inline-block.para-h8" ) . first ( ) . text ( ) . trim ( ) )
157
+ for ( let i = 2 ; i <= end ; i ++ ) {
158
+ results = results . concat ( await this . doSearchRequest ( original_url , i , end ) )
159
+ }
160
+ }
161
+ return results ;
162
+ }
163
+ }
164
+
165
+ async searchRequest ( query : SearchRequest , metadata : any ) : Promise < PagedResults > {
166
+ let url = `${ BASE } /search/?name_sel=contain`
167
+ if ( query . title ) {
168
+ url += `&name=${ query . title } ` ;
169
+ }
170
+ if ( query . author ) {
171
+ url += `&author_sel=contain&author=${ query . author } ` ;
172
+ }
173
+ return createPagedResults ( {
174
+ results : await this . doSearchRequest ( url )
175
+ } ) ;
176
+ }
177
+
178
+ async getViewMoreItems ( homepageSectionId : string , metadata : any ) : Promise < PagedResults > {
179
+ const options : Request = createRequestObject ( {
180
+ url : `${ BASE } /category/${ homepageSectionId } .html` ,
181
+ method : 'GET'
182
+ } ) ;
183
+ let response = await this . requestManager . schedule ( options , 1 ) ;
184
+ let $ = this . cheerio . load ( response . data ) ;
185
+ let results = this . parser . parseMangaListingPage ( $ , BASE ) ;
186
+ return createPagedResults ( {
187
+ results : results
188
+ } ) ;
189
+ }
190
+
191
+ async filterUpdatedManga ( mangaUpdatesFoundCallback : ( updates : MangaUpdates ) => void , time : Date , ids : string [ ] ) : Promise < void > {
192
+ mangaUpdatesFoundCallback ( createMangaUpdates ( {
193
+ ids : ids
194
+ } ) ) ;
195
+ }
196
+ }
0 commit comments