| import express from 'express'; |
| import path from 'path'; |
| import os from 'os'; |
| import PDFDocument from 'pdfkit'; |
| import fs from 'fs'; |
| import axios from 'axios'; |
| import { promisify } from 'util'; |
| import { createRequire } from 'module'; |
| import { fileURLToPath } from 'url'; |
| const __dirname = path.dirname(fileURLToPath(import.meta.url)); |
| import puppeteer from "puppeteer" |
| import sharp from 'sharp'; |
| import { fileTypeFromBuffer } from 'file-type'; |
| const require = createRequire(import.meta.url); |
| const PORT = process.env.PORT || 7860; |
| const app = express(); |
| const writeFileAsync = promisify(fs.writeFile); |
| const fss = fs.promises; |
| import sizeOf from 'image-size'; |
| const { exec } = require('child_process'); |
| const cheerio = require('cheerio'); |
| app.use('/static', express.static(os.tmpdir())); |
| import AdmZip from "adm-zip"; |
| const deleteFilesAfter = 2 * 60 * 1000; |
| const execAsync = promisify(exec); |
| const tmpDir = os.tmpdir(); |
| import crypto from 'crypto'; |
|
|
|
|
| function getRandomUserAgent() { |
| const userAgents = [ |
| 'Mozilla/5.0 (Linux; Android 12; SM-G991B Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.88 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/363.0.0.30.112;]', |
| 'Mozilla/5.0 (Linux; Android 11; SM-G986N Build/RP1A.200720.012; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.163 Whale/1.0.0.0 Crosswalk/25.80.14.21 Mobile Safari/537.36 NAVER(inapp; search; 730; 10.32.5)', |
| 'Mozilla/5.0 (Linux; Android 12; SM-G998B Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.125 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/372.1.0.23.107;]', |
| 'Mozilla/5.0 (Linux; Android 12; Galaxy S21+) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.100 Mobile Safari/537.36 WhatsApp/1.2.3', |
| 'Mozilla/5.0 (Linux; Android 13; SM-S918W Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.67 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/405.0.0.23.72;]', |
| 'Mozilla/5.0 (Linux; Android 9; SM-A730F) AppleWebKit/537.36 (KHTML, like Gecko) coc_coc_browser/87.0.162 Mobile Chrome/81.0.4044.162 Mobile Safari/537.36 WhatsApp/1.2.3', |
| 'Mozilla/5.0 (Linux; Android 11; SM-M215G Build/RP1A.200720.012; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.101 Mobile Safari/537.36 GSA/13.5.13.23.arm64', |
| 'Mozilla/5.0 (Linux; Android 13; SM-M146B Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.196 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/421.0.0.33.47;]', |
| 'Mozilla/5.0 (Linux; Android 13; 2201123G Build/TKQ1.220807.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.61 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/418.0.0.33.69;]', |
| 'Mozilla/5.0 (Linux; Android 12; 22081212UG Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/110.0.5481.153 Mobile Safari/537.36 [FB_IAB/Orca-Android;FBAV/400.0.0.11.90;]', |
| 'Mozilla/5.0 (Linux; U; Android 13; zh-cn; 2203121C Build/TKQ1.220829.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.127 Mobile Safari/537.36 XiaoMi/MiuiBrowser/17.5.120328 swan-mibrowser', |
| 'Mozilla/5.0 (Linux; U; Android 14; zh-cn; 2206122SC Build/UKQ1.231003.002) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.5414.118 Mobile Safari/537.36 XiaoMi/MiuiBrowser/18.2.150419', |
| 'Mozilla/5.0 (Linux; Android 13; 2304FPN6DC Build/TKQ1.221114.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/118.0.0.0 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/438.0.0.33.118;]', |
| 'Mozilla/5.0 (Linux; U; Android 14; zh-CN; 24053PY09C Build/UKQ1.240116.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 Quark/7.0.0.590 Mobile Safari/537.36', |
| 'Mozilla/5.0 (Linux; U; Android 12; zh-CN; M2007J1SC Build/SKQ1.211006.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/5.8.2.221 Mobile Safari/537.36', |
| 'Mozilla/5.0 (Linux; Android 10; Redmi K30S) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Mobile Safari/537.36 EdgA/88.0.705.53', |
| 'Mozilla/5.0 (Linux; U; Android 12; zh-cn; 22041211AC Build/SP1A.210812.016) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.102 MQQBrowser/13.5 Mobile Safari/537.36 COVC/046333', |
| 'Mozilla/5.0 (Linux; Android 13; 23078RKD5C Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/89.0.4389.72 MQQBrowser/6.2 TBS/046279 Mobile Safari/537.36 StApp/m6/2.6.5/android', |
| 'Mozilla/5.0 (Linux; Android 11; 21091116AI Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.78 Mobile Safari/537.36 GSA/13.21.16.26.arm64', |
| 'Mozilla/5.0 (Linux; Android 12; 21091116I Build/SP1A.210812.016; ) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/109.0.0.0 Mobile Safari/537.36 BingSapphire/25.3.410526302', |
| 'Mozilla/5.0 (Linux; Android 11; 21091116AI Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.129 Mobile Safari/537.36 WpsMoffice/16.4/arm64-v8a/1331', |
| 'Mozilla/5.0 (Linux; Android 12; 21091116I Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/105.0.5195.136 Mobile Safari/537.36 [FB_IAB/Orca-Android;FBAV/378.0.0.25.106;]', |
| 'Mozilla/5.0 (Linux; Android 11; 21091116AI Build/RP1A.200720.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/101.0.4951.61 Mobile Safari/537.36 GoogleApp/13.18.7.23.arm64', |
| 'Mozilla/5.0 (Linux; Android 14; Pixel Fold Build/UQ1A.231205.015.A1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/120.0.6099.193 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/445.0.0.34.118;]', |
| 'Mozilla/5.0 (Linux; Android 14; Pixel 8 Pro Build/UD1A.231105.004; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/119.0.6045.193 Mobile Safari/537.36 Brave/1.62.162', |
| 'Mozilla/5.0 (Linux; Android 14; Pixel 8 Pro Build/UD1A.230803.041; en-us) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Mobile Safari/537.36 Puffin/10.0.0.51608AP', |
| 'Mozilla/5.0 (Linux; Android 14; Pixel 8 Build/UD1A.230803.022.A5; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.61 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/441.1.0.39.109;]', |
| 'Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G) Build/RQ3A.210805.001.A1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.166 Mobile Safari/537.36 GoogleApp/12.34.17.29.arm64', |
| 'Mozilla/5.0 (Linux; Android 14; Infinix X6871 Build/UP1A.231005.007; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.47 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/468.1.0.56.78;]', |
| 'Mozilla/5.0 (Linux; Android 13; Infinix X6739 Build/TP1A.220624.014; en-us) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Mobile Safari/537.36 Puffin/10.1.0.51631AP', |
| 'Mozilla/5.0 (Linux; Android 13; Infinix X6711 Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/108.0.5359.128 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/441.0.0.32.109;]', |
| 'Mozilla/5.0 (Linux; Android 13; Infinix X6710 Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.60 Mobile Safari/537.36 YandexSearch/7.53 YandexSearchBrowser/7.53', |
| 'Mozilla/5.0 (Linux; Android 13; Infinix X6832 Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/123.0.6312.40 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/454.1.0.49.104;]', |
| 'Mozilla/5.0 (Linux; Android 12; Infinix X6820 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/112.0.5615.101 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/411.1.0.29.112;]' |
| ]; |
|
|
| const randomIndex = Math.floor(Math.random() * userAgents.length); |
| return userAgents[randomIndex]; |
| } |
|
|
| app.get('/puppet', async (req, res) => { |
| const url = req.query.url; |
| if (!url) { |
| return res.status(400).send('URL query parameter is required'); |
| } |
| try { |
| const browser = await puppeteer.launch(); |
| |
| |
| |
| |
| 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.setExtraHTTPHeaders({ |
| 'Accept-Language': 'en-US,en;q=0.9', |
| 'Accept-Encoding': 'gzip, deflate, br', |
| 'Connection': 'keep-alive' |
| }); |
|
|
| await page.goto(url, { |
| waitUntil: 'domcontentloaded', |
| timeout: 60000 |
| }); |
|
|
| await page.waitForNavigation({ |
| waitUntil: 'networkidle0', |
| timeout: 60000 |
| }); |
| |
| const htmlContent = await page.content(); |
| await new Promise(resolve => setTimeout(resolve, 15000)); |
| await browser.close(); |
| res.send(htmlContent); |
| } catch (error) { |
| console.error('Error fetching HTML:', error); |
| res.status(500).send('Error fetching HTML content'); |
| } |
| }); |
|
|
| const generateRandomIP = () => { |
| const octet = () => Math.floor(Math.random() * 256); |
| return `${octet()}.${octet()}.${octet()}.${octet()}`; |
| }; |
|
|
| 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 toonCubus(url) { |
| const instanceID = generateRandomID(); |
| const tempDir = path.join(os.tmpdir(), instanceID); |
| let browser; |
|
|
| try { |
| |
| await fss.mkdir(tempDir, { recursive: true }); |
|
|
| |
| const title = url.split('/').pop().split('.')[0]; |
|
|
| 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(url, { waitUntil: 'networkidle2' }); |
|
|
| const data = await page.evaluate(() => { |
| const elements = document.querySelectorAll("#Blog1 > div > div.check-box > center > a img"); |
| return Array.from(elements).map(img => ({ path: img.src })); |
| }); |
|
|
| const imagePaths = await downloadImages(data, tempDir, instanceID); |
| console.log(imagePaths) |
| const pdfPath = await createPDF(imagePaths, instanceID, tempDir); |
|
|
| return { |
| url: `https://arashicode-komik.hf.space/static/${instanceID}.pdf`, |
| path: `/static/${instanceID}.pdf`, |
| title: title, |
| Pdf_path: pdfPath |
| }; |
| } catch (error) { |
| console.error('Error in toonCubus:', error); |
| throw error; |
| } finally { |
| if (browser) { |
| await browser.close(); |
| } |
| try { |
| await fss.rmdir(tempDir, { recursive: true, force: true }); |
| } catch (cleanupError) { |
| console.error('Error cleaning up temp directory:', cleanupError); |
| } |
| } |
| } |
|
|
|
|
| app.get('/tooncubus', async (req, res) => { |
| const { url } = req.query; |
| if (!url) { |
| return res.status(400).send('URL is required'); |
| } |
| try { |
| const result = await toonCubus(url); |
| exec(`ls ${os.tmpdir()}`, (err, stdout) => { |
| if (err) console.error(err); |
| else console.log(stdout); |
| }); |
| res.json(result); |
| setTimeout(async () => { |
| try { |
| await fs.unlink(result.Pdf_path); |
| console.log(`File deleted: ${result.Pdf_path}`); |
| } catch (err) { |
| console.error(`Error deleting file: ${err.message}`); |
| } |
| }, 330000); |
| } catch (error) { |
| res.status(500).send('Error processing request'); |
| } |
| }); |
| |
|
|
| |
| function extractGalleryToken(url) { |
| const regex = /https:\/\/e-hentai\.org\/g\/(\d+)\/([\w-]+)\/?/; |
| const match = url.match(regex); |
| return match |
| ? { gallery_id: match[1], gallery_token: match[2], valid: true } |
| : { gallery_id: null, gallery_token: null, valid: false }; |
| } |
|
|
| async function E_Hentai(url) { |
| const checkUrl = extractGalleryToken(url); |
| if (!checkUrl.valid) throw new Error('URL invalid'); |
| |
| const instanceID = generateRandomID(); |
| const tempDir = path.join(os.tmpdir(), instanceID); |
|
|
| try { |
| |
| await fss.mkdir(tempDir, { recursive: true }); |
|
|
| const { data: metadata } = await axios.post('https://files.xianqiao.wang/https://api.e-hentai.org/api.php', { |
| method: "gdata", |
| gidlist: [ |
| [Number(checkUrl.gallery_id), checkUrl.gallery_token] |
| ], |
| namespace: 1 |
| }, { |
| headers: { |
| 'Content-Type': 'application/json' |
| } |
| }); |
|
|
| const { data } = await axios.get(url, { headers: { |
| 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0.1; SM-N916S Build/MMB29K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/106.0.5249.126 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/389.0.0.42.111;]', |
| 'Referer': url, |
| }}); |
| |
| const $ = cheerio.load(data); |
| |
| const imageList = []; |
| const tds = $('body > div:nth-child(10) > table > tbody > tr > td'); |
| const noClassTds = tds.filter((i, td) => !$(td).attr('class')).length; |
|
|
| if (noClassTds > 0) { |
| |
| for (let i = 1; i <= noClassTds; i++) { |
| let newUrl = `${url}?p=${i - 1}`; |
| console.log(newUrl) |
| const response = await axios.get(newUrl, { headers: { |
| 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0.1; SM-N916S Build/MMB29K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/106.0.5249.126 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/389.0.0.42.111;]', |
| 'Referer': url, |
| }}); |
|
|
| const $cada = cheerio.load(response.data); |
| let imageLinks = [] |
| $cada('#gdt > div').each((_, element) => { |
| const link = $cada(element).find('div > a').attr('href'); |
| if (link) { |
| imageLinks.push("https://files.xianqiao.wang/" + link); |
| } |
| }); |
|
|
| await Promise.all(imageLinks.map(async (link) => { |
| try { |
| const { data: imgPageData } = await axios.get(link); |
| const $imgPage = cheerio.load(imgPageData); |
| const imageSrc = $imgPage('#img').attr('src'); |
| if (imageSrc) { |
| imageList.push({ path: "https://files.xianqiao.wang/" + imageSrc }); |
| } |
| } catch (error) { |
| console.error(`Error fetching URL ${link}:`, error.message); |
| } |
| })); |
| } |
| } else { |
| |
| let imageLinks = [] |
| $('#gdt > div').each((_, element) => { |
| const link = $(element).find('div > a').attr('href'); |
| if (link) { |
| imageLinks.push("https://files.xianqiao.wang/" + link); |
| } |
| }); |
|
|
| await Promise.all(imageLinks.map(async (link) => { |
| try { |
| const { data: imgPageData } = await axios.get(link); |
| const $imgPage = cheerio.load(imgPageData); |
| const imageSrc = $imgPage('#img').attr('src'); |
| if (imageSrc) { |
| imageList.push({ path: "https://files.xianqiao.wang/" + imageSrc }); |
| } |
| } catch (error) { |
| console.error(`Error fetching URL ${link}:`, error.message); |
| } |
| })); |
| } |
| |
| console.log(imageList) |
| console.log(imageList.length) |
|
|
| const imagePaths = await downloadImages(imageList, tempDir, instanceID); |
| const pdfPath = await createPDF(imagePaths, instanceID, tempDir); |
| |
| return { |
| url: `https://arashicode-komik.hf.space/static/${instanceID}.pdf`, |
| path: `/static/${instanceID}.pdf`, |
| metadata, |
| Pdf_path: pdfPath |
| }; |
| } catch (error) { |
| console.error('Error in E_Hentai:', error); |
| throw error; |
| } finally { |
| try { |
| await fss.rmdir(tempDir, { recursive: true }); |
| } catch (cleanupError) { |
| console.error('Error cleaning up temp directory:', cleanupError); |
| } |
| } |
| } |
|
|
| app.get('/ehentai', async (req, res) => { |
| const { url } = req.query; |
| if (!url) { |
| return res.status(400).send('URL is required'); |
| } |
| try { |
| const result = await E_Hentai(url); |
| exec(`ls ${os.tmpdir()}`, (err, stdout) => { |
| if (err) console.error(err); |
| else console.log(stdout); |
| }); |
| res.json(result); |
| setTimeout(async () => { |
| try { |
| await fs.unlink(result.Pdf_path); |
| console.log(`File deleted: ${result.Pdf_path}`); |
| } catch (err) { |
| console.error(`Error deleting file: ${err.message}`); |
| } |
| }, 330000); |
| } catch (error) { |
| res.status(500).send('Error processing request'); |
| } |
| }); |
|
|
| |
|
|
|
|
|
|
| async function komiku_download(url) { |
| const instanceID = generateRandomID(); |
| const tempDir = path.join(os.tmpdir(), instanceID); |
| await fss.mkdir(tempDir); |
|
|
| const title = url.split('/').filter(part => part).pop(); |
|
|
| try { |
| const response = await axios.get(url, { |
| headers: { |
| 'User-Agent': getRandomUserAgent() || 'Mozilla/5.0 (Linux; Android 6.0.1; SM-N916S Build/MMB29K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/106.0.5249.126 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/389.0.0.42.111;]', |
| 'Referer': 'https://komiku.id/devious-son-of-heaven-chapter-04/', |
| 'X-Forwarded-For': generateRandomIP() |
| } |
| }); |
| const html = response.data; |
| const $ = cheerio.load(html); |
| const imgList = []; |
|
|
| $('#Baca_Komik img').each((index, element) => { |
| const src = $(element).attr('src'); |
| imgList.push({ path: "https://files.xianqiao.wang/" + src }); |
| }); |
|
|
| const imagePaths = await downloadImages(imgList, tempDir, instanceID); |
| const pdfPath = await createPDF(imagePaths, instanceID, tempDir); |
|
|
| return { url: "https://arashicode-komik.hf.space/static/" + instanceID + ".pdf", path: `/static/${instanceID}.pdf`, title: title, Pdf_path: pdfPath }; |
| } catch (error) { |
| console.log(error); |
| throw error; |
| } finally { |
| await fss.rmdir(tempDir, { recursive: true }); |
| } |
| } |
|
|
| async function downloadImage(image, tempDir, instanceID) { |
| try { |
| |
| const response = await axios.get(image.path, { |
| responseType: 'arraybuffer', |
| headers: { |
| 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0.1; SM-N916S Build/MMB29K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/106.0.5249.126 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/389.0.0.42.111;]', |
| 'Referer': image.path, |
| } |
| }); |
| const buffer = Buffer.from(response.data, 'binary'); |
| const mimesd = await fileTypeFromBuffer(buffer); |
| const ext = mimesd ? mimesd.ext : 'jpeg'; |
| const imagePath = `${tempDir}/image_${instanceID}_${Date.now()}_${Math.floor(Math.random() * 1000)}.${ext}`; |
| await writeFileAsync(imagePath, buffer); |
| return imagePath; |
| } catch (error) { |
| console.error('Error downloading image:', error); |
| throw error; |
| } |
| } |
|
|
| async function downloadImages(imgList, tempDir, instanceID) { |
| const imagePaths = []; |
| for (const img of imgList) { |
| const imagePath = await downloadImage(img, tempDir, instanceID); |
| imagePaths.push(imagePath); |
| } |
| return imagePaths; |
| } |
|
|
| async function createPDF(imagePaths, instanceID, tempDir) { |
| const pdfPath = path.join(os.tmpdir(), `${instanceID}.pdf`); |
| const doc = new PDFDocument({ autoFirstPage: false }); |
|
|
| doc.pipe(fs.createWriteStream(pdfPath)); |
|
|
| for (const imagePath of imagePaths) { |
| try { |
| |
| const imageExt = path.extname(imagePath).toLowerCase(); |
| const supportedExtensions = ['.jpg', '.jpeg', '.png']; |
| let convertedImagePath = imagePath; |
| |
| if (!fs.existsSync(imagePath) || fs.statSync(imagePath).size === 0) { |
| throw new Error(`Invalid or empty image file: ${imagePath}`); |
| } |
|
|
| if (!supportedExtensions.includes(imageExt)) { |
| convertedImagePath = await convertImage(imagePath); |
| } |
|
|
| const { width, height } = await getImageDimensions(convertedImagePath); |
| doc.addPage({ size: [width, height] }); |
| doc.image(convertedImagePath, 0, 0, { width: width, height: height }); |
|
|
| |
| if (convertedImagePath !== imagePath) { |
| fs.unlinkSync(convertedImagePath); |
| } |
| } catch (error) { |
| console.error(`Error processing image ${imagePath}:`, error.message); |
| } |
| } |
|
|
| doc.end(); |
|
|
| return pdfPath; |
| } |
|
|
| async function getImageDimensions(imagePath) { |
| const dimensions = await sizeOf(imagePath); |
| return dimensions; |
| } |
|
|
| async function convertImage(imagePath) { |
| return new Promise((resolve, reject) => { |
| const outputImagePath = imagePath.replace(/\.\w+$/, '.jpg'); |
| exec(`convert "${imagePath}" "${outputImagePath}"`, (error, stdout, stderr) => { |
| if (error) { |
| console.error('ImageMagick Error:', stderr); |
| return reject(error); |
| } |
| resolve(outputImagePath); |
| }); |
| }); |
| } |
|
|
| app.get('/download', async (req, res) => { |
| const { url } = req.query; |
| if (!url) { |
| return res.status(400).send('URL is required'); |
| } |
|
|
| try { |
| const result = await komiku_download(url); |
| res.json(result); |
| setTimeout(() => { |
| fs.unlink(result.Pdf_path, (err) => { |
| if (err) { |
| console.error(`Error deleting file: ${err.message}`); |
| } else { |
| console.log(`File deleted: ${result.Pdf_path}`); |
| } |
| }); |
| }, 330000); |
| } catch (error) { |
| res.status(500).send('Error processing request'); |
| } |
| }); |
|
|
| async function nhentai(url) { |
| const instanceID = generateRandomID(); |
| const tempDir = path.join(os.tmpdir(), instanceID); |
| await fs.promises.mkdir(tempDir, { recursive: true }); |
|
|
| try { |
| const response = await axios.get(url, { |
| headers: { |
| 'User-Agent': 'Mozilla/5.0', |
| 'Referer': 'https://nhentai.net/' |
| } |
| }); |
|
|
| const $ = cheerio.load(response.data); |
| const scriptContent = $('script') |
| .filter((i, el) => $(el).html().includes('window._gallery = JSON.parse')) |
| .html(); |
|
|
| const jsonString = scriptContent.match(/JSON\.parse\("(.*)"\)/)[1]; |
| const decodedString = jsonString.replace(/\\u0022/g, '"').replace(/\\u005C/g, '\\'); |
| const jsonData = JSON.parse(decodedString); |
|
|
| const imgList = jsonData.images.pages.map((_, index) => ({ |
| path: `https://i5.nhentai.net/galleries/${jsonData.media_id}/${index + 1}.${jsonData.images.pages[index].t === "w" ? "webp" : jsonData.images.pages[index].t === "p" ? "png" : "jpg"}` |
| })); |
|
|
| const imagePaths = []; |
| for (const img of imgList) { |
| const downloadedImagePath = await downloadImageNh(img, tempDir, instanceID); |
| imagePaths.push(downloadedImagePath); |
| } |
|
|
| const pdfPath = await createPDF(imagePaths, instanceID, tempDir); |
| console.log(`PDF successfully created: ${pdfPath}`); |
| return { |
| url: `https://arashicode-komik.hf.space/static/${instanceID}.pdf`, |
| path: pdfPath, |
| result: jsonData |
| }; |
| } catch (error) { |
| console.error(error); |
| throw error; |
| } finally { |
| await fs.promises.rm(tempDir, { recursive: true }); |
| } |
| } |
|
|
|
|
| |
| async function convertImageV2(inputPath, outputPath) { |
| try { |
| await sharp(inputPath).toFormat('jpeg').toFile(outputPath); |
| console.log(`Converted ${inputPath} to ${outputPath}`); |
| return outputPath; |
| } catch (error) { |
| console.error(`Error converting image: ${error.message}`); |
| throw new Error(`Failed to convert image ${inputPath} to JPG.`); |
| } |
| } |
|
|
|
|
| async function convertImageToJPG(inputPath, outputPath) { |
| try { |
| await execAsync(`ffmpeg -i "${inputPath}" -q:v 1 "${outputPath}"`); |
| console.log(`Converted ${inputPath} to ${outputPath}`); |
| return outputPath; |
| } catch (error) { |
| console.error(`Error converting image: ${error.message}`); |
| throw new Error(`Failed to convert image ${inputPath} to JPG.`); |
| } |
| } |
|
|
| async function downloadImageNh(image, tempDir, instanceID) { |
| const servers = [ |
| "https://i1.nhentai.net", |
| "https://i2.nhentai.net", |
| "https://i4.nhentai.net", |
| "https://i5.nhentai.net", |
| "https://i3.nhentai.net", |
| "https://i7.nhentai.net" |
| ]; |
|
|
| for (const server of servers) { |
| try { |
| const imageUrl = `${server}/galleries/${image.path.split('galleries/')[1]}`; |
| console.log(`Downloading image from: ${imageUrl}`); |
|
|
| const response = await axios.get(imageUrl, { |
| responseType: 'arraybuffer', |
| headers: { |
| 'User-Agent': 'Mozilla/5.0', |
| 'Referer': 'https://nhentai.net/' |
| } |
| }); |
|
|
| let imagePath = `${tempDir}/image_${instanceID}_${Date.now()}_${Math.floor(Math.random() * 1000)}.webp`; |
| await fs.promises.writeFile(imagePath, response.data); |
|
|
| const isWebp = path.extname(imagePath).toLowerCase() === '.webp'; |
| if (isWebp) { |
| const convertedPath = imagePath.replace('.webp', '.jpg'); |
| imagePath = await convertImageToJPG(imagePath, convertedPath); |
| fs.unlinkSync(imagePath.replace('.jpg', '.webp')); |
| } |
|
|
| return imagePath; |
| } catch (error) { |
| console.error(`Error downloading image from ${server}:`, error.message); |
| } |
| } |
|
|
| throw new Error('Failed to download image from all servers.'); |
| } |
|
|
|
|
| async function downloadImageNhs(imgList, tempDir, instanceID) { |
| const imagePaths = []; |
| for (const img of imgList) { |
| const imagePath = await downloadImageNh(img, tempDir, instanceID); |
| imagePaths.push(imagePath); |
| } |
| return imagePaths; |
| } |
|
|
| app.get('/nhentai', async (req, res) => { |
| const { url } = req.query; |
| if (!url) { |
| return res.status(400).send('URL is required'); |
| } |
| try { |
| const result = await nhentai(url); |
| res.json(result); |
| setTimeout(() => { |
| fs.unlink(result.path, (err) => { |
| if (err) { |
| console.error(`Error deleting file: ${err.message}`); |
| } else { |
| console.log(`File deleted: ${result.path}`); |
| } |
| }); |
| }, 370000); |
| } catch (error) { |
| res.status(500).send('Error processing request'); |
| } |
| }); |
|
|
|
|
| async function downloadFromUrl(url, filePath, biskuit) { |
| const writer = fs.createWriteStream(filePath); |
|
|
| const response = await axios({ |
| url, |
| method: 'GET', |
| responseType: 'stream', |
| headers: { |
| 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', |
| 'Referer': url, |
| 'Cookie': biskuit |
| } |
| }); |
|
|
| response.data.pipe(writer); |
|
|
| return new Promise((resolve, reject) => { |
| writer.on('finish', resolve); |
| writer.on('error', reject); |
| }); |
| } |
|
|
|
|
|
|
| async function Rules34Infonues(url_r34) { |
| try { |
| const browser = await puppeteer.launch(); |
| const page = await browser.newPage(); |
|
|
| await page.setExtraHTTPHeaders({ |
| 'User-Agent': getRandomUserAgent() || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', |
| 'Referer': url_r34 |
| }); |
|
|
| await page.goto(url_r34, { referer: url_r34 }); |
|
|
| const htmlContent = await page.content(); |
| const $ = cheerio.load(htmlContent); |
|
|
| const title = $("body > div > div.wrapper > div.main > div.container > div > div > div:nth-child(1) > div.heading > h1").text().trim() || |
| url_r34.match(/\/video\/\d+\/(.*)\//)?.[1]; |
|
|
| const infoElements = $("#tab_video_info > div"); |
| const result = { |
| title, |
| artist: [], |
| uploader: [], |
| tags: [], |
| download: [], |
| category: [] |
| }; |
|
|
| if (infoElements.length > 0) { |
| const [videoInfo, tags, download] = [ |
| infoElements.eq(infoElements.length - 3), |
| infoElements.eq(infoElements.length - 2), |
| infoElements.eq(infoElements.length - 1) |
| ]; |
|
|
| tags.find("div.wrap > a").each((_, element) => { |
| result.tags.push({ title: $(element).text().trim(), url: $(element).attr('href') }); |
| }); |
| result.tags.pop(); |
|
|
| download.find("div.wrap > a").each((_, element) => { |
| result.download.push({ quality: $(element).text().trim(), url: $(element).attr('href') }); |
| }); |
|
|
| videoInfo.find("div.cols > div").each((_, col) => { |
| $(col).find("div.col:nth-child(1) > a").each((_, link) => { |
| result.category.push({ title: $(link).text().trim(), url: $(link).attr('href') }); |
| }); |
|
|
| $(col).find("div.col:nth-child(2) > a").each((_, link) => { |
| result.artist.push({ title: $(link).text().trim(), url: $(link).attr('href') }); |
| }); |
|
|
| $(col).find("div.col:nth-child(3) > a").each((_, link) => { |
| result.uploader.push({ title: $(link).text().trim(), url: $(link).attr('href') }); |
| }); |
| }); |
| } |
|
|
| await browser.close(); |
| return result; |
| } catch (error) { |
| console.error('Error fetching data:', error); |
| throw error; |
| } |
| } |
|
|
|
|
|
|
| async function Rules34info(url_r34) { |
| try { |
| |
| const response = await axios.get(url_r34, { |
| headers: { |
| 'User-Agent': getRandomUserAgent() || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', |
| 'Referer': url_r34 |
| } |
| }); |
| |
| const htmlContent = response.data; |
| const $ = cheerio.load(htmlContent); |
|
|
| const title = $("body > div > div.wrapper > div.main > div.container > div > div > div:nth-child(1) > div.heading > h1").text().trim() || url_r34.match(/\/video\/\d+\/(.*)\//)?.[1]; |
|
|
| const infoElements = $("#tab_video_info > div"); |
| const result = { |
| title: title, |
| artist: [], |
| uploader: [], |
| tags: [], |
| category: [] |
| }; |
|
|
| if (infoElements.length > 0) { |
| const tags = infoElements.eq(infoElements.length - 2); |
| const videoInfo = infoElements.eq(infoElements.length - 3); |
|
|
| if (tags.length > 0) { |
| tags.find("div.wrap > a").each((index, element) => { |
| result.tags.push({ title: $(element).text().trim(), url: $(element).attr('href') }); |
| }); |
| result.tags.pop(); |
| } |
|
|
| if (videoInfo.length > 0) { |
| videoInfo.find("div.cols > div").each((index, col) => { |
| const categoryLinks = $(col).find("div.col:nth-child(1) > a"); |
| categoryLinks.each((index, link) => { |
| result.category.push({ title: $(link).text().trim(), url: $(link).attr('href') }); |
| }); |
|
|
| const artistLinks = $(col).find("div.col:nth-child(2) > a"); |
| artistLinks.each((index, link) => { |
| result.artist.push({ title: $(link).text().trim(), url: $(link).attr('href') }); |
| }); |
|
|
| const uploaderLinks = $(col).find("div.col:nth-child(3) > a"); |
| uploaderLinks.each((index, link) => { |
| result.uploader.push({ title: $(link).text().trim(), url: $(link).attr('href') }); |
| }); |
| }); |
| } |
| } |
|
|
| return result; |
| } catch (error) { |
| console.error('Error fetching data:', error); |
| throw error; |
| } |
| } |
|
|
| async function Rules34(url_r34) { |
| try { |
| const browser = await puppeteer.launch(); |
| const page = await browser.newPage(); |
|
|
| await page.setExtraHTTPHeaders({ |
| 'User-Agent': getRandomUserAgent() || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', |
| 'Referer': url_r34 |
| }); |
| await page.goto(url_r34, { referer: url_r34 }); |
|
|
| const htmlContent = await page.content(); |
| const $ = cheerio.load(htmlContent); |
|
|
| const title = $("body > div > div.wrapper > div.main > div.container > div > div > div:nth-child(1) > div.heading > h1").text().trim() || url_r34.match(/\/video\/\d+\/(.*)\//)?.[1]; |
|
|
| const infoElements = $("#tab_video_info > div"); |
| const result = { |
| title: title, |
| artist: [], |
| uploader: [], |
| tags: [], |
| download: [], |
| category: [] |
| }; |
|
|
| if (infoElements.length > 0) { |
| const tags = infoElements.eq(infoElements.length - 2); |
| const download = infoElements.eq(infoElements.length - 1); |
| const videoInfo = infoElements.eq(infoElements.length - 3); |
|
|
| if (tags.length > 0) { |
| tags.find("div.wrap > a").each((index, element) => { |
| result.tags.push({ title: $(element).text().trim(), url: $(element).attr('href') }); |
| }); |
| result.tags.pop(); |
| } |
|
|
| if (download.length > 0) { |
| download.find("div.wrap > a").each((index, element) => { |
| result.download.push({ quality: $(element).text().trim(), url: $(element).attr('href') }); |
| }); |
|
|
| |
| const lastDownloadUrl = result.download[result.download.length - 1].url; |
| const downloadPath = path.resolve(os.tmpdir()) |
| let filenem = `${Date.now()}_file.mp4` |
| const filePath = path.join(downloadPath, filenem) |
| |
| const biskuit = await page.cookies(); |
| |
|
|
| await downloadFromUrl(lastDownloadUrl, filePath, biskuit); |
|
|
| result.downloadPath = filePath; |
| result.downloadUrl = "https://arashicode-komik.hf.space/static/" + filenem; |
| } |
|
|
| if (videoInfo.length > 0) { |
| videoInfo.find("div.cols > div").each((index, col) => { |
| const categoryLinks = $(col).find("div.col:nth-child(1) > a"); |
| categoryLinks.each((index, link) => { |
| result.category.push({ title: $(link).text().trim(), url: $(link).attr('href') }); |
| }); |
|
|
| const artistLinks = $(col).find("div.col:nth-child(2) > a"); |
| artistLinks.each((index, link) => { |
| result.artist.push({ title: $(link).text().trim(), url: $(link).attr('href') }); |
| }); |
|
|
| const uploaderLinks = $(col).find("div.col:nth-child(3) > a"); |
| uploaderLinks.each((index, link) => { |
| result.uploader.push({ title: $(link).text().trim(), url: $(link).attr('href') }); |
| }); |
| }); |
| } |
| } |
|
|
| await browser.close(); |
| return result; |
| } catch (error) { |
| console.error('Error fetching data:', error); |
| throw error; |
| } |
| } |
|
|
|
|
| app.get('/r34', async (req, res) => { |
| const { url } = req.query; |
| if (!url) { |
| return res.status(400).send('URL is required'); |
| } |
| try { |
| const result = await Rules34(url); |
| res.json(result); |
| const filePath = result.downloadPath; |
| |
| setTimeout(() => { |
| fs.unlink(filePath, (err) => { |
| if (err) { |
| console.error(`Error deleting file: ${err.message}`); |
| } else { |
| console.log(`File deleted: ${filePath}`); |
| } |
| }); |
| }, 280000); |
| } catch (error) { |
| res.status(500).send('Error processing request'); |
| } |
| }); |
|
|
|
|
| app.get('/r34/download', async (req, res) => { |
| const { url, type = 'download' } = req.query; |
| if (!url) { |
| return res.status(400).send('URL is required'); |
| } |
|
|
| try { |
| const result = await Rules34(url); |
| const filePath = result.downloadPath; |
|
|
| |
| if (!fs.existsSync(filePath)) { |
| return res.status(404).send('File not found'); |
| } |
|
|
| const fileName = path.basename(filePath); |
| const mimeType = 'video/mp4'; |
|
|
| res.setHeader('Content-Type', mimeType); |
|
|
| if (type === 'stream') { |
| const range = req.headers.range; |
|
|
| if (range) { |
| const stat = fs.statSync(filePath); |
| const fileSize = stat.size; |
| |
| const parts = range.replace(/bytes=/, "").split("-"); |
| const start = parseInt(parts[0], 10); |
| const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1; |
|
|
| const chunksize = (end - start) + 1; |
| const file = fs.createReadStream(filePath, { start, end }); |
| const head = { |
| 'Content-Range': `bytes ${start}-${end}/${fileSize}`, |
| 'Accept-Ranges': 'bytes', |
| 'Content-Length': chunksize, |
| 'Content-Type': mimeType, |
| }; |
|
|
| res.writeHead(206, head); |
| file.pipe(res); |
| } else { |
| res.setHeader('Content-Length', fileSize); |
| res.sendFile(filePath); |
| } |
| } else if (type === 'buffer') { |
| fs.readFile(filePath, (err, data) => { |
| if (err) { |
| console.error('Gagal membaca file:', err); |
| res.status(500).send('Gagal membaca file: \n' + err); |
| } else { |
| res.setHeader('Content-Length', data.length); |
| res.send(data); |
| } |
| }); |
| } else { |
| res.download(filePath, fileName, (err) => { |
| if (err) { |
| console.error('Gagal mengirim file:', err); |
| res.status(500).send('Gagal mengirim file: \n' + err); |
| } |
| }); |
| } |
| } catch (error) { |
| console.error('Error processing request:', error); |
| res.status(500).send('Error processing request'); |
| } |
| }); |
|
|
|
|
| app.get('/r34/info', async (req, res) => { |
| const { url } = req.query; |
| if (!url) { |
| return res.status(400).send('URL is required'); |
| } |
| try { |
| const result = await Rules34Infonues(url); |
| res.json(result); |
| } catch (error) { |
| res.status(500).send('Error processing request'); |
| } |
| }); |
|
|
|
|
| async function r34Cookie(url) { |
| const browser = await puppeteer.launch({ |
| headless: true, |
| args: ['--no-sandbox', '--disable-setuid-sandbox'] |
| }); |
| const page = await browser.newPage(); |
| |
| await page.setExtraHTTPHeaders({ |
| 'User-Agent': getRandomUserAgent(), |
| 'Referer': url, |
| 'X-Forwarded-For': generateRandomIP() |
| }); |
| await page.goto(url); |
| const cookies = await page.cookies(); |
| await browser.close(); |
| return { cookies }; |
| } |
|
|
| app.get('/r34cookie', async (req, res) => { |
| const { url } = req.query; |
| if (!url) { |
| return res.status(400).send('URL is required'); |
| } |
| try { |
| const result = await r34Cookie(url); |
| res.json(result); |
| } catch (error) { |
| res.status(500).send('Error processing request'); |
| } |
| }); |
|
|
| let kue = 'p_ab_id=5; p_ab_id_2=4; p_ab_d_id=1131020051; PHPSESSID=98423123_ooWiGNZmn10FSApJ6AE7tfFStuzzSPvS; device_token=204de0e72a664d1b93d4d9bf1913c6cf; privacy_policy_agreement=7; webp_available=1; c_type=19; privacy_policy_notification=0; a_type=0; b_type=2; yuid_b=I0QxAZA; first_visit_datetime=2024-10-23%2016%3A18%3A55; __cf_bm=AF3_34pfnlX3j.z9HgTHRXT_VPiboGN1xCtpGEIAl6g-1729667935-1.0.1.1-i8bf6DbM4hqEBcXVI8PtrjFt4pgvg.SNNkr9y1wwhnilldAD6qQYltFmwlFJgVgug3zR41_1NO43zA4kdLe0MvRYRu3SkoiyaH8_bf7S4Rw; cf_clearance=myv1GHmvbUejqJyyBWI.VKf26uxBSPf_TIslXxb1t74-1729667943-1.2.1.1-pbZD7QZA95M9OqhnIuUreLC4aGuTLgXpm8DN7eRAb_XmjwLv53uYqq3vVTF06MMKOxQmVER9aZIUU7vw2zT3sGK_3nrDLHCSJ4CeAezc7yjS69guPqtmkqn.tMIuxt399W82C.9zagzJ.Eo0vs91tllX1yVBNPIZ8rV2BunLinWWIcHR8lqiVyXUgRh1VEk_juC0_Tsezh1OcZ39LswLY8da0Vf5g6z5REZRgw1X18LwBNARVetsNojdIiUasWn7jLbPCGYezaHrMsg7Eqy.sfb8T6xlGGS4hDjr_dD9sTIp7RcU6geIAl5KiY4dXjhTY3Kn1B8MugIzpSjNzBvMqkTI9fEVuil7iaPXfw_O8Dc8TPc7z2q.wk0ofJVSn.7O'; |
|
|
|
|
| |
| async function pixivGetData(illustId) { |
| const headers = { |
| 'User-Agent': 'Mozilla/5.0 (Linux; Android 12; SM-G998B Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.58 Mobile Safari/537.36 WhatsApp/1.2.3', |
| 'Referer': 'https://www.pixiv.net/', |
| "Sec-Ch-Ua": `"Not-A.Brand";v="99", "Chromium";v="124"`, |
| 'Baggage': "sentry-environment=production,sentry-release=1ab9ad920c28fb6fd4598d3745c828c3e2facd3a,sentry-public_key=e0efdb023498416a827321504f31f009,sentry-trace_id=bc354f2c0c8a461eaab6764025f0b7e1,sentry-sample_rate=0.0001", |
| 'Cookie': kue |
| }; |
|
|
| try { |
| const response = await axios.get(`https://www.pixiv.net/touch/ajax/illust/details?illust_id=${illustId}&lang=en`, { headers }); |
| return response.data; |
| } catch (error) { |
| console.error("Error fetching data from Pixiv:", error); |
| throw error; |
| } |
| } |
|
|
| |
| async function downloadAndExtractZipFromPixivData(pixivData) { |
| const pixivId = pixivData.body.illust_details.id; |
| const zipUrl = pixivData.body.illust_details.ugoira_meta.src; |
| |
| |
| const randomFolderName = crypto.randomBytes(8).toString('hex'); |
| const outputDirectory = path.join(tmpDir, `${pixivId}_${randomFolderName}`); |
|
|
| try { |
| const headers = { |
| 'User-Agent': 'Mozilla/5.0 (Linux; Android 12; SM-G998B Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/99.0.4844.58 Mobile Safari/537.36 WhatsApp/1.2.3', |
| 'Referer': 'https://www.pixiv.net/', |
| "Sec-Ch-Ua": `"Not-A.Brand";v="99", "Chromium";v="124"`, |
| 'Baggage': "sentry-environment=production,sentry-release=1ab9ad920c28fb6fd4598d3745c828c3e2facd3a,sentry-public_key=e0efdb023498416a827321504f31f009,sentry-trace_id=bc354f2c0c8a461eaab6764025f0b7e1,sentry-sample_rate=0.0001", |
| 'Cookie': kue |
| }; |
| const response = await axios.get(zipUrl, { responseType: 'arraybuffer', headers }); |
|
|
| if (!fs.existsSync(outputDirectory)) { |
| fs.mkdirSync(outputDirectory); |
| } |
|
|
| const zipPath = path.join(outputDirectory, `${pixivId}_ugoira.zip`); |
| fs.writeFileSync(zipPath, response.data); |
|
|
| const zip = new AdmZip(zipPath); |
| zip.extractAllTo(outputDirectory, true); |
| console.log(`File zip berhasil diekstrak ke ${outputDirectory}`); |
|
|
| return outputDirectory; |
| } catch (error) { |
| console.error("Error downloading or extracting zip:", error); |
| throw error; |
| } |
| } |
|
|
|
|
| |
| async function createVideoFromExtractedImages(pixivData, frameDir) { |
| const pixivId = pixivData.body.illust_details.id; |
| const frames = pixivData.body.illust_details.ugoira_meta.frames; |
|
|
| const frameListFile = path.join(frameDir, 'frames.txt'); |
| const frameListContent = frames |
| .map(frame => { |
| const framePath = path.join(frameDir, frame.file); |
| return `file '${frame.file}'\nduration ${frame.delay / 1000}`; |
| }) |
| .join('\n'); |
|
|
| fs.writeFileSync(frameListFile, frameListContent); |
| console.log(`File frame list berhasil disimpan di ${frameListFile}`); |
|
|
| const outputVideoPath = path.join(frameDir, `${pixivId}.mp4`); |
|
|
| if (fs.existsSync(frameListFile)) { |
| |
| await execAsync(`ffmpeg -f concat -safe 0 -i "${frameListFile}" -vf "format=yuv420p,scale=trunc(iw/2)*2:trunc(ih/2)*2" -fps_mode vfr -pix_fmt yuv420p "${outputVideoPath}"`); |
| |
| console.log(`Video berhasil dibuat: ${outputVideoPath}`); |
| return outputVideoPath; |
| } else { |
| throw new Error(`File frames.txt tidak ditemukan di ${frameListFile}`); |
| } |
| } |
|
|
| |
| function scheduleFolderDeletion(directory) { |
| setTimeout(() => { |
| fs.rmSync(directory, { recursive: true, force: true }); |
| console.log(`Folder ${directory} dan isinya telah dihapus.`); |
| }, deleteFilesAfter); |
| } |
|
|
| |
| app.get("/process-pixiv/:illustId", async (req, res) => { |
| const { illustId } = req.params; |
|
|
| try { |
| const pixivData = await pixivGetData(illustId); |
| const frameDir = await downloadAndExtractZipFromPixivData(pixivData); |
| const videoPath = await createVideoFromExtractedImages(pixivData, frameDir); |
|
|
| |
| const videoUrl = `https://arashicode-komik.hf.space/static/${path.relative(tmpDir, videoPath)}`; |
|
|
| |
| res.json({ url: videoUrl }); |
|
|
| |
| scheduleFolderDeletion(frameDir); |
| } catch (error) { |
| console.error("Error processing Pixiv illustration:", error); |
| res.status(500).send("Error processing illustration."); |
| } |
| }); |
|
|
|
|
| async function scrapeHAnime(query) { |
| const baseUrl = "https://animeidhentai.com"; |
| const searchUrl = `${baseUrl}/?s=${encodeURIComponent(query)}`; |
| const browser = await puppeteer.launch({ |
| headless: true, |
| args: ['--no-sandbox', '--disable-setuid-sandbox'] |
| }); |
| const page = await browser.newPage(); |
| await page.goto(searchUrl, { waitUntil: 'domcontentloaded' }); |
|
|
| try { |
| |
| const videos = await page.evaluate(() => { |
| return [...document.querySelectorAll("body > main > section > div.anime-list.dg.gt2.gg1.mgt1.a-gtf.v-grid > article")].map(article => { |
| const urlElement = article.querySelector("a"); |
| const titleElement = article.querySelector("header > div"); |
| const descElement = article.querySelector("div.description.dn > p"); |
| const thumbnailElement = article.querySelector("div.anime-tb.pctr.rad1.por > figure > img"); |
|
|
| return { |
| url: urlElement ? urlElement.href : null, |
| title: titleElement ? titleElement.textContent.trim() : null, |
| description: descElement ? descElement.textContent.trim() : null, |
| thumbnail: thumbnailElement ? thumbnailElement.src : null |
| }; |
| }); |
| }); |
|
|
| |
| const nextPage = await page.evaluate(() => { |
| const nextButton = document.querySelector("body > main > section > div.pagination-wrapper > a.next.page-numbers.ljoptimizer"); |
| if (nextButton) { |
| const currentUrl = window.location.href; |
| const currentPageMatch = currentUrl.match(/page\/(\d+)/); |
| const currentPage = currentPageMatch ? parseInt(currentPageMatch[1], 10) : 1; |
| return currentPage + 1; |
| } |
| return null; |
| }); |
| console.log(videos) |
|
|
| const result = { |
| next: nextPage ? `${baseUrl}/page/${nextPage}/?s=${encodeURIComponent(query)}` : null, |
| videos |
| }; |
|
|
| await browser.close(); |
| return result; |
|
|
| } catch (error) { |
| console.log("Error scraping data:", error); |
| await browser.close(); |
| return { next: null, videos: [] }; |
| } |
| } |
|
|
|
|
| async function scrapeHAnimeDetails(url) { |
| const browser = await puppeteer.launch({ |
| headless: true, |
| args: ["--no-sandbox", "--disable-setuid-sandbox"], |
| }); |
|
|
| 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, { waitUntil: "domcontentloaded" }); |
|
|
| |
| const result = await page.evaluate(() => { |
| const getText = (selector) => { |
| const element = document.querySelector(selector); |
| return element ? element.textContent.trim() : null; |
| }; |
|
|
| const getGenre = () => { |
| return [...document.querySelectorAll("body > main > article > aside.anime-cn.clb > div.genres.mgt.df.fww.por > a")] |
| .map((genre) => genre.textContent.trim()); |
| }; |
|
|
| return { |
| title: getText("body > main > article > aside.anime-cn.clb > header > h1"), |
| tahunRilis: getText("body > main > article > aside.anime-cn.clb > header > div > p > a.mgr.mgb.fwb"), |
| tahunUpload: getText("body > main > article > aside.anime-cn.clb > header > div > p > span:nth-child(9)"), |
| subtitleLang: getText("body > main > article > aside.anime-cn.clb > header > div > p > a:nth-child(5)"), |
| quality: getText("body > main > article > aside.anime-cn.clb > header > div > p > a:nth-child(3)"), |
| description: getText("body > main > article > aside.anime-cn.clb > div.description.link-co.mgb2"), |
| genre: getGenre(), |
| }; |
| }); |
|
|
| |
|
|
| |
| await page.waitForSelector( |
| "body > main > div.player.mgt.mgb2 > div.vdplbx.c-df > aside.vdpl.fg1 > div > iframe", |
| { timeout: 20000 } |
| ); |
|
|
| |
| const iframeSrc = await page.evaluate(() => { |
| const iframe = document.querySelector( |
| "body > main > div.player.mgt.mgb2 > div.vdplbx.c-df > aside.vdpl.fg1 > div > iframe" |
| ); |
| return iframe ? iframe.src : null; |
| }); |
|
|
| if (!iframeSrc) throw new Error("Iframe tidak ditemukan!"); |
|
|
| console.log("Iframe Source:", iframeSrc); |
|
|
| |
| const responseA = await axios.get(`https://arashicode-api.hf.space/html?url=${iframeSrc}`); |
| const iframeHTML = responseA.data; |
| result.iframeHTML = iframeHTML; |
|
|
| |
| const $ = cheerio.load(iframeHTML); |
| const dataIdElement = $("div.servers > ul > li"); |
| const dataId = dataIdElement.length |
| ? "https://nhplayer.com" + dataIdElement.attr("data-id") |
| : null; |
|
|
| if (dataId) { |
| console.log("Data-ID URL:", dataId); |
| |
| |
| const responseB = await axios.get(`https://arashicode-api.hf.space/html?url=${dataId}`); |
| const newPageHTML = responseB.data; |
| console.log("HTML Konten Data-ID:", newPageHTML); |
| |
| |
| const videoUrlRegex = /file:\s*"(https?:\/\/[^"]+\.mp4)"/; |
| const match = newPageHTML.match(videoUrlRegex); |
| |
| if (match && match[1]) { |
| result.video = match[1]; |
| console.log("Video URL:", result.video); |
| } else { |
| console.log("Video URL tidak ditemukan dalam HTML!"); |
| } |
| } |
|
|
|
|
|
|
| await browser.close(); |
| return result; |
| } catch (error) { |
| console.log("Error scraping details:", error); |
|
|
| |
| await browser.close(); |
| return { error: error.message }; |
| } |
| } |
|
|
|
|
|
|
|
|
| app.get('/hanime/search', async (req, res) => { |
| const { query } = req.query; |
| if (!query) { |
| return res.status(400).send('query is required'); |
| } |
| try { |
| const result = await scrapeHAnime(query); |
| res.json(result); |
| } catch (error) { |
| res.status(500).send('Error processing request \n\n' + error); |
| } |
| }); |
|
|
| app.get('/hanime/download', async (req, res) => { |
| const { url } = req.query; |
| if (!url) { |
| return res.status(400).send('url is required'); |
| } |
| try { |
| const result = await scrapeHAnimeDetails(url); |
| res.json(result); |
| } catch (error) { |
| res.status(500).send('Error processing request \n\n' + error); |
| } |
| }); |
|
|
| function delay(ms) { |
| return new Promise((resolve) => setTimeout(resolve, ms)); |
| } |
|
|
|
|
|
|
| |
| 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/komik/'); |
| console.log("Ping"); |
| await browser.close(); |
| } |
|
|
| |
| async function pingEvery5Hours() { |
| await pingWebsite(); |
| setInterval(async () => { |
| await pingWebsite(); |
| }, 5 * 60 * 60 * 1000); |
| } |
|
|
| |
| pingEvery5Hours(); |
|
|
| app.listen(PORT, () => { |
| console.log(`Server is running on port ${PORT}`); |
| }); |