yaoi
Version:
anime stream scraping
655 lines (654 loc) • 27.6 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAnimesByAlphabet = getAnimesByAlphabet;
const index_1 = require("../index");
const axios_1 = __importDefault(require("axios"));
const cheerio = __importStar(require("cheerio"));
const cache_1 = __importDefault(require("../cache"));
const event_1 = require("../event/event");
const PREFIX_CACHE = "animasu";
const BASE_URL = process.env.ANIMASU_BASE_URL || "https://v9.animasu.cc";
function getAnimes(params, option) {
return __awaiter(this, void 0, void 0, function* () {
try {
const cacheKey = `${PREFIX_CACHE}-animes-${JSON.stringify(params)}`;
const cachedData = cache_1.default.get(cacheKey);
if (cachedData && !(option === null || option === void 0 ? void 0 : option.noCache)) {
(0, event_1.callGetAnimes)({
provider: index_1.Provider.ANIMASU,
animes: cachedData.data,
});
return cachedData;
}
const res = yield axios_1.default.get((params === null || params === void 0 ? void 0 : params.search)
? `${BASE_URL}/page/${params.page || 1}/`
: `${BASE_URL}/pencarian/`, {
params: {
s: (params === null || params === void 0 ? void 0 : params.search) || "",
halaman: (params === null || params === void 0 ? void 0 : params.page) || 1,
urutan: (params === null || params === void 0 ? void 0 : params.sort) || "update",
"genre[]": (params === null || params === void 0 ? void 0 : params.genre) !== undefined ? [params.genre] : (params === null || params === void 0 ? void 0 : params.genres) || [],
"season[]": (params === null || params === void 0 ? void 0 : params.season) !== undefined
? [params.season]
: (params === null || params === void 0 ? void 0 : params.seasons) || [],
"karakter[]": (params === null || params === void 0 ? void 0 : params.characterType) !== undefined
? [params.characterType]
: (params === null || params === void 0 ? void 0 : params.characterTypes) || [],
status: (params === null || params === void 0 ? void 0 : params.status) || "",
tipe: (params === null || params === void 0 ? void 0 : params.type) || "",
},
});
const $ = cheerio.load(res.data);
const animes = [];
$(".bs").each((index, el) => {
const title = $(el).find(".tt").text().trim();
const link = $(el).find("a").attr("href");
const slug = (link === null || link === void 0 ? void 0 : link.split("/")[4].trim()) || "";
const image = $(el).find("img").attr("data-src") || $(el).find("img").attr("src");
const type = $(el).find(".typez").text().trim();
const episode = $(el).find(".epx").text().trim();
let status = $(el).find(".sb").text().trim();
if (status == "🔥🔥🔥") {
status = "ONGOING";
}
else if (status == "Selesai ✓") {
status = "COMPLETE";
}
else {
status = "UPCOMING";
}
animes.push({
title,
slug,
image: image || "",
type,
episode,
status: status,
});
});
const hasNext = $(".hpage .r").length > 0 || $(".pagination .next").length > 0;
const data = {
data: animes,
hasNext,
};
cache_1.default.set(cacheKey, data);
// call event
(0, event_1.callGetAnimes)({
provider: index_1.Provider.ANIMASU,
animes: data.data,
});
return data;
}
catch (error) {
console.error("Error saat mengambil data anime:", error);
return {
hasNext: false,
data: [],
};
}
});
}
function getAnime(slug, option) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e;
try {
const cacheKey = `${PREFIX_CACHE}-anime-detail-${slug}`;
const cachedData = cache_1.default.get(cacheKey);
if (cachedData && !(option === null || option === void 0 ? void 0 : option.noCache)) {
(0, event_1.callGetAnimeDetail)({
provider: index_1.Provider.ANIMASU,
anime: cachedData,
});
return cachedData;
}
const res = yield axios_1.default.get(`${BASE_URL}/anime/${slug}/`);
const $ = cheerio.load(res.data);
const infox = $(".infox");
// Parsing data utama
const title = infox.find("h1[itemprop='headline']").text().trim();
const synonym = infox.find(".alter").text().trim();
const synopsis = $(".sinopsis p").text().trim();
let image = $(".bigcontent .thumb img").attr("src") || "";
if (!image.includes("http")) {
image = `https:${image}`;
}
const rating = $(".rating strong").text().trim() || "N/A";
const trailer = ((_a = $(".trailer iframe").attr("src")) === null || _a === void 0 ? void 0 : _a.trim()) || "";
// Parsing genres
const genres = [];
infox
.find(".spe span")
.first()
.find("a")
.each((_, el) => {
const genreUrl = $(el).attr("href");
const genreName = $(el).text().trim();
const genreSlug = (genreUrl === null || genreUrl === void 0 ? void 0 : genreUrl.split("/")[4]) || "";
genres.push({
name: genreName,
slug: genreSlug,
});
});
// Parsing status
let status = "";
infox.find(".spe span").each((_, el) => {
var _a;
const text = $(el).text().trim();
if (text.toLowerCase().startsWith("status:")) {
const value = (_a = text.split(":")[1]) === null || _a === void 0 ? void 0 : _a.trim();
status =
value === "🔥🔥🔥"
? "ONGOING"
: value === "Selesai ✓"
? "COMPLETE"
: "UPCOMING";
}
});
// Parsing elemen lain
const aired = (_b = infox
.find(".spe span.split")
.filter((_, el) => $(el).text().toLowerCase().startsWith("rilis:"))
.text()
.split(":")[1]) === null || _b === void 0 ? void 0 : _b.trim();
const type = (_c = infox
.find(".spe span")
.filter((_, el) => $(el).text().toLowerCase().startsWith("jenis:"))
.text()
.split(":")[1]) === null || _c === void 0 ? void 0 : _c.trim();
const episode = (_d = infox
.find(".spe span")
.filter((_, el) => $(el).text().toLowerCase().startsWith("episode:"))
.text()
.split(":")[1]) === null || _d === void 0 ? void 0 : _d.trim();
const duration = (_e = infox
.find(".spe span")
.filter((_, el) => $(el).text().toLowerCase().startsWith("durasi:"))
.text()
.split(":")[1]) === null || _e === void 0 ? void 0 : _e.trim();
const author = infox
.find(".spe span")
.filter((_, el) => $(el).text().toLowerCase().startsWith("pengarang:"))
.find("a")
.text()
.trim();
const studio = infox
.find(".spe span")
.filter((_, el) => $(el).text().toLowerCase().startsWith("studio:"))
.find("a")
.text()
.trim();
const season = infox
.find(".spe span")
.filter((_, el) => $(el).text().toLowerCase().startsWith("musim:"))
.find("a")
.text()
.trim();
const posted = infox.find(".spe span[itemprop='author'] i").text().trim();
const updateAt = infox
.find(".spe span.split time[itemprop='dateModified']")
.attr("datetime") || "";
const episodes = [];
$("#daftarepisode li").each((index, el) => {
const a = $(el).find(".lchx a");
const episode = a.text().trim();
const url = a.attr("href") || "";
const slug = url.split("/")[3] || "";
episodes.push({
episode,
slug,
});
});
const batches = [];
$(".soraddlx .soraurlx").each((index, el) => {
const resolution = $(el).find("strong").text().trim();
$(el)
.find("a")
.each((_index, _el) => {
const url = $(_el).attr("href") || "";
const name = $(_el).text().trim();
batches.push({
name,
resolution,
url,
});
});
});
const characterTypes = [];
try {
$("#tikar_shw a").each((index, el) => {
const href = $(el).attr("href") || "";
const name = $(el).text().trim();
const slug = href.split("/")[4] || "";
characterTypes.push({
name,
slug,
});
});
}
catch (er) { }
const data = {
slug,
title,
synonym,
synopsis,
image,
rating: Number(rating.split(" ")[1]) || 0,
author,
genres,
characterTypes,
status,
aired: aired || "Unknown",
type: type || "Unknown",
episode: episode || "Unknown",
duration: duration || "Unknown",
studio: studio || "Unknown",
season: season || "Unknown",
trailer,
updateAt,
episodes,
batches,
};
cache_1.default.set(cacheKey, data);
// call event
(0, event_1.callGetAnimeDetail)({
provider: index_1.Provider.ANIMASU,
anime: data,
});
return data;
}
catch (error) {
console.error("Error saat mengambil data anime:", error);
}
});
}
function getStreams(episodeSlug, option) {
return __awaiter(this, void 0, void 0, function* () {
try {
const cacheKey = `${PREFIX_CACHE}-anime-streams-${episodeSlug}`;
const cachedData = cache_1.default.get(cacheKey);
if (cachedData && !(option === null || option === void 0 ? void 0 : option.noCache)) {
return cachedData;
}
const streams = [];
const res = yield axios_1.default.get(`${BASE_URL}/${episodeSlug}/`);
const $ = cheerio.load(res.data);
$(".mirror option").each((index, el) => {
var _a, _b;
const value = (_a = $(el).attr("value")) === null || _a === void 0 ? void 0 : _a.trim();
if (value) {
const name = $(el).text().trim();
const $$ = cheerio.load(`<div>${atob(value)}</div>`);
streams.push({
name,
url: ((_b = $$("iframe").attr("src")) === null || _b === void 0 ? void 0 : _b.trim()) || "",
});
}
});
cache_1.default.set(cacheKey, streams);
return streams;
}
catch (error) {
console.error("Error saat mengambil data stream:", error);
return [];
}
});
}
function getGenres(option) {
return __awaiter(this, void 0, void 0, function* () {
try {
const cacheKey = `${PREFIX_CACHE}-genres`;
const cachedData = cache_1.default.get(cacheKey);
if (cachedData && !(option === null || option === void 0 ? void 0 : option.noCache)) {
return cachedData;
}
const res = yield axios_1.default.get(`${BASE_URL}/kumpulan-genre-anime-lengkap/`);
const $ = cheerio.load(res.data);
const genres = [];
$(".genrepage a").each((index, el) => {
const name = $(el).text().trim();
const url = $(el).attr("href") || "";
const slug = url.split("/")[4] || "";
genres.push({
name,
slug,
});
});
cache_1.default.set(cacheKey, genres);
return genres;
}
catch (error) {
console.error("Error saat mengambil data genre:", error);
return [];
}
});
}
function getCharacters(option) {
return __awaiter(this, void 0, void 0, function* () {
try {
const cacheKey = `${PREFIX_CACHE}-characters`;
const cachedData = cache_1.default.get(cacheKey);
if (cachedData && !(option === null || option === void 0 ? void 0 : option.noCache)) {
return cachedData;
}
const res = yield axios_1.default.get(`${BASE_URL}/kumpulan-tipe-karakter-lengkap/`);
const $ = cheerio.load(res.data);
const characters = [];
$(".genrepage a").each((index, el) => {
const name = $(el).text().trim();
const url = $(el).attr("href") || "";
const slug = url.split("/")[4] || "";
characters.push({
name,
slug,
});
});
cache_1.default.set(cacheKey, characters);
return characters;
}
catch (error) {
console.error("Error saat mengambil data character:", error);
return [];
}
});
}
function getAnimesByDay(day, option) {
return __awaiter(this, void 0, void 0, function* () {
try {
const cacheKey = `${PREFIX_CACHE}-animes-by-jadwal-${day}`;
const cachedData = cache_1.default.get(cacheKey);
if (cachedData && !(option === null || option === void 0 ? void 0 : option.noCache)) {
(0, event_1.callGetAnimes)({
provider: index_1.Provider.ANIMASU,
animes: cachedData,
});
return cachedData;
}
const res = yield axios_1.default.get(`${BASE_URL}/jadwal/`);
const $ = cheerio.load(res.data);
const animes = [];
$(".bixbox").each((index, el) => {
const $$ = $(el);
const $day = ($$.find(".releases h3 span").text().trim() || "")
.toLowerCase()
.replace("update acak", "random")
.replace("'", "");
if ($day == day) {
$(el)
.find(".bs")
.each((_index, _el) => {
const $$$ = $(_el);
const title = $$$.find(".tt").text().trim();
const link = $$$.find("a").attr("href");
const slug = (link === null || link === void 0 ? void 0 : link.split("/")[4].trim()) || "";
const image = $$$.find("img").attr("data-src") || $$$.find("img").attr("src");
const type = $$$.find(".typez").text().trim();
const episode = $$$.find(".epx").text().trim();
let status = $$$.find(".sb").text().trim();
if (status == "🔥🔥🔥") {
status = "ONGOING";
}
else if (status == "Selesai ✓") {
status = "COMPLETE";
}
else {
status = "UPCOMING";
}
animes.push({
title,
slug,
image: image || "",
type,
episode,
status: status,
});
});
}
});
(0, event_1.callGetAnimes)({
provider: index_1.Provider.ANIMASU,
animes,
});
cache_1.default.set(cacheKey, animes);
return animes;
}
catch (error) {
console.error("Error saat mengambil data anime:", error);
return [];
}
});
}
function getScheduleAnimes(option) {
return __awaiter(this, void 0, void 0, function* () {
const schedules = {
senin: [],
selasa: [],
rabu: [],
kamis: [],
jumat: [],
sabtu: [],
minggu: [],
random: [],
};
try {
const cacheKey = `${PREFIX_CACHE}-schedule-animes`;
const cachedData = cache_1.default.get(cacheKey);
if (cachedData && !(option === null || option === void 0 ? void 0 : option.noCache)) {
for (const key in cachedData) {
(0, event_1.callGetAnimes)({
provider: index_1.Provider.ANIMASU,
animes: cachedData[key],
});
}
return cachedData;
}
const res = yield axios_1.default.get(`${BASE_URL}/jadwal/`);
const $ = cheerio.load(res.data);
$(".bixbox").each((index, el) => {
const $$ = $(el);
const $day = ($$.find(".releases h3 span").text().trim() || "")
.toLowerCase()
.replace("update acak", "random")
.replace("'", "");
const animes = [];
$$.find(".bs").each((_index, _el) => {
const $$$ = $(_el);
const title = $$$.find(".tt").text().trim();
const link = $$$.find("a").attr("href");
const slug = (link === null || link === void 0 ? void 0 : link.split("/")[4].trim()) || "";
const image = $$$.find("img").attr("data-src") || $$$.find("img").attr("src");
const type = $$$.find(".typez").text().trim();
const episode = $$$.find(".epx").text().trim();
let status = $$$.find(".sb").text().trim();
if (status == "🔥🔥🔥") {
status = "ONGOING";
}
else if (status == "Selesai ✓") {
status = "COMPLETE";
}
else {
status = "UPCOMING";
}
animes.push({
title,
slug,
image: image || "",
type,
episode,
status: status,
});
});
// call event
(0, event_1.callGetAnimes)({
provider: index_1.Provider.ANIMASU,
animes,
});
schedules[$day] = animes;
});
cache_1.default.set(cacheKey, schedules);
}
catch (error) {
console.error("Error saat mengambil data jadwal:", error);
}
return schedules;
});
}
function getAnimesByAlphabet(alphabet_1) {
return __awaiter(this, arguments, void 0, function* (alphabet, page = 1, option) {
try {
const cacheKey = `${PREFIX_CACHE}-animes-by-alphabet-${alphabet}-${page}`;
const cachedData = cache_1.default.get(cacheKey);
if (cachedData && !(option === null || option === void 0 ? void 0 : option.noCache)) {
(0, event_1.callGetAnimes)({
provider: index_1.Provider.ANIMASU,
animes: cachedData.data,
});
return cachedData;
}
const res = yield axios_1.default.get(`${BASE_URL}/daftar-anime/page/${page}/`, {
params: {
show: alphabet.toUpperCase(), // Convert alphabet to uppercase
},
});
// Parse the HTML response using Cheerio
const $ = cheerio.load(res.data);
// Determine if there is a next page
const hasNext = $(".hpage .r").length > 0 || $(".pagination .next").length > 0;
// Array to store anime data
const animes = [];
// Iterate through each element matching the class .bx
$(".bx").each((index, el) => {
var _a, _b;
const $$ = $(el);
// Extract image data
const image = ((_b = (_a = $$.find(".imgx img")) === null || _a === void 0 ? void 0 : _a.attr("data-src")) === null || _b === void 0 ? void 0 : _b.trim()) || "";
// Extract title and slug
const title = $$.find(".inx h2 a").text().trim();
let slug = $$.find(".inx h2 a").attr("href") || "";
slug = slug.substring(0, slug.lastIndexOf("/")).split("/").pop() || "";
// Extract type
const type = $($$.find(".inx span").get(3)).text().trim();
// Extract episode
const episode = $($$.find(".inx span").get(4))
.text()
.trim()
.replace(", ", "");
// Extract status
const status = $$.find(".inx span:contains('[Selesai]')").length
? "COMPLETE"
: $$.find(".inx span:contains('Ongoing')").length
? "ONGOING"
: "UPCOMING";
animes.push({
title,
slug,
image,
type,
episode,
status,
});
});
const result = {
hasNext,
data: animes,
};
cache_1.default.set(cacheKey, result);
(0, event_1.callGetAnimes)({
provider: index_1.Provider.ANIMASU,
animes: result.data,
});
return result;
}
catch (error) {
console.error("Error fetching anime data:", error);
return {
hasNext: false,
data: [],
};
}
});
}
// async function getNewUpdate(): Promise<AnimeDetail | undefined> {
// try {
// const resCbox = await axios.get(
// `https://www5.cbox.ws/box/?boxid=946129&boxtag=dHK21Z`
// );
// const $ = cheerio.load(resCbox.data);
// let messagers = $(".msg");
// const el = messagers.get(messagers.length - 1);
// const $$ = $(el);
// const isBot = $$.find(".nme").text().trim() === "Bot Animasu";
// const isUpdate = $$.find(".body").text().trim().includes("Update:");
// if (isBot && isUpdate) {
// const epsUrl = $$.find(".body a").attr("href");
// const epsSlug = epsUrl?.split("/")[3];
// const
// if(epsSlug?.includes("-episode-")){
// }
// const animeSlug = epsSlug?.split("-episode-")[0].replace("nonton-", "");
// if(animeSlug && epsSlug){
// const anime = await getAnime(animeSlug || "");
// }
// }
// // const lastMessage = messagers.get(messagers.length - 1);
// // console.log($(lastMessage).text().trim());
// } catch (error) {
// console.error("Error saat mengambil data anime:", error);
// return;
// }
// }
exports.default = {
getAnimes,
getAnime,
getStreams,
getGenres,
getCharacters,
getAnimesByDay,
getScheduleAnimes,
getAnimesByAlphabet,
// getNewUpdate,
};