diff --git a/plugins/multisrc/madara/filters/novelnice.json b/plugins/multisrc/madara/filters/novelnice.json new file mode 100644 index 000000000..3d11b419f --- /dev/null +++ b/plugins/multisrc/madara/filters/novelnice.json @@ -0,0 +1,324 @@ +{ + "filters": { + "genre[]": { + "type": "Checkbox", + "label": "Genre", + "value": [], + "options": [ + { + "label": "Action", + "value": "action" + }, + { + "label": "Adventure", + "value": "adventure" + }, + { + "label": "Anime & Comics", + "value": "anime-comics" + }, + { + "label": "Comedy", + "value": "comedy" + }, + { + "label": "Drama", + "value": "drama" + }, + { + "label": "Eastern", + "value": "eastern" + }, + { + "label": "Fan-fiction", + "value": "fan-fiction" + }, + { + "label": "Fanfiction", + "value": "fanfiction" + }, + { + "label": "Fantasy", + "value": "fantasy" + }, + { + "label": "Game", + "value": "game" + }, + { + "label": "Games", + "value": "games" + }, + { + "label": "Gender Bender", + "value": "gender-bender" + }, + { + "label": "General", + "value": "general" + }, + { + "label": "Harem", + "value": "harem" + }, + { + "label": "Historical", + "value": "historical" + }, + { + "label": "Horror", + "value": "horror" + }, + { + "label": "Isekai", + "value": "isekai" + }, + { + "label": "Josei", + "value": "josei" + }, + { + "label": "LitRPG", + "value": "litrpg" + }, + { + "label": "Magic", + "value": "magic" + }, + { + "label": "Magical Realism", + "value": "magical-realism" + }, + { + "label": "Martial Arts", + "value": "martial-arts" + }, + { + "label": "Mature", + "value": "mature" + }, + { + "label": "Mecha", + "value": "mecha" + }, + { + "label": "Modern Life", + "value": "modern-life" + }, + { + "label": "Mystery", + "value": "mystery" + }, + { + "label": "Other", + "value": "other" + }, + { + "label": "Psychological", + "value": "psychological" + }, + { + "label": "Reincarnation", + "value": "reincarnation" + }, + { + "label": "Romance", + "value": "romance" + }, + { + "label": "School Life", + "value": "school-life" + }, + { + "label": "Sci-fi", + "value": "sci-fi" + }, + { + "label": "Seinen", + "value": "seinen" + }, + { + "label": "Shoujo", + "value": "shoujo" + }, + { + "label": "Shoujo Ai", + "value": "shoujo-ai" + }, + { + "label": "Shounen", + "value": "shounen" + }, + { + "label": "Shounen Ai", + "value": "shounen-ai" + }, + { + "label": "Slice of Life", + "value": "slice-of-life" + }, + { + "label": "Smut", + "value": "smut" + }, + { + "label": "Sports", + "value": "sports" + }, + { + "label": "Supernatural", + "value": "supernatural" + }, + { + "label": "System", + "value": "system" + }, + { + "label": "Thriller", + "value": "thriller" + }, + { + "label": "Tragedy", + "value": "tragedy" + }, + { + "label": "Urban", + "value": "urban" + }, + { + "label": "Urban Life", + "value": "urban-life" + }, + { + "label": "Video Games", + "value": "video-games" + }, + { + "label": "War", + "value": "war" + }, + { + "label": "Wuxia", + "value": "wuxia" + }, + { + "label": "Xianxia", + "value": "xianxia" + }, + { + "label": "Xuanhuan", + "value": "xuanhuan" + }, + { + "label": "Yaoi", + "value": "yaoi" + }, + { + "label": "Yuri", + "value": "yuri" + } + ] + }, + "op": { + "type": "Switch", + "label": "having all selected genres", + "value": false + }, + "author": { + "type": "Text", + "label": "Author", + "value": "" + }, + "artist": { + "type": "Text", + "label": "Artist", + "value": "" + }, + "release": { + "type": "Text", + "label": "Year of Released", + "value": "" + }, + "adult": { + "type": "Picker", + "label": "Adult content", + "value": "", + "options": [ + { + "label": "All", + "value": "" + }, + { + "label": "None adult content", + "value": "0" + }, + { + "label": "Only adult content", + "value": "1" + } + ] + }, + "status[]": { + "type": "Checkbox", + "label": "Status", + "value": [], + "options": [ + { + "label": "OnGoing", + "value": "on-going" + }, + { + "label": "Completed", + "value": "end" + }, + { + "label": "Canceled", + "value": "canceled" + }, + { + "label": "On Hold", + "value": "on-hold" + }, + { + "label": "Upcoming", + "value": "upcoming" + } + ] + }, + "m_orderby": { + "type": "Picker", + "label": "Order by", + "value": "", + "options": [ + { + "label": "Relevance", + "value": "" + }, + { + "label": "Latest", + "value": "latest" + }, + { + "label": "A-Z", + "value": "alphabet" + }, + { + "label": "Rating", + "value": "rating" + }, + { + "label": "Trending", + "value": "trending" + }, + { + "label": "Most Views", + "value": "views" + }, + { + "label": "New", + "value": "new-manga" + } + ] + } + } +} diff --git a/plugins/multisrc/madara/sources.json b/plugins/multisrc/madara/sources.json index 6f4b088e4..62b243d4f 100644 --- a/plugins/multisrc/madara/sources.json +++ b/plugins/multisrc/madara/sources.json @@ -651,5 +651,14 @@ "useNewChapterEndpoint": true, "versionIncrements": 2 } + }, + { + "id": "novelnice", + "sourceSite": "https://novelnice.com/", + "sourceName": "Novel Nice", + "options": { + "lang": "English", + "useNewChapterEndpoint": true + } } ] diff --git a/plugins/multisrc/madara/template.ts b/plugins/multisrc/madara/template.ts index ed392b0f1..91b01be6c 100644 --- a/plugins/multisrc/madara/template.ts +++ b/plugins/multisrc/madara/template.ts @@ -304,6 +304,30 @@ export class MadaraPlugin implements Plugin.PluginBase { method: 'POST', referrer: this.site + novelPath, }).then((res: Response) => res.text()); + + const $firstPage = parseHTML(html); + const pageLinks = $firstPage('.pagination a[data-page]'); + if (pageLinks.length > 0) { + const maxPage = Math.max( + ...pageLinks + .map((_, el) => + parseInt($firstPage(el).attr('data-page') || '1', 10), + ) + .get(), + ); + const lastHref = pageLinks.last().attr('href') || ''; + const queryIndex = lastHref.indexOf('?'); + if (queryIndex !== -1) { + const queryTemplate = lastHref.slice(queryIndex).replace(/\d+$/, ''); + for (let page = 2; page <= maxPage; page++) { + const pageHtml = await fetchApi( + this.site + novelPath + 'ajax/chapters/' + queryTemplate + page, + { method: 'POST', referrer: this.site + novelPath }, + ).then((res: Response) => res.text()); + if (pageHtml && pageHtml !== '0') html += pageHtml; + } + } + } } else { const novelId = loadedCheerio('.rating-post-id').attr('value') || diff --git a/public/static/multisrc/madara/novelnice/icon.png b/public/static/multisrc/madara/novelnice/icon.png new file mode 100644 index 000000000..539ebb8df Binary files /dev/null and b/public/static/multisrc/madara/novelnice/icon.png differ