added Anna's Archive

This commit is contained in:
Schnitzel5
2025-05-05 20:13:41 +02:00
parent f35de178d3
commit 85f17b4359

View File

@@ -1,6 +1,6 @@
const mangayomiSources = [ const mangayomiSources = [
{ {
"name": "Anna's Archive", "name": "Annas Archive",
"lang": "en", "lang": "en",
"baseUrl": "https://annas-archive.org", "baseUrl": "https://annas-archive.org",
"apiUrl": "", "apiUrl": "",
@@ -14,14 +14,15 @@ const mangayomiSources = [
"pkgPath": "novel/src/all/annasarchive.js", "pkgPath": "novel/src/all/annasarchive.js",
"isNsfw": false, "isNsfw": false,
"hasCloudflare": true, "hasCloudflare": true,
"notes": "EPUBs need to be downloaded to view chapters!" "notes": "EPUBs need to be downloaded to view chapters!",
} },
]; ];
class DefaultExtension extends MProvider { class DefaultExtension extends MProvider {
headers = { headers = {
Priority: "u=0, i",
"User-Agent": "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" "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) { getHeaders(url) {
@@ -29,46 +30,47 @@ class DefaultExtension extends MProvider {
} }
mangaListFromPage(res) { mangaListFromPage(res) {
const doc = new Document(res.body.replaceAll(RegExp("<!--|-->"), "")); const doc = new Document(res.body.replaceAll(/<!--|-->/g, ""));
const mangaElements = doc.select("a"); const mangaElements = doc.select("a");
const list = []; const list = [];
for (const element of mangaElements) { for (const element of mangaElements) {
const name = element.selectFirst("h3").text; const name = element.selectFirst("h3").text;
const imageUrl = element.selectFirst("img").getSrc; const imageUrl = element.selectFirst("img").getSrc;
const link = element.getHref; const link = element.getHref;
if (link.includes("/md5/")) {
list.push({ name, imageUrl, link }); list.push({ name, imageUrl, link });
} }
}
const hasNextPage = true; const hasNextPage = true;
return { list: list, hasNextPage }; 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) { async getPopular(page) {
const res = await new Client().get( const lang = this.source.lang != "all" ? `&lang=${this.source.lang}` : "";
`${this.source.baseUrl}/search?index=&page=${page}&q=&display=&ext=epub&src=lgli&sort=`, let url = `${this.source.baseUrl}/search?index=&page=${page}&q=&display=&ext=epub&src=zlib&sort=`;
this.headers if (lang !== "") {
); url += `&lang=${lang}`;
}
const res = await new Client().get(url, this.headers);
return this.mangaListFromPage(res); return this.mangaListFromPage(res);
} }
async getLatestUpdates(page) { async getLatestUpdates(page) {
const res = await new Client().get( const lang = this.source.lang != "all" ? `&lang=${this.source.lang}` : "";
`${this.source.baseUrl}/search?index=&page=${page}&q=&display=&ext=epub&src=lgli&sort=newest`, let url = `${this.source.baseUrl}/search?index=&page=${page}&q=&display=&ext=epub&src=zlib&sort=newest`;
this.headers if (lang !== "") {
); url += `&lang=${lang}`;
}
const res = await new Client().get(url, this.headers);
return this.mangaListFromPage(res); return this.mangaListFromPage(res);
} }
async search(query, page, filters) { async search(query, page, filters) {
//const lang = this.source.lang != "all" ? `&lang=${this.source.lang}` : ""; const lang = this.source.lang != "all" ? `&lang=${this.source.lang}` : "";
let url = `${this.source.baseUrl}/series-finder/?sf=1&sh=${query}&pg=${page}`; let url = `${this.source.baseUrl}/search?index=&page=${page}&q=${query}&display=&ext=epub&src=zlib&sort=`;
if (lang !== "") {
url += `&lang=${lang}`;
}
const res = await new Client().get(url, this.headers); const res = await new Client().get(url, this.headers);
return this.mangaListFromPage(res); return this.mangaListFromPage(res);
@@ -76,28 +78,45 @@ class DefaultExtension extends MProvider {
async getDetail(url) { async getDetail(url) {
const client = new Client(); const client = new Client();
const res = await client.get(url, this.headers); const res = await client.get(this.source.baseUrl + url, this.headers);
const doc = new Document(res.body); const doc = new Document(res.body);
const imageUrl = doc.selectFirst(".wpb_wrapper img")?.getSrc; const main = doc.selectFirst('main[class="main"]');
const type = doc.selectFirst("#showtype")?.text.trim();
const description = const description = doc
doc.selectFirst("#editdescription")?.text.trim() + `\n\nType: ${type}`; .selectFirst('div[class="mb-1"]')
const author = doc ?.text.trim()
.select("#authtag") .replace("description", "");
.map((el) => el.text.trim()) const author = doc.selectFirst('div[class="italic"]')?.text.trim();
.join(", "); const status = 1;
const artist = doc const genre = [];
.select("#artiststag") console.log(description);
.map((el) => el.text.trim())
.join(", "); const mirrorLink = main
const status = this.toStatus(doc.selectFirst("#editstatus")?.text.trim()); .selectFirst('ul[class="list-inside mb-4 ml-1 js-show-external hidden"]')
const genre = doc.select("#seriesgenre > a").map((el) => el.text.trim()); .select("li > a")
.find((el) => el.getHref?.includes("z-lib.fm")).getHref;
const bookLink = await this._getMirrorLink(client, mirrorLink);
const bytes = await client.getBytes("https://z-lib.fm" + bookLink, {
Connection: "Keep-Alive",
...this.headers,
});
const book = await parseEpub(this.Utf8ArrayToStr(bytes));
const chapters = []; const chapters = [];
for (const chapterTitle in book.chapters) {
chapters.push({
name: chapterTitle,
url: mirrorLink + ";;;" + chapterTitle,
dateUpload: Date.now(),
scanlator: null,
});
}
chapters.reverse(); chapters.reverse();
return { return {
imageUrl,
description, description,
genre, genre,
author, author,
@@ -107,22 +126,100 @@ class DefaultExtension extends MProvider {
}; };
} }
async getHtmlContent(url) { // http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt
const client = await new Client(); /* utf.js - UTF-8 <=> UTF-16 convertion
const res = await client.get(url, { *
Priority: "u=0, i", * Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
"User-Agent": * Version: 1.0
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36", * LastModified: Dec 25 1999
* This library is free. You can redistribute it and/or modify it.
*/
Utf8ArrayToStr(array) {
var out, i, len, c;
var char2, char3;
out = "";
len = array.length;
i = 0;
while (i < len) {
c = array[i++];
switch (c >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
// 0xxxxxxx
out += String.fromCharCode(c);
break;
case 12:
case 13:
// 110x xxxx 10xx xxxx
char2 = array[i++];
out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(
((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0)
);
break;
}
}
return out;
}
async _getMirrorLink(client, mirrorLink) {
const res = await client.get(mirrorLink, {
Origin: this.source.baseUrl,
...this.headers,
}); });
return await this.cleanHtmlContent(res.body); const doc = new Document(res.body);
return doc.selectFirst(
"div.book-details-button > div.btn-group > a.addDownloadedBook"
).getHref;
/*const res = await client.get(mirrorLink, {
"Host": "annas-archive.org",
"Origin": this.source.baseUrl,
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
...this.headers
});
const doc = new Document(res.body);
const links = doc.select('ul[class="mb-4"] > li > a').map((el) => el.getHref).filter((el) => el);
for (var url in links) {
try {
const response = await client.head(url, this.headers);
if (response.statusCode == 200) {
return url;
}
} catch (e) {}
}
return null;*/
}
async getHtmlContent(url) {
const urls = url.split(";;;");
const client = await new Client();
const bookLink = await this._getMirrorLink(client, urls[0]);
const bytes = await client.getBytes("https://z-lib.fm" + bookLink, {
Connection: "Keep-Alive",
...this.headers,
});
return await parseEpubChapter(this.Utf8ArrayToStr(bytes), urls[1]);
} }
async cleanHtmlContent(html) { async cleanHtmlContent(html) {
const client = await new Client(); return html;
const doc = new Document(html);
const domain = html;
return `<p>Domain not supported yet. Content might not load properly!</p>`;
} }
getFilterList() { getFilterList() {