animob 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +245 -0
- package/animb.png +0 -0
- package/dist/extractors/index.d.ts +11 -0
- package/dist/extractors/index.js +27 -0
- package/dist/extractors/index.js.map +1 -0
- package/dist/extractors/kwik.d.ts +18 -0
- package/dist/extractors/kwik.js +117 -0
- package/dist/extractors/kwik.js.map +1 -0
- package/dist/extractors/lplayer.d.ts +11 -0
- package/dist/extractors/lplayer.js +131 -0
- package/dist/extractors/lplayer.js.map +1 -0
- package/dist/extractors/megacloud.d.ts +10 -0
- package/dist/extractors/megacloud.js +44 -0
- package/dist/extractors/megacloud.js.map +1 -0
- package/dist/extractors/megaup.d.ts +31 -0
- package/dist/extractors/megaup.js +79 -0
- package/dist/extractors/megaup.js.map +1 -0
- package/dist/extractors/mixdrop.d.ts +7 -0
- package/dist/extractors/mixdrop.js +32 -0
- package/dist/extractors/mixdrop.js.map +1 -0
- package/dist/extractors/movearnpre.d.ts +9 -0
- package/dist/extractors/movearnpre.js +154 -0
- package/dist/extractors/movearnpre.js.map +1 -0
- package/dist/extractors/sendvid.d.ts +8 -0
- package/dist/extractors/sendvid.js +76 -0
- package/dist/extractors/sendvid.js.map +1 -0
- package/dist/extractors/sibnet.d.ts +8 -0
- package/dist/extractors/sibnet.js +44 -0
- package/dist/extractors/sibnet.js.map +1 -0
- package/dist/extractors/streamsb.d.ts +11 -0
- package/dist/extractors/streamsb.js +65 -0
- package/dist/extractors/streamsb.js.map +1 -0
- package/dist/extractors/streamtape.d.ts +7 -0
- package/dist/extractors/streamtape.js +32 -0
- package/dist/extractors/streamtape.js.map +1 -0
- package/dist/extractors/streamwish.d.ts +11 -0
- package/dist/extractors/streamwish.js +46 -0
- package/dist/extractors/streamwish.js.map +1 -0
- package/dist/extractors/vidcloud.d.ts +11 -0
- package/dist/extractors/vidcloud.js +109 -0
- package/dist/extractors/vidcloud.js.map +1 -0
- package/dist/extractors/videostr.d.ts +10 -0
- package/dist/extractors/videostr.js +44 -0
- package/dist/extractors/videostr.js.map +1 -0
- package/dist/extractors/vidmoly.d.ts +7 -0
- package/dist/extractors/vidmoly.js +75 -0
- package/dist/extractors/vidmoly.js.map +1 -0
- package/dist/extractors/voe.d.ts +10 -0
- package/dist/extractors/voe.js +44 -0
- package/dist/extractors/voe.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/models/anime-parser.d.ts +26 -0
- package/dist/models/anime-parser.js +14 -0
- package/dist/models/anime-parser.js.map +1 -0
- package/dist/models/base-parser.d.ts +10 -0
- package/dist/models/base-parser.js +7 -0
- package/dist/models/base-parser.js.map +1 -0
- package/dist/models/base-provider.d.ts +40 -0
- package/dist/models/base-provider.js +45 -0
- package/dist/models/base-provider.js.map +1 -0
- package/dist/models/base-types.d.ts +22 -0
- package/dist/models/base-types.js +3 -0
- package/dist/models/base-types.js.map +1 -0
- package/dist/models/book-parser.d.ts +4 -0
- package/dist/models/book-parser.js +7 -0
- package/dist/models/book-parser.js.map +1 -0
- package/dist/models/comic-parser.d.ts +4 -0
- package/dist/models/comic-parser.js +7 -0
- package/dist/models/comic-parser.js.map +1 -0
- package/dist/models/index.d.ts +13 -0
- package/dist/models/index.js +39 -0
- package/dist/models/index.js.map +1 -0
- package/dist/models/lightnovel-parser.d.ts +16 -0
- package/dist/models/lightnovel-parser.js +7 -0
- package/dist/models/lightnovel-parser.js.map +1 -0
- package/dist/models/manga-parser.d.ts +17 -0
- package/dist/models/manga-parser.js +10 -0
- package/dist/models/manga-parser.js.map +1 -0
- package/dist/models/movie-parser.d.ts +26 -0
- package/dist/models/movie-parser.js +7 -0
- package/dist/models/movie-parser.js.map +1 -0
- package/dist/models/news-parser.d.ts +4 -0
- package/dist/models/news-parser.js +7 -0
- package/dist/models/news-parser.js.map +1 -0
- package/dist/models/proxy.d.ts +25 -0
- package/dist/models/proxy.js +83 -0
- package/dist/models/proxy.js.map +1 -0
- package/dist/models/type-objects.d.ts +48 -0
- package/dist/models/type-objects.js +57 -0
- package/dist/models/type-objects.js.map +1 -0
- package/dist/models/types.d.ts +515 -0
- package/dist/models/types.js +118 -0
- package/dist/models/types.js.map +1 -0
- package/dist/models/video-extractor.d.ts +19 -0
- package/dist/models/video-extractor.js +10 -0
- package/dist/models/video-extractor.js.map +1 -0
- package/dist/providers/anime/animekai.d.ts +94 -0
- package/dist/providers/anime/animekai.js +661 -0
- package/dist/providers/anime/animekai.js.map +1 -0
- package/dist/providers/anime/animepahe.d.ts +41 -0
- package/dist/providers/anime/animepahe.js +270 -0
- package/dist/providers/anime/animepahe.js.map +1 -0
- package/dist/providers/anime/animesama.d.ts +25 -0
- package/dist/providers/anime/animesama.js +504 -0
- package/dist/providers/anime/animesama.js.map +1 -0
- package/dist/providers/anime/animesaturn.d.ts +32 -0
- package/dist/providers/anime/animesaturn.js +298 -0
- package/dist/providers/anime/animesaturn.js.map +1 -0
- package/dist/providers/anime/animeunity.d.ts +27 -0
- package/dist/providers/anime/animeunity.js +157 -0
- package/dist/providers/anime/animeunity.js.map +1 -0
- package/dist/providers/anime/hianime.d.ts +150 -0
- package/dist/providers/anime/hianime.js +825 -0
- package/dist/providers/anime/hianime.js.map +1 -0
- package/dist/providers/anime/index.d.ts +17 -0
- package/dist/providers/anime/index.js +22 -0
- package/dist/providers/anime/index.js.map +1 -0
- package/dist/providers/anime/kickassanime.d.ts +65 -0
- package/dist/providers/anime/kickassanime.js +582 -0
- package/dist/providers/anime/kickassanime.js.map +1 -0
- package/dist/providers/books/index.d.ts +2 -0
- package/dist/providers/books/index.js +4 -0
- package/dist/providers/books/index.js.map +1 -0
- package/dist/providers/comics/getComics.d.ts +9 -0
- package/dist/providers/comics/getComics.js +54 -0
- package/dist/providers/comics/getComics.js.map +1 -0
- package/dist/providers/comics/index.d.ts +5 -0
- package/dist/providers/comics/index.js +8 -0
- package/dist/providers/comics/index.js.map +1 -0
- package/dist/providers/index.d.ts +9 -0
- package/dist/providers/index.js +23 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/light-novels/index.d.ts +5 -0
- package/dist/providers/light-novels/index.js +8 -0
- package/dist/providers/light-novels/index.js.map +1 -0
- package/dist/providers/light-novels/novelupdates.d.ts +26 -0
- package/dist/providers/light-novels/novelupdates.js +155 -0
- package/dist/providers/light-novels/novelupdates.js.map +1 -0
- package/dist/providers/manga/asurascans.d.ts +16 -0
- package/dist/providers/manga/asurascans.js +143 -0
- package/dist/providers/manga/asurascans.js.map +1 -0
- package/dist/providers/manga/comick.d.ts +36 -0
- package/dist/providers/manga/comick.js +141 -0
- package/dist/providers/manga/comick.js.map +1 -0
- package/dist/providers/manga/comix.d.ts +36 -0
- package/dist/providers/manga/comix.js +265 -0
- package/dist/providers/manga/comix.js.map +1 -0
- package/dist/providers/manga/index.d.ts +21 -0
- package/dist/providers/manga/index.js +26 -0
- package/dist/providers/manga/index.js.map +1 -0
- package/dist/providers/manga/mangadex.d.ts +26 -0
- package/dist/providers/manga/mangadex.js +301 -0
- package/dist/providers/manga/mangadex.js.map +1 -0
- package/dist/providers/manga/mangahere.d.ts +29 -0
- package/dist/providers/manga/mangahere.js +376 -0
- package/dist/providers/manga/mangahere.js.map +1 -0
- package/dist/providers/manga/mangakakalot.d.ts +56 -0
- package/dist/providers/manga/mangakakalot.js +461 -0
- package/dist/providers/manga/mangakakalot.js.map +1 -0
- package/dist/providers/manga/mangapill.d.ts +15 -0
- package/dist/providers/manga/mangapill.js +104 -0
- package/dist/providers/manga/mangapill.js.map +1 -0
- package/dist/providers/manga/mangareader.d.ts +15 -0
- package/dist/providers/manga/mangareader.js +110 -0
- package/dist/providers/manga/mangareader.js.map +1 -0
- package/dist/providers/manga/weebcentral.d.ts +12 -0
- package/dist/providers/manga/weebcentral.js +169 -0
- package/dist/providers/manga/weebcentral.js.map +1 -0
- package/dist/providers/meta/anilist.d.ts +206 -0
- package/dist/providers/meta/anilist.js +2025 -0
- package/dist/providers/meta/anilist.js.map +1 -0
- package/dist/providers/meta/index.d.ts +9 -0
- package/dist/providers/meta/index.js +10 -0
- package/dist/providers/meta/index.js.map +1 -0
- package/dist/providers/meta/mal.d.ts +39 -0
- package/dist/providers/meta/mal.js +529 -0
- package/dist/providers/meta/mal.js.map +1 -0
- package/dist/providers/meta/tmdb.d.ts +48 -0
- package/dist/providers/meta/tmdb.js +364 -0
- package/dist/providers/meta/tmdb.js.map +1 -0
- package/dist/providers/movies/dramacool.d.ts +98 -0
- package/dist/providers/movies/dramacool.js +367 -0
- package/dist/providers/movies/dramacool.js.map +1 -0
- package/dist/providers/movies/flixhq.d.ts +90 -0
- package/dist/providers/movies/flixhq.js +438 -0
- package/dist/providers/movies/flixhq.js.map +1 -0
- package/dist/providers/movies/goku.d.ts +80 -0
- package/dist/providers/movies/goku.js +369 -0
- package/dist/providers/movies/goku.js.map +1 -0
- package/dist/providers/movies/himovies.d.ts +102 -0
- package/dist/providers/movies/himovies.js +445 -0
- package/dist/providers/movies/himovies.js.map +1 -0
- package/dist/providers/movies/index.d.ts +17 -0
- package/dist/providers/movies/index.js +22 -0
- package/dist/providers/movies/index.js.map +1 -0
- package/dist/providers/movies/netmirror.d.ts +27 -0
- package/dist/providers/movies/netmirror.js +259 -0
- package/dist/providers/movies/netmirror.js.map +1 -0
- package/dist/providers/movies/sflix.d.ts +106 -0
- package/dist/providers/movies/sflix.js +490 -0
- package/dist/providers/movies/sflix.js.map +1 -0
- package/dist/providers/movies/turkish123.d.ts +32 -0
- package/dist/providers/movies/turkish123.js +141 -0
- package/dist/providers/movies/turkish123.js.map +1 -0
- package/dist/providers/news/animenewsnetwork.d.ts +30 -0
- package/dist/providers/news/animenewsnetwork.js +105 -0
- package/dist/providers/news/animenewsnetwork.js.map +1 -0
- package/dist/providers/news/index.d.ts +5 -0
- package/dist/providers/news/index.js +8 -0
- package/dist/providers/news/index.js.map +1 -0
- package/dist/providers/others/index.d.ts +0 -0
- package/dist/providers/others/index.js +2 -0
- package/dist/providers/others/index.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +33 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/providers-list.d.ts +11 -0
- package/dist/utils/providers-list.js +40 -0
- package/dist/utils/providers-list.js.map +1 -0
- package/dist/utils/queries.d.ts +13 -0
- package/dist/utils/queries.js +31 -0
- package/dist/utils/queries.js.map +1 -0
- package/dist/utils/utils.d.ts +32 -0
- package/dist/utils/utils.js +324 -0
- package/dist/utils/utils.js.map +1 -0
- package/package.json +107 -0
|
@@ -0,0 +1,661 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const cheerio_1 = require("cheerio");
|
|
4
|
+
const models_1 = require("../../models");
|
|
5
|
+
const extractors_1 = require("../../extractors");
|
|
6
|
+
const { GenerateToken, DecodeIframeData } = new extractors_1.MegaUp();
|
|
7
|
+
/**
|
|
8
|
+
* Parses an AJAX response that may come as:
|
|
9
|
+
* 1. A parsed JSON object (axios auto-parsed)
|
|
10
|
+
* 2. A raw JSON string
|
|
11
|
+
* 3. An HTML-wrapped JSON string (e.g. <html>...<pre>{JSON}</pre>...</html>)
|
|
12
|
+
*
|
|
13
|
+
* @param data The raw response data from axios
|
|
14
|
+
* @returns The parsed JSON object, or undefined if parsing failed
|
|
15
|
+
*/
|
|
16
|
+
function parseAjaxResponse(data) {
|
|
17
|
+
if (typeof data === 'object')
|
|
18
|
+
return data;
|
|
19
|
+
if (typeof data === 'string') {
|
|
20
|
+
let jsonStr = data;
|
|
21
|
+
if (jsonStr.trimStart().startsWith('<')) {
|
|
22
|
+
const $ = (0, cheerio_1.load)(jsonStr);
|
|
23
|
+
jsonStr = $('pre').text();
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(jsonStr);
|
|
27
|
+
}
|
|
28
|
+
catch (_a) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Checks if the response HTML is a Cloudflare access denied / challenge page.
|
|
36
|
+
* Throws a descriptive error so callers know the issue is Cloudflare, not a bug.
|
|
37
|
+
*/
|
|
38
|
+
function assertNotCloudflareBlock(html, context) {
|
|
39
|
+
if (typeof html === 'string' &&
|
|
40
|
+
(html.includes('Access denied') || html.includes('Just a moment')) &&
|
|
41
|
+
html.includes('Cloudflare')) {
|
|
42
|
+
throw new Error(`[${context}] Cloudflare blocked the request. The response is a challenge/block page, not the actual site content.`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
class AnimeKai extends models_1.AnimeParser {
|
|
46
|
+
constructor() {
|
|
47
|
+
super(...arguments);
|
|
48
|
+
this.name = 'AnimeKai';
|
|
49
|
+
this.baseUrl = 'https://anikai.to';
|
|
50
|
+
this.logo = 'https://anikai.to/assets/uploads/37585a3ffa8ec292ee9e2255f3f63b48ceca17ef2a0386.png';
|
|
51
|
+
this.classPath = 'ANIME.AnimeKai';
|
|
52
|
+
/**
|
|
53
|
+
* Fetch anime information
|
|
54
|
+
* @param id Anime ID/slug
|
|
55
|
+
* @returns Promise<IAnimeInfo>
|
|
56
|
+
*/
|
|
57
|
+
this.fetchAnimeInfo = async (id) => {
|
|
58
|
+
var _a;
|
|
59
|
+
// Strip episode params ($ep=...,$token=...) if present — only use the anime slug
|
|
60
|
+
const animeSlug = id.split('$')[0];
|
|
61
|
+
const info = {
|
|
62
|
+
id: animeSlug,
|
|
63
|
+
title: '',
|
|
64
|
+
};
|
|
65
|
+
try {
|
|
66
|
+
const { data } = await this.client.get(`${this.baseUrl}/watch/${animeSlug}`, {
|
|
67
|
+
headers: this.Headers(),
|
|
68
|
+
});
|
|
69
|
+
if (typeof data === 'string')
|
|
70
|
+
assertNotCloudflareBlock(data, 'fetchAnimeInfo');
|
|
71
|
+
const $ = (0, cheerio_1.load)(typeof data === 'string' ? data : '');
|
|
72
|
+
info.title = $('.entity-scroll > .title').text();
|
|
73
|
+
info.japaneseTitle = (_a = $('.entity-scroll > .title').attr('data-jp')) === null || _a === void 0 ? void 0 : _a.trim();
|
|
74
|
+
info.image = $('div.poster > div >img').attr('src');
|
|
75
|
+
info.description = $('.entity-scroll > .desc').text().trim();
|
|
76
|
+
// Movie, TV, OVA, ONA, Special, Music
|
|
77
|
+
info.type = $('.entity-scroll > .info').children().last().text().toUpperCase();
|
|
78
|
+
info.url = `${this.baseUrl}/watch/${animeSlug}`;
|
|
79
|
+
info.recommendations = [];
|
|
80
|
+
$('section.sidebar-section:not(#related-anime) .aitem-col .aitem').each((i, ele) => {
|
|
81
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
82
|
+
const aTag = $(ele);
|
|
83
|
+
const id = (_a = aTag.attr('href')) === null || _a === void 0 ? void 0 : _a.replace('/watch/', '');
|
|
84
|
+
(_b = info.recommendations) === null || _b === void 0 ? void 0 : _b.push({
|
|
85
|
+
id: id,
|
|
86
|
+
title: aTag.find('.title').text().trim(),
|
|
87
|
+
url: `${this.baseUrl}${aTag.attr('href')}`,
|
|
88
|
+
image: (_d = (_c = aTag.attr('style')) === null || _c === void 0 ? void 0 : _c.match(/background-image:\s*url\('(.+?)'\)/)) === null || _d === void 0 ? void 0 : _d[1],
|
|
89
|
+
japaneseTitle: (_e = aTag.find('.title').attr('data-jp')) === null || _e === void 0 ? void 0 : _e.trim(),
|
|
90
|
+
type: aTag.find('.info').children().last().text().trim(),
|
|
91
|
+
sub: parseInt((_f = aTag.find('.info span.sub')) === null || _f === void 0 ? void 0 : _f.text()) || 0,
|
|
92
|
+
dub: parseInt((_g = aTag.find('.info span.dub')) === null || _g === void 0 ? void 0 : _g.text()) || 0,
|
|
93
|
+
episodes: parseInt((_h = aTag.find('.info').children().eq(-2).text().trim()) !== null && _h !== void 0 ? _h : (_j = aTag.find('.info span.sub')) === null || _j === void 0 ? void 0 : _j.text()) || 0,
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
info.relations = [];
|
|
97
|
+
$('section#related-anime .aitem-col a.aitem').each((_, el) => {
|
|
98
|
+
var _a, _b, _c, _d, _e, _f;
|
|
99
|
+
const aTag = $(el);
|
|
100
|
+
const infoBox = aTag.find('.info');
|
|
101
|
+
const id = (_b = (_a = aTag.attr('href')) === null || _a === void 0 ? void 0 : _a.replace('/watch/', '')) !== null && _b !== void 0 ? _b : '';
|
|
102
|
+
const title = aTag.find('.title').text().trim();
|
|
103
|
+
const japaneseTitle = (_c = aTag.find('.title').attr('data-jp')) === null || _c === void 0 ? void 0 : _c.trim();
|
|
104
|
+
const sub = parseInt(infoBox.find('.sub').text()) || 0;
|
|
105
|
+
const dub = parseInt(infoBox.find('.dub').text()) || 0;
|
|
106
|
+
const bolds = infoBox.find('span > b');
|
|
107
|
+
let episodes = 0;
|
|
108
|
+
let type = '';
|
|
109
|
+
let relationType = '';
|
|
110
|
+
bolds.each((_, b) => {
|
|
111
|
+
const text = $(b).text().trim();
|
|
112
|
+
if ($(b).hasClass('text-muted')) {
|
|
113
|
+
relationType = text;
|
|
114
|
+
}
|
|
115
|
+
else if (/^\d+$/.test(text)) {
|
|
116
|
+
episodes = parseInt(text);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
type = text; // TV, MOVIE, etc
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
(_d = info.relations) === null || _d === void 0 ? void 0 : _d.push({
|
|
123
|
+
id,
|
|
124
|
+
title,
|
|
125
|
+
url: `${this.baseUrl}${aTag.attr('href')}`,
|
|
126
|
+
image: (_f = (_e = aTag.attr('style')) === null || _e === void 0 ? void 0 : _e.match(/background-image:\s*url\('(.+?)'\)/)) === null || _f === void 0 ? void 0 : _f[1],
|
|
127
|
+
japaneseTitle,
|
|
128
|
+
type: type.toUpperCase(),
|
|
129
|
+
sub,
|
|
130
|
+
dub,
|
|
131
|
+
relationType,
|
|
132
|
+
episodes,
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
const hasSub = $('.entity-scroll > .info > span.sub').length > 0;
|
|
136
|
+
const hasDub = $('.entity-scroll > .info > span.dub').length > 0;
|
|
137
|
+
if (hasSub) {
|
|
138
|
+
info.subOrDub = models_1.SubOrSub.SUB;
|
|
139
|
+
info.hasSub = hasSub;
|
|
140
|
+
}
|
|
141
|
+
if (hasDub) {
|
|
142
|
+
info.subOrDub = models_1.SubOrSub.DUB;
|
|
143
|
+
info.hasDub = hasDub;
|
|
144
|
+
}
|
|
145
|
+
if (hasSub && hasDub) {
|
|
146
|
+
info.subOrDub = models_1.SubOrSub.BOTH;
|
|
147
|
+
}
|
|
148
|
+
info.genres = [];
|
|
149
|
+
$('.entity-scroll > .detail')
|
|
150
|
+
.find('div')
|
|
151
|
+
.each(function () {
|
|
152
|
+
const text = $(this).text().trim();
|
|
153
|
+
if (text.startsWith('Genres:')) {
|
|
154
|
+
const genresText = text.replace('Genres:', '').trim();
|
|
155
|
+
const genres = genresText.split(',').map(g => g.trim());
|
|
156
|
+
info.genres = genres;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
switch ($('.entity-scroll > .detail').find("div:contains('Status') > span").text().trim()) {
|
|
160
|
+
case 'Completed':
|
|
161
|
+
info.status = models_1.MediaStatus.COMPLETED;
|
|
162
|
+
break;
|
|
163
|
+
case 'Releasing':
|
|
164
|
+
info.status = models_1.MediaStatus.ONGOING;
|
|
165
|
+
break;
|
|
166
|
+
case 'Not yet aired':
|
|
167
|
+
info.status = models_1.MediaStatus.NOT_YET_AIRED;
|
|
168
|
+
break;
|
|
169
|
+
default:
|
|
170
|
+
info.status = models_1.MediaStatus.UNKNOWN;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
info.season = $('.entity-scroll > .detail').find("div:contains('Premiered') > span").text().trim();
|
|
174
|
+
info.duration = $('.entity-scroll > .detail').find("div:contains('Duration') > span").text().trim();
|
|
175
|
+
$('.entity-scroll > .detail div')
|
|
176
|
+
.filter((_, el) => $(el).text().includes('Links:'))
|
|
177
|
+
.find('a')
|
|
178
|
+
.each((_, el) => {
|
|
179
|
+
var _a, _b, _c, _d, _e;
|
|
180
|
+
const href = (_a = $(el).attr('href')) !== null && _a !== void 0 ? _a : '';
|
|
181
|
+
if (href.includes('myanimelist'))
|
|
182
|
+
info.malId = (_c = (_b = href.match(/anime\/(\d+)/)) === null || _b === void 0 ? void 0 : _b[1]) !== null && _c !== void 0 ? _c : '';
|
|
183
|
+
if (href.includes('anilist'))
|
|
184
|
+
info.anilistId = (_e = (_d = href.match(/anime\/(\d+)/)) === null || _d === void 0 ? void 0 : _d[1]) !== null && _e !== void 0 ? _e : '';
|
|
185
|
+
});
|
|
186
|
+
const ani_id = $('.rate-box#anime-rating').attr('data-id');
|
|
187
|
+
const episodesAjax = await this.client.get(`${this.baseUrl}/ajax/episodes/list?ani_id=${ani_id}&_=${await GenerateToken(ani_id)}`, {
|
|
188
|
+
headers: {
|
|
189
|
+
...this.Headers(),
|
|
190
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
191
|
+
Referer: `${this.baseUrl}/watch/${animeSlug}`,
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
const episodesParsed = parseAjaxResponse(episodesAjax.data);
|
|
195
|
+
const episodesResult = episodesParsed === null || episodesParsed === void 0 ? void 0 : episodesParsed.result;
|
|
196
|
+
if (!episodesResult || typeof episodesResult !== 'string') {
|
|
197
|
+
info.totalEpisodes = 0;
|
|
198
|
+
info.episodes = [];
|
|
199
|
+
return info;
|
|
200
|
+
}
|
|
201
|
+
const $$ = (0, cheerio_1.load)(episodesResult);
|
|
202
|
+
info.totalEpisodes = $$('div.eplist > ul > li').length;
|
|
203
|
+
info.episodes = [];
|
|
204
|
+
$$('div.eplist > ul > li > a').each((i, el) => {
|
|
205
|
+
var _a;
|
|
206
|
+
const episodeId = `${animeSlug}$ep=${$$(el).attr('num')}$token=${$$(el).attr('token')}`; //appending token to episode id, as it is required to fetch servers keeping the structure same as other providers
|
|
207
|
+
const number = parseInt($$(el).attr('num'));
|
|
208
|
+
const title = $$(el).children('span').text().trim();
|
|
209
|
+
const url = `${this.baseUrl}/watch/${animeSlug}${$$(el).attr('href')}ep=${$$(el).attr('num')}`;
|
|
210
|
+
const isFiller = $$(el).hasClass('filler');
|
|
211
|
+
const isSubbed = number <= (parseInt($('.entity-scroll > .info > span.sub').text().trim()) || 0);
|
|
212
|
+
const isDubbed = number <= (parseInt($('.entity-scroll > .info > span.dub').text().trim()) || 0);
|
|
213
|
+
(_a = info.episodes) === null || _a === void 0 ? void 0 : _a.push({
|
|
214
|
+
id: episodeId,
|
|
215
|
+
number: number,
|
|
216
|
+
title: title,
|
|
217
|
+
isFiller: isFiller,
|
|
218
|
+
isSubbed: isSubbed,
|
|
219
|
+
isDubbed: isDubbed,
|
|
220
|
+
url: url,
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
return info;
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
throw new Error(err.message);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* Fetch episode video sources
|
|
231
|
+
* @param episodeId Episode ID
|
|
232
|
+
* @param server Server type (default: VidCloud)
|
|
233
|
+
* @param subOrDub Sub or dub preference (default: SUB)
|
|
234
|
+
* @returns Promise<ISource>
|
|
235
|
+
*/
|
|
236
|
+
this.fetchEpisodeSources = async (episodeId, server = models_1.StreamingServers.MegaUp, subOrDub = models_1.SubOrSub.SUB) => {
|
|
237
|
+
var _a, _b;
|
|
238
|
+
if (episodeId.startsWith('http')) {
|
|
239
|
+
const serverUrl = new URL(episodeId);
|
|
240
|
+
switch (server) {
|
|
241
|
+
case models_1.StreamingServers.MegaUp:
|
|
242
|
+
return {
|
|
243
|
+
headers: { Referer: serverUrl.href },
|
|
244
|
+
...(await new extractors_1.MegaUp(this.proxyConfig, this.adapter).extract(serverUrl)),
|
|
245
|
+
download: serverUrl.href.replace(/\/e\//, '/download/'),
|
|
246
|
+
};
|
|
247
|
+
default:
|
|
248
|
+
return {
|
|
249
|
+
headers: { Referer: serverUrl.href },
|
|
250
|
+
...(await new extractors_1.MegaUp(this.proxyConfig, this.adapter).extract(serverUrl)),
|
|
251
|
+
download: serverUrl.href.replace(/\/e\//, '/download/'),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
try {
|
|
256
|
+
const servers = await this.fetchEpisodeServers(episodeId, subOrDub);
|
|
257
|
+
const i = servers.findIndex(s => s.name.toLowerCase().includes(server)); //for now only megaup is available, hence directly using it
|
|
258
|
+
if (i === -1) {
|
|
259
|
+
throw new Error(`Server ${server} not found`);
|
|
260
|
+
}
|
|
261
|
+
const serverUrl = new URL(servers[i].url);
|
|
262
|
+
const sources = await this.fetchEpisodeSources(serverUrl.href, server, subOrDub);
|
|
263
|
+
sources.intro = (_a = servers[i]) === null || _a === void 0 ? void 0 : _a.intro;
|
|
264
|
+
sources.outro = (_b = servers[i]) === null || _b === void 0 ? void 0 : _b.outro;
|
|
265
|
+
return sources;
|
|
266
|
+
}
|
|
267
|
+
catch (err) {
|
|
268
|
+
throw new Error(err.message);
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* @param url string
|
|
273
|
+
*/
|
|
274
|
+
this.scrapeCardPage = async (url) => {
|
|
275
|
+
var _a, _b;
|
|
276
|
+
try {
|
|
277
|
+
const res = {
|
|
278
|
+
currentPage: 0,
|
|
279
|
+
hasNextPage: false,
|
|
280
|
+
totalPages: 0,
|
|
281
|
+
results: [],
|
|
282
|
+
};
|
|
283
|
+
const { data } = await this.client.get(url, {
|
|
284
|
+
headers: this.Headers(),
|
|
285
|
+
});
|
|
286
|
+
if (typeof data === 'string')
|
|
287
|
+
assertNotCloudflareBlock(data, 'scrapeCardPage');
|
|
288
|
+
const $ = (0, cheerio_1.load)(typeof data === 'string' ? data : '');
|
|
289
|
+
const pagination = $('ul.pagination');
|
|
290
|
+
res.currentPage = parseInt(pagination.find('.page-item.active span.page-link').text().trim()) || 0;
|
|
291
|
+
const nextPage = (_a = pagination
|
|
292
|
+
.find('.page-item.active')
|
|
293
|
+
.next()
|
|
294
|
+
.find('a.page-link')
|
|
295
|
+
.attr('href')) === null || _a === void 0 ? void 0 : _a.split('page=')[1];
|
|
296
|
+
if (nextPage != undefined && nextPage != '') {
|
|
297
|
+
res.hasNextPage = true;
|
|
298
|
+
}
|
|
299
|
+
const totalPages = (_b = pagination.find('.page-item:last-child a.page-link').attr('href')) === null || _b === void 0 ? void 0 : _b.split('page=')[1];
|
|
300
|
+
if (totalPages === undefined || totalPages === '') {
|
|
301
|
+
res.totalPages = res.currentPage;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
res.totalPages = parseInt(totalPages) || 0;
|
|
305
|
+
}
|
|
306
|
+
res.results = await this.scrapeCard($);
|
|
307
|
+
if (res.results.length === 0) {
|
|
308
|
+
res.currentPage = 0;
|
|
309
|
+
res.hasNextPage = false;
|
|
310
|
+
res.totalPages = 0;
|
|
311
|
+
}
|
|
312
|
+
return res;
|
|
313
|
+
}
|
|
314
|
+
catch (err) {
|
|
315
|
+
throw new Error('Something went wrong. Please try again later.');
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* @param $ cheerio instance
|
|
320
|
+
*/
|
|
321
|
+
this.scrapeCard = async ($) => {
|
|
322
|
+
try {
|
|
323
|
+
const results = [];
|
|
324
|
+
$('.aitem').each((i, ele) => {
|
|
325
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
326
|
+
const card = $(ele);
|
|
327
|
+
const atag = card.find('div.inner > a');
|
|
328
|
+
const id = (_a = atag.attr('href')) === null || _a === void 0 ? void 0 : _a.replace('/watch/', '');
|
|
329
|
+
const type = (_b = card.find('.info').children().last()) === null || _b === void 0 ? void 0 : _b.text().trim();
|
|
330
|
+
results.push({
|
|
331
|
+
id: id,
|
|
332
|
+
title: atag.text().trim(),
|
|
333
|
+
url: `${this.baseUrl}${atag.attr('href')}`,
|
|
334
|
+
image: (_d = (_c = card.find('img')) === null || _c === void 0 ? void 0 : _c.attr('data-src')) !== null && _d !== void 0 ? _d : (_e = card.find('img')) === null || _e === void 0 ? void 0 : _e.attr('src'),
|
|
335
|
+
// duration: card.find('.fdi-duration')?.text(),
|
|
336
|
+
japaneseTitle: (_g = (_f = card.find('a.title')) === null || _f === void 0 ? void 0 : _f.attr('data-jp')) === null || _g === void 0 ? void 0 : _g.trim(),
|
|
337
|
+
type: type,
|
|
338
|
+
// nsfw: card.find('.tick-rate')?.text() === '18+' ? true : false,
|
|
339
|
+
sub: parseInt((_h = card.find('.info span.sub')) === null || _h === void 0 ? void 0 : _h.text()) || 0,
|
|
340
|
+
dub: parseInt((_j = card.find('.info span.dub')) === null || _j === void 0 ? void 0 : _j.text()) || 0,
|
|
341
|
+
episodes: parseInt((_k = card.find('.info').children().eq(-2).text().trim()) !== null && _k !== void 0 ? _k : (_l = card.find('.info span.sub')) === null || _l === void 0 ? void 0 : _l.text()) || 0, //if no direct episode count, then just use sub count
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
return results;
|
|
345
|
+
}
|
|
346
|
+
catch (err) {
|
|
347
|
+
throw new Error('Something went wrong. Please try again later.');
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* Fetch available episode servers
|
|
352
|
+
* @param episodeId Episode ID
|
|
353
|
+
* @param subOrDub Sub or dub preference (default: SUB)
|
|
354
|
+
* @returns Promise<IEpisodeServer[]>
|
|
355
|
+
*/
|
|
356
|
+
this.fetchEpisodeServers = async (episodeId, subOrDub = models_1.SubOrSub.SUB) => {
|
|
357
|
+
if (!episodeId.startsWith(this.baseUrl + '/ajax')) {
|
|
358
|
+
const token = episodeId.split('$token=')[1];
|
|
359
|
+
episodeId = `${this.baseUrl}/ajax/links/list?token=${token}&_=${await GenerateToken(token)}`;
|
|
360
|
+
}
|
|
361
|
+
try {
|
|
362
|
+
const { data } = await this.client.get(episodeId, { headers: this.Headers() });
|
|
363
|
+
const parsed = parseAjaxResponse(data);
|
|
364
|
+
const resultHtml = parsed === null || parsed === void 0 ? void 0 : parsed.result;
|
|
365
|
+
if (!resultHtml || typeof resultHtml !== 'string') {
|
|
366
|
+
return [];
|
|
367
|
+
}
|
|
368
|
+
const $ = (0, cheerio_1.load)(resultHtml);
|
|
369
|
+
const servers = [];
|
|
370
|
+
const subOrDubStr = subOrDub === models_1.SubOrSub.SUB ? 'softsub' : 'dub';
|
|
371
|
+
const serverItems = $(`.server-items.lang-group[data-id="${subOrDubStr}"] .server`);
|
|
372
|
+
await Promise.all(serverItems.map(async (i, server) => {
|
|
373
|
+
const id = $(server).attr('data-lid');
|
|
374
|
+
const linkResp = await this.client.get(`${this.baseUrl}/ajax/links/view?id=${id}&_=${await GenerateToken(id)}`, { headers: this.Headers() });
|
|
375
|
+
const linkParsed = parseAjaxResponse(linkResp.data);
|
|
376
|
+
const decodedIframeData = await DecodeIframeData(linkParsed === null || linkParsed === void 0 ? void 0 : linkParsed.result);
|
|
377
|
+
servers.push({
|
|
378
|
+
name: `MegaUp ${$(server).text().trim()}`.toLowerCase(), //megaup is the only server for now
|
|
379
|
+
url: decodedIframeData.url,
|
|
380
|
+
intro: {
|
|
381
|
+
start: decodedIframeData === null || decodedIframeData === void 0 ? void 0 : decodedIframeData.skip.intro[0],
|
|
382
|
+
end: decodedIframeData === null || decodedIframeData === void 0 ? void 0 : decodedIframeData.skip.intro[1],
|
|
383
|
+
},
|
|
384
|
+
outro: {
|
|
385
|
+
start: decodedIframeData === null || decodedIframeData === void 0 ? void 0 : decodedIframeData.skip.outro[0],
|
|
386
|
+
end: decodedIframeData === null || decodedIframeData === void 0 ? void 0 : decodedIframeData.skip.outro[1],
|
|
387
|
+
},
|
|
388
|
+
});
|
|
389
|
+
}));
|
|
390
|
+
return servers;
|
|
391
|
+
}
|
|
392
|
+
catch (err) {
|
|
393
|
+
throw new Error(err.message);
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Search for anime
|
|
399
|
+
* @param query Search query string
|
|
400
|
+
* @param page Page number (default: 1)
|
|
401
|
+
* @returns Promise<ISearch<IAnimeResult>>
|
|
402
|
+
*/
|
|
403
|
+
search(query, page = 1) {
|
|
404
|
+
if (0 >= page) {
|
|
405
|
+
page = 1;
|
|
406
|
+
}
|
|
407
|
+
return this.scrapeCardPage(`${this.baseUrl}/browser?keyword=${query.replace(/[\W_]+/g, '+')}&page=${page}`);
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* @param page number
|
|
411
|
+
*/
|
|
412
|
+
fetchLatestCompleted(page = 1) {
|
|
413
|
+
if (0 >= page) {
|
|
414
|
+
page = 1;
|
|
415
|
+
}
|
|
416
|
+
return this.scrapeCardPage(`${this.baseUrl}/completed?page=${page}`);
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* @param page number
|
|
420
|
+
*/
|
|
421
|
+
fetchRecentlyAdded(page = 1) {
|
|
422
|
+
if (0 >= page) {
|
|
423
|
+
page = 1;
|
|
424
|
+
}
|
|
425
|
+
return this.scrapeCardPage(`${this.baseUrl}/recent?page=${page}`);
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* @param page number
|
|
429
|
+
*/
|
|
430
|
+
fetchRecentlyUpdated(page = 1) {
|
|
431
|
+
if (0 >= page) {
|
|
432
|
+
page = 1;
|
|
433
|
+
}
|
|
434
|
+
return this.scrapeCardPage(`${this.baseUrl}/updates?page=${page}`);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* @param page number
|
|
438
|
+
*/
|
|
439
|
+
fetchNewReleases(page = 1) {
|
|
440
|
+
if (0 >= page) {
|
|
441
|
+
page = 1;
|
|
442
|
+
}
|
|
443
|
+
return this.scrapeCardPage(`${this.baseUrl}/new-releases?page=${page}`);
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* @param page number
|
|
447
|
+
*/
|
|
448
|
+
fetchMovie(page = 1) {
|
|
449
|
+
if (0 >= page) {
|
|
450
|
+
page = 1;
|
|
451
|
+
}
|
|
452
|
+
return this.scrapeCardPage(`${this.baseUrl}/movie?page=${page}`);
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* @param page number
|
|
456
|
+
*/
|
|
457
|
+
fetchTV(page = 1) {
|
|
458
|
+
if (0 >= page) {
|
|
459
|
+
page = 1;
|
|
460
|
+
}
|
|
461
|
+
return this.scrapeCardPage(`${this.baseUrl}/tv?page=${page}`);
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* @param page number
|
|
465
|
+
*/
|
|
466
|
+
fetchOVA(page = 1) {
|
|
467
|
+
if (0 >= page) {
|
|
468
|
+
page = 1;
|
|
469
|
+
}
|
|
470
|
+
return this.scrapeCardPage(`${this.baseUrl}/ova?page=${page}`);
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* @param page number
|
|
474
|
+
*/
|
|
475
|
+
fetchONA(page = 1) {
|
|
476
|
+
if (0 >= page) {
|
|
477
|
+
page = 1;
|
|
478
|
+
}
|
|
479
|
+
return this.scrapeCardPage(`${this.baseUrl}/ona?page=${page}`);
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* @param page number
|
|
483
|
+
*/
|
|
484
|
+
fetchSpecial(page = 1) {
|
|
485
|
+
if (0 >= page) {
|
|
486
|
+
page = 1;
|
|
487
|
+
}
|
|
488
|
+
return this.scrapeCardPage(`${this.baseUrl}/special?page=${page}`);
|
|
489
|
+
}
|
|
490
|
+
async fetchGenres() {
|
|
491
|
+
try {
|
|
492
|
+
const res = [];
|
|
493
|
+
const { data } = await this.client.get(`${this.baseUrl}/home`, { headers: this.Headers() });
|
|
494
|
+
if (typeof data === 'string')
|
|
495
|
+
assertNotCloudflareBlock(data, 'fetchGenres');
|
|
496
|
+
const $ = (0, cheerio_1.load)(typeof data === 'string' ? data : '');
|
|
497
|
+
const sideBar = $('#menu');
|
|
498
|
+
sideBar.find('ul.c4 li a').each((i, ele) => {
|
|
499
|
+
const genres = $(ele);
|
|
500
|
+
res.push(genres.text().toLowerCase());
|
|
501
|
+
});
|
|
502
|
+
return res;
|
|
503
|
+
}
|
|
504
|
+
catch (err) {
|
|
505
|
+
throw new Error('Something went wrong. Please try again later.');
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* @param page number
|
|
510
|
+
*/
|
|
511
|
+
genreSearch(genre, page = 1) {
|
|
512
|
+
if (genre == '') {
|
|
513
|
+
throw new Error('genre is empty');
|
|
514
|
+
}
|
|
515
|
+
if (0 >= page) {
|
|
516
|
+
page = 1;
|
|
517
|
+
}
|
|
518
|
+
return this.scrapeCardPage(`${this.baseUrl}/genres/${genre}?page=${page}`);
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Fetches the schedule for a given date.
|
|
522
|
+
* @param date The date in format 'YYYY-MM-DD'. Defaults to the current date.
|
|
523
|
+
* @returns A promise that resolves to an object containing the search results.
|
|
524
|
+
*/
|
|
525
|
+
async fetchSchedule(date = new Date().toISOString().split('T')[0]) {
|
|
526
|
+
try {
|
|
527
|
+
const res = {
|
|
528
|
+
results: [],
|
|
529
|
+
};
|
|
530
|
+
const { data } = await this.client.get(`${this.baseUrl}/ajax/schedule/items?tz=5.5&time=${Math.floor(new Date(`${date}T00:00:00Z`).getTime() / 1000)}`, { headers: this.Headers() });
|
|
531
|
+
const parsed = parseAjaxResponse(data);
|
|
532
|
+
let htmlContent = (parsed === null || parsed === void 0 ? void 0 : parsed.result) || data;
|
|
533
|
+
if (typeof htmlContent === 'object' && htmlContent.html) {
|
|
534
|
+
htmlContent = htmlContent.html;
|
|
535
|
+
}
|
|
536
|
+
const $ = (0, cheerio_1.load)(typeof htmlContent === 'string' ? htmlContent : '');
|
|
537
|
+
$('ul li').each((i, ele) => {
|
|
538
|
+
var _a;
|
|
539
|
+
const card = $(ele);
|
|
540
|
+
const titleElement = card.find('span.title');
|
|
541
|
+
const episodeText = card.find('span').last().text().trim();
|
|
542
|
+
res.results.push({
|
|
543
|
+
id: (_a = card.find('a').attr('href')) === null || _a === void 0 ? void 0 : _a.split('/')[2], // Extract anime ID
|
|
544
|
+
title: titleElement.text().trim(),
|
|
545
|
+
japaneseTitle: titleElement.attr('data-jp'),
|
|
546
|
+
airingTime: card.find('span.time').text().trim(),
|
|
547
|
+
airingEpisode: episodeText.replace('EP ', ''), // Extract episode number
|
|
548
|
+
});
|
|
549
|
+
});
|
|
550
|
+
return res;
|
|
551
|
+
}
|
|
552
|
+
catch (err) {
|
|
553
|
+
throw new Error('Something went wrong. Please try again later.');
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
async fetchSpotlight() {
|
|
557
|
+
try {
|
|
558
|
+
const res = { results: [] };
|
|
559
|
+
const { data } = await this.client.get(`${this.baseUrl}/home`, { headers: this.Headers() });
|
|
560
|
+
if (typeof data === 'string')
|
|
561
|
+
assertNotCloudflareBlock(data, 'fetchSpotlight');
|
|
562
|
+
const $ = (0, cheerio_1.load)(typeof data === 'string' ? data : '');
|
|
563
|
+
$('div.swiper-wrapper > div.swiper-slide').each((i, el) => {
|
|
564
|
+
var _a, _b;
|
|
565
|
+
const card = $(el);
|
|
566
|
+
const titleElement = card.find('div.detail > p.title');
|
|
567
|
+
const id = (_a = card.find('div.swiper-ctrl > a.btn').attr('href')) === null || _a === void 0 ? void 0 : _a.replace('/watch/', '');
|
|
568
|
+
const img = card.attr('style');
|
|
569
|
+
res.results.push({
|
|
570
|
+
id: id,
|
|
571
|
+
title: titleElement.text(),
|
|
572
|
+
japaneseTitle: titleElement.attr('data-jp'),
|
|
573
|
+
banner: ((_b = img === null || img === void 0 ? void 0 : img.match(/background-image:\s*url\(["']?(.+?)["']?\)/)) === null || _b === void 0 ? void 0 : _b[1]) || null,
|
|
574
|
+
url: `${this.baseUrl}/watch/${id}`,
|
|
575
|
+
type: card.find('div.detail > div.info').children().eq(-2).text().trim(),
|
|
576
|
+
genres: card
|
|
577
|
+
.find('div.detail > div.info')
|
|
578
|
+
.children()
|
|
579
|
+
.last()
|
|
580
|
+
.text()
|
|
581
|
+
.trim()
|
|
582
|
+
.split(',')
|
|
583
|
+
.map(genre => genre.trim()),
|
|
584
|
+
releaseDate: card
|
|
585
|
+
.find('div.detail > div.mics >div:contains("Release")')
|
|
586
|
+
.children('span')
|
|
587
|
+
.text()
|
|
588
|
+
.trim(),
|
|
589
|
+
quality: card.find('div.detail > div.mics >div:contains("Quality")').children('span').text().trim(),
|
|
590
|
+
sub: parseInt(card.find('div.detail > div.info > span.sub').text().trim()) || 0,
|
|
591
|
+
dub: parseInt(card.find('div.detail > div.info > span.dub').text().trim()) || 0,
|
|
592
|
+
description: card.find('div.detail > p.desc').text().trim(),
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
return res;
|
|
596
|
+
}
|
|
597
|
+
catch (error) {
|
|
598
|
+
throw new Error('Something went wrong. Please try again later.');
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
async fetchSearchSuggestions(query) {
|
|
602
|
+
var _a, _b;
|
|
603
|
+
try {
|
|
604
|
+
const { data } = await this.client.get(`${this.baseUrl}/ajax/anime/search?keyword=${query.replace(/[\W_]+/g, '+')}`, { headers: this.Headers() });
|
|
605
|
+
const parsed = parseAjaxResponse(data);
|
|
606
|
+
const $ = (0, cheerio_1.load)((_b = (_a = parsed === null || parsed === void 0 ? void 0 : parsed.result) === null || _a === void 0 ? void 0 : _a.html) !== null && _b !== void 0 ? _b : '');
|
|
607
|
+
const res = {
|
|
608
|
+
results: [],
|
|
609
|
+
};
|
|
610
|
+
$('a.aitem').each((i, el) => {
|
|
611
|
+
var _a, _b, _c, _d, _e;
|
|
612
|
+
const card = $(el);
|
|
613
|
+
const image = card.find('.poster img').attr('src');
|
|
614
|
+
const titleElement = card.find('.title');
|
|
615
|
+
const title = titleElement.text().trim();
|
|
616
|
+
const japaneseTitle = titleElement.attr('data-jp');
|
|
617
|
+
const id = (_a = card.attr('href')) === null || _a === void 0 ? void 0 : _a.split('/')[2];
|
|
618
|
+
const year = card.find('.info').children().eq(-2).text().trim();
|
|
619
|
+
const type = card.find('.info').children().eq(-3).text().trim();
|
|
620
|
+
const sub = parseInt((_b = card.find('.info span.sub')) === null || _b === void 0 ? void 0 : _b.text()) || 0;
|
|
621
|
+
const dub = parseInt((_c = card.find('.info span.dub')) === null || _c === void 0 ? void 0 : _c.text()) || 0;
|
|
622
|
+
const episodes = parseInt((_d = card.find('.info').children().eq(-4).text().trim()) !== null && _d !== void 0 ? _d : (_e = card.find('.info span.sub')) === null || _e === void 0 ? void 0 : _e.text()) || 0;
|
|
623
|
+
res.results.push({
|
|
624
|
+
id: id,
|
|
625
|
+
title: title,
|
|
626
|
+
url: `${this.baseUrl}/watch/${id}`,
|
|
627
|
+
image: image,
|
|
628
|
+
japaneseTitle: japaneseTitle || null,
|
|
629
|
+
type: type,
|
|
630
|
+
year: year,
|
|
631
|
+
sub: sub,
|
|
632
|
+
dub: dub,
|
|
633
|
+
episodes: episodes,
|
|
634
|
+
});
|
|
635
|
+
});
|
|
636
|
+
return res;
|
|
637
|
+
}
|
|
638
|
+
catch (error) {
|
|
639
|
+
throw new Error('Something went wrong. Please try again later.');
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
Headers() {
|
|
643
|
+
return {
|
|
644
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36',
|
|
645
|
+
Connection: 'keep-alive',
|
|
646
|
+
Accept: 'text/html, */*; q=0.01',
|
|
647
|
+
'Accept-Language': 'en-US,en;q=0.5',
|
|
648
|
+
'Sec-GPC': '1',
|
|
649
|
+
'Sec-Fetch-Dest': 'empty',
|
|
650
|
+
'Sec-Fetch-Mode': 'cors',
|
|
651
|
+
'Sec-Fetch-Site': 'same-origin',
|
|
652
|
+
Priority: 'u=0',
|
|
653
|
+
Pragma: 'no-cache',
|
|
654
|
+
'Cache-Control': 'no-cache',
|
|
655
|
+
Referer: `${this.baseUrl}/`,
|
|
656
|
+
Cookie: '__p_mov=1; usertype=guest; session=vLrU4aKItp0QltI2asH83yugyWDsSSQtyl9sxWKO',
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
exports.default = AnimeKai;
|
|
661
|
+
//# sourceMappingURL=animekai.js.map
|