const os = require('os') const mime = require('mime') const axios = require('axios') const bytes = require('bytes') const sharp = require('sharp') const morgan = require('morgan') const express = require('express') const PDFDocument = require('pdfkit') const app = express() app.set('json spaces', 4) app.use(morgan('dev')) app.use(express.json()) app.all('/', (req, res) => { const status = {} const used = process.memoryUsage() for (let key in used) status[key] = formatSize(used[key]) const totalmem = os.totalmem() const freemem = os.freemem() status.memoryUsage = `${formatSize(totalmem - freemem)} / ${formatSize(totalmem)}` res.json({ creator: '@rippanteq7', message: 'Hello World', uptime: new Date(process.uptime() * 1000).toUTCString().split(' ')[4], status }) }) app.post('/imagetopdf', async (req, res) => { try { console.log(req.body) const { images } = req.body if (!images) return res.json({ success: false, message: 'Required an array image url' }) const buffer = await toPDF(images) res.setHeader('Content-Disposition', `attachment; filename=${Math.random().toString(36).slice(2)}.pdf`) res.setHeader('Content-Type', 'application/pdf') res.setHeader('Content-Length', buffer.byteLength) res.send(buffer) } catch (e) { console.log(e) e = String(e) res.json({ error: true, message: e === '[object Object]' ? 'Internal Server Error' : e }) } }) app.all('/yt', async (req, res) => { if (!['GET', 'POST'].includes(req.method)) return res.status(405).json({ success: false, message: 'Method Not Allowed' }) try { const url = req.method !== 'GET' ? req.body.url : req.query.url if (!url) return res.json({ success: false, message: 'Input parameter url' }) if (!/^https?:\/\//.test(url)) return res.json({ success: false, message: 'Invalid url' }) const response = await fetch(`https://srvcdn3.2convert.me/api/json?url=${url}`, { headers: { referer: 'https://y2mate.is/' }}) const json = await response.json() if (json.error) return res.json({ success: false, message: json.message || json.errorMessage }) const { duration } = json.formats const result = { ...json.formats, lengthSeconds: +duration, duration: new Date(duration * 1000).toUTCString().split(' ')[4], video: {}, audio: {} } for (const type of ['video', 'audio']) { json.formats[type].forEach((data) => { const { quality: q, fileType, needConvert, fileSize, url: dlUrl } = data const quality = type === 'video' ? q : `${q}kbps` result[type][quality] = { quality, fileType, fileSizeH: formatSize(fileSize), fileSize, needConvert, url: !needConvert ? dlUrl : `https://${process.env.SPACE_HOST}${req.path}/convert?hash=${encodeURIComponent(dlUrl)}` } }) } res.json({ success: true, result }) } catch (e) { console.log(e) e = String(e) res.status(500).json({ error: true, message: e === '[object Object]' ? 'Internal Server Error' : e }) } }) app.get('/yt/convert', async (req, res) => { try { const { hash } = req.query if (!hash) return res.json({ success: false, message: 'Invalid hash' }) const fetchPost = (url, body) => (fetch(url, { method: 'POST', body, headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Referer': 'https://y2mate.is/' } })) const reqTaskId = await fetchPost('https://srvcdn3.2convert.me/api/json', `hash=${encodeURIComponent(hash)}`) if (!reqTaskId.ok) return res.json({ success: false, message: 'Hash not found' }) const reqTaskJson = await reqTaskId.json() if (reqTaskJson.error) return res.json({ success: false, message: reqTaskJson.message }) let result while (!result) { const fetchTaskId = await fetchPost('https://srvcdn3.2convert.me/api/json/task', `taskId=${reqTaskJson.taskId}`) const fetchTaskJson = await fetchTaskId.json() console.log(fetchTaskJson) if (fetchTaskJson.status === 'finished') { result = fetchTaskJson break } await new Promise(resolve => setTimeout(resolve, 1000)) } const { download, title, ext } = result const response = await axios.get(download, { responseType: 'stream' }) res.setHeader('Content-Disposition', `attachment; filename=${title}.${ext}`) res.setHeader('Content-Type', mime.types[ext]) response.data.pipe(res) } catch (e) { console.log(e) e = String(e) res.status(500).json({ error: true, message: e === '[object Object]' ? 'Internal Server Error' : e }) } }) const PORT = process.env.PORT || 7860 app.listen(PORT, () => console.log('App running on port', PORT)) function formatSize(num) { return bytes(+num || 0, { unitSeparator: ' ' }) } function toPDF(urls) { return new Promise(async (resolve, reject) => { try { if (!Array.isArray(urls)) urls = [urls] const doc = new PDFDocument({ margin: 0, size: 'A4' }) const buffers = [] for (let i = 0; i < urls.length; i++) { const response = await fetch(urls[i], { headers: { referer: urls[i] }}) if (!response.ok) continue const type = response.headers.get('content-type') if (!/image/.test(type)) continue let buffer = Buffer.from(await response.arrayBuffer()) if (/gif|webp/.test(type)) buffer = await sharp(buffer).png().toBuffer() doc.image(buffer, 0, 0, { fit: [595.28, 841.89], align: 'center', valign: 'center' }) if (urls.length !== i + 1) doc.addPage() } doc.on('data', (chunk) => buffers.push(chunk)) doc.on('end', () => resolve(Buffer.concat(buffers))) doc.on('error', reject) doc.end() } catch (e) { console.log(e) reject(e) } }) }