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