Spaces:
Paused
Paused
| import axios from 'axios'; | |
| import * as cheerio from 'cheerio'; | |
| import { createRequire } from 'module'; | |
| import os from 'os'; | |
| import express from 'express'; | |
| import { promisify, format } from 'util'; | |
| import { fileTypeFromBuffer } from 'file-type'; | |
| import ffmpeg from 'fluent-ffmpeg'; | |
| import nodeID3 from 'node-id3'; | |
| import ytdl from 'ytdl-core'; | |
| import FormData from 'form-data'; | |
| import fetch from 'node-fetch'; | |
| import mime from "mime-types"; | |
| const require = createRequire(import.meta.url); | |
| const fs = require('fs'); | |
| const path = require('path'); | |
| const { google } = require('googleapis'); | |
| const puppeteer = require('puppeteer'); | |
| import { fileURLToPath } from 'url'; | |
| const PORT = process.env.PORT || 7860; | |
| const app = express(); | |
| const readFileAsync = promisify(fs.readFile); | |
| const tempDir = path.join(os.tmpdir(), "temp"); | |
| const fss = fs.promises; | |
| const __dirname = path.dirname(fileURLToPath(import.meta.url)); | |
| // Membuat direktori sementara jika belum ada | |
| (async () => { | |
| if (!fs.existsSync(tempDir)) { | |
| await fss.mkdir(tempDir, { recursive: true }); | |
| } | |
| })(); | |
| const { exec } = require('child_process'); | |
| const writeFileAsync = promisify(fs.writeFile); | |
| const execPromise = promisify(exec); | |
| const youtube = google.youtube({ version: 'v3', auth: 'AIzaSyBPkpdJEGtAHebbaP3_CcA1_urfMFfeLLg' }); | |
| const bodyParser = require('body-parser'); | |
| app.use(bodyParser.json()); | |
| const tempDirBase = tempDir | |
| const https = require('https'); | |
| const agent = new https.Agent({ | |
| rejectUnauthorized: false // Nonaktifkan verifikasi sertifikat | |
| }); | |
| app.use('/temp', express.static(tempDir)); | |
| app.use(express.json()); | |
| app.use(express.raw({ type: '*/*', limit: '10mb' })); // Untuk menangani buffer dan data binary | |
| app.use(express.urlencoded({ extended: true })); | |
| app.all('/axios/:method/*', async (req, res) => { | |
| const { method } = req.params; | |
| const targetUrl = decodeURIComponent(req.params[0]); // Menangani URL setelah /:method/ | |
| const responseType = req.query.responseType || ''; // Menangani opsi responseType | |
| let option = { | |
| headers: { | |
| ...req.headers, // Menyalin semua header dari permintaan asli | |
| 'User-Agent': req.headers['user-agent'] || 'Mozilla/5.0 (Linux; Android 12; SM-S908B Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.58 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/357.0.0.23.115;] WhatsApp/1.2.3', // Menambahkan custom user-agent | |
| }, | |
| httpsAgent: agent | |
| }; | |
| if (responseType) { | |
| option.responseType = responseType; | |
| } | |
| try { | |
| let response; | |
| if (method.toLowerCase() === 'get') { | |
| response = await axios.get(targetUrl, option); | |
| } else if (method.toLowerCase() === 'post') { | |
| option.data = req.body; | |
| response = await axios.post(targetUrl, req.body, option); | |
| } else { | |
| res.status(405).json({ error: 'Method not allowed' }); | |
| return; | |
| } | |
| // Mengambil Content-Type dari header respons | |
| const mimeType = response.headers['content-type']; | |
| const buffer = Buffer.from(response.data, 'binary'); | |
| res.status(response.status); | |
| res.set(response.headers); // Set headers dari respons API | |
| // Menangani respons berdasarkan Content-Type | |
| if (mimeType && (mimeType.includes('text') || mimeType.includes('json') || mimeType.includes('html') || mimeType.includes('plain'))) { | |
| // Kirim data sebagai teks | |
| res.send(buffer.toString('utf-8')); | |
| } else { | |
| // Kirim file binary, termasuk PDF | |
| res.setHeader('Content-Length', buffer.length); | |
| res.send(buffer); | |
| } | |
| } catch (error) { | |
| console.error('Error:', error.response ? error.response.data : error.message); | |
| const statusCode = error.response ? error.response.status : 500; | |
| const errorMessage = error.response ? error.response.data : error.message; | |
| res.status(statusCode).json({ | |
| error: errorMessage | |
| }); | |
| } | |
| }); | |
| app.get("/", (req, res) => { | |
| res.type("json"); | |
| const keluaran = { | |
| success: true, | |
| author: "Nex", | |
| data: { | |
| igdl: "/igdl", | |
| twdl: "/twdl" | |
| }, | |
| }; | |
| res.send(keluaran); | |
| }); | |
| // Fungsi untuk menghasilkan IP acak | |
| const generateRandomIP = () => { | |
| const octet = () => Math.floor(Math.random() * 256); | |
| return `${octet()}.${octet()}.${octet()}.${octet()}`; | |
| }; | |
| async function XnDl(url) { | |
| const browser = await puppeteer.launch({ | |
| headless: true, | |
| args: ['--no-sandbox', '--disable-setuid-sandbox'], | |
| timeout: 60000 // Timeout untuk peluncuran browser | |
| }); | |
| try { | |
| const page = await browser.newPage(); | |
| await page.setUserAgent("Mozilla/5.0 (Linux; Android 10; SM-G965U Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.141 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/420.0.0.32.61;]"); | |
| await page.goto(url.replace("xnxx.com", "xnxxvideodownload.com"), { | |
| waitUntil: 'domcontentloaded', | |
| timeout: 60000 // Timeout untuk navigasi | |
| }); | |
| await page.waitForNavigation({ | |
| waitUntil: 'networkidle0', | |
| timeout: 60000 // Timeout untuk menunggu navigasi selesai | |
| }); | |
| const data = await page.evaluate(() => { | |
| const title = document.querySelector("body > main > section.e.j.d2.dsection > h2")?.textContent || ''; | |
| const thumbnail = document.querySelector("body > main > section.e.j.d2.dsection > div > div.thumbdiv > img")?.src || ''; | |
| const url = document.querySelector("body > main > section.e.j.d2.dsection > div > div.thumbdiv > a")?.href || ''; | |
| const table = document.getElementById('dtable')?.getElementsByTagName('table')[0]; | |
| const videoDownload = []; | |
| if (table) { | |
| for (let i = 0; i < table.rows.length; i++) { | |
| const row = table.rows[i]; | |
| const rowData = { | |
| quality: row.cells[0]?.innerText || '', | |
| ext: row.cells[1]?.innerText || '', | |
| url: row.cells[2]?.getElementsByTagName('a')[0]?.href || '' | |
| }; | |
| videoDownload.push(rowData); | |
| } | |
| } | |
| return { title, thumbnail, url, videoDownload }; | |
| }); | |
| return data; | |
| } catch (error) { | |
| console.error('Error:', error); | |
| return null; | |
| } finally { | |
| await browser.close(); | |
| } | |
| } | |
| app.get('/xnxx', async (req, res) => { | |
| try { | |
| const { url } = req.query; | |
| if (!url) return res.status(400).json({ error: 'Parameter url is required' }); | |
| let result = await XnDl(url); | |
| res.send(result); | |
| } catch (error) { | |
| console.error('Error processing request:', error); | |
| res.status(500).json({ | |
| error: 'Failed to process request\n' + error | |
| }); | |
| } | |
| }); | |
| /* | |
| ┏┓┏━┓┏━━━┓┏━┓┏━┓┏━━┓┏┓┏━┓┏┓╋┏┓ | |
| ┃┃┃┏┛┃┏━┓┃┃┃┗┛┃┃┗┫┣┛┃┃┃┏┛┃┃╋┃┃ | |
| ┃┗┛┛╋┃┃╋┃┃┃┏┓┏┓┃╋┃┃╋┃┗┛┛╋┃┃╋┃┃ | |
| ┃┏┓┃╋┃┃╋┃┃┃┃┃┃┃┃╋┃┃╋┃┏┓┃╋┃┃╋┃┃ | |
| ┃┃┃┗┓┃┗━┛┃┃┃┃┃┃┃┏┫┣┓┃┃┃┗┓┃┗━┛┃ | |
| ┗┛┗━┛┗━━━┛┗┛┗┛┗┛┗━━┛┗┛┗━┛┗━━━┛ | |
| */ | |
| function generateRandomID(length = 8) { | |
| const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; | |
| let result = ''; | |
| for (let i = 0; i < length; i++) { | |
| result += characters.charAt(Math.floor(Math.random() * characters.length)); | |
| } | |
| return result; | |
| } | |
| async function iwaraDL(url) { | |
| const browser = await puppeteer.launch({ | |
| headless: true, | |
| args: ['--no-sandbox', '--disable-setuid-sandbox'] | |
| }); | |
| const page = await browser.newPage(); | |
| await page.setUserAgent("Mozilla/5.0 (Linux; Android 10; SM-G965U Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.141 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/420.0.0.32.61;]"); | |
| await page.goto("https://fetchfile.me/download-iwara/", { waitUntil: 'domcontentloaded' }); | |
| await page.type('#url', url); | |
| await page.click('#ring'); | |
| await page.waitForSelector('#result > div > div.youtube.col-md-7 > ul > li'); | |
| const title = await page.$eval('#result > div > div.youtube.col-md-7 > h2', el => el.innerText); | |
| const originalSource = await page.$eval('#mp4 > table > tbody > tr:nth-child(1) > td:nth-child(3) > a.dlw', el => el.href || null); | |
| const high = await page.$eval('#mp4 > table > tbody > tr:nth-child(2) > td:nth-child(3) > a.dlw', el => el.href || null); | |
| const standard = await page.$eval('#mp4 > table > tbody > tr:nth-child(3) > td:nth-child(3) > a.dlw', el => el.href || null); | |
| const low = await page.$eval('#mp4 > table > tbody > tr:nth-child(4) > td:nth-child(3) > a.dlw', el => el.href || null); | |
| let ht = await page.content(); | |
| console.log("\n========================\n\n\n " + ht + " \n========================\n") | |
| await browser.close(); | |
| return { | |
| title, | |
| originalSource: originalSource || 'Original source not available', | |
| high: high || 'High quality not available', | |
| standard: standard || 'Standard quality not available', | |
| low: low || 'Low quality not available' | |
| }; | |
| } | |
| // Rute untuk menerima data melalui query string (GET) | |
| app.get('/iwara/download', async (req, res) => { | |
| const { url } = req.query; | |
| if (!url) return res.status(400).json({ error: 'Parameter url is required' }); | |
| try { | |
| const base64Result = await iwaraDL(url); | |
| res.json(base64Result); // Mengirimkan buffer gambar sebagai respons | |
| } catch (error) { | |
| res.status(500).send(error); | |
| } | |
| }); | |
| async function XnxxDown(inputUrl) { | |
| const browser = await puppeteer.launch({ | |
| headless: true, | |
| args: ['--no-sandbox', '--disable-setuid-sandbox'] | |
| }); | |
| const context = await browser.createIncognitoBrowserContext(); | |
| const page = await context.newPage(); | |
| await page.setUserAgent("Mozilla/5.0 (Linux; Android 10; SM-G965U Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.141 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/420.0.0.32.61;]"); | |
| await page.goto(`https://www.locoloader.com/?url=${encodeURIComponent(inputUrl)}`, { waitUntil: 'domcontentloaded' }); | |
| await page.waitForSelector("#extraction > div > div.hl > h1 > a"); | |
| const title = await page.$eval( | |
| "#extraction > div > div.hl > h1 > a", | |
| el => el.innerText.trim() | |
| ); | |
| const url = await page.$eval( | |
| "#extraction > div > div.hl > h1 > a", | |
| el => el.href | |
| ); | |
| const img = await page.$eval( | |
| "#extraction > div > div.content-final-single__thumb-wrapper > div > div > img", | |
| el => el.src | |
| ); | |
| const type = await page.$eval( | |
| "#extraction > div > div:nth-child(3) > div.display-table-cell.linkInfo > div.icon-media", | |
| el => el.innerText.trim() | |
| ); | |
| const downloadLink = await page.$eval( | |
| "#extraction > div > div:nth-child(3) > div.display-table-cell.linkButtons > a.bt.dl", | |
| el => el.href | |
| ); | |
| await browser.close(); | |
| return { title, url, img, type, downloadLink }; | |
| } | |
| app.get('/xnxx/download', async (req, res) => { | |
| const { url } = req.query; | |
| if (!url) return res.status(400).json({ error: 'Parameter url is required' }); | |
| try { | |
| const base64Result = await XnxxDown(url); | |
| res.json(base64Result); // Mengirimkan buffer gambar sebagai respons | |
| } catch (error) { | |
| res.status(500).send(error); | |
| } | |
| }); | |
| class Xnxx { | |
| constructor() { | |
| } | |
| async search(nama_porn, page) { | |
| let urls = `https://www.xnxx.com/search/${nama_porn}`; | |
| if (this.page > 0) { | |
| urls += `/${Number(page) - 1}`; | |
| } | |
| const ress = await axios.get(urls); | |
| const $ = cheerio.load(ress.data); | |
| let dataVideo = []; | |
| const videoPromises = []; | |
| $('div.thumb-block').each((i, element) => { | |
| const judul = $(element).find('p a').attr('title'); | |
| const url = $(element).find('p a').attr('href'); | |
| const thumbnail = $(element).find('div.thumb-inside div.thumb a img').attr('data-src') || $(element).find('p a img').attr('src'); | |
| const views = $(element).find('.metadata .right').text().trim(); | |
| const durasi = $(element).find('.metadata').contents().filter(function() { | |
| return this.nodeType === 3; | |
| }).text().trim(); | |
| const urlVideo = `https://www.xnxx.com${url}`; | |
| videoPromises.push( | |
| axios.get(urlVideo).then((resss) => { | |
| const $$ = cheerio.load(resss.data); | |
| const detailJudul = $$('#video-content-metadata .video-title strong').text().trim() || judul; | |
| const detailDurasiMatch = $$('#video-content-metadata .metadata').text().match(/(\d+min \d+sec|\d+sec)/); | |
| const detailDurasi = detailDurasiMatch ? detailDurasiMatch[0] : durasi; | |
| const detailViewsMatch = $$('#video-content-metadata .metadata').html().match(/(\d+(?:,\d+)?)\s*<span class="icon-f icf-eye"><\/span>/); | |
| const detailViews = detailViewsMatch ? detailViewsMatch[1].replace(/,/g, '') : views; | |
| const detailRating = $$('#video-votes .rating-box.value').text().trim(); | |
| const jumlahKomentar = $$('#tabComments .nb-video-comments').text().trim(); | |
| const tag = $$('.video-tags a.is-keyword').map((_, tag) => $$(tag).text()).get().join(', '); | |
| dataVideo.push({ | |
| judul: detailJudul, | |
| thumbnail: thumbnail, | |
| url: urlVideo, | |
| views: detailViews, | |
| durasi: detailDurasi, | |
| rating: detailRating, | |
| jumlahKomentar: jumlahKomentar, | |
| tag: tag | |
| }); | |
| }) | |
| ); | |
| }); | |
| await Promise.all(videoPromises); | |
| let next = $("#content-thumbs > div:nth-child(4) > ul > li") | |
| .find("a.no-page") | |
| .attr('href')?.match(/\/(\d+)$/)?.[1] || null; | |
| return { next, dataVideo }; | |
| } | |
| async download(videoURL) { | |
| try { | |
| const ress = await axios.get("https://arashicode-api.hf.space/xnxx/download?url=" + videoURL); | |
| return ress.data; | |
| } catch (err) { | |
| throw new Error(`Gagal mengambil link download: ${err}`); | |
| } | |
| } | |
| } | |
| app.get('/xnxx/search', async (req, res) => { | |
| const { query, page } = req.query; | |
| if (!query) return res.status(400).json({ error: 'Parameter query is required' }); | |
| try { | |
| const xnxx = new Xnxx(); | |
| let result = await xnxx.search(query, page); | |
| res.json(result); // Mengirimkan buffer gambar sebagai respons | |
| } catch (error) { | |
| res.status(500).send(error); | |
| } | |
| }); | |
| /**********************************************************************************/ | |
| class XvideosScraper { | |
| constructor() { | |
| this.baseURL = 'https://www.xvideos.com'; | |
| this.browser = null; | |
| this.page = null; | |
| this.context = null; | |
| } | |
| async initialize() { | |
| this.browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); | |
| this.context = await this.browser.createIncognitoBrowserContext(); | |
| this.page = await this.context.newPage(); | |
| await this.page.setUserAgent("Mozilla/5.0 (Linux; Android 10; SM-G965U Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.141 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/420.0.0.32.61;]"); | |
| } | |
| async search(query, pageNumber) { | |
| const url = `${this.baseURL}/?k=${encodeURIComponent(query)}`; | |
| if(pageNumber > 0) { | |
| url += `&p=${pageNumber}`; | |
| } | |
| console.log(`Navigating to: ${url}`); | |
| await this.page.goto(url, { waitUntil: 'networkidle2' }); | |
| const result = await this.page.evaluate(() => { | |
| function generateVideoUrl(url, use169, replaceJpgWithMp4) { | |
| if (replaceJpgWithMp4) { | |
| return url.replace(".jpg", ".mp4"); | |
| } | |
| let newUrl = url.substring(0, url.lastIndexOf("/")) | |
| .replace(/\/thumbs(169)?(xnxx)?((l*)|(poster))\//, "/videopreview/"); | |
| newUrl += use169 ? "_169.mp4" : "_43.mp4"; | |
| newUrl = newUrl.replace(/(-[0-9]+)_([0-9]+)/, "_$2$1"); | |
| return newUrl; | |
| } | |
| const elements = document.querySelectorAll('#content > div.mozaique > div'); | |
| const next = document.querySelector("#content > div.pagination > ul > li:last-child > a")?.href || null; | |
| const data = Array.from(elements).map(el => { | |
| const link = el.querySelector('div.thumb-inside > div > a')?.href || null; | |
| const image = el.querySelector('div.thumb-inside > div > a > img')?.src || null; | |
| const title = el.querySelector('div.thumb-under > p.title > a')?.getAttribute("title") || ''; | |
| const duration = el.querySelector('div.thumb-under > p.metadata > span > span.duration')?.textContent.trim() || ''; | |
| const quality = el.querySelector('div.thumb-inside > div > a > span')?.textContent.trim() || ''; | |
| const uploader = el.querySelector('div.thumb-under > p.metadata > span > span:nth-child(2) > a > span')?.textContent.trim() || ''; | |
| const idMatch = el.querySelector('script')?.innerHTML.match(/xv\.thumbs\.prepareVideo\((\d+)\)/); | |
| const id = idMatch ? idMatch[1] : ''; | |
| const preview = image ? generateVideoUrl(image, true, false) : ''; | |
| return { link, image, title, duration, quality, uploader, id, preview }; | |
| }).filter(item => item.title.length >= 1); | |
| return { next, data }; | |
| }); | |
| return result; | |
| } | |
| async close() { | |
| await this.browser.close(); | |
| } | |
| async download(videoURL) { | |
| try { | |
| const ress = await axios.get("https://arashicode-api.hf.space/xnxx/download?url=" + videoURL); | |
| return ress.data; | |
| } catch (err) { | |
| throw new Error(`Gagal mengambil link download: ${err}`); | |
| } | |
| } | |
| } | |
| app.get('/xvideos/search', async (req, res) => { | |
| const { query, page } = req.query; | |
| if (!query) return res.status(400).json({ error: 'Parameter query is required' }); | |
| try { | |
| const scraper = new XvideosScraper(); | |
| await scraper.initialize(); | |
| let result = await scraper.search(query, page); | |
| res.json(result); // Mengirimkan buffer gambar sebagai respons | |
| } catch (error) { | |
| res.status(500).send(error); | |
| } | |
| }); | |
| app.get('/xvideos/download', async (req, res) => { | |
| const { url } = req.query; | |
| if (!url) return res.status(400).json({ error: 'Parameter url is required' }); | |
| try { | |
| const base64Result = await XnxxDown(url); | |
| res.json(base64Result); // Mengirimkan buffer gambar sebagai respons | |
| } catch (error) { | |
| res.status(500).send(error); | |
| } | |
| }); | |
| /**********************************************************************************/ | |
| const SearchWhentai = async (query) => { | |
| const headers = { | |
| 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', | |
| }; | |
| try { | |
| const { data } = await axios.get("https://watchhentai.net/?s=" + query, { headers }); | |
| const $ = cheerio.load(data); | |
| const results = []; | |
| $('.result-item').each((_, element) => { | |
| const title = $(element).find('.title a').text().trim(); | |
| const link = $(element).find('.title a').attr('href'); | |
| const year = $(element).find('.meta .year').text().trim(); | |
| const description = $(element).find('.contenido p').text().trim(); | |
| const image = $(element).find('.image img').attr('src'); | |
| results.push({ title, link, year, description, image }); | |
| }); | |
| return results; | |
| } catch (error) { | |
| throw new Error(`Failed to scrape data: ${error.message}`); | |
| } | |
| }; | |
| const getDataWhentai = async (url) => { | |
| try { | |
| const { data } = await axios.get(url, { | |
| headers: { | |
| 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', | |
| }, | |
| }); | |
| const $ = cheerio.load(data); | |
| const title = $("#single > div.content.right > div.sheader > div.data > h1").text().trim(); | |
| const thumb = $("#single > div.content.right > div.sheader > div.poster > img").attr('src'); | |
| const type = $("#single > div.content.right > div.sheader > div.poster > div > span").text().trim(); | |
| const year = $("#single > div.content.right > div.sheader > div.data > div.sgeneros > a:nth-child(1)").text().trim(); | |
| const tags = $("#single > div.content.right > div.sheader > div.data > div.sgeneros > a") | |
| .map((_, el) => $(el).text().trim()) | |
| .get(); | |
| const sinopsis = $("#single > div.content.right > div:nth-child(2) > div > p").text().trim(); | |
| const alternativeTitle = $("#single > div.content.right > div:nth-child(5) > div:nth-child(2) > span > h3").text().trim(); | |
| const releaseDate = $("#single > div.content.right > div:nth-child(5) > div:nth-child(3) > span").text().trim(); | |
| const lastUpdated = $("#single > div.content.right > div:nth-child(5) > div:nth-child(4) > span").text().trim(); | |
| const season = $("#single > div.content.right > div:nth-child(5) > div:nth-child(5) > span").text().trim(); | |
| const totalEpisodes = $("#single > div.content.right > div:nth-child(5) > div:nth-child(6) > span").text().trim(); | |
| const averageDuration = $("#single > div.content.right > div:nth-child(5) > div:nth-child(7) > span").text().trim(); | |
| const quality = $("#single > div.content.right > div:nth-child(5) > div:nth-child(8) > span > a") | |
| .map((_, el) => $(el).text().trim()) | |
| .get(); | |
| const studio = $("#single > div.content.right > div:nth-child(5) > div:nth-child(9) > span > a").text().trim(); | |
| const episodes = $("#seasons > div > div > ul > li").map((_, el) => { | |
| const episodeThumb = $(el).find("div.imagen > img").attr('src'); | |
| const episodeUrl = $(el).find("div.episodiotitle > a").attr('href').replace("/videos/", "/download/"); | |
| const episodeTitle = $(el).find("div.episodiotitle > a").text().trim(); | |
| const uploadDate = $(el).find("div.episodiotitle > span").text().trim(); | |
| return { episodeUrl, episodeTitle, uploadDate }; | |
| }).get(); | |
| return { | |
| title, | |
| thumb, | |
| type, | |
| year, | |
| tags, | |
| sinopsis, | |
| episodes, | |
| }; | |
| } catch (error) { | |
| throw new Error(`Failed to scrape data: ${error.message}`); | |
| } | |
| }; | |
| const DownloadWhentai = async (url) => { | |
| try { | |
| const { data } = await axios.get(url, { | |
| headers: { | |
| 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', | |
| }, | |
| }); | |
| const $ = cheerio.load(data); | |
| const buttons = $("#single > div.content.right > div > div._4continuar > button").map((_, el) => { | |
| const href = $(el).attr('onclick')?.match(/window\.location\.href\s*=\s*'([^']+)'/)?.[1]; | |
| const text = $(el).text().trim(); | |
| return { href, text }; | |
| }).get(); | |
| return buttons | |
| } catch (error) { | |
| throw new Error(`Failed to scrape data: ${error.message}`); | |
| } | |
| }; | |
| app.get('/whentai/search', async (req, res) => { | |
| const { query } = req.query; | |
| if (!query) return res.status(400).json({ error: 'Parameter query is required' }); | |
| try { | |
| let result = await SearchWhentai(query); | |
| res.json(result); // Mengirimkan buffer gambar sebagai respons | |
| } catch (error) { | |
| res.status(500).send(error); | |
| } | |
| }); | |
| app.get('/whentai/detail', async (req, res) => { | |
| const { url } = req.query; | |
| if (!url) return res.status(400).json({ error: 'Parameter url is required' }); | |
| try { | |
| let result = await getDataWhentai(url); | |
| res.json(result); // Mengirimkan buffer gambar sebagai respons | |
| } catch (error) { | |
| res.status(500).send(error); | |
| } | |
| }); | |
| app.get('/whentai/download', async (req, res) => { | |
| const { url } = req.query; | |
| if (!url) return res.status(400).json({ error: 'Parameter url is required' }); | |
| try { | |
| let result = await DownloadWhentai(url); | |
| res.json({ result }); // Mengirimkan buffer gambar sebagai respons | |
| } catch (error) { | |
| res.status(500).send(error); | |
| } | |
| }); | |
| /*******************************/ | |
| // Fungsi untuk ping website | |
| async function pingWebsite() { | |
| const browser = await puppeteer.launch({ | |
| headless: true, | |
| args: ['--no-sandbox', '--disable-setuid-sandbox'] | |
| }); | |
| const page = await browser.newPage(); | |
| await page.setUserAgent("Mozilla/5.0 (Linux; Android 10; SM-G965U Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.141 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/420.0.0.32.61;]"); | |
| await page.goto('https://huggingface.co/spaces/ArashiCode/api'); | |
| console.log("Ping"); | |
| await browser.close(); | |
| } | |
| // Ping website setiap 5 jam | |
| async function pingEvery5Hours() { | |
| await pingWebsite(); | |
| setInterval(async () => { | |
| await pingWebsite(); | |
| }, 5 * 60 * 60 * 1000); // 5 hours in milliseconds | |
| } | |
| // Mulai ping | |
| pingEvery5Hours(); | |
| app.listen(PORT, () => { | |
| console.log(`Server is running on port ${PORT}`); | |
| }); |