From c5bfad49f01b49695d879248abd52e849ae3710e Mon Sep 17 00:00:00 2001
From: Schnitzel5 <36087291+Schnitzel5@users.noreply.github.com>
Date: Wed, 8 Jan 2025 13:19:23 +0000
Subject: [PATCH] adjusted novel sources
---
javascript/novel/src/en/novelupdates.js | 92 +++----
javascript/novel/src/en/wordrain69.js | 310 ++++++++++++------------
wip/wuxiaclick.js | 150 ++++++++++++
3 files changed, 355 insertions(+), 197 deletions(-)
create mode 100644 wip/wuxiaclick.js
diff --git a/javascript/novel/src/en/novelupdates.js b/javascript/novel/src/en/novelupdates.js
index e83591c6..cca98911 100644
--- a/javascript/novel/src/en/novelupdates.js
+++ b/javascript/novel/src/en/novelupdates.js
@@ -7,7 +7,7 @@ const mangayomiSources = [{
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/en.novelupdates.png",
"typeSource": "single",
"itemType": 2,
- "version": "0.0.2",
+ "version": "0.0.3",
"dateFormat": "",
"dateFormatLocale": "",
"pkgPath": "novel/src/en/novelupdates.js",
@@ -188,8 +188,13 @@ class DefaultExtension extends MProvider {
"User-Agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
});
- const doc = new Document(res.body);
- const domain = res.body;
+ return await this.cleanHtmlContent(res.body);
+ }
+
+ async cleanHtmlContent(html) {
+ const client = await new Client();
+ const doc = new Document(html);
+ const domain = html;
if (domain.includes("anotivereads")) {
const title =
@@ -424,50 +429,49 @@ class DefaultExtension extends MProvider {
return e?.toLowerCase().includes("wordpress") || e?.toLowerCase().includes("site kit by google")
});
-
let title =
- doc.selectFirst(".entry-title")?.text.trim() ||
- doc.selectFirst(".entry-title-main")?.text.trim() ||
- doc.selectFirst(".chapter__title")?.text.trim() ||
- doc.selectFirst(".sp-title")?.text.trim() ||
- doc.selectFirst(".title-content")?.text.trim() ||
- doc.selectFirst(".wp-block-post-title")?.text.trim() ||
- doc.selectFirst(".title_story")?.text.trim() ||
- doc.selectFirst(".active")?.text.trim() ||
- doc.selectFirst("head title")?.text.trim() ||
- doc.selectFirst("h1.leading-none ~ h2")?.text.trim() ||
- "";
- const subtitle =
- doc.selectFirst(".cat-series")?.text.trim() ||
- doc.selectFirst("h1.leading-none ~ span")?.text.trim() ||
- "";
- if (subtitle && subtitle != "") {
- title = subtitle;
- }
- const content =
- doc.selectFirst(".rdminimal")?.innerHtml ||
- doc.selectFirst(".entry-content")?.innerHtml ||
- doc.selectFirst(".chapter__content")?.innerHtml ||
- doc.selectFirst(".prevent-select")?.innerHtml ||
- doc.selectFirst(".text_story")?.innerHtml ||
- doc.selectFirst(".contenta")?.innerHtml ||
- doc.selectFirst(".single_post")?.innerHtml ||
- doc.selectFirst(".post-entry")?.innerHtml ||
- doc.selectFirst(".main-content")?.innerHtml ||
- doc.selectFirst(".post-content")?.innerHtml ||
- doc.selectFirst(".content")?.innerHtml ||
- doc.selectFirst(".page-body")?.innerHtml ||
- doc.selectFirst(".td-page-content")?.innerHtml ||
- doc.selectFirst(".reader-content")?.innerHtml ||
- doc.selectFirst("#content")?.innerHtml ||
- doc.selectFirst("#the-content")?.innerHtml ||
- doc.selectFirst("article.post")?.innerHtml;
-
- if (isWordpress || domain.includes("etherreads") || domain.includes("soafp")) {
- return `
${title}
${content}`;
+ doc.selectFirst(".entry-title")?.text.trim() ||
+ doc.selectFirst(".entry-title-main")?.text.trim() ||
+ doc.selectFirst(".chapter__title")?.text.trim() ||
+ doc.selectFirst(".sp-title")?.text.trim() ||
+ doc.selectFirst(".title-content")?.text.trim() ||
+ doc.selectFirst(".wp-block-post-title")?.text.trim() ||
+ doc.selectFirst(".title_story")?.text.trim() ||
+ doc.selectFirst(".active")?.text.trim() ||
+ doc.selectFirst("head title")?.text.trim() ||
+ doc.selectFirst("h1.leading-none ~ h2")?.text.trim() ||
+ "";
+ const subtitle =
+ doc.selectFirst(".cat-series")?.text.trim() ||
+ doc.selectFirst("h1.leading-none ~ span")?.text.trim() ||
+ "";
+ if (subtitle && subtitle != "") {
+ title = subtitle;
}
+ const content =
+ doc.selectFirst(".rdminimal")?.innerHtml ||
+ doc.selectFirst(".entry-content")?.innerHtml ||
+ doc.selectFirst(".chapter__content")?.innerHtml ||
+ doc.selectFirst(".prevent-select")?.innerHtml ||
+ doc.selectFirst(".text_story")?.innerHtml ||
+ doc.selectFirst(".contenta")?.innerHtml ||
+ doc.selectFirst(".single_post")?.innerHtml ||
+ doc.selectFirst(".post-entry")?.innerHtml ||
+ doc.selectFirst(".main-content")?.innerHtml ||
+ doc.selectFirst(".post-content")?.innerHtml ||
+ doc.selectFirst(".content")?.innerHtml ||
+ doc.selectFirst(".page-body")?.innerHtml ||
+ doc.selectFirst(".td-page-content")?.innerHtml ||
+ doc.selectFirst(".reader-content")?.innerHtml ||
+ doc.selectFirst("#content")?.innerHtml ||
+ doc.selectFirst("#the-content")?.innerHtml ||
+ doc.selectFirst("article.post")?.innerHtml;
- return `Domain not supported yet. Content might not load properly!
+ if (isWordpress || domain.includes("etherreads") || domain.includes("soafp")) {
+ return `${title}
${content}`;
+ }
+
+ return `Domain not supported yet. Content might not load properly!
${title}
${content}`;
}
diff --git a/javascript/novel/src/en/wordrain69.js b/javascript/novel/src/en/wordrain69.js
index 80f2a996..7180abe9 100644
--- a/javascript/novel/src/en/wordrain69.js
+++ b/javascript/novel/src/en/wordrain69.js
@@ -1,156 +1,160 @@
const mangayomiSources = [{
- "name": "Wordrain69",
- "lang": "en",
- "baseUrl": "https://wordrain69.com",
- "apiUrl": "",
- "iconUrl":
- "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/en.wordrain69.png",
- "typeSource": "single",
- "itemType": 2,
- "version": "0.0.1",
- "dateFormat": "",
- "dateFormatLocale": "",
- "pkgPath": "novel/src/en/wordrain69.js",
- "appMinVerReq": "0.4.0",
- "isNsfw": false,
- "hasCloudflare": false
- }];
-
- class DefaultExtension extends MProvider {
- getHeaders(url) {
- throw new Error("getHeaders not implemented");
- }
-
- mangaListFromPage(res) {
- const doc = new Document(res.body);
- const mangaElements = doc.select("div.page-item-detail");
- const list = [];
- for (const element of mangaElements) {
- const name = element.selectFirst(".item-thumb > a").attr("title");
- const link = element.selectFirst(".item-thumb > a").getHref;
- const imageUrl = element.selectFirst("img").getSrc;
- list.push({ name, imageUrl, link });
- }
- const hasNextPage =
- doc.selectFirst("nav > div.nav-links > a").text?.includes("Posts") ?? false;
- return { list: list, hasNextPage };
- }
-
- toStatus(status) {
- if (status.includes("OnGoing")) return 0;
- else if (status.includes("Completed")) return 1;
- else if (status.includes("Hiatus")) return 2;
- else if (status.includes("Dropped")) return 3;
- else return 5;
- }
-
- async getPopular(page) {
- const res = await new Client().get(
- `${this.source.baseUrl}/manga-genre/novel/page/${page}/?m_orderby=trending`,
- );
- return this.mangaListFromPage(res);
- }
-
- async getLatestUpdates(page) {
- const res = await new Client().get(
- `${this.source.baseUrl}/manga-genre/novel/page/${page}/?m_orderby=latest`,
- );
- return this.mangaListFromPage(res);
- }
-
- async search(query, page, filters) {
- let url = `${this.source.baseUrl}/?s=${query}`;
- const res = await new Client().get(url);
- return this.mangaListFromPage(res);
- }
-
- async getDetail(url) {
- const client = new Client();
- const res = await client.get(url);
- const doc = new Document(res.body);
- const imageUrl = doc.selectFirst("div.summary_image > a > img")?.getSrc;
- const description = doc.select("div.summary__content > p > span").map((el) => el.text).join(" ");
- const author = doc.selectFirst("div.author-content > a")?.text.trim();
- const artist = doc.selectFirst("div.artist-content > a")?.text.trim();
- const status = this.toStatus(doc.selectFirst("div.post-status > div.post-content_item > div.summary-content")?.text.trim());
- const tags = doc.select("div.summary-content > div.tags-content > a").map((el) => el.text.trim());
- let genre = doc.select("div.summary-content > div.genres-content > a").map((el) => el.text.trim());
- if (tags.length != 0) {
- genre.push(tags);
- }
+ "name": "Wordrain69",
+ "lang": "en",
+ "baseUrl": "https://wordrain69.com",
+ "apiUrl": "",
+ "iconUrl":
+ "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/en.wordrain69.png",
+ "typeSource": "single",
+ "itemType": 2,
+ "version": "0.0.2",
+ "dateFormat": "",
+ "dateFormatLocale": "",
+ "pkgPath": "novel/src/en/wordrain69.js",
+ "appMinVerReq": "0.4.0",
+ "isNsfw": false,
+ "hasCloudflare": false
+}];
- const chapters = [];
- const chapterRes = await client.post(`${url}ajax/chapters/`, {
- Priority: "u=0, i",
- "Origin": this.source.baseUrl,
- "Referer": url,
- });
- const chapterDoc = new Document(chapterRes.body);
-
- const chapterElements = chapterDoc.select("li.free-chap");
- for (const el of chapterElements) {
- let chapterName = el.selectFirst("a")?.text.trim();
- const chapterUrl = el.selectFirst("a").getHref;
- let dateUpload;
- try {
- dateUpload = this.parseDate(el.selectFirst("span.chapter-release-date > i")?.text.trim());
- } catch (_) {
- dateUpload = null;
- }
- chapters.push({
- name: chapterName,
- url: chapterUrl,
- dateUpload: dateUpload,
- scanlator: null,
- });
- }
-
- chapters.reverse();
-
- return {
- imageUrl,
- description,
- genre,
- author,
- artist,
- status,
- chapters,
- };
- }
-
- async getHtmlContent(url) {
- const client = await new Client();
- const res = await client.get(url);
- const doc = new Document(res.body);
- const title =
- doc.selectFirst("#chapter-heading")?.text.trim() ||
- "";
- const content = doc.selectFirst(".entry-content")?.innerHtml;
- return `${title}
${content}`;
- }
-
- getFilterList() {
- return [];
- }
-
- getSourcePreferences() {
- throw new Error("getSourcePreferences not implemented");
- }
-
- parseDate(date) {
- const months = {
- "January": "01", "February": "02", "March": "03", "April": "04", "May": "05", "June": "06",
- "July": "07", "August": "08", "September": "09", "October": "10", "November": "11", "December": "12"
- };
- date = date.toLowerCase().replace(",", "").split(" ");
-
- if (!(date[0] in months)) {
- return String(new Date().valueOf())
- }
-
- date[0] = months[date[0]];
- date = [date[2], date[0], date[1]];
- date = date.join("-");
- return String(new Date(date).valueOf());
- }
+class DefaultExtension extends MProvider {
+ getHeaders(url) {
+ throw new Error("getHeaders not implemented");
}
+
+ mangaListFromPage(res) {
+ const doc = new Document(res.body);
+ const mangaElements = doc.select("div.page-item-detail");
+ const list = [];
+ for (const element of mangaElements) {
+ const name = element.selectFirst(".item-thumb > a").attr("title");
+ const link = element.selectFirst(".item-thumb > a").getHref;
+ const imageUrl = element.selectFirst("img").getSrc;
+ list.push({ name, imageUrl, link });
+ }
+ const hasNextPage =
+ doc.selectFirst("nav > div.nav-links > a").text?.includes("Posts") ?? false;
+ return { list: list, hasNextPage };
+ }
+
+ toStatus(status) {
+ if (status.includes("OnGoing")) return 0;
+ else if (status.includes("Completed")) return 1;
+ else if (status.includes("Hiatus")) return 2;
+ else if (status.includes("Dropped")) return 3;
+ else return 5;
+ }
+
+ async getPopular(page) {
+ const res = await new Client().get(
+ `${this.source.baseUrl}/manga-genre/novel/page/${page}/?m_orderby=trending`,
+ );
+ return this.mangaListFromPage(res);
+ }
+
+ async getLatestUpdates(page) {
+ const res = await new Client().get(
+ `${this.source.baseUrl}/manga-genre/novel/page/${page}/?m_orderby=latest`,
+ );
+ return this.mangaListFromPage(res);
+ }
+
+ async search(query, page, filters) {
+ let url = `${this.source.baseUrl}/?s=${query}`;
+ const res = await new Client().get(url);
+ return this.mangaListFromPage(res);
+ }
+
+ async getDetail(url) {
+ const client = new Client();
+ const res = await client.get(url);
+ const doc = new Document(res.body);
+ const imageUrl = doc.selectFirst("div.summary_image > a > img")?.getSrc;
+ const description = doc.select("div.summary__content > p > span").map((el) => el.text).join(" ");
+ const author = doc.selectFirst("div.author-content > a")?.text.trim();
+ const artist = doc.selectFirst("div.artist-content > a")?.text.trim();
+ const status = this.toStatus(doc.selectFirst("div.post-status > div.post-content_item > div.summary-content")?.text.trim());
+ const tags = doc.select("div.summary-content > div.tags-content > a").map((el) => el.text.trim());
+ let genre = doc.select("div.summary-content > div.genres-content > a").map((el) => el.text.trim());
+ if (tags.length != 0) {
+ genre.push(tags);
+ }
+
+ const chapters = [];
+ const chapterRes = await client.post(`${url}ajax/chapters/`, {
+ Priority: "u=0, i",
+ "Origin": this.source.baseUrl,
+ "Referer": url,
+ });
+ const chapterDoc = new Document(chapterRes.body);
+
+ const chapterElements = chapterDoc.select("li.free-chap");
+ for (const el of chapterElements) {
+ let chapterName = el.selectFirst("a")?.text.trim();
+ const chapterUrl = el.selectFirst("a").getHref;
+ let dateUpload;
+ try {
+ dateUpload = this.parseDate(el.selectFirst("span.chapter-release-date > i")?.text.trim());
+ } catch (_) {
+ dateUpload = null;
+ }
+ chapters.push({
+ name: chapterName,
+ url: chapterUrl,
+ dateUpload: dateUpload,
+ scanlator: null,
+ });
+ }
+
+ chapters.reverse();
+
+ return {
+ imageUrl,
+ description,
+ genre,
+ author,
+ artist,
+ status,
+ chapters,
+ };
+ }
+
+ async getHtmlContent(url) {
+ const client = await new Client();
+ const res = await client.get(url);
+ return await this.cleanHtmlContent(res.body);
+ }
+
+ async cleanHtmlContent(html) {
+ const doc = new Document(html);
+ const title =
+ doc.selectFirst("#chapter-heading")?.text.trim() ||
+ "";
+ const content = doc.selectFirst(".entry-content")?.innerHtml;
+ return `${title}
${content}`;
+ }
+
+ getFilterList() {
+ return [];
+ }
+
+ getSourcePreferences() {
+ throw new Error("getSourcePreferences not implemented");
+ }
+
+ parseDate(date) {
+ const months = {
+ "January": "01", "February": "02", "March": "03", "April": "04", "May": "05", "June": "06",
+ "July": "07", "August": "08", "September": "09", "October": "10", "November": "11", "December": "12"
+ };
+ date = date.toLowerCase().replace(",", "").split(" ");
+
+ if (!(date[0] in months)) {
+ return String(new Date().valueOf())
+ }
+
+ date[0] = months[date[0]];
+ date = [date[2], date[0], date[1]];
+ date = date.join("-");
+ return String(new Date(date).valueOf());
+ }
+}
\ No newline at end of file
diff --git a/wip/wuxiaclick.js b/wip/wuxiaclick.js
new file mode 100644
index 00000000..59ab3e28
--- /dev/null
+++ b/wip/wuxiaclick.js
@@ -0,0 +1,150 @@
+const mangayomiSources = [{
+ "name": "WuxiaClick",
+ "lang": "en",
+ "baseUrl": "https://wuxia.click",
+ "apiUrl": "",
+ "iconUrl":
+ "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/en.wuxiaclick.png",
+ "typeSource": "single",
+ "itemType": 2,
+ "version": "0.0.1",
+ "dateFormat": "",
+ "dateFormatLocale": "",
+ "pkgPath": "novel/src/en/wuxiaclick.js",
+ "appMinVerReq": "0.4.0",
+ "isNsfw": false,
+ "hasCloudflare": false
+ }];
+
+ class DefaultExtension extends MProvider {
+ getHeaders(url) {
+ throw new Error("getHeaders not implemented");
+ }
+
+ mangaListFromPage(res) {
+ const doc = new Document(res.body);
+ const mangaElements = doc.select("div.mantine-grid-root > div.mantine-grid-col > div");
+ const list = [];
+ for (const element of mangaElements) {
+ const name = element.selectFirst("a > div > div > div.mantine-Text-root")?.text.trim();
+ const link = this.source.baseUrl + element.selectFirst("a").getHref;
+ const imageUrl = element.selectFirst("img").getSrc;
+ list.push({ name, imageUrl, link });
+ }
+ const pagination = doc.select("button.mantine-y4zem1 > svg > path").map((el) => el.attr("d"));
+ const hasNextPage = pagination.length > 1 ? pagination[1].startsWith("M8") : false;
+ return { list: list, hasNextPage };
+ }
+
+ toStatus(status) {
+ if (status.includes("Ongoing")) return 0;
+ else if (status.includes("Completed")) return 1;
+ else if (status.includes("Hiatus")) return 2;
+ else if (status.includes("Dropped")) return 3;
+ else return 5;
+ }
+
+ async getPopular(page) {
+ const res = await new Client().get(
+ `${this.source.baseUrl}/advance_search?order=-weekly_views&page=${page}`,
+ );
+ return this.mangaListFromPage(res);
+ }
+
+ async getLatestUpdates(page) {
+ const res = await new Client().get(
+ `${this.source.baseUrl}/advance_search?order=-created_at&page=${page}`,
+ );
+ return this.mangaListFromPage(res);
+ }
+
+ async search(query, page, filters) {
+ let url = `${this.source.baseUrl}/advance_search?order=&page=${page}&search=${encodeURI(query)}`;
+ const res = await new Client().get(url);
+ return this.mangaListFromPage(res);
+ }
+
+ async getDetail(url) {
+ const client = new Client();
+ const res = await client.get(url);
+ const doc = new Document(res.body);
+ const imageUrl = doc.selectFirst("figure > div > img")?.getSrc;
+ const description = doc.select("div.mantine-Spoiler-root > div > div > div.mantine-Text-root")?.text.trim();
+ const author = doc.selectFirst("div.mantine-lqk3v2 > div")?.text.trim();
+ const status = this.toStatus(doc.selectFirst("div.mantine-1uxmzbt > div.mantine-1huvzos")?.text.trim());
+ const genre = doc.select("div.mantine-bl3g33 > div > a > div > div > span").map((el) => el.text.trim());
+
+ const chapterElements = doc.select("div.mantine-1x5ubwi > div");
+ for (const el of chapterElements) {
+ let chapterName = el.selectFirst("div.mantine-Group-root > div > a > div > h4")?.text.trim();
+ if (!chapterName) {
+ continue;
+ }
+ const chapterUrl = this.source.baseUrl + el.selectFirst("div.mantine-Group-root > div > a").getHref;
+ let dateUpload;
+ try {
+ dateUpload = this.parseDate(el.selectFirst("div > a > div > div > div.mantine-Text-root")?.text.trim());
+ } catch (_) {
+ dateUpload = null;
+ }
+ chapters.push({
+ name: chapterName,
+ url: chapterUrl,
+ dateUpload: dateUpload,
+ scanlator: null,
+ });
+ }
+
+ chapters.reverse();
+
+ return {
+ imageUrl,
+ description,
+ genre,
+ author,
+ artist,
+ status,
+ chapters,
+ };
+ }
+
+ async getHtmlContent(url) {
+ const client = await new Client();
+ const res = await client.get(url);
+ return await this.cleanHtmlContent(res.body);
+ }
+
+ async cleanHtmlContent(html) {
+ const doc = new Document(html);
+ const title =
+ doc.selectFirst("div.mantine-Center-root > h1.mantine-Title-root")?.text.trim() ||
+ "";
+ const content = doc.select("div.mantine-Container-root > div.mantine-Paper-root > div")[2]?.innerHtml;
+ return `${title}
${content}`;
+ }
+
+ getFilterList() {
+ return [];
+ }
+
+ getSourcePreferences() {
+ throw new Error("getSourcePreferences not implemented");
+ }
+
+ parseDate(date) {
+ const months = {
+ "January": "01", "February": "02", "March": "03", "April": "04", "May": "05", "June": "06",
+ "July": "07", "August": "08", "September": "09", "October": "10", "November": "11", "December": "12"
+ };
+ date = date.toLowerCase().replace(",", "").split(" ");
+
+ if (!(date[0] in months)) {
+ return String(new Date().valueOf())
+ }
+
+ date[0] = months[date[0]];
+ date = [date[2], date[0], date[1]];
+ date = date.join("-");
+ return String(new Date(date).valueOf());
+ }
+ }