From 007dedb72c2c962f7cb59ea6e6deada874345622 Mon Sep 17 00:00:00 2001 From: aka paul <50n50@noreply.localhost> Date: Sat, 3 Jan 2026 19:51:40 +0000 Subject: [PATCH] Add animepahe/animepahe.js --- animepahe/animepahe.js | 421 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 421 insertions(+) create mode 100644 animepahe/animepahe.js diff --git a/animepahe/animepahe.js b/animepahe/animepahe.js new file mode 100644 index 0000000..5471358 --- /dev/null +++ b/animepahe/animepahe.js @@ -0,0 +1,421 @@ +async function searchResults(keyword) { + try { + const encodedKeyword = encodeURIComponent(keyword); + const ddosInterceptor = new DdosGuardInterceptor(); + const responseText = await ddosInterceptor.fetchWithBypass(`https://animepahe.si/api?m=search&q=${encodedKeyword}`); + const dataText = await responseText.text(); + console.log(dataText); + const data = JSON.parse(dataText); + const transformedResults = data.data.map(result => { + return { + title: result.title, + image: result.poster, + href: `https://animepahe.si/anime/${result.session}` + }; + }); + + return JSON.stringify(transformedResults); + } catch (error) { + console.log("Fetch error in searchResults: " + error); + return JSON.stringify([{ title: "Error", image: "", href: "" }]); + } +} + +async function extractDetails(url) { + try { + const ddosInterceptor = new DdosGuardInterceptor(); + const responseText = await ddosInterceptor.fetchWithBypass(url); + const dataText = await responseText.text(); + + const descMatch = dataText.match(/
(.*?)<\/div>/s); + const description = descMatch ? descMatch[1].replace(//gi, '\n').trim() : 'N/A'; + + const aliasMatch = dataText.match(/Synonyms: <\/strong>(.*?)<\/p>/); + const aliases = aliasMatch ? aliasMatch[1].trim() : 'N/A'; + + const airMatch = dataText.match(/Aired:<\/strong>(.*?)<\/p>/s); + const airdate = airMatch ? airMatch[1].replace(/\s+/g, ' ').trim() : 'N/A'; + + return JSON.stringify([{ + description, + aliases, + airdate + }]); + } catch (err) { + return JSON.stringify([{ + description: "Error", + aliases: "Error", + airdate: "Error" + }]); + } +} + +async function extractEpisodes(url) { + const results = []; + try { + const uuidMatch = url.match(/\/anime\/([^\/]+)/); + if (!uuidMatch) throw new Error("Invalid URL"); + const id = uuidMatch[1]; + + const ddosInterceptor = new DdosGuardInterceptor(); + + let page = 1; + const apiUrl1 = `https://animepahe.si/api?m=release&id=${id}&sort=episode_asc&page=${page}`; + const response1 = await ddosInterceptor.fetchWithBypass(apiUrl1); + const dataText1 = await response1.text(); + const data1 = JSON.parse(dataText1); + + for (const item of data1.data) { + results.push({ + href: `https://animepahe.si/play/${id}/${item.session}`, + number: item.episode + }); + } + + const lastPage = data1.last_page; + if (lastPage > 1) { + const promises = []; + for (let p = 2; p <= lastPage; p++) { + const apiUrl = `https://animepahe.si/api?m=release&id=${id}&sort=episode_asc&page=${p}`; + promises.push(ddosInterceptor.fetchWithBypass(apiUrl).then(response => response.text()).then(text => JSON.parse(text))); + } + const datas = await Promise.all(promises); + for (const data of datas) { + for (const item of data.data) { + results.push({ + href: `https://animepahe.si/play/${id}/${item.session}`, + number: item.episode + }); + } + } + } + + return JSON.stringify(results); + } catch (err) { + return JSON.stringify([{ + href: "Error", + number: "Error" + }]); + } +} + +async function extractStreamUrl(url) { + try { + const ddosInterceptor = new DdosGuardInterceptor(); + const responseText = await ddosInterceptor.fetchWithBypass(url); + const dataText = await responseText.text(); + + const buttonMatches = dataText.match(/]*data-src="([^"]*)"[^>]*>/g); + if (!buttonMatches) { + return JSON.stringify({ streams: [], subtitle: "" }); + } + + const streams = []; + + for (const buttonHtml of buttonMatches) { + const srcMatch = buttonHtml.match(/data-src="([^"]*)"/); + const resMatch = buttonHtml.match(/data-resolution="([^"]*)"/); + const audioMatch = buttonHtml.match(/data-audio="([^"]*)"/); + const fansubMatch = buttonHtml.match(/data-fansub="([^"]*)"/); + + if (!srcMatch || !srcMatch[1].includes('kwik.cx')) continue; + + const kwikUrl = srcMatch[1]; + const resolution = resMatch ? resMatch[1] : "Unknown"; + const audio = audioMatch ? audioMatch[1] : "jpn"; + const fansub = fansubMatch ? fansubMatch[1] : "Unknown"; + + try { + const html = await fetchv2(kwikUrl).then(r => r.text()); + const scriptMatch = html.match(/