komik / index.js
Nexchan's picture
Update index.js
349c03b verified
raw
history blame contribute delete
No virus
39.1 kB
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}`);
});