From 88e518057cc395a3b40222c9329e664bd2d11f9e Mon Sep 17 00:00:00 2001 From: D3ICIDE <183315953+D3ICIDE@users.noreply.github.com> Date: Tue, 6 Oct 2026 21:44:44 +0530 Subject: [PATCH 1/2] left novelbin and novelarrow untouched --- .../readnovelfull/filters/novelping.json | 238 ++++++++++++++++++ plugins/multisrc/readnovelfull/sources.json | 11 + plugins/multisrc/readnovelfull/template.ts | 30 +-- .../multisrc/readnovelfull/novelping/icon.png | Bin 0 -> 2965 bytes 4 files changed, 255 insertions(+), 24 deletions(-) create mode 100644 plugins/multisrc/readnovelfull/filters/novelping.json create mode 100644 public/static/multisrc/readnovelfull/novelping/icon.png diff --git a/plugins/multisrc/readnovelfull/filters/novelping.json b/plugins/multisrc/readnovelfull/filters/novelping.json new file mode 100644 index 000000000..6181fe0f8 --- /dev/null +++ b/plugins/multisrc/readnovelfull/filters/novelping.json @@ -0,0 +1,238 @@ +{ + "filters": { + "type": { + "type": "Picker", + "label": "Novel Listing", + "value": "sort/popular", + "options": [ + { + "label": "Hot Novel", + "value": "sort/hot" + }, + { + "label": "Completed Novel", + "value": "sort/complete" + }, + { + "label": "Most Popular", + "value": "sort/popular" + } + ] + }, + "genres": { + "type": "Picker", + "label": "Genre (Cancels out 'Novel Listing')", + "value": "", + "options": [ + { + "label": "Action", + "value": "novelping-genres/action" + }, + { + "label": "Adventure", + "value": "novelping-genres/adventure" + }, + { + "label": "Anime & comics", + "value": "novelping-genres/anime-&-comics" + }, + { + "label": "Comedy", + "value": "novelping-genres/comedy" + }, + { + "label": "Drama", + "value": "novelping-genres/drama" + }, + { + "label": "Eastern", + "value": "novelping-genres/eastern" + }, + { + "label": "Fan-fic", + "value": "novelping-genres/fan-fic" + }, + { + "label": "Fan-fiction", + "value": "novelping-genres/fan-fiction" + }, + { + "label": "Fantasy", + "value": "novelping-genres/fantasy" + }, + { + "label": "Game", + "value": "novelping-genres/game" + }, + { + "label": "Gender bender", + "value": "novelping-genres/gender-bender" + }, + { + "label": "Harem", + "value": "novelping-genres/harem" + }, + { + "label": "Historical", + "value": "novelping-genres/historical" + }, + { + "label": "Horror", + "value": "novelping-genres/horror" + }, + { + "label": "Isekai", + "value": "novelping-genres/isekai" + }, + { + "label": "Josei", + "value": "novelping-genres/josei" + }, + { + "label": "Litrpg", + "value": "novelping-genres/litrpg" + }, + { + "label": "Magic", + "value": "novelping-genres/magic" + }, + { + "label": "Magical realism", + "value": "novelping-genres/magical-realism" + }, + { + "label": "Martial arts", + "value": "novelping-genres/martial-arts" + }, + { + "label": "Mature", + "value": "novelping-genres/mature" + }, + { + "label": "Mecha", + "value": "novelping-genres/mecha" + }, + { + "label": "Military", + "value": "novelping-genres/military" + }, + { + "label": "Modern life", + "value": "novelping-genres/modern-life" + }, + { + "label": "Mystery", + "value": "novelping-genres/mystery" + }, + { + "label": "Psychological", + "value": "novelping-genres/psychological" + }, + { + "label": "Realistic", + "value": "novelping-genres/realistic" + }, + { + "label": "Reincarnation", + "value": "novelping-genres/reincarnation" + }, + { + "label": "Romance", + "value": "novelping-genres/romance" + }, + { + "label": "School life", + "value": "novelping-genres/school-life" + }, + { + "label": "Sci-fi", + "value": "novelping-genres/sci-fi" + }, + { + "label": "Seinen", + "value": "novelping-genres/seinen" + }, + { + "label": "Shoujo", + "value": "novelping-genres/shoujo" + }, + { + "label": "Shoujo ai", + "value": "novelping-genres/shoujo-ai" + }, + { + "label": "Shounen", + "value": "novelping-genres/shounen" + }, + { + "label": "Shounen ai", + "value": "novelping-genres/shounen-ai" + }, + { + "label": "Slice of life", + "value": "novelping-genres/slice-of-life" + }, + { + "label": "Smut", + "value": "novelping-genres/smut" + }, + { + "label": "Sports", + "value": "novelping-genres/sports" + }, + { + "label": "Supernatural", + "value": "novelping-genres/supernatural" + }, + { + "label": "System", + "value": "novelping-genres/system" + }, + { + "label": "Thriller", + "value": "novelping-genres/thriller" + }, + { + "label": "Tragedy", + "value": "novelping-genres/tragedy" + }, + { + "label": "Urban", + "value": "novelping-genres/urban" + }, + { + "label": "Urban fantasy", + "value": "novelping-genres/urban-fantasy" + }, + { + "label": "Video games", + "value": "novelping-genres/video-games" + }, + { + "label": "War", + "value": "novelping-genres/war" + }, + { + "label": "Wuxia", + "value": "novelping-genres/wuxia" + }, + { + "label": "Xianxia", + "value": "novelping-genres/xianxia" + }, + { + "label": "Xuanhuan", + "value": "novelping-genres/xuanhuan" + }, + { + "label": "Yaoi", + "value": "novelping-genres/yaoi" + }, + { + "label": "Yuri", + "value": "novelping-genres/yuri" + } + ] + } + } +} \ No newline at end of file diff --git a/plugins/multisrc/readnovelfull/sources.json b/plugins/multisrc/readnovelfull/sources.json index dba4c9787..31189bf08 100644 --- a/plugins/multisrc/readnovelfull/sources.json +++ b/plugins/multisrc/readnovelfull/sources.json @@ -81,6 +81,17 @@ "customJs": "$('[class*=\"app-promo\"]').remove();" } }, + { + "id": "novelping", + "sourceSite": "https://novelping.com/", + "sourceName": "Novel Ping", + "options": { + "latestPage": "sort/updates", + "searchPage": "search", + "versionIncrements": 0, + "customJs": "$('[class*=\"app-promo\"]').remove();" + } + }, { "id": "FWN.com", "sourceSite": "https://freewebnovel.com/", diff --git a/plugins/multisrc/readnovelfull/template.ts b/plugins/multisrc/readnovelfull/template.ts index 3da6e4891..188c918bc 100644 --- a/plugins/multisrc/readnovelfull/template.ts +++ b/plugins/multisrc/readnovelfull/template.ts @@ -26,7 +26,6 @@ type ReadNovelFullOptions = { pageAsPath?: boolean; customJs?: string; chapterListPaginated?: boolean; - imageReferer?: boolean; }; export type ReadNovelFullMetadata = { @@ -45,7 +44,6 @@ export class ReadNovelFullPlugin implements Plugin.PluginBase { version: string; options: ReadNovelFullOptions; filters?: Filters | undefined; - imageRequestInit?: Plugin.ImageRequestInit; constructor(metadata: ReadNovelFullMetadata) { this.id = metadata.id; @@ -56,13 +54,6 @@ export class ReadNovelFullPlugin implements Plugin.PluginBase { this.version = `2.2.${1 + versionIncrements}`; this.options = metadata.options; this.filters = metadata.filters; - if (this.options?.imageReferer) { - this.imageRequestInit = { - headers: { - 'Referer': this.site, - }, - }; - } } lastSearch: number | null = null; @@ -103,12 +94,7 @@ export class ReadNovelFullPlugin implements Plugin.PluginBase { switch (name) { case 'img': { - const cover = [ - attribs['data-src'], - attribs['data-cfsrc'], - attribs['data-original'], - attribs.src, - ].find(attr => attr && !attr.startsWith('data:')); + const cover = attribs['data-src'] || attribs.src; if (cover) { tempNovel.cover = new URL(cover, this.site).href; } @@ -429,12 +415,8 @@ export class ReadNovelFullPlugin implements Plugin.PluginBase { break; case 'img': if (state === ParsingState.Cover) { - const cover = [ - attribs['data-src'], - attribs['data-cfsrc'], - attribs['data-original'], - attribs.src, - ].find(attr => attr && !attr.startsWith('data:')); + const cover = + attribs.src ?? attribs['data-cfsrc'] ?? attribs['data-src']; const name = attribs.title; if (cover) { novel.cover = new URL(cover, this.site).href; @@ -710,9 +692,9 @@ export class ReadNovelFullPlugin implements Plugin.PluginBase { } if (chapterHref !== undefined) { - const path = chapterHref.startsWith('/') - ? chapterHref.slice(1) - : chapterHref.replace(this.site + '/', ''); + const path = new URL(chapterHref, this.site).pathname.substring( + 1, + ); tempAjaxChapter.path = path; tempAjaxChapter.name = initialName; } diff --git a/public/static/multisrc/readnovelfull/novelping/icon.png b/public/static/multisrc/readnovelfull/novelping/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..02a2d652430ed8859d505bc63a5da7f62db4ff65 GIT binary patch literal 2965 zcmeHIi8s`b7XJ=ojAbb6gp4K92xFTv{0M^?*_R|nLx{2rMieoWEXk5&33--z%F-ZX z4Q0vLmnb9q77;32$n!hzym!t!=e+l~GCx$kWmY5g|Sv z4mMC@LrvwYm(;wRjMT)KFh5s2<39x14}NWb|F%3oJw7_r{kE#;*`tU6_siO6Po0GQ z-rw8Z+5EY_@?~yn>|<|dYjyrDCnJ`D+K2vE4AkW|W|+^fib3nT+OUeETwAN3D&icu zS=VyCIs40_Wjj1CNb&bv({2Cod8sgJF!17yp!><$jM;Y()9VkKc!eEE@QEJ+)=!RG zJO!Kh%G*23NO+i)JPyX6X{PDivy@ycPVmBgjc-XSySp&*zHd_B+=l4p6MpQ3txIUE zc-HITH<_2{x5??#f-6}^gR_(IrUvZGoRDK|LJ_v-2uC3qvcYAtt25aRbIsrF2mlq7 z3R*!KrGP@)D5Ehbb&QI#JPL(Dp@KNmw*G_Q?d$64e*1qDAa+W|M+CWlcOZLuy9JP) zy-ELtqw>!t#Fqk40D#osvAQ-M6RV?3c8@&;0MbB~MKU+vwwi0>wZ3G$08# zlVk^_DV;6?+ubhco6Rx+c<J>jS~y`89!Qu(lysE#k~i;WZ>uQIRRLrPOK?Jk|q zAWWTDbXuqAXRWVp(KEc?Dv*?q_#2x**aSeQmG7W}FekjOod_v7qr)gX>k=xF*DZ6V zX$e4ymcJ?0^LCEwKYkE6VvB&yuB!{V%4W)8xrn_sZmapHk~>8U89>iBg7Z zSrW}d(F2cPM3P?? zz3}vf(z@jm5XJp=$hxKG6oYE--~9za2sD!E|K>reFFOeVT}^H`8(eW;?OYf=MY~(y zIGh3iwX_yv>MfZRaMV0YJS2V`y^$*03{D65i7X}*4ixBL&hJ;i#s^u!U2+^XUzs|q zsl8syTC$X1kR@A;&X!sR(R@G=6{<$P#%Q5tXRj6j&Fw_9^xx_@VNaxpUgAy4mNN~~ zNFz7qT`XCl(;6*W6@=*Ft1Vw49}o?M%iRifMDKx8fgsx~bIjsnMbqvP)_w~Q6Ahuo zE_wb!LW2!qQn#+;Mj#wP@~|by27a)+T9+=1oZX$F&BN8=&=FLLKR~A^7s3rfhqbX_Ny6w9Awt|1RIQTf6G+te%WNrXz`$$b|X7;)%MLfU&n3! z4fr1{0@)Y_-5vM*r&ZI=sib$4q>CY&BM@!2V5`sJc&708l)Kih(7Nl1F+;L+o6ah` zdE>6TO##@DJN=Tld^LAL%jz|-*GS`}7-ZJWU?o--mlpkkn!w(7gAX4JDiCZ zZ@;8{$E5T2cbk2at%k{=@v4ZJH4c3%*hO=L2b)u|u(EGC2YqgRt>(|?lEigh#^04w zwzlI39~yK?%xAtFV&-kn7bkr5WnR|I=A2!RPdzTjsB+8SSj2j_8>Sl+# zoVdQ44Xbw&ySTLV2n=oBjZd{afzb3M-$~Bs1_k67u)V!|(s$%UEp_<*VUdQoQ_8}x zGO5HT&Yo<`XXWm2MN~6?M4__D)#Ny z`gIOzXR=2A%ZJ|N_`|C$&AP1xe2F=>XuXcyiR)|M5_2%SQ0(x@aWoP)yHnZAq576y z5Lh;#&e`)OcThlmU~MloW6Ka%y4tLdsn@A^Ah3Lh%yfy_EZ2ncefCkC;u`cw4V}=a zc%?MB8(LwTZ)))b@#GQt= Date: Tue, 6 Oct 2026 22:05:54 +0530 Subject: [PATCH 2/2] revert --- plugins/multisrc/readnovelfull/template.ts | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/plugins/multisrc/readnovelfull/template.ts b/plugins/multisrc/readnovelfull/template.ts index 188c918bc..f1e9a76bb 100644 --- a/plugins/multisrc/readnovelfull/template.ts +++ b/plugins/multisrc/readnovelfull/template.ts @@ -26,6 +26,7 @@ type ReadNovelFullOptions = { pageAsPath?: boolean; customJs?: string; chapterListPaginated?: boolean; + imageReferer?: boolean; }; export type ReadNovelFullMetadata = { @@ -44,6 +45,7 @@ export class ReadNovelFullPlugin implements Plugin.PluginBase { version: string; options: ReadNovelFullOptions; filters?: Filters | undefined; + imageRequestInit?: Plugin.ImageRequestInit; constructor(metadata: ReadNovelFullMetadata) { this.id = metadata.id; @@ -54,6 +56,13 @@ export class ReadNovelFullPlugin implements Plugin.PluginBase { this.version = `2.2.${1 + versionIncrements}`; this.options = metadata.options; this.filters = metadata.filters; + if (this.options?.imageReferer) { + this.imageRequestInit = { + headers: { + 'Referer': this.site, + }, + }; + } } lastSearch: number | null = null; @@ -94,7 +103,12 @@ export class ReadNovelFullPlugin implements Plugin.PluginBase { switch (name) { case 'img': { - const cover = attribs['data-src'] || attribs.src; + const cover = [ + attribs['data-src'], + attribs['data-cfsrc'], + attribs['data-original'], + attribs.src, + ].find(attr => attr && !attr.startsWith('data:')); if (cover) { tempNovel.cover = new URL(cover, this.site).href; } @@ -415,8 +429,12 @@ export class ReadNovelFullPlugin implements Plugin.PluginBase { break; case 'img': if (state === ParsingState.Cover) { - const cover = - attribs.src ?? attribs['data-cfsrc'] ?? attribs['data-src']; + const cover = [ + attribs['data-src'], + attribs['data-cfsrc'], + attribs['data-original'], + attribs.src, + ].find(attr => attr && !attr.startsWith('data:')); const name = attribs.title; if (cover) { novel.cover = new URL(cover, this.site).href;