all extensions to new format :P
This commit is contained in:
154
mangadex.js
154
mangadex.js
@@ -1,10 +1,9 @@
|
||||
class MangaDex {
|
||||
constructor(fetchPath, cheerioPath, browser) {
|
||||
this.fetchPath = fetchPath;
|
||||
this.browser = browser;
|
||||
constructor() {
|
||||
this.baseUrl = "https://mangadex.org";
|
||||
this.apiUrl = "https://api.mangadex.org";
|
||||
this.type = "book-board";
|
||||
this.type = "book-board";
|
||||
this.mediaType = "manga";
|
||||
}
|
||||
|
||||
getHeaders() {
|
||||
@@ -14,79 +13,122 @@ class MangaDex {
|
||||
};
|
||||
}
|
||||
|
||||
async _fetch(url, options = {}) {
|
||||
if (typeof fetch === 'function') {
|
||||
return fetch(url, options);
|
||||
}
|
||||
const nodeFetch = require(this.fetchPath);
|
||||
return nodeFetch(url, options);
|
||||
}
|
||||
|
||||
async fetchSearchResult(query = "", page = 1) {
|
||||
async search(queryObj) {
|
||||
const query = queryObj.query?.trim() || "";
|
||||
const limit = 25;
|
||||
const offset = (page - 1) * limit;
|
||||
const offset = (1 - 1) * limit;
|
||||
|
||||
let url;
|
||||
if (!query || query.trim() === "") {
|
||||
url = `${this.apiUrl}/manga?limit=${limit}&offset=${offset}&includes[]=cover_art&contentRating[]=safe&contentRating[]=suggestive&availableTranslatedLanguage[]=en&order[followedCount]=desc`;
|
||||
} else {
|
||||
url = `${this.apiUrl}/manga?title=${encodeURIComponent(query)}&limit=${limit}&offset=${offset}&includes[]=cover_art&contentRating[]=safe&contentRating[]=suggestive&availableTranslatedLanguage[]=en`;
|
||||
}
|
||||
const url = `${this.apiUrl}/manga?title=${encodeURIComponent(query)}&limit=${limit}&offset=${offset}&includes[]=cover_art&contentRating[]=safe&contentRating[]=suggestive&availableTranslatedLanguage[]=en`;
|
||||
|
||||
try {
|
||||
const response = await this._fetch(url, { headers: this.getHeaders() });
|
||||
const response = await fetch(url, { headers: this.getHeaders() });
|
||||
if (!response.ok) {
|
||||
console.error(`MangaDex API Error: ${response.statusText}`);
|
||||
return { results: [], hasNextPage: false, page };
|
||||
return [];
|
||||
}
|
||||
|
||||
const json = await response.json();
|
||||
if (!json || !Array.isArray(json.data)) {
|
||||
return { results: [], hasNextPage: false, page };
|
||||
return [];
|
||||
}
|
||||
|
||||
const results = json.data.map(manga => {
|
||||
return json.data.map(manga => {
|
||||
const attributes = manga.attributes;
|
||||
const titleObject = attributes.title || {};
|
||||
const title = titleObject.en || Object.values(titleObject)[0] || 'Unknown Title';
|
||||
|
||||
const coverRelationship = manga.relationships?.find(rel => rel.type === 'cover_art');
|
||||
const coverFileName = coverRelationship?.attributes?.fileName;
|
||||
|
||||
const coverUrl = coverFileName
|
||||
? `https://uploads.mangadex.org/covers/${manga.id}/${coverFileName}.256.jpg`
|
||||
: '';
|
||||
|
||||
const fullCoverUrl = coverFileName
|
||||
? `https://uploads.mangadex.org/covers/${manga.id}/${coverFileName}`
|
||||
|
||||
const coverUrl = coverFileName
|
||||
? `https://uploads.mangadex.org/covers/${manga.id}/${coverFileName}.256.jpg`
|
||||
: '';
|
||||
|
||||
const tags = attributes.tags
|
||||
? attributes.tags.map(t => t.attributes.name.en)
|
||||
: [];
|
||||
|
||||
return {
|
||||
id: manga.id,
|
||||
image: coverUrl,
|
||||
sampleImageUrl: fullCoverUrl,
|
||||
title: title,
|
||||
tags: tags,
|
||||
rating: null,
|
||||
type: 'book'
|
||||
};
|
||||
});
|
||||
|
||||
const total = json.total || 0;
|
||||
const hasNextPage = (offset + limit) < total;
|
||||
} catch (e) {
|
||||
console.error("Error during MangaDex search:", e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getMetadata(id) {
|
||||
try {
|
||||
const res = await fetch(`https://api.mangadex.org/manga/${id}?includes[]=cover_art`);
|
||||
if (!res.ok) throw new Error("MangaDex API error");
|
||||
|
||||
const json = await res.json();
|
||||
const manga = json.data;
|
||||
const attr = manga.attributes;
|
||||
|
||||
const title =
|
||||
attr.title?.en ||
|
||||
Object.values(attr.title || {})[0] ||
|
||||
"";
|
||||
|
||||
const summary =
|
||||
attr.description?.en ||
|
||||
Object.values(attr.description || {})[0] ||
|
||||
"";
|
||||
|
||||
const genres = manga.relationships
|
||||
?.filter(r => r.type === "tag")
|
||||
?.map(r =>
|
||||
r.attributes?.name?.en ||
|
||||
Object.values(r.attributes?.name || {})[0]
|
||||
)
|
||||
?.filter(Boolean) || [];
|
||||
|
||||
const coverRel = manga.relationships.find(r => r.type === "cover_art");
|
||||
const coverFile = coverRel?.attributes?.fileName;
|
||||
const image = coverFile
|
||||
? `https://uploads.mangadex.org/covers/${id}/${coverFile}.512.jpg`
|
||||
: "";
|
||||
|
||||
const score100 = 0;
|
||||
|
||||
const statusMap = {
|
||||
ongoing: "Ongoing",
|
||||
completed: "Completed",
|
||||
hiatus: "Hiatus",
|
||||
cancelled: "Cancelled"
|
||||
};
|
||||
|
||||
return {
|
||||
results,
|
||||
hasNextPage,
|
||||
page
|
||||
id,
|
||||
title,
|
||||
format: "Manga",
|
||||
score: score100,
|
||||
genres,
|
||||
status: statusMap[attr.status] || "",
|
||||
published: attr.year ? String(attr.year) : "???",
|
||||
summary,
|
||||
chapters: attr.lastChapter ? Number(attr.lastChapter) || 0 : 0,
|
||||
image
|
||||
};
|
||||
|
||||
} catch (e) {
|
||||
console.error("Error during MangaDex search:", e);
|
||||
return { results: [], hasNextPage: false, error: e.message };
|
||||
console.error("MangaDex getMetadata error:", e);
|
||||
return {
|
||||
id,
|
||||
title: "",
|
||||
format: "Manga",
|
||||
score: 0,
|
||||
genres: [],
|
||||
status: "",
|
||||
published: "???",
|
||||
summary: "",
|
||||
chapters: 0,
|
||||
image: ""
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +138,7 @@ class MangaDex {
|
||||
const url = `${this.apiUrl}/manga/${mangaId}/feed?translatedLanguage[]=en&order[chapter]=asc&limit=500&includes[]=scanlation_group`;
|
||||
|
||||
try {
|
||||
const response = await this._fetch(url, { headers: this.getHeaders() });
|
||||
const response = await fetch(url, { headers: this.getHeaders() });
|
||||
let chapters = [];
|
||||
|
||||
if (response.ok) {
|
||||
@@ -107,7 +149,7 @@ class MangaDex {
|
||||
.map((ch, index) => ({
|
||||
id: ch.id,
|
||||
title: ch.attributes.title || `Chapter ${ch.attributes.chapter}`,
|
||||
chapter: ch.attributes.chapter,
|
||||
number: ch.attributes.chapter,
|
||||
index: index,
|
||||
language: ch.attributes.translatedLanguage
|
||||
}));
|
||||
@@ -124,23 +166,7 @@ class MangaDex {
|
||||
}
|
||||
}
|
||||
|
||||
let highResCover = null;
|
||||
try {
|
||||
const mangaRes = await this._fetch(`${this.apiUrl}/manga/${mangaId}?includes[]=cover_art`);
|
||||
if (mangaRes.ok) {
|
||||
const mangaJson = await mangaRes.json();
|
||||
const coverRel = mangaJson.data.relationships.find(r => r.type === 'cover_art');
|
||||
if(coverRel && coverRel.attributes && coverRel.attributes.fileName) {
|
||||
highResCover = `https://uploads.mangadex.org/covers/${mangaId}/${coverRel.attributes.fileName}`;
|
||||
}
|
||||
}
|
||||
} catch(e) { }
|
||||
|
||||
return {
|
||||
chapters: chapters,
|
||||
cover: highResCover
|
||||
};
|
||||
|
||||
return chapters;
|
||||
} catch (e) {
|
||||
console.error("Error finding MangaDex chapters:", e);
|
||||
return { chapters: [], cover: null };
|
||||
@@ -153,7 +179,7 @@ class MangaDex {
|
||||
const url = `${this.apiUrl}/at-home/server/${chapterId}`;
|
||||
|
||||
try {
|
||||
const response = await this._fetch(url, { headers: this.getHeaders() });
|
||||
const response = await fetch(url, { headers: this.getHeaders() });
|
||||
if (!response.ok) throw new Error(`Failed to fetch pages: ${response.statusText}`);
|
||||
|
||||
const json = await response.json();
|
||||
@@ -177,4 +203,4 @@ class MangaDex {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { MangaDex };
|
||||
module.exports = MangaDex;
|
||||
Reference in New Issue
Block a user