diff --git a/plugins/multisrc/lightnovelworld/sources.json b/plugins/multisrc/lightnovelworld/sources.json deleted file mode 100644 index 922937c4e..000000000 --- a/plugins/multisrc/lightnovelworld/sources.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "id": "webnovelworld", - "sourceName": "Web Novel Pub", - "sourceSite": "https://www.webnovelworld.org/" - }, - { - "id": "lightnovelpubvip", - "sourceName": "LightNovelPub Vip", - "sourceSite": "https://lightnovelpub.vip/" - }, - { - "id": "lightnovelcave", - "sourceName": "LightNovelCave", - "sourceSite": "https://www.lightnovelcave.com/" - } -] diff --git a/plugins/multisrc/webnovelworld/filters/lightnovelcave.json b/plugins/multisrc/webnovelworld/filters/lightnovelcave.json new file mode 100644 index 000000000..99078231d --- /dev/null +++ b/plugins/multisrc/webnovelworld/filters/lightnovelcave.json @@ -0,0 +1,73 @@ +{ + "filters": { + "order": { + "value": "popular", + "label": "Order by", + "options": [ + { "label": "New", "value": "new" }, + { "label": "Popular", "value": "popular" }, + { "label": "Updates", "value": "updated" } + ], + "type": "Picker" + }, + "status": { + "value": "all", + "label": "Status", + "options": [ + { "label": "All", "value": "all" }, + { "label": "Completed", "value": "completed" }, + { "label": "Ongoing", "value": "ongoing" } + ], + "type": "Picker" + }, + "genres": { + "value": "all", + "label": "Genre", + "options": [ + { "label": "All", "value": "all" }, + { "label": "Action", "value": "action" }, + { "label": "Adventure", "value": "adventure" }, + { "label": "Drama", "value": "drama" }, + { "label": "Fantasy", "value": "fantasy" }, + { "label": "Harem", "value": "harem" }, + { "label": "Martial Arts", "value": "martial-arts" }, + { "label": "Mature", "value": "mature" }, + { "label": "Romance", "value": "romance" }, + { "label": "Tragedy", "value": "tragedy" }, + { "label": "Xuanhuan", "value": "xuanhuan" }, + { "label": "Ecchi", "value": "ecchi" }, + { "label": "Comedy", "value": "comedy" }, + { "label": "Slice of Life", "value": "slice-of-life" }, + { "label": "Mystery", "value": "mystery" }, + { "label": "Supernatural", "value": "supernatural" }, + { "label": "Psychological", "value": "psychological" }, + { "label": "Sci-fi", "value": "sci-fi" }, + { "label": "Xianxia", "value": "xianxia" }, + { "label": "School Life", "value": "school-life" }, + { "label": "Josei", "value": "josei" }, + { "label": "Wuxia", "value": "wuxia" }, + { "label": "Shounen", "value": "shounen" }, + { "label": "Horror", "value": "horror" }, + { "label": "Mecha", "value": "mecha" }, + { "label": "Historical", "value": "historical" }, + { "label": "Shoujo", "value": "shoujo" }, + { "label": "Adult", "value": "adult" }, + { "label": "Seinen", "value": "seinen" }, + { "label": "Sports", "value": "sports" }, + { "label": "Lolicon", "value": "lolicon" }, + { "label": "Gender Bender", "value": "gender-bender" }, + { "label": "Shounen Ai", "value": "shounen-ai" }, + { "label": "Yaoi", "value": "yaoi" }, + { "label": "Video Games", "value": "video-games" }, + { "label": "Smut", "value": "smut" }, + { "label": "Magical Realism", "value": "magical-realism" }, + { "label": "Eastern Fantasy", "value": "eastern-fantasy" }, + { "label": "Contemporary Romance", "value": "contemporary-romance" }, + { "label": "Fantasy Romance", "value": "fantasy-romance" }, + { "label": "Shoujo Ai", "value": "shoujo-ai" }, + { "label": "Yuri", "value": "yuri" } + ], + "type": "Picker" + } + } +} diff --git a/plugins/multisrc/webnovelworld/filters/lightnovelpubvip.json b/plugins/multisrc/webnovelworld/filters/lightnovelpubvip.json new file mode 100644 index 000000000..99078231d --- /dev/null +++ b/plugins/multisrc/webnovelworld/filters/lightnovelpubvip.json @@ -0,0 +1,73 @@ +{ + "filters": { + "order": { + "value": "popular", + "label": "Order by", + "options": [ + { "label": "New", "value": "new" }, + { "label": "Popular", "value": "popular" }, + { "label": "Updates", "value": "updated" } + ], + "type": "Picker" + }, + "status": { + "value": "all", + "label": "Status", + "options": [ + { "label": "All", "value": "all" }, + { "label": "Completed", "value": "completed" }, + { "label": "Ongoing", "value": "ongoing" } + ], + "type": "Picker" + }, + "genres": { + "value": "all", + "label": "Genre", + "options": [ + { "label": "All", "value": "all" }, + { "label": "Action", "value": "action" }, + { "label": "Adventure", "value": "adventure" }, + { "label": "Drama", "value": "drama" }, + { "label": "Fantasy", "value": "fantasy" }, + { "label": "Harem", "value": "harem" }, + { "label": "Martial Arts", "value": "martial-arts" }, + { "label": "Mature", "value": "mature" }, + { "label": "Romance", "value": "romance" }, + { "label": "Tragedy", "value": "tragedy" }, + { "label": "Xuanhuan", "value": "xuanhuan" }, + { "label": "Ecchi", "value": "ecchi" }, + { "label": "Comedy", "value": "comedy" }, + { "label": "Slice of Life", "value": "slice-of-life" }, + { "label": "Mystery", "value": "mystery" }, + { "label": "Supernatural", "value": "supernatural" }, + { "label": "Psychological", "value": "psychological" }, + { "label": "Sci-fi", "value": "sci-fi" }, + { "label": "Xianxia", "value": "xianxia" }, + { "label": "School Life", "value": "school-life" }, + { "label": "Josei", "value": "josei" }, + { "label": "Wuxia", "value": "wuxia" }, + { "label": "Shounen", "value": "shounen" }, + { "label": "Horror", "value": "horror" }, + { "label": "Mecha", "value": "mecha" }, + { "label": "Historical", "value": "historical" }, + { "label": "Shoujo", "value": "shoujo" }, + { "label": "Adult", "value": "adult" }, + { "label": "Seinen", "value": "seinen" }, + { "label": "Sports", "value": "sports" }, + { "label": "Lolicon", "value": "lolicon" }, + { "label": "Gender Bender", "value": "gender-bender" }, + { "label": "Shounen Ai", "value": "shounen-ai" }, + { "label": "Yaoi", "value": "yaoi" }, + { "label": "Video Games", "value": "video-games" }, + { "label": "Smut", "value": "smut" }, + { "label": "Magical Realism", "value": "magical-realism" }, + { "label": "Eastern Fantasy", "value": "eastern-fantasy" }, + { "label": "Contemporary Romance", "value": "contemporary-romance" }, + { "label": "Fantasy Romance", "value": "fantasy-romance" }, + { "label": "Shoujo Ai", "value": "shoujo-ai" }, + { "label": "Yuri", "value": "yuri" } + ], + "type": "Picker" + } + } +} diff --git a/plugins/multisrc/webnovelworld/filters/webnovelworld.json b/plugins/multisrc/webnovelworld/filters/webnovelworld.json new file mode 100644 index 000000000..99078231d --- /dev/null +++ b/plugins/multisrc/webnovelworld/filters/webnovelworld.json @@ -0,0 +1,73 @@ +{ + "filters": { + "order": { + "value": "popular", + "label": "Order by", + "options": [ + { "label": "New", "value": "new" }, + { "label": "Popular", "value": "popular" }, + { "label": "Updates", "value": "updated" } + ], + "type": "Picker" + }, + "status": { + "value": "all", + "label": "Status", + "options": [ + { "label": "All", "value": "all" }, + { "label": "Completed", "value": "completed" }, + { "label": "Ongoing", "value": "ongoing" } + ], + "type": "Picker" + }, + "genres": { + "value": "all", + "label": "Genre", + "options": [ + { "label": "All", "value": "all" }, + { "label": "Action", "value": "action" }, + { "label": "Adventure", "value": "adventure" }, + { "label": "Drama", "value": "drama" }, + { "label": "Fantasy", "value": "fantasy" }, + { "label": "Harem", "value": "harem" }, + { "label": "Martial Arts", "value": "martial-arts" }, + { "label": "Mature", "value": "mature" }, + { "label": "Romance", "value": "romance" }, + { "label": "Tragedy", "value": "tragedy" }, + { "label": "Xuanhuan", "value": "xuanhuan" }, + { "label": "Ecchi", "value": "ecchi" }, + { "label": "Comedy", "value": "comedy" }, + { "label": "Slice of Life", "value": "slice-of-life" }, + { "label": "Mystery", "value": "mystery" }, + { "label": "Supernatural", "value": "supernatural" }, + { "label": "Psychological", "value": "psychological" }, + { "label": "Sci-fi", "value": "sci-fi" }, + { "label": "Xianxia", "value": "xianxia" }, + { "label": "School Life", "value": "school-life" }, + { "label": "Josei", "value": "josei" }, + { "label": "Wuxia", "value": "wuxia" }, + { "label": "Shounen", "value": "shounen" }, + { "label": "Horror", "value": "horror" }, + { "label": "Mecha", "value": "mecha" }, + { "label": "Historical", "value": "historical" }, + { "label": "Shoujo", "value": "shoujo" }, + { "label": "Adult", "value": "adult" }, + { "label": "Seinen", "value": "seinen" }, + { "label": "Sports", "value": "sports" }, + { "label": "Lolicon", "value": "lolicon" }, + { "label": "Gender Bender", "value": "gender-bender" }, + { "label": "Shounen Ai", "value": "shounen-ai" }, + { "label": "Yaoi", "value": "yaoi" }, + { "label": "Video Games", "value": "video-games" }, + { "label": "Smut", "value": "smut" }, + { "label": "Magical Realism", "value": "magical-realism" }, + { "label": "Eastern Fantasy", "value": "eastern-fantasy" }, + { "label": "Contemporary Romance", "value": "contemporary-romance" }, + { "label": "Fantasy Romance", "value": "fantasy-romance" }, + { "label": "Shoujo Ai", "value": "shoujo-ai" }, + { "label": "Yuri", "value": "yuri" } + ], + "type": "Picker" + } + } +} diff --git a/plugins/multisrc/lightnovelworld/generator.js b/plugins/multisrc/webnovelworld/generator.js similarity index 77% rename from plugins/multisrc/lightnovelworld/generator.js rename to plugins/multisrc/webnovelworld/generator.js index 3b0f098b2..01b39e7a2 100644 --- a/plugins/multisrc/lightnovelworld/generator.js +++ b/plugins/multisrc/webnovelworld/generator.js @@ -12,10 +12,10 @@ export const generateAll = function () { const filters = readFileSync( join(folder, 'filters', source.id + '.json'), ); - source.filters = JSON.parse(filters); + source.filters = JSON.parse(filters).filters; } console.log( - `[lightnovelworld] Generating: ${source.id}${' '.repeat(20 - source.id.length)} ${source.filters ? '🔎with filters🔍' : '🚫no filters🚫'}`, + `[webnovelworld] Generating: ${source.id}${' '.repeat(20 - source.id.length)} ${source.filters ? '🔎with filters🔍' : '🚫no filters🚫'}`, ); return generator(source); }); @@ -28,7 +28,7 @@ const generator = function generator(source) { const pluginScript = ` ${LightNovelWPTemplate} -const plugin = new LightNovelWorld(${JSON.stringify(source)}); +const plugin = new WebNovelWorld(${JSON.stringify(source)}); export default plugin; `.trim(); diff --git a/plugins/multisrc/webnovelworld/sources.json b/plugins/multisrc/webnovelworld/sources.json new file mode 100644 index 000000000..677463827 --- /dev/null +++ b/plugins/multisrc/webnovelworld/sources.json @@ -0,0 +1,29 @@ +[ + { + "id": "webnovelworld", + "sourceName": "Web Novel Pub", + "sourceSite": "https://www.webnovelworld.org/", + "options": { + "down": true, + "downSince": 1768289212945 + } + }, + { + "id": "lightnovelpubvip", + "sourceName": "LightNovelPub Vip", + "sourceSite": "https://lightnovelpub.vip/", + "options": { + "down": true, + "downSince": 1768289212945 + } + }, + { + "id": "lightnovelcave", + "sourceName": "LightNovelCave", + "sourceSite": "https://www.lightnovelcave.com/", + "options": { + "down": true, + "downSince": 1768289212945 + } + } +] diff --git a/plugins/multisrc/lightnovelworld/template.ts b/plugins/multisrc/webnovelworld/template.ts similarity index 60% rename from plugins/multisrc/lightnovelworld/template.ts rename to plugins/multisrc/webnovelworld/template.ts index 162de9366..95576400c 100644 --- a/plugins/multisrc/lightnovelworld/template.ts +++ b/plugins/multisrc/webnovelworld/template.ts @@ -1,23 +1,25 @@ import { load as parseHTML } from 'cheerio'; import { fetchApi } from '@libs/fetch'; import { Plugin } from '@/types/plugin'; -import { Filters, FilterTypes } from '@libs/filterInputs'; +import { Filters } from '@libs/filterInputs'; import dayjs from 'dayjs'; -type LightNovelWorldOptions = { +type WebNovelWorldOptions = { lang?: string; versionIncrements?: number; + down?: boolean; + downSince?: number; }; -export type LightNovelWorldMetadata = { +export type WebNovelWorldMetadata = { id: string; sourceSite: string; sourceName: string; - options?: LightNovelWorldOptions; + options?: WebNovelWorldOptions; filters?: Filters; }; -export class LightNovelWorld implements Plugin.PagePlugin { +export class WebNovelWorld implements Plugin.PagePlugin { id: string; name: string; site: string; @@ -30,16 +32,18 @@ export class LightNovelWorld implements Plugin.PagePlugin { imageRequestInit?: Plugin.ImageRequestInit | undefined = { headers: this.headers, }; - options?: LightNovelWorldOptions; + options?: WebNovelWorldOptions; + filters?: Filters; - constructor(metadata: LightNovelWorldMetadata) { + constructor(metadata: WebNovelWorldMetadata) { this.id = metadata.id; this.name = metadata.sourceName; - this.icon = `multisrc/lightnovelworld/${metadata.id.toLowerCase()}/icon.png`; + this.icon = `multisrc/webnovelworld/${metadata.id.toLowerCase()}/icon.png`; this.site = metadata.sourceSite; const versionIncrements = metadata.options?.versionIncrements || 0; - this.version = `1.0.${1 + versionIncrements}`; + this.version = `1.0.${2 + versionIncrements}`; this.options = metadata.options; + this.filters = metadata.filters; } async popularNovels( @@ -47,9 +51,9 @@ export class LightNovelWorld implements Plugin.PagePlugin { { filters }: Plugin.PopularNovelsOptions, ): Promise { let link = `${this.site}browse/`; - link += `${filters.genres.value}/`; - link += `${filters.order.value}/`; - link += `${filters.status.value}/`; + link += `${filters?.genres?.value || 'all'}/`; + link += `${filters?.order?.value || 'popular'}/`; + link += `${filters?.status?.value || 'all'}/`; link += page; const body = await fetchApi(link).then((r: Response) => r.text()); @@ -191,76 +195,4 @@ export class LightNovelWorld implements Plugin.PagePlugin { return novels; } - - filters = { - order: { - value: 'popular', - label: 'Order by', - options: [ - { label: 'New', value: 'new' }, - { label: 'Popular', value: 'popular' }, - { label: 'Updates', value: 'updated' }, - ], - type: FilterTypes.Picker, - }, - status: { - value: 'all', - label: 'Status', - options: [ - { label: 'All', value: 'all' }, - { label: 'Completed', value: 'completed' }, - { label: 'Ongoing', value: 'ongoing' }, - ], - type: FilterTypes.Picker, - }, - genres: { - value: 'all', - label: 'Genre', - options: [ - { label: 'All', value: 'all' }, - { label: 'Action', value: 'action' }, - { label: 'Adventure', value: 'adventure' }, - { label: 'Drama', value: 'drama' }, - { label: 'Fantasy', value: 'fantasy' }, - { label: 'Harem', value: 'harem' }, - { label: 'Martial Arts', value: 'martial-arts' }, - { label: 'Mature', value: 'mature' }, - { label: 'Romance', value: 'romance' }, - { label: 'Tragedy', value: 'tragedy' }, - { label: 'Xuanhuan', value: 'xuanhuan' }, - { label: 'Ecchi', value: 'ecchi' }, - { label: 'Comedy', value: 'comedy' }, - { label: 'Slice of Life', value: 'slice-of-life' }, - { label: 'Mystery', value: 'mystery' }, - { label: 'Supernatural', value: 'supernatural' }, - { label: 'Psychological', value: 'psychological' }, - { label: 'Sci-fi', value: 'sci-fi' }, - { label: 'Xianxia', value: 'xianxia' }, - { label: 'School Life', value: 'school-life' }, - { label: 'Josei', value: 'josei' }, - { label: 'Wuxia', value: 'wuxia' }, - { label: 'Shounen', value: 'shounen' }, - { label: 'Horror', value: 'horror' }, - { label: 'Mecha', value: 'mecha' }, - { label: 'Historical', value: 'historical' }, - { label: 'Shoujo', value: 'shoujo' }, - { label: 'Adult', value: 'adult' }, - { label: 'Seinen', value: 'seinen' }, - { label: 'Sports', value: 'sports' }, - { label: 'Lolicon', value: 'lolicon' }, - { label: 'Gender Bender', value: 'gender-bender' }, - { label: 'Shounen Ai', value: 'shounen-ai' }, - { label: 'Yaoi', value: 'yaoi' }, - { label: 'Video Games', value: 'video-games' }, - { label: 'Smut', value: 'smut' }, - { label: 'Magical Realism', value: 'magical-realism' }, - { label: 'Eastern Fantasy', value: 'eastern-fantasy' }, - { label: 'Contemporary Romance', value: 'contemporary-romance' }, - { label: 'Fantasy Romance', value: 'fantasy-romance' }, - { label: 'Shoujo Ai', value: 'shoujo-ai' }, - { label: 'Yuri', value: 'yuri' }, - ], - type: FilterTypes.Picker, - }, - } satisfies Filters; } diff --git a/public/static/multisrc/lightnovelworld/lightnovelcave/icon.png b/public/static/multisrc/webnovelworld/lightnovelcave/icon.png similarity index 100% rename from public/static/multisrc/lightnovelworld/lightnovelcave/icon.png rename to public/static/multisrc/webnovelworld/lightnovelcave/icon.png diff --git a/public/static/multisrc/lightnovelworld/lightnovelpubvip/icon.png b/public/static/multisrc/webnovelworld/lightnovelpubvip/icon.png similarity index 100% rename from public/static/multisrc/lightnovelworld/lightnovelpubvip/icon.png rename to public/static/multisrc/webnovelworld/lightnovelpubvip/icon.png diff --git a/public/static/multisrc/lightnovelworld/webnovelworld/icon.png b/public/static/multisrc/webnovelworld/webnovelworld/icon.png similarity index 100% rename from public/static/multisrc/lightnovelworld/webnovelworld/icon.png rename to public/static/multisrc/webnovelworld/webnovelworld/icon.png