diff --git a/anime/animeav1/source.js b/anime/animeav1/source.js deleted file mode 100644 index a6909e7..0000000 --- a/anime/animeav1/source.js +++ /dev/null @@ -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(/]*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(/]*>\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;