|
for (let sign of ['unhandledRejection', 'uncaughtException']) process.on(sign, console.error) |
|
|
|
const os = require('os') |
|
const util = require('util') |
|
const uuid = require('uuid') |
|
const logger = require('morgan') |
|
const express = require('express') |
|
const puppeteer = require('puppeteer').executablePath() |
|
const rateLimit = require('express-rate-limit') |
|
const { execSync } = require('child_process') |
|
const axios = require('axios'); |
|
const cheerio = require('cheerio'); |
|
const { Eiyuu } = require('eiyuu'); |
|
const Booru = require('booru'); |
|
const search = new Eiyuu(); |
|
|
|
const app = express() |
|
app.set('trust proxy', 1) |
|
app.set('json spaces', 4) |
|
app.use(logger('dev')) |
|
app.use(express.urlencoded({ extended: true })) |
|
|
|
const headers = { |
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36' |
|
}; |
|
|
|
|
|
async function searchBooru(query, site, counts) { |
|
return new Promise(async (resolve, reject) => { |
|
try { |
|
var dan = Booru.forSite(site.toLowerCase()); |
|
var data = await dan.search(query, { limit: counts }); |
|
var result = data.map((obg) => { |
|
return { |
|
nsfw: obg.booru.site.nsfw, |
|
domain: obg.booru.site.domain, |
|
tag_copyright: obg.data.tag_string_copyright, |
|
artist: obg.data.tag_string_artist, |
|
pixiv_id: obg.data.pixiv_id, |
|
source: obg.source, |
|
HD_url: obg.fileUrl, |
|
id: obg.id, |
|
tags: obg.tags.join(", "), |
|
}; |
|
}); |
|
resolve(result); |
|
} catch (error) { |
|
reject(error); |
|
} |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
async function extractVideoUrl(url) { |
|
try { |
|
let res = await axios.get(url, { |
|
headers |
|
}); |
|
let result = res.data; |
|
let $ = cheerio.load(result); |
|
let liElement = $('li[data-id]'); |
|
let dataIdValue = liElement.attr('data-id'); |
|
|
|
let final = new URL(dataIdValue, 'https://nhplayer.com').toString(); |
|
const response = await axios.get(final); |
|
const html = response.data; |
|
const $2 = cheerio.load(html); |
|
|
|
const scriptContent = $2('script:contains("file: ")').html(); |
|
const match = scriptContent.match(/file:\s*["']([^"']+)["']/); |
|
|
|
if (match && match[1]) { |
|
const videoUrl = match[1]; |
|
return { |
|
url: videoUrl |
|
}; |
|
} else { |
|
console.log('Tidak dapat menemukan URL video.'); |
|
return null; |
|
} |
|
} catch (error) { |
|
console.error('Error:', error); |
|
return { |
|
msg: error |
|
} |
|
} |
|
} |
|
|
|
async function findChromiumPath() { |
|
let cmd = execSync('nix eval nixpkgs.chromium.outPath --raw').toString(); |
|
return `${cmd.trim()}/bin/chromium`; |
|
} |
|
|
|
async function scrapeAndFindIframeSrc(main_url) { |
|
|
|
|
|
const browser = await puppeteer.launch({ |
|
|
|
headless: false, |
|
args: [ |
|
'--no-sandbox', |
|
] |
|
}); |
|
|
|
const page = await browser.newPage(); |
|
|
|
try { |
|
await page.goto(main_url); |
|
await page.click('button.btn.uppercase'); |
|
await page.waitForNavigation(); |
|
await page.waitForSelector('.aspect-video.-lg\\:-mx-2.order-first iframe'); |
|
|
|
const iframeSrc = await page.$eval('.aspect-video.-lg\\:-mx-2.order-first iframe', iframe => iframe.src); |
|
|
|
return { |
|
url: iframeSrc |
|
} |
|
} catch (error) { |
|
return { |
|
msg: error |
|
} |
|
} finally { |
|
await browser.close(); |
|
} |
|
} |
|
|
|
async function hentaitv(url) { |
|
try { |
|
var data = await scrapeAndFindIframeSrc(url) |
|
var result = await extractVideoUrl(data.url) |
|
return { |
|
file_url: result.url |
|
} |
|
} catch (error) { |
|
return { |
|
msg: error |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
async function getTags(query, site) { |
|
const siteLower = site.toLowerCase(); |
|
if (siteLower === "danbooru") { |
|
let anu = await search.danbooru(query); |
|
return { tag: query, all_tags: anu }; |
|
} else if (siteLower === "safebooru") { |
|
let anu = await search.safebooru(query); |
|
return { tag: query, all_tags: anu }; |
|
} else if (siteLower === "hypnohub") { |
|
let anu = await search.hypnohub(query); |
|
return { tag: query, all_tags: anu }; |
|
} else if (siteLower === "yandere") { |
|
let anu = await search.yandere(query); |
|
return { tag: query, all_tags: anu }; |
|
} else if (siteLower === "konachan") { |
|
let anu = await search.konachan(query); |
|
return { tag: query, all_tags: anu }; |
|
} else if (siteLower === "gelbooru") { |
|
let anu = await search.gelbooru(query); |
|
return { tag: query, all_tags: anu }; |
|
} |
|
} |
|
|
|
|
|
|
|
app.all('/', (req, res) => { |
|
const obj = {} |
|
const used = process.memoryUsage() |
|
for (let key in used) obj[key] = `${Math.round(used[key] / 1000 / 1000 * 100) / 100} MB` |
|
|
|
const disk = execSync('du -sh').toString().split('M')[0] |
|
obj.diskUsage = `${disk} MB` |
|
|
|
const totalmem = os.totalmem() |
|
const freemem = os.freemem() |
|
obj.memoryUsage = |
|
`${((totalmem - freemem) / Math.pow(1024, 3)).toFixed(1)} GB / ${(totalmem / Math.pow(1024, 3)).toFixed(1)} GB` |
|
|
|
res.json({ |
|
success: true, |
|
message: 'Hello World', |
|
uptime: new Date(process.uptime() * 1000).toUTCString().split(' ')[4], |
|
status: obj |
|
}) |
|
}) |
|
|
|
app.get('/ip', (req, res) => res.send(req.ip)) |
|
|
|
|
|
app.get('/htv', async (req, res) => { |
|
try { |
|
const { url } = req.query; |
|
if (!url) { |
|
return res.json({ success: false, message: 'Input parameter url' }); |
|
} |
|
let datas = await hentaitv(url) |
|
res.json({ success: true, result : datas }); |
|
} catch (error) { |
|
console.error('Error:', error); |
|
res.json({ success: false, message: 'An error occurred ' + error }); |
|
} |
|
}); |
|
|
|
app.get('/ping', (req, res) => { |
|
res.send('Pong'); |
|
}); |
|
|
|
app.get('/gettags', async (req, res) => { |
|
const { query, site } = req.query; |
|
|
|
try { |
|
const tags = await getTags(query, site); |
|
res.json(tags); |
|
} catch (error) { |
|
console.error('Terjadi kesalahan:', error.message); |
|
res.status(500).json({ error: 'Terjadi kesalahan', msg: error.message}); |
|
} |
|
}); |
|
|
|
|
|
app.get('/booru', async (req, res) => { |
|
const { query, site, counts } = req.query; |
|
|
|
try { |
|
const tags = await searchBooru(query, site, counts); |
|
res.json(tags); |
|
} catch (error) { |
|
console.error('Terjadi kesalahan:', error.message); |
|
res.status(500).json({ error: 'Terjadi kesalahan', msg: error.message}); |
|
} |
|
}); |
|
|
|
|
|
const PORT = process.env.PORT || 7860 |
|
app.listen(PORT, () => console.log('App running on port', PORT)) |
|
setInterval(() => { |
|
axios.head('https://nultx-hent-ai.hf.space/ping') |
|
.catch(error => { |
|
console.log('Error:', error); |
|
}); |
|
}, 30 * 1000); |