mirror of
https://git.luna-app.eu/50n50/sources
synced 2025-12-21 21:26:19 +01:00
Add anicore/anicore.js
This commit is contained in:
parent
363a942e85
commit
b6720e86be
1 changed files with 220 additions and 0 deletions
220
anicore/anicore.js
Normal file
220
anicore/anicore.js
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
async function searchResults(keyword) {
|
||||
const results = [];
|
||||
|
||||
const headers = {
|
||||
"Host": 'graphql.anilist.co',
|
||||
"User-Agent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:147.0) Gecko/20100101 Firefox/147.0',
|
||||
"Accept": 'application/json',
|
||||
"Accept-Language": 'en-US,en;q=0.9',
|
||||
"Accept-Encoding": 'gzip, deflate, br, zstd',
|
||||
"Referer": 'https://anicore.tv/',
|
||||
"Content-Type": 'application/json',
|
||||
"Content-Length": '1380',
|
||||
"Origin": 'https://anicore.tv',
|
||||
"Connection": 'keep-alive',
|
||||
"Sec-Fetch-Dest": 'empty',
|
||||
"Sec-Fetch-Mode": 'cors',
|
||||
"Sec-Fetch-Site": 'cross-site',
|
||||
"Priority": 'u=4',
|
||||
"TE": 'trailers'
|
||||
};
|
||||
|
||||
const postData = {"query":"\nquery ($page: Int = 1, $perPage: Int = 50, $type: MediaType = ANIME, $search: String, $format_in: [MediaFormat], $status: MediaStatus, $countryOfOrigin: CountryCode, $season: MediaSeason, $seasonYear: Int, $genre_in: [String], $tag_in: [String], $sort:[MediaSort], $isAdult: Boolean) {\n Page(page: $page, perPage: $perPage) {\n pageInfo {\n total\n perPage\n currentPage\n lastPage\n hasNextPage\n }\n media(type: $type, sort: $sort, season: $season, seasonYear: $seasonYear, search: $search, genre_in: $genre_in, tag_in: $tag_in, format_in: $format_in, status: $status, countryOfOrigin: $countryOfOrigin, isAdult: $isAdult){\n id\n title {\n english\n romaji\n }\n coverImage {\n extraLarge\n color\n }\n startDate {\n year\n month\n day\n }\n bannerImage\n season\n seasonYear\n description\n type\n format\n status(version: 2)\n episodes\n duration\n chapters\n volumes\n genres\n isAdult\n averageScore\n popularity\n nextAiringEpisode {\n airingAt\n timeUntilAiring\n episode\n }\n mediaListEntry {\n id\n status\n }\n }\n }\n}","variables":{"search":`${keyword}`,"type":"ANIME","sort":"POPULARITY_DESC","page":1}};
|
||||
|
||||
try {
|
||||
const response = await fetchv2("https://graphql.anilist.co/", headers, "POST", postData);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.data && data.data.Page && data.data.Page.media) {
|
||||
const media = data.data.Page.media;
|
||||
for (const item of media) {
|
||||
results.push({
|
||||
title: item.title.english || item.title.romaji || "Unknown",
|
||||
image: item.coverImage.extraLarge || "",
|
||||
href: `${item.id}`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(results);
|
||||
} catch (err) {
|
||||
return JSON.stringify([{
|
||||
title: "Error",
|
||||
image: "Error",
|
||||
href: "Error"
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractDetails(ID) {
|
||||
try {
|
||||
const headers = {
|
||||
"Host": 'graphql.anilist.co',
|
||||
"User-Agent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:147.0) Gecko/20100101 Firefox/147.0',
|
||||
"Accept": 'application/json',
|
||||
"Accept-Language": 'en-US,en;q=0.9',
|
||||
"Accept-Encoding": 'gzip, deflate, br, zstd',
|
||||
"Referer": 'https://anicore.tv/',
|
||||
"Content-Type": 'application/json',
|
||||
"Content-Length": '1380',
|
||||
"Origin": 'https://anicore.tv',
|
||||
"Connection": 'keep-alive',
|
||||
"Sec-Fetch-Dest": 'empty',
|
||||
"Sec-Fetch-Mode": 'cors',
|
||||
"Sec-Fetch-Site": 'cross-site',
|
||||
"Priority": 'u=4',
|
||||
"TE": 'trailers'
|
||||
};
|
||||
|
||||
const postData = {"query":"query media($id:Int,$type:MediaType,$isAdult:Boolean){Media(id:$id,type:$type,isAdult:$isAdult){id title{userPreferred romaji english native}coverImage{extraLarge large}bannerImage startDate{year month day}endDate{year month day}description season seasonYear type format status(version:2)episodes duration chapters volumes genres synonyms source(version:3)isAdult isLocked meanScore averageScore popularity favourites isFavouriteBlocked hashtag countryOfOrigin isLicensed isFavourite isRecommendationBlocked isFavouriteBlocked isReviewBlocked nextAiringEpisode{airingAt timeUntilAiring episode}relations{edges{id relationType(version:2)node{id title{userPreferred}format type status(version:2)bannerImage coverImage{large}}}}characterPreview:characters(perPage:6,sort:[ROLE,RELEVANCE,ID]){edges{id role name voiceActors(language:JAPANESE,sort:[RELEVANCE,ID]){id name{userPreferred}language:languageV2 image{large}}node{id name{userPreferred}image{large}}}}staffPreview:staff(perPage:8,sort:[RELEVANCE,ID]){edges{id role node{id name{userPreferred}language:languageV2 image{large}}}}studios{edges{isMain node{id name}}}reviewPreview:reviews(perPage:2,sort:[RATING_DESC,ID]){pageInfo{total}nodes{id summary rating ratingAmount user{id name avatar{large}}}}recommendations(perPage:7,sort:[RATING_DESC,ID]){pageInfo{total}nodes{id rating userRating mediaRecommendation{id title{userPreferred}format type status(version:2)bannerImage coverImage{large}}user{id name avatar{large}}}}externalLinks{id site url type language color icon notes isDisabled}streamingEpisodes{site title thumbnail url}trailer{id site}rankings{id rank type format year season allTime context}tags{id name description rank isMediaSpoiler isGeneralSpoiler userId}mediaListEntry{id status score}stats{statusDistribution{status amount}scoreDistribution{score amount}}}}","variables":{"id":ID,"type":"ANIME"}};
|
||||
const response = await fetchv2("https://graphql.anilist.co/", headers, "POST", postData);
|
||||
const data = await response.json();
|
||||
|
||||
const media = data.data.Media;
|
||||
return JSON.stringify([{
|
||||
description: clean(media.description),
|
||||
aliases: media.title.romaji + " / " + media.title.english + " / " + media.title.native,
|
||||
airdate: media.startDate.year
|
||||
}]);
|
||||
} catch (err) {
|
||||
return JSON.stringify([{
|
||||
description: "Error",
|
||||
aliases: "Error",
|
||||
airdate: "Error"
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractEpisodes(ID) {
|
||||
const results = [];
|
||||
try {
|
||||
const response = await fetchv2("https://anicore-api.vercel.app/api/episodes?id=" + ID);
|
||||
const data = await response.json();
|
||||
|
||||
if (Array.isArray(data)) {
|
||||
for (const episode of data) {
|
||||
results.push({
|
||||
href: `${ID}-${episode.number}`,
|
||||
number: episode.number
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(results);
|
||||
} catch (err) {
|
||||
return JSON.stringify([{
|
||||
href: "Error",
|
||||
number: "Error"
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractStreamUrl(url) {
|
||||
try {
|
||||
const parts = url.split('-');
|
||||
const animeID = parts[0];
|
||||
const episodeNumber = parseInt(parts[1], 10);
|
||||
|
||||
const episodesResponse = await fetchv2("https://anicore-api.vercel.app/api/episodes?id=" + animeID);
|
||||
const episodesData = await episodesResponse.json();
|
||||
|
||||
const episode = episodesData.find(ep => ep.number === episodeNumber);
|
||||
if (!episode) {
|
||||
return JSON.stringify({
|
||||
streams: [],
|
||||
subtitle: ""
|
||||
});
|
||||
}
|
||||
|
||||
const excludedProviders = ['oni', 'yuki', 'kami'];
|
||||
const subProviders = (episode.subProviders || []).filter(p => !excludedProviders.includes(p));
|
||||
const dubProviders = (episode.dubProviders || []).filter(p => !excludedProviders.includes(p));
|
||||
|
||||
if (subProviders.length === 0 && dubProviders.length === 0) {
|
||||
return JSON.stringify({
|
||||
streams: [],
|
||||
subtitle: ""
|
||||
});
|
||||
}
|
||||
|
||||
const streamPromises = [];
|
||||
|
||||
for (const provider of subProviders) {
|
||||
streamPromises.push(
|
||||
fetchv2(`https://anicore-api.vercel.app/api/stream?id=${animeID}&host=${provider}&ep=${episodeNumber}&type=sub`)
|
||||
.then(res => res.json())
|
||||
.then(data => ({
|
||||
provider,
|
||||
type: 'sub',
|
||||
data
|
||||
}))
|
||||
.catch(() => ({
|
||||
provider,
|
||||
type: 'sub',
|
||||
data: null
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
for (const provider of dubProviders) {
|
||||
streamPromises.push(
|
||||
fetchv2(`https://anicore-api.vercel.app/api/stream?id=${animeID}&host=${provider}&ep=${episodeNumber}&type=dub`)
|
||||
.then(res => res.json())
|
||||
.then(data => ({
|
||||
provider,
|
||||
type: 'dub',
|
||||
data
|
||||
}))
|
||||
.catch(() => ({
|
||||
provider,
|
||||
type: 'dub',
|
||||
data: null
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
const streamResults = await Promise.all(streamPromises);
|
||||
|
||||
const streams = [];
|
||||
let englishSubtitle = "";
|
||||
|
||||
for (const result of streamResults) {
|
||||
if (result.data && result.data.sources && result.data.sources.length > 0) {
|
||||
const source = result.data.sources[0];
|
||||
const typeLabel = result.type === 'dub' ? 'DUB' : 'SUB';
|
||||
streams.push({
|
||||
title: `${result.provider.toUpperCase()} - ${typeLabel}`,
|
||||
streamUrl: source.url,
|
||||
headers: result.data.headers || {}
|
||||
});
|
||||
|
||||
if (!englishSubtitle && result.type === 'sub' && result.data.subtitles && Array.isArray(result.data.subtitles)) {
|
||||
const engSub = result.data.subtitles.find(sub =>
|
||||
sub.language === 'eng' || sub.language === 'en' || sub.name === 'eng' || sub.name === 'en'
|
||||
);
|
||||
if (engSub) {
|
||||
englishSubtitle = engSub.url || "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify({
|
||||
streams: streams.length > 0 ? streams : [],
|
||||
subtitle: englishSubtitle
|
||||
});
|
||||
} catch (err) {
|
||||
return JSON.stringify({
|
||||
streams: [],
|
||||
subtitle: ""
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const clean = html =>
|
||||
html
|
||||
.replace(/<br\s*\/?>/gi, '\n')
|
||||
.replace(/<\/?i>/gi, '')
|
||||
.replace(/<\/?b>/gi, '')
|
||||
.replace(/<\/?[^>]+>/g, '');
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue