|
const express = require('express'); |
|
const axios = require('axios'); |
|
const cheerio = require('cheerio'); |
|
const puppeteer = require('puppeteer-core'); |
|
|
|
const app = express(); |
|
const PORT = 7860; |
|
|
|
|
|
const cors = require('cors'); |
|
app.use(cors()); |
|
|
|
app.get('/anime/:title/:episode', async (req, res) => { |
|
const animeTitle = req.params.title; |
|
const episodeNumber = req.params.episode; |
|
|
|
console.log(`Requested: ${animeTitle} Episode ${episodeNumber}`); |
|
|
|
try { |
|
const episodeData = await searchGogoanime(animeTitle, episodeNumber); |
|
res.json(episodeData); |
|
} catch (error) { |
|
res.status(500).json({ error: "Failed to fetch episode data", details: error.message }); |
|
} |
|
}); |
|
|
|
async function searchGogoanime(animeTitle, episodeNumber) { |
|
try { |
|
console.log(`Searching for: ${animeTitle} Episode ${episodeNumber}`); |
|
|
|
|
|
const searchUrl = `https://ww24.gogoanimes.fi/search.html?keyword=${encodeURIComponent(animeTitle)}`; |
|
const searchResponse = await axios.get(searchUrl); |
|
const $ = cheerio.load(searchResponse.data); |
|
|
|
|
|
const firstResult = $('.items li a').first(); |
|
const animeSlug = firstResult.attr('href')?.split('/')[2]; |
|
const foundTitle = firstResult.text().trim(); |
|
if (!animeSlug) throw new Error("Anime not found"); |
|
|
|
console.log(`Anime Found: ${foundTitle} (${animeSlug})`); |
|
|
|
|
|
const episodeUrl = `https://ww24.gogoanimes.fi/${animeSlug}-episode-${episodeNumber}`; |
|
console.log(`Episode URL: ${episodeUrl}`); |
|
|
|
return await getEpisodeInfo(episodeUrl, foundTitle, episodeNumber); |
|
} catch (error) { |
|
throw new Error("Error searching Gogoanime: " + error.message); |
|
} |
|
} |
|
|
|
async function getEpisodeInfo(episodeUrl, animeTitle, episodeNumber) { |
|
try { |
|
console.log(`Fetching: ${episodeUrl}`); |
|
const response = await axios.get(episodeUrl); |
|
const $ = cheerio.load(response.data); |
|
|
|
|
|
const thumbnail = $('.anime_info_body_bg img').attr('src'); |
|
const summary = $('.anime_info_body_bg p.type').last().text().trim(); |
|
|
|
|
|
const downloadPageUrl = $('.dowloads a').attr('href'); |
|
if (!downloadPageUrl) throw new Error("Download page not found"); |
|
|
|
console.log(`S3embtaku Download Page Found: ${downloadPageUrl}`); |
|
|
|
const downloadLinks = await getVideoLinks(downloadPageUrl); |
|
|
|
return { |
|
anime: animeTitle, |
|
episode: episodeNumber, |
|
thumbnail, |
|
summary, |
|
owner: "Reiker", |
|
downloads: downloadLinks |
|
}; |
|
} catch (error) { |
|
throw new Error("Error fetching episode info: " + error.message); |
|
} |
|
} |
|
|
|
async function getVideoLinks(downloadPageUrl) { |
|
console.log(`Opening Puppeteer: ${downloadPageUrl}`); |
|
|
|
const browser = await puppeteer.launch({ |
|
executablePath: "/usr/bin/chromium", |
|
args: ["--no-sandbox", "--disable-setuid-sandbox"] |
|
}); |
|
|
|
const page = await browser.newPage(); |
|
|
|
try { |
|
await page.goto(downloadPageUrl, { waitUntil: 'networkidle2' }); |
|
|
|
|
|
await page.waitForSelector('a[href*="ggredi.info/download.php"]', { timeout: 10000 }); |
|
|
|
|
|
const videoLinks = await page.evaluate(() => { |
|
const links = Array.from(document.querySelectorAll('a[href*="ggredi.info/download.php"]')); |
|
return links.map(link => ({ |
|
quality: link.innerText.trim(), |
|
url: link.href |
|
})); |
|
}); |
|
|
|
await browser.close(); |
|
|
|
return videoLinks; |
|
} catch (error) { |
|
console.error("Error extracting video links:", error.message); |
|
await browser.close(); |
|
return []; |
|
} |
|
} |
|
|
|
async function getFinalMp4Link(redirectLink) { |
|
try { |
|
console.log(`Following redirect: ${redirectLink}`); |
|
|
|
|
|
const response = await axios.get(redirectLink, { maxRedirects: 5 }); |
|
|
|
if (response.request.res.responseUrl) { |
|
console.log(`Final MP4 Link: ${response.request.res.responseUrl}`); |
|
return response.request.res.responseUrl; |
|
} else { |
|
console.log("No final MP4 link found."); |
|
return null; |
|
} |
|
} catch (error) { |
|
console.error("Error fetching final MP4 link:", error.message); |
|
return null; |
|
} |
|
} |
|
|
|
|
|
app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`)); |