Spaces:
Running
Running
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) | |
} | |
}) | |
} | |