const express = require('express'); const { chromium } = require('playwright-core'); const axios = require('axios'); const cheerio = require('cheerio'); const app = express(); const PORT = 7860; // Disable SSL verification for Axios const axiosInstance = axios.create({ httpsAgent: new (require('https').Agent)({ rejectUnauthorized: false }) }); app.get('/getDownload', async (req, res) => { try { const { moviename, episode } = req.query; if (!moviename) { return res.status(400).json({ error: "moviename query parameter is required" }); } const searchQuery = moviename.trim(); const episodeFilter = episode ? episode.trim() : null; const searchUrl = `https://nkiri.com/?s=${encodeURIComponent(searchQuery)}`; let firstMovieLink = null; console.log("\n🔍 Searching for:", searchQuery); try { // Attempt with Axios const { data: searchPage } = await axiosInstance.get(searchUrl); const $search = cheerio.load(searchPage); firstMovieLink = $search('article.post a').attr('href') || $search('h2.entry-title a').attr('href'); } catch (error) { console.log("\n⚠️ Axios failed, switching to Playwright..."); } if (!firstMovieLink) { // Fallback to Playwright if Axios fails const browser = await chromium.launch({ headless: true, args: ['--ignore-certificate-errors'] }); const page = await browser.newPage(); await page.goto(searchUrl, { waitUntil: 'networkidle' }); await page.waitForSelector('article.post a, h2.entry-title a', { timeout: 10000 }); firstMovieLink = await page.evaluate(() => { let linkElement = document.querySelector('article.post a') || document.querySelector('h2.entry-title a'); return linkElement ? linkElement.href : null; }); await browser.close(); } if (!firstMovieLink) { return res.status(404).json({ error: "No movie found" }); } console.log("\n✅ First Movie Page Found:", firstMovieLink); // =========================== // 2️⃣ GET DOWNLOAD LINKS FROM THE MOVIE PAGE // =========================== const { data: moviePage } = await axiosInstance.get(firstMovieLink); const $movie = cheerio.load(moviePage); let downloadLinks = []; const videoExtensions = ['.mkv', '.mp4', '.mov', '.avi']; $movie('a').each((i, el) => { const link = $movie(el).attr('href'); if ( link && (link.includes('downloadwella.com') || link.includes('wetafiles.com') || videoExtensions.some(ext => link.endsWith(ext))) ) { downloadLinks.push(link); } }); if (downloadLinks.length === 0) { return res.status(404).json({ error: "No valid download links found" }); } let selectedLink = downloadLinks[0]; // Default to first link if (downloadLinks.length > 1 && episodeFilter) { const filteredLinks = downloadLinks.filter(link => link.includes(`E${episodeFilter}`) || link.includes(`e${episodeFilter}`)); if (filteredLinks.length > 0) { selectedLink = filteredLinks[0]; // Use episode-specific link if found } } console.log("\n✅ Selected Download Link:", selectedLink); // Extract movie name from filename const filename = selectedLink.split('/').pop(); const movieTitle = filename.replace(/\.(mkv|mp4|mov|avi).*$/, '').replace(/[\.\-_\(\)]/g, ' ').trim(); // =========================== // 3️⃣ HANDLE FINAL DOWNLOAD LINK (WITH PLAYWRIGHT) // =========================== if (videoExtensions.some(ext => selectedLink.endsWith(ext))) { return res.json({ movie: movieTitle, finalDownloadUrl: selectedLink }); } // Open Playwright browser const browser = await chromium.launch({ headless: true, args: ['--ignore-certificate-errors'] }); const context = await browser.newContext({ ignoreHTTPSErrors: true }); const page = await context.newPage(); await page.goto(selectedLink, { waitUntil: 'networkidle' }); // Wait for the "Create Download Link" button await page.waitForSelector('#downloadbtn', { timeout: 15000 }); console.log("\n✅ Download button found, clicking..."); // Capture final download link let finalDownloadUrl = null; page.on('response', async (response) => { const requestUrl = response.url(); if (requestUrl.includes('/d/') && videoExtensions.some(ext => requestUrl.endsWith(ext))) { finalDownloadUrl = requestUrl; console.log("\n✅ FINAL DOWNLOAD LINK:", finalDownloadUrl); } }); // Click the button to generate final link await page.evaluate(() => document.querySelector('#downloadbtn').click()); // Wait for some time to capture responses await new Promise(resolve => setTimeout(resolve, 10000)); await browser.close(); if (!finalDownloadUrl) { return res.status(404).json({ error: "Failed to extract final download link" }); } res.json({ movie: movieTitle, finalDownloadUrl }); } catch (error) { console.error("\n❌ Error:", error.message); res.status(500).json({ error: "Internal server error" }); } }); // Start the API server app.listen(PORT, () => { console.log(`✅ API is running on http://localhost:${PORT}`); });