Delete anime/animeav1/source.js
This commit is contained in:
@@ -1,175 +0,0 @@
|
|||||||
class AnimeAV1 {
|
|
||||||
constructor() {
|
|
||||||
this.type = "anime-board";
|
|
||||||
this.version = "1.0.0";
|
|
||||||
this.api = "https://animeav1.com";
|
|
||||||
}
|
|
||||||
|
|
||||||
getSettings() {
|
|
||||||
return { episodeServers: ["HLS", "HLS-DUB"], supportsDub: true };
|
|
||||||
}
|
|
||||||
|
|
||||||
_nativeFetch(url, method, headers, body) {
|
|
||||||
const raw = Native.fetch(String(url), method || "GET", JSON.stringify(headers || {}), body == null ? "" : String(body));
|
|
||||||
try { return JSON.parse(raw || "{}"); } catch (e) { return { ok: false, status: 0, headers: {}, body: "" }; }
|
|
||||||
}
|
|
||||||
|
|
||||||
_getText(url, headers) {
|
|
||||||
const res = this._nativeFetch(url, "GET", headers, "");
|
|
||||||
return String(res.body || "");
|
|
||||||
}
|
|
||||||
|
|
||||||
_getJson(url, headers) {
|
|
||||||
const res = this._nativeFetch(url, "GET", headers, "");
|
|
||||||
try { return JSON.parse(String(res.body || "{}")); } catch (e) { return {}; }
|
|
||||||
}
|
|
||||||
|
|
||||||
_postJson(url, headers, obj) {
|
|
||||||
const res = this._nativeFetch(url, "POST", headers, JSON.stringify(obj || {}));
|
|
||||||
try { return JSON.parse(String(res.body || "{}")); } catch (e) { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
search(query) {
|
|
||||||
const q =
|
|
||||||
(query && typeof query === "object" && query.query) ? String(query.query)
|
|
||||||
: (typeof query === "string" ? query : "");
|
|
||||||
|
|
||||||
if (!q.trim()) return [];
|
|
||||||
|
|
||||||
const data = this._postJson(
|
|
||||||
`${this.api}/api/search`,
|
|
||||||
{ "Content-Type": "application/json" },
|
|
||||||
{ query: q }
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!Array.isArray(data)) return [];
|
|
||||||
|
|
||||||
return data.map((anime) => {
|
|
||||||
const slug = anime && anime.slug ? String(anime.slug) : "";
|
|
||||||
if (!slug) return null;
|
|
||||||
return {
|
|
||||||
id: slug,
|
|
||||||
title: (anime && anime.title) ? String(anime.title) : "Unknown",
|
|
||||||
url: `${this.api}/media/${slug}`,
|
|
||||||
subOrDub: "both",
|
|
||||||
};
|
|
||||||
}).filter(Boolean);
|
|
||||||
}
|
|
||||||
|
|
||||||
getMetadata(id) {
|
|
||||||
const slug = String(id || "").trim();
|
|
||||||
if (!slug) throw new Error("Missing id");
|
|
||||||
|
|
||||||
const html = this._getText(`${this.api}/media/${slug}`, {});
|
|
||||||
const parsed = this.parseSvelteData(html);
|
|
||||||
const media = (parsed.find(x => x && x.data && x.data.media)?.data?.media) || {};
|
|
||||||
|
|
||||||
let image = null;
|
|
||||||
const imageMatch = html.match(/<img[^>]*class="aspect-poster[^"]*"[^>]*src="([^"]+)"/i);
|
|
||||||
if (imageMatch && imageMatch[1]) image = imageMatch[1];
|
|
||||||
|
|
||||||
let year = null;
|
|
||||||
if (media.startDate) {
|
|
||||||
const y = Number(String(media.startDate).slice(0, 4));
|
|
||||||
if (!Number.isNaN(y)) year = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
title: media.title || "Unknown",
|
|
||||||
summary: media.synopsis || "No summary available",
|
|
||||||
episodes: media.episodesCount || 0,
|
|
||||||
characters: [],
|
|
||||||
season: media.seasons || null,
|
|
||||||
status: media.status || "Unknown",
|
|
||||||
studio: "Unknown",
|
|
||||||
score: media.score || 0,
|
|
||||||
year,
|
|
||||||
genres: (media.genres || []).map(g => g && g.name ? g.name : "").filter(Boolean),
|
|
||||||
image,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
findEpisodes(id) {
|
|
||||||
const slug = String(id || "").trim();
|
|
||||||
if (!slug) throw new Error("Missing id");
|
|
||||||
|
|
||||||
const html = this._getText(`${this.api}/media/${slug}`, {});
|
|
||||||
const parsed = this.parseSvelteData(html);
|
|
||||||
const media = (parsed.find(x => x && x.data && x.data.media)?.data?.media) || null;
|
|
||||||
|
|
||||||
if (!media || !Array.isArray(media.episodes)) throw new Error("No episodes");
|
|
||||||
|
|
||||||
return media.episodes.map((ep, i) => {
|
|
||||||
const nRaw = ep && ep.number != null ? ep.number : (i + 1);
|
|
||||||
const n = Number(nRaw);
|
|
||||||
const num = Number.isFinite(n) ? n : (i + 1);
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: `${media.slug || slug}$${num}`,
|
|
||||||
number: num,
|
|
||||||
title: (ep && ep.title) ? String(ep.title) : `Episode ${num}`,
|
|
||||||
url: `${this.api}/media/${media.slug || slug}/${num}`,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
findEpisodeServer(episodeOrId, server) {
|
|
||||||
let ep = episodeOrId;
|
|
||||||
if (typeof ep === "string") { try { ep = JSON.parse(ep); } catch (e) {} }
|
|
||||||
ep = ep || {};
|
|
||||||
|
|
||||||
const srv = String(server || "").trim();
|
|
||||||
if (srv !== "HLS" && srv !== "HLS-DUB") throw new Error("Unknown server");
|
|
||||||
|
|
||||||
const pageUrl =
|
|
||||||
ep.url ||
|
|
||||||
(typeof ep.id === "string" && ep.id.includes("$")
|
|
||||||
? `${this.api}/media/${ep.id.split("$")[0]}/${ep.number || ep.id.split("$")[1]}`
|
|
||||||
: null);
|
|
||||||
|
|
||||||
if (!pageUrl) throw new Error("Missing episode url");
|
|
||||||
|
|
||||||
const html = this._getText(pageUrl, { Referer: `${this.api}/` });
|
|
||||||
const parsed = this.parseSvelteData(html);
|
|
||||||
|
|
||||||
const entry = parsed.find(x => x && x.data && x.data.embeds) || parsed[3];
|
|
||||||
const embeds = entry && entry.data ? entry.data.embeds : null;
|
|
||||||
if (!embeds) throw new Error("No embeds");
|
|
||||||
|
|
||||||
const list = (srv === "HLS") ? (embeds.SUB || []) : (embeds.DUB || []);
|
|
||||||
if (!Array.isArray(list) || !list.length) throw new Error("No mirrors");
|
|
||||||
|
|
||||||
const match = list.find(m => String((m && m.url) || "").includes("zilla-networks.com/play/"));
|
|
||||||
if (!match || !match.url) throw new Error("No valid source");
|
|
||||||
|
|
||||||
return {
|
|
||||||
server: srv,
|
|
||||||
headers: { Referer: pageUrl },
|
|
||||||
videoSources: [{
|
|
||||||
url: String(match.url).replace("/play/", "/m3u8/"),
|
|
||||||
type: "m3u8",
|
|
||||||
quality: "auto",
|
|
||||||
subtitles: []
|
|
||||||
}]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
parseSvelteData(html) {
|
|
||||||
const scriptMatch = html.match(/<script[^>]*>\s*({[^<]*__sveltekit_[\s\S]*?)<\/script>/i);
|
|
||||||
if (!scriptMatch) throw new Error("Svelte data not found");
|
|
||||||
|
|
||||||
const dataMatch = scriptMatch[1].match(/data:\s*(\[[\s\S]*?\])\s*,\s*form:/);
|
|
||||||
if (!dataMatch) throw new Error("Data block missing");
|
|
||||||
|
|
||||||
const jsArray = dataMatch[1];
|
|
||||||
|
|
||||||
try {
|
|
||||||
return new Function(`"use strict"; return (${jsArray});`)();
|
|
||||||
} catch (e) {
|
|
||||||
const cleaned = jsArray.replace(/\bvoid 0\b/g, "null").replace(/undefined/g, "null");
|
|
||||||
return new Function(`"use strict"; return (${cleaned});`)();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = AnimeAV1;
|
|
||||||
Reference in New Issue
Block a user