mirror of
https://git.luna-app.eu/50n50/sources
synced 2025-12-21 13:16:21 +01:00
animevost.js push
animevost.js Push
This commit is contained in:
parent
8e5de589ca
commit
5c72191628
2 changed files with 181 additions and 0 deletions
161
animevost/animevost.js
Normal file
161
animevost/animevost.js
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
// AnimeVost for Sora (AsyncJS)
|
||||
// Author: emp0ry
|
||||
// Version: 1.0.0
|
||||
|
||||
const API_BASE = "https://api.animevost.org/v1/";
|
||||
const FORM_CT = "application/x-www-form-urlencoded; charset=UTF-8";
|
||||
|
||||
// --- utils ---
|
||||
function encodeForm(fields) {
|
||||
return Object.keys(fields)
|
||||
.map(k => `${encodeURIComponent(k)}=${encodeURIComponent(fields[k])}`)
|
||||
.join("&");
|
||||
}
|
||||
|
||||
async function postForm(url, fields) {
|
||||
const bodyStr = encodeForm(fields);
|
||||
try {
|
||||
const resA = await fetchv2(url, { "Content-Type": FORM_CT }, "POST", bodyStr);
|
||||
if (resA && typeof resA.text === "function") return resA;
|
||||
} catch (_) {}
|
||||
return await fetchv2(url, { method: "POST", headers: { "Content-Type": FORM_CT }, body: bodyStr });
|
||||
}
|
||||
|
||||
async function parseJsonSafe(res) {
|
||||
const txt = await res.text();
|
||||
try { return JSON.parse(txt); }
|
||||
catch { return JSON.parse(txt.replace(/^\uFEFF/, "").trim()); }
|
||||
}
|
||||
|
||||
function cleanTitle(raw) {
|
||||
if (!raw || typeof raw !== "string") return "Unknown title";
|
||||
let t = raw.split(" /")[0];
|
||||
return t.replace(/\s*\[.*?\]\s*$/g, "").trim() || "Unknown title";
|
||||
}
|
||||
|
||||
function htmlToText(html) {
|
||||
if (!html || typeof html !== "string") return "";
|
||||
return html
|
||||
.replace(/<br\s*\/?>/gi, "\n")
|
||||
.replace(/<\/p>/gi, "\n")
|
||||
.replace(/<[^>]+>/g, "")
|
||||
.replace(/\n{3,}/g, "\n\n")
|
||||
.trim();
|
||||
}
|
||||
|
||||
// Pack payload into href to avoid relying on global state.
|
||||
function makeHrefFromPayload(obj) {
|
||||
return `animevost://payload/${encodeURIComponent(JSON.stringify(obj))}`;
|
||||
}
|
||||
function readPayloadFromHref(href) {
|
||||
const m = String(href).match(/^animevost:\/\/payload\/(.+)$/);
|
||||
if (!m) return null;
|
||||
try { return JSON.parse(decodeURIComponent(m[1])); } catch { return null; }
|
||||
}
|
||||
function parseIdFromAny(hrefOrId) {
|
||||
const p = readPayloadFromHref(hrefOrId);
|
||||
if (p && p.id) return parseInt(p.id, 10);
|
||||
const m1 = String(hrefOrId).match(/^animevost:\/\/release\/(\d+)$/);
|
||||
if (m1) return parseInt(m1[1], 10);
|
||||
const m2 = String(hrefOrId).match(/[?&]id=(\d+)/);
|
||||
if (m2) return parseInt(m2[1], 10);
|
||||
if (/^\d+$/.test(String(hrefOrId))) return parseInt(hrefOrId, 10);
|
||||
return null;
|
||||
}
|
||||
|
||||
// --- search (POST /search) ---
|
||||
async function searchResults(keyword) {
|
||||
try {
|
||||
let res = await postForm(API_BASE + "search", { name: String(keyword) });
|
||||
let json = await parseJsonSafe(res);
|
||||
|
||||
if (json?.error || !Array.isArray(json?.data) || json.data.length === 0) {
|
||||
res = await postForm(API_BASE + "search", { name: `"${String(keyword)}"` });
|
||||
json = await parseJsonSafe(res);
|
||||
}
|
||||
|
||||
if (json?.error) {
|
||||
return JSON.stringify([]);
|
||||
}
|
||||
|
||||
const list = Array.isArray(json?.data) ? json.data : [];
|
||||
if (!list.length) {
|
||||
return JSON.stringify([]);
|
||||
}
|
||||
|
||||
const tiles = list.map(item => {
|
||||
const payload = {
|
||||
id: item.id,
|
||||
title: cleanTitle(item.title),
|
||||
description: htmlToText(item.description || ""),
|
||||
year: item.year || "",
|
||||
type: item.type || "",
|
||||
image: item.urlImagePreview || ""
|
||||
};
|
||||
return {
|
||||
title: payload.title,
|
||||
image: payload.image,
|
||||
href: makeHrefFromPayload(payload)
|
||||
};
|
||||
});
|
||||
|
||||
return JSON.stringify(tiles);
|
||||
} catch (e) {
|
||||
return JSON.stringify([]);
|
||||
}
|
||||
}
|
||||
|
||||
// --- details (from payload) ---
|
||||
async function extractDetails(href) {
|
||||
try {
|
||||
const p = readPayloadFromHref(href);
|
||||
const out = [{
|
||||
description: p?.description || "No description available.",
|
||||
aliases: `Type: ${p?.type || "Unknown"}`,
|
||||
airdate: p?.year ? String(p.year) : "Unknown"
|
||||
}];
|
||||
return JSON.stringify(out);
|
||||
} catch (e) {
|
||||
return JSON.stringify([]);
|
||||
}
|
||||
}
|
||||
|
||||
// --- episodes (POST /playlist) ---
|
||||
async function extractEpisodes(href) {
|
||||
try {
|
||||
const p = readPayloadFromHref(href);
|
||||
const id = p?.id ?? parseIdFromAny(href);
|
||||
if (!id) {
|
||||
return JSON.stringify([]);
|
||||
}
|
||||
|
||||
const res = await postForm(API_BASE + "playlist", { id: String(id) });
|
||||
const arr = await parseJsonSafe(res);
|
||||
|
||||
if (!Array.isArray(arr)) return JSON.stringify([]);
|
||||
|
||||
const out = arr.map((ep, idx) => {
|
||||
const name = ep?.name || "";
|
||||
const m = name.match(/(\d+)/);
|
||||
const num = m ? parseInt(m[1], 10) : (idx + 1);
|
||||
const link = ep?.hd || ep?.std || null;
|
||||
if (!link) return null;
|
||||
|
||||
return {
|
||||
number: num,
|
||||
title: name || `Episode ${num}`,
|
||||
image: ep?.preview || "",
|
||||
href: link
|
||||
};
|
||||
}).filter(Boolean);
|
||||
|
||||
return JSON.stringify(out);
|
||||
} catch (e) {
|
||||
return JSON.stringify([]);
|
||||
}
|
||||
}
|
||||
|
||||
// --- stream ---
|
||||
async function extractStreamUrl(url) {
|
||||
try { return url; } catch { return null; }
|
||||
}
|
||||
20
animevost/animevost.json
Normal file
20
animevost/animevost.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"sourceName": "AnimeVost",
|
||||
"iconUrl": "https://animevost.org/apple-touch-icon.png",
|
||||
"author": {
|
||||
"name": "emp0ry",
|
||||
"icon": "https://avatars.githubusercontent.com/u/64217088"
|
||||
},
|
||||
"version": "1.0.0",
|
||||
"language": "Russian",
|
||||
"streamType": "MP4",
|
||||
"quality": "720p",
|
||||
"baseUrl": "https://api.animevost.org/v1/",
|
||||
"searchBaseUrl": "https://api.animevost.org/v1/search?name=%s",
|
||||
"scriptUrl": "https://git.luna-app.eu/50n50/sources/raw/branch/main/animevost/animevost.js",
|
||||
"asyncJS": true,
|
||||
"streamAsyncJS": false,
|
||||
"softsub": false,
|
||||
"type": "anime",
|
||||
"downloadSupport": true
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue