Spaces:
Running
Running
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 cheerio from 'cheerio'; | |
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; | |
const sizeOf = promisify(require('image-size')); | |
const { exec } = require('child_process'); | |
app.use('/static', express.static(os.tmpdir())); | |
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(); | |
/*({ | |
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.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 // Timeout untuk navigasi | |
}); | |
await page.waitForNavigation({ | |
waitUntil: 'networkidle0', | |
timeout: 60000 // Timeout untuk menunggu navigasi selesai | |
}); | |
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 { | |
// Ensure tempDir creation | |
await fss.mkdir(tempDir, { recursive: true }); | |
// Extract title safely | |
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); // 5 minutes | |
} 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 { | |
// Ensure tempDir creation | |
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) { | |
// Jika ada td tanpa kelas, ambil gambar untuk setiap halaman | |
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 { | |
// Jika tidak ada td tanpa kelas, ambil gambar dari halaman pertama | |
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); // 5 minutes | |
} 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 { | |
// Fetch the image data | |
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 { | |
// Check if image needs conversion | |
const imageExt = path.extname(imagePath).toLowerCase(); | |
const supportedExtensions = ['.jpg', '.jpeg', '.png']; | |
let convertedImagePath = 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 }); | |
// Remove converted images if they were created | |
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 = `./${instanceID}`; | |
await fss.mkdir(tempDir); | |
const title = url.split('g/').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://nhentai.net/', | |
'X-Forwarded-For': generateRandomIP() | |
} | |
}) | |
const $ = cheerio.load(response.data); | |
const scriptContent = $('script').filter((i, el) => { | |
return $(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); | |
console.log(jsonData) | |
const imgList = []; | |
for (let i = 0; i < jsonData.images.pages.length; i++) { | |
imgList.push({ path: `https://external-content.duckduckgo.com/iu/?u=https://i5.nhentai.net/galleries/${jsonData.media_id}/${i + 1}.jpg&f=1&nofb=1` }); | |
} | |
const imagePaths = await downloadImageNhs(imgList, tempDir, instanceID); | |
const pdfPath = await createPDF(imagePaths, instanceID, tempDir); | |
console.log(`PDF berhasil dibuat: ${pdfPath}`); | |
return { url: "https://arashicode-komik.hf.space/static/" + instanceID + ".pdf", path: pdfPath, result: jsonData }; | |
} catch (error) { | |
console.log(error); | |
throw error; | |
} finally { | |
await fss.rmdir(tempDir, { recursive: true }); | |
} | |
} | |
async function downloadImageNh(image, tempDir, instanceID) { | |
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': 'https://nhentai.net/' | |
} | |
}); | |
const imagePath = `${tempDir}/image_${instanceID}_${Date.now()}_${Math.floor(Math.random() * 1000)}.jpg`; | |
await writeFileAsync(imagePath, response.data); | |
return imagePath; | |
} | |
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) { | |
const writer = fs.createWriteStream(filePath); | |
const response = await axios({ | |
url, | |
method: 'GET', | |
responseType: 'stream' | |
}); | |
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(); // Menghapus elemen terakhir dari tags | |
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; // Lempar ulang error untuk ditangani di level atas | |
} | |
} | |
async function Rules34info(url_r34) { | |
try { | |
// Mengambil halaman HTML dengan Axios | |
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(); // Menghapus elemen terakhir dari tags | |
} | |
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; // Rethrow error to handle it upstream | |
} | |
} | |
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(); // Menghapus elemen terakhir dari tags | |
} | |
if (download.length > 0) { | |
download.find("div.wrap > a").each((index, element) => { | |
result.download.push({ quality: $(element).text().trim(), url: $(element).attr('href') }); | |
}); | |
// Mendownload dari URL terakhir di array download | |
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) | |
await downloadFromUrl(lastDownloadUrl, filePath); | |
result.downloadPath = filePath; // Menambahkan path file yang telah di-download ke dalam objek result | |
result.downloadUrl = "https://arashicode-komik.hf.space/static/" + filenem; // Menambahkan path file yang telah di-download ke dalam objek result | |
} | |
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; // Rethrow error to handle it upstream | |
} | |
} | |
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; | |
// Hapus file setelah 8 menit (480000 milidetik) | |
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); // Mendapatkan jalur unduhan dari modul Rules34 | |
const filePath = result.downloadPath; | |
// Cek apakah file benar-benar ada sebelum mengirim | |
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); // Menggunakan res.sendFile untuk mengirim file | |
} | |
} 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 { // Default to 'download' | |
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, // Non-headless untuk debugging | |
args: ['--no-sandbox', '--disable-setuid-sandbox'] | |
}); | |
const page = await browser.newPage(); | |
// Setel header User-Agent dan Referer | |
await page.setExtraHTTPHeaders({ | |
'User-Agent': getRandomUserAgent(), | |
'Referer': url, | |
'X-Forwarded-For': generateRandomIP() | |
}); | |
await page.goto(url); // Buka URL yang diberikan | |
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'); | |
} | |
}); | |
// 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/komik/'); | |
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}`); | |
}); |