1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { fetch } from "https://esm.town/v/std/fetch";
import { sify } from "npm:chinese-conv";
const getAll = async () => {
const txt = await fetch("https://d1zquzjgwo9yb.cloudfront.net/").then((r) => r.text());
const list = (
JSON.parse(sify(txt)) as Array<
[cat: string, name: string, status: string, year: string, season: string, source: string]
>
).map((item) => {
const [cat, name, status, year, season, source] = item;
return {
cat,
name: name.replace(/<a href.+>(.*)<\/a>/, "$1"),
status,
year,
season,
source,
url: "https://anime1.me/?cat=" + cat,
};
});
return list;
};
const nameToCat = async (name: string) => {
const all = await getAll();
const cat = all.find((c) => c.name.includes(name));
if (!cat) throw new Error("Cannot find cat by name");
return cat.cat;
};
const getCat = async (catOrName: number | string) => {
const cat = typeof catOrName === "string" ? await nameToCat(catOrName) : catOrName;
const res = await fetch("https://anime1.me/?cat=" + cat);
if (!res.ok) throw new Error(res.statusText);
const html = await res.text();
const name = html.match(/<title>(.+) &#8211;.+<\/title>/)?.[1];
if (!name) throw new Error("Cannot get cat");
const result: any[] = [];
for (const re of html.matchAll(/data-apireq="(.[^"]+)"/g)) {
const encoded = re[1];
const decoded: {
c: string; // cat
e: string; // episode
t: number; // time, new Date(t*1000)
p: string; // always 0
s: string;
} = JSON.parse(decodeURIComponent(encoded));
const { c: cat, e: episode } = decoded;
result.push({
cat,
name: sify(name) as string,
episode,
ep: Number.parseInt(episode),
encoded,
});
}
return result;
};
const getEpisode = async (catOrName: number | string, episode: string | number) => {
const cat = await getCat(catOrName);
const ep = cat.find((c) => c.episode.startsWith(String(episode)));
if (!ep) throw new Error("Episode not exists");
const res = await fetch("https://v.anime1.me/api", {
method: "POST",
headers: {
referer: "https://anime1.me/",
"content-type": "application/x-www-form-urlencoded",
},
body: "d=" + ep.encoded,
});
const getSetCookie = (headers: Headers) => {
const cookie: string[] = [];
headers.forEach((value, key) => {
if (key === "set-cookie") cookie.push(value);
});
return cookie;
};
const cookie = getSetCookie(res.headers);
const json: {
s: Array<{
src: string;
type: string;
}>;
} = await res.json();
json.s = json.s.map((j) => ({
...j,
src: j.src.startsWith("//") ? "https:" + j.src : j.src,
}));
return json.s.map((s) => ({
...s,
cookie,
eval: cookie.length === 0
? ""
: cookie.map((c) => `document.cookie='${c.split("; ").slice(0, 5).join("; ")}'`).join(";") + ";",
}));
};
export async function anime(catOrName?: number | string, episode?: string | number) {
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
v2
October 24, 2023