Reaperxxxx commited on
Commit
d17a758
·
verified ·
1 Parent(s): 06333a7

Create server.js

Browse files
Files changed (1) hide show
  1. server.js +145 -0
server.js ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require('express');
2
+ const axios = require('axios');
3
+ const cheerio = require('cheerio');
4
+ const puppeteer = require('puppeteer');
5
+
6
+ const app = express();
7
+ const PORT = 7860;
8
+
9
+ // Enable CORS
10
+ const cors = require('cors');
11
+ app.use(cors());
12
+
13
+ app.get('/anime/:title/:episode', async (req, res) => {
14
+ const animeTitle = req.params.title;
15
+ const episodeNumber = req.params.episode;
16
+
17
+ console.log(`Requested: ${animeTitle} Episode ${episodeNumber}`);
18
+
19
+ try {
20
+ const episodeData = await searchGogoanime(animeTitle, episodeNumber);
21
+ res.json(episodeData);
22
+ } catch (error) {
23
+ res.status(500).json({ error: "Failed to fetch episode data", details: error.message });
24
+ }
25
+ });
26
+
27
+ async function searchGogoanime(animeTitle, episodeNumber) {
28
+ try {
29
+ console.log(`Searching for: ${animeTitle} Episode ${episodeNumber}`);
30
+
31
+ // Search Gogoanime
32
+ const searchUrl = `https://ww24.gogoanimes.fi/search.html?keyword=${encodeURIComponent(animeTitle)}`;
33
+ const searchResponse = await axios.get(searchUrl);
34
+ const $ = cheerio.load(searchResponse.data);
35
+
36
+ // Find first result
37
+ const firstResult = $('.items li a').first();
38
+ const animeSlug = firstResult.attr('href')?.split('/')[2];
39
+ const foundTitle = firstResult.text().trim();
40
+ if (!animeSlug) throw new Error("Anime not found");
41
+
42
+ console.log(`Anime Found: ${foundTitle} (${animeSlug})`);
43
+
44
+ // Episode page URL
45
+ const episodeUrl = `https://ww24.gogoanimes.fi/${animeSlug}-episode-${episodeNumber}`;
46
+ console.log(`Episode URL: ${episodeUrl}`);
47
+
48
+ return await getEpisodeInfo(episodeUrl, foundTitle, episodeNumber);
49
+ } catch (error) {
50
+ throw new Error("Error searching Gogoanime: " + error.message);
51
+ }
52
+ }
53
+
54
+ async function getEpisodeInfo(episodeUrl, animeTitle, episodeNumber) {
55
+ try {
56
+ console.log(`Fetching: ${episodeUrl}`);
57
+ const response = await axios.get(episodeUrl);
58
+ const $ = cheerio.load(response.data);
59
+
60
+ // Extract anime details
61
+ const thumbnail = $('.anime_info_body_bg img').attr('src');
62
+ const summary = $('.anime_info_body_bg p.type').last().text().trim();
63
+
64
+ // Find download link page
65
+ const downloadPageUrl = $('.dowloads a').attr('href');
66
+ if (!downloadPageUrl) throw new Error("Download page not found");
67
+
68
+ console.log(`S3embtaku Download Page Found: ${downloadPageUrl}`);
69
+
70
+ const downloadLinks = await getVideoLinks(downloadPageUrl);
71
+
72
+ return {
73
+ anime: animeTitle,
74
+ episode: episodeNumber,
75
+ thumbnail,
76
+ summary,
77
+ owner: "Reiker",
78
+ downloads: downloadLinks
79
+ };
80
+ } catch (error) {
81
+ throw new Error("Error fetching episode info: " + error.message);
82
+ }
83
+ }
84
+
85
+ async function getVideoLinks(downloadPageUrl) {
86
+ console.log(`Opening Puppeteer: ${downloadPageUrl}`);
87
+ const browser = await puppeteer.launch({ headless: true });
88
+ const page = await browser.newPage();
89
+
90
+ try {
91
+ await page.goto(downloadPageUrl, { waitUntil: 'networkidle2' });
92
+
93
+ // Wait for the download buttons to load
94
+ await page.waitForSelector('a[href*="ggredi.info/download.php"]', { timeout: 10000 });
95
+
96
+ // Get all quality links
97
+ const videoLinks = await page.evaluate(() => {
98
+ const links = Array.from(document.querySelectorAll('a[href*="ggredi.info/download.php"]'));
99
+ return links.map(link => ({
100
+ quality: link.innerText.trim(),
101
+ url: link.href
102
+ }));
103
+ });
104
+
105
+ await browser.close();
106
+
107
+ // Convert to dictionary format
108
+ const directDownloadLinks = {};
109
+ for (const link of videoLinks) {
110
+ const directLink = await getFinalMp4Link(link.url);
111
+ if (link.quality.includes('360')) directDownloadLinks["360p"] = directLink;
112
+ if (link.quality.includes('480')) directDownloadLinks["480p"] = directLink;
113
+ if (link.quality.includes('720')) directDownloadLinks["720p"] = directLink;
114
+ }
115
+
116
+ return directDownloadLinks;
117
+ } catch (error) {
118
+ console.error("Error extracting video links:", error.message);
119
+ await browser.close();
120
+ return {};
121
+ }
122
+ }
123
+
124
+ async function getFinalMp4Link(redirectLink) {
125
+ try {
126
+ console.log(`Following redirect: ${redirectLink}`);
127
+
128
+ // Step 1: Follow Redirect and Get Final Video URL
129
+ const response = await axios.get(redirectLink, { maxRedirects: 5 });
130
+
131
+ if (response.request.res.responseUrl) {
132
+ console.log(`Final MP4 Link: ${response.request.res.responseUrl}`);
133
+ return response.request.res.responseUrl;
134
+ } else {
135
+ console.log("No final MP4 link found.");
136
+ return null;
137
+ }
138
+ } catch (error) {
139
+ console.error("Error fetching final MP4 link:", error.message);
140
+ return null;
141
+ }
142
+ }
143
+
144
+ // Start API Server
145
+ app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));