Merge branch 'temp/annasarchive' into novel/annasarchive

This commit is contained in:
Schnitzel5
2025-05-07 22:35:35 +02:00
8 changed files with 189 additions and 7 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,176 @@
const mangayomiSources = [
{
"name": "Annas Archive",
"lang": "en",
"baseUrl": "https://annas-archive.org",
"apiUrl": "",
"iconUrl":
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/all.annasarchive.png",
"typeSource": "single",
"itemType": 2,
"version": "0.0.1",
"dateFormat": "",
"dateFormatLocale": "",
"pkgPath": "novel/src/all/annasarchive.js",
"isNsfw": false,
"hasCloudflare": true,
"notes": "EPUBs are automatically downloaded to view chapters! Downloads from Libgen might be slow!",
},
];
class DefaultExtension extends MProvider {
headers = {
Priority: "u=0, i",
"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",
};
getHeaders(url) {
throw new Error("getHeaders not implemented");
}
mangaListFromPage(res) {
const doc = new Document(res.body.replaceAll(/<!--|-->/g, ""));
const mangaElements = doc.select("a");
const list = [];
for (const element of mangaElements) {
const name = element.selectFirst("h3")?.text.replaceAll("🔍", "").trim();
const imageUrl = element.selectFirst("img").getSrc;
const link = element.getHref;
if (link.includes("/md5/")) {
list.push({ name, imageUrl, link });
}
}
const hasNextPage = true;
return { list: list, hasNextPage };
}
async getPopular(page) {
let url = `${this.source.baseUrl}/search?index=&page=${page}&q=&display=&ext=epub&src=lgli&sort=`;
if (this.source.lang != "all") {
url += `&lang=${this.source.lang}`;
}
const res = await new Client().get(url, this.headers);
return this.mangaListFromPage(res);
}
async getLatestUpdates(page) {
let url = `${this.source.baseUrl}/search?index=&page=${page}&q=&display=&ext=epub&src=lgli&sort=newest`;
if (this.source.lang != "all") {
url += `&lang=${this.source.lang}`;
}
const res = await new Client().get(url, this.headers);
return this.mangaListFromPage(res);
}
async search(query, page, filters) {
let url = `${this.source.baseUrl}/search?index=&page=${page}&q=${query}&display=&ext=epub&src=lgli&sort=`;
if (this.source.lang != "all") {
url += `&lang=${this.source.lang}`;
}
const res = await new Client().get(url, this.headers);
return this.mangaListFromPage(res);
}
async getDetail(url) {
const client = new Client();
const res = await client.get(this.source.baseUrl + url, this.headers);
const doc = new Document(res.body);
const main = doc.selectFirst('main[class="main"]');
const name = doc.selectFirst('div.text-3xl.font-bold')?.text.trim();
const description = doc
.selectFirst('div[class="mb-1"]')
?.text.trim()
.replace("description", "");
const author = doc.selectFirst('div[class="italic"]')?.text.replaceAll("🔍", "").trim();
const status = 1;
const genre = [];
const mirrorLink = main
.selectFirst('ul[class="list-inside mb-4 ml-1 js-show-external hidden"]')
.select("li > a")
.find((el) => el.getHref?.includes("libgen.is")).getHref;
const bookLink = await this._getMirrorLink(client, mirrorLink);
if (!bookLink) {
return {
description,
genre,
author,
status,
chapters: [],
};
}
const book = await parseEpub(name, bookLink, {
Connection: "Keep-Alive",
...this.headers,
});
const chapters = [];
for (const chapterTitle of book.chapters) {
chapters.push({
name: chapterTitle,
url: mirrorLink + ";;;" + chapterTitle,
dateUpload: String(Date.now()),
scanlator: null,
});
}
return {
description,
genre,
author,
status,
chapters,
};
}
async _getMirrorLink(client, mirrorLink) {
const res = await client.get(mirrorLink, {
Origin: this.source.baseUrl,
...this.headers,
});
const doc = new Document(res.body);
const links = doc.select(
"a"
);
const libgenRs = links.find((el) => el.getHref?.includes("books.ms"))?.getHref;
const libgenLi = links.find((el) => el.getHref?.includes("libgen.li"))?.getHref;
if (libgenRs && (await client.head(libgenRs, this.headers)).statusCode === 200) {
const response = await client.get(libgenRs, this.headers);
const document = new Document(response.body);
return document.selectFirst('div#download > h2 > a')?.getHref;
} else if (libgenLi && (await client.head(libgenLi, this.headers)).statusCode === 200) {
const response = await client.get(libgenLi, this.headers);
const document = new Document(response.body);
return "https://libgen.li/" + document.selectFirst('tbody > tr > td > a')?.getHref;
}
return null;
}
async getHtmlContent(name, url) {
const urls = url.split(";;;");
const client = await new Client();
const bookLink = await this._getMirrorLink(client, urls[0]);
return await parseEpubChapter(name, bookLink, {
Connection: "Keep-Alive",
...this.headers,
}, urls[1]);
}
async cleanHtmlContent(html) {
return html;
}
getFilterList() {
return [];
}
getSourcePreferences() {
throw new Error("getSourcePreferences not implemented");
}
}

View File

@@ -7,12 +7,13 @@ const mangayomiSources = [{
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/en.novelupdates.png", "https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/en.novelupdates.png",
"typeSource": "single", "typeSource": "single",
"itemType": 2, "itemType": 2,
"version": "0.0.3", "version": "0.0.5",
"dateFormat": "", "dateFormat": "",
"dateFormatLocale": "", "dateFormatLocale": "",
"pkgPath": "novel/src/en/novelupdates.js", "pkgPath": "novel/src/en/novelupdates.js",
"isNsfw": false, "isNsfw": false,
"hasCloudflare": true "hasCloudflare": true,
"notes": "This extension requires you to login to view the chapters!"
}]; }];
class DefaultExtension extends MProvider { class DefaultExtension extends MProvider {
@@ -180,7 +181,7 @@ class DefaultExtension extends MProvider {
}; };
} }
async getHtmlContent(url) { async getHtmlContent(name, url) {
const client = await new Client(); const client = await new Client();
const res = await client.get(url, { const res = await client.get(url, {
Priority: "u=0, i", Priority: "u=0, i",

View File

@@ -115,7 +115,7 @@ class DefaultExtension extends MProvider {
}; };
} }
async getHtmlContent(url) { async getHtmlContent(name, url) {
const client = await new Client(); const client = await new Client();
const res = await client.get(url); const res = await client.get(url);
return await this.cleanHtmlContent(res.body); return await this.cleanHtmlContent(res.body);

View File

@@ -37,6 +37,8 @@ class Source {
int? sourceCodeLanguage; int? sourceCodeLanguage;
String? notes;
Source({ Source({
this.id = null, this.id = null,
this.name = "", this.name = "",
@@ -57,6 +59,7 @@ class Source {
this.appMinVerReq = "0.5.0", this.appMinVerReq = "0.5.0",
this.additionalParams = "", this.additionalParams = "",
this.sourceCodeLanguage = 0, this.sourceCodeLanguage = 0,
this.notes = "",
}); });
Source.fromJson(Map<String, dynamic> json) { Source.fromJson(Map<String, dynamic> json) {
final sourceCodeLang = json['sourceCodeLanguage'] ?? 0; final sourceCodeLang = json['sourceCodeLanguage'] ?? 0;
@@ -84,6 +87,7 @@ class Source {
version = json['version'] ?? ""; version = json['version'] ?? "";
additionalParams = json['additionalParams'] ?? ""; additionalParams = json['additionalParams'] ?? "";
sourceCodeLanguage = sourceCodeLang; sourceCodeLanguage = sourceCodeLang;
notes = json['notes'] ?? "";
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@@ -107,6 +111,7 @@ class Source {
"appMinVerReq": appMinVerReq, "appMinVerReq": appMinVerReq,
"additionalParams": additionalParams, "additionalParams": additionalParams,
"sourceCodeLanguage": sourceCodeLanguage, "sourceCodeLanguage": sourceCodeLanguage,
"notes": notes,
}; };
} }
} }

View File

@@ -1 +1 @@
[{"name":"Wordrain69","id":422341482,"baseUrl":"https://wordrain69.com","lang":"en","typeSource":"single","iconUrl":"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/en.wordrain69.png","dateFormat":"","dateFormatLocale":"","isNsfw":false,"hasCloudflare":false,"sourceCodeUrl":"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/novel/src/en/wordrain69.js","apiUrl":"","version":"0.0.3","isManga":false,"itemType":2,"isFullData":false,"appMinVerReq":"0.5.0","additionalParams":"","sourceCodeLanguage":1},{"name":"Novel Updates","id":413730324,"baseUrl":"https://www.novelupdates.com","lang":"en","typeSource":"single","iconUrl":"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/en.novelupdates.png","dateFormat":"","dateFormatLocale":"","isNsfw":false,"hasCloudflare":true,"sourceCodeUrl":"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/novel/src/en/novelupdates.js","apiUrl":"","version":"0.0.3","isManga":false,"itemType":2,"isFullData":false,"appMinVerReq":"0.5.0","additionalParams":"","sourceCodeLanguage":1}] [{"name":"Wordrain69","id":422341482,"baseUrl":"https://wordrain69.com","lang":"en","typeSource":"single","iconUrl":"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/en.wordrain69.png","dateFormat":"","dateFormatLocale":"","isNsfw":false,"hasCloudflare":false,"sourceCodeUrl":"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/novel/src/en/wordrain69.js","apiUrl":"","version":"0.0.3","isManga":false,"itemType":2,"isFullData":false,"appMinVerReq":"0.5.0","additionalParams":"","sourceCodeLanguage":1,"notes":""},{"name":"Novel Updates","id":413730324,"baseUrl":"https://www.novelupdates.com","lang":"en","typeSource":"single","iconUrl":"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/en.novelupdates.png","dateFormat":"","dateFormatLocale":"","isNsfw":false,"hasCloudflare":true,"sourceCodeUrl":"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/novel/src/en/novelupdates.js","apiUrl":"","version":"0.0.4","isManga":false,"itemType":2,"isFullData":false,"appMinVerReq":"0.5.0","additionalParams":"","sourceCodeLanguage":1,"notes":"This extension requires you to login to view the chapters!"},{"name":"Anna's Archive","id":620172119,"baseUrl":"https://annas-archive.org","lang":"en","typeSource":"single","iconUrl":"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/icon/all.annasarchive.png","dateFormat":"","dateFormatLocale":"","isNsfw":false,"hasCloudflare":true,"sourceCodeUrl":"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/main/javascript/novel/src/all/annasarchive.js","apiUrl":"","version":"0.0.1","isManga":false,"itemType":2,"isFullData":false,"appMinVerReq":"0.5.0","additionalParams":"","sourceCodeLanguage":1,"notes":"EPUBs need to be downloaded to view chapters!"}]

View File

@@ -86,7 +86,7 @@ List<Source> _searchJsSources(Directory dir) {
..appMinVerReq = ..appMinVerReq =
sourceJson["appMinVerReq"] ?? defaultSource.appMinVerReq sourceJson["appMinVerReq"] ?? defaultSource.appMinVerReq
..sourceCodeUrl = ..sourceCodeUrl =
"https://raw.githubusercontent.com/kodjodevf/mangayomi-extensions/$branchName/javascript/${sourceJson["pkgPath"] ?? sourceJson["pkgName"]}"; "https://raw.githubusercontent.com/Schnitzel5/mangayomi-extensions/$branchName/javascript/${sourceJson["pkgPath"] ?? sourceJson["pkgName"]}";
if (sourceJson["id"] != null) { if (sourceJson["id"] != null) {
source = source..id = int.tryParse("${sourceJson["id"]}"); source = source..id = int.tryParse("${sourceJson["id"]}");
} }