helper / index.js
rippanteq7's picture
Create index.js
3c6a32a verified
import bytes from 'bytes'
import carbon from 'carbon-now-scraper'
import cp from 'child_process'
import express from 'express'
import fs from 'fs'
import morgan from 'morgan'
import os from 'os'
import PDFDocument from 'pdfkit'
import sharp from 'sharp'
import util from 'util'
const app = express()
const tmpDir = os.tmpdir()
app.set('json spaces', 4)
app.use(morgan('dev'))
app.use(express.json({ limit: '200mb' }))
app.use(express.urlencoded({ extended: true, limit: '200mb' }))
app.use((_, __, next) => {
fs.readdirSync(tmpDir).map((file) => {
file = `${tmpDir}/${file}`
const stat = fs.statSync(file)
const exp = Date.now() - stat.mtimeMs >= 1000 * 60 * 30
if (stat.isFile() && exp) {
console.log('Deleted file', file)
fs.unlinkSync(file)
}
})
next()
})
app.use('/file', express.static(tmpDir))
app.all('/', (_, res) => {
const status = {}
status['diskUsage'] = cp.execSync('du -sh').toString().split('M')[0] + ' MB'
const used = process.memoryUsage()
for (let x in used) status[x] = formatSize(used[x])
const totalmem = os.totalmem()
const freemem = os.freemem()
status['memoryUsage'] = `${formatSize(totalmem - freemem)} / ${formatSize(totalmem)}`
res.json({
creator: `@${process.env['SPACE_AUTHOR_NAME'] || 'rippanteq7'}`,
message: 'Hello World!',
uptime: new Date(process.uptime() * 1000).toUTCString().split(' ')[4],
status
})
})
app.all('/carbon', async (req, res) => {
if (!['GET', 'POST'].includes(req.method)) return res.status(405).json({ success: false, message: 'Method Not Allowed' })
try {
const obj = req.method !== 'GET' ? req.body : req.query
if (!obj.code) return res.status(400).json({ success: false, message: 'Required parameter "code"' })
const filePath = `${tmpDir}/${randomName('.png')}`
const image = await carbon(obj.code, filePath, {
...obj, puppeteer: { executablePath: process.env.CHROME_BIN }
})
const resultUrl = `https://${req.hostname}/${image.replace(tmpDir, 'file')}`
isTrue(obj.json) ? res.json({ success: true, result: resultUrl }) : res.send(resultUrl)
} catch (e) {
console.log(e)
res.status(500).json({ error: true, message: getError(e) })
}
})
app.all('/topdf', async (req, res) => {
if (req.method !== 'POST') return res.status(405).json({ success: false, message: 'Method Not Allowed' })
try {
const { images: urls, json } = req.body
if (!urls) return res.status(400).json({ success: false, message: 'Payload "images" requires an array of urls' })
if (!Array.isArray(urls)) urls = [urls]
const bufferPDF = await toPDF(urls)
if (!bufferPDF.length) return res.status(400).json({ success: false, message: 'Can\'t convert to pdf' })
const fileName = randomName('.pdf')
await fs.promises.writeFile(`${tmpDir}/${fileName}`, bufferPDF)
const resultUrl = `https://${req.hostname}/file/${fileName}`
isTrue(json) ? res.json({ success: true, result: resultUrl }) : res.send(resultUrl)
} catch (e) {
console.log(e)
res.status(500).json({ error: true, message: getError(e) })
}
})
app.all(/^\/webp2(gif|mp4|png)/, async (req, res) => {
if (req.method !== 'POST') return res.status(405).json({ success: false, message: 'Method Not Allowed' })
try {
const { file, json } = req.body
if (!file) return res.status(400).json({ success: false, message: 'Payload "file" requires base64 string' })
if (!isBase64(file)) return res.status(400).json({ success: false, message: 'Invalid base64 format' })
const type = req.params[0]
if (type === 'png') {
const fileName = randomName('.png')
const fileBuffer = await sharp(Buffer.from(file, 'base64')).png().toBuffer()
await fs.promises.writeFile(`${tmpDir}/${fileName}`, fileBuffer)
const resultUrl = `https://${req.hostname}/file/${fileName}`
isTrue(json) ? res.json({ success: true, result: resultUrl }) : res.send(resultUrl)
return
} else {
const fileName = randomName('.webp')
const filePath = `${tmpDir}/${fileName}`
await fs.promises.writeFile(filePath, Buffer.from(file, 'base64'))
const exec = util.promisify(cp.exec).bind(cp)
await exec(`convert ${filePath} ${filePath.replace('webp', 'gif')}`)
let resultUrl
if (type === 'gif') resultUrl = `https://${req.hostname}/file/${fileName.replace('webp', 'gif')}`
else {
await exec(`ffmpeg -i ${filePath.replace('webp', 'gif')} -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" ${filePath.replace('webp', 'mp4')}`)
resultUrl = `https://${req.hostname}/file/${fileName.replace('webp', 'mp4')}`
}
isTrue(json) ? res.json({ success: true, result: resultUrl }) : res.send(resultUrl)
}
} catch (e) {
console.log(e)
res.status(500).json({ error: true, message: getError(e) })
}
})
app.listen(7860, () => console.log('App running on port 7860'))
function formatSize(n) {
return bytes(+n, { unitSeparator: ' ' })
}
function getError(e) {
e = String(e)
return e !== '[object Object]' ? e : 'Internal Server Error'
}
function isBase64(str) {
try {
return btoa(atob(str)) === str
} catch {
return false
}
}
function isTrue(str) {
return [true, 'true'].includes(str)
}
function randomName(ext = '') {
return Math.random().toString(36).slice(2) + ext
}
function toPDF(urls) {
return new Promise(async (resolve, reject) => {
const doc = new PDFDocument({ margin: 0, size: 'A4' })
const buffs = []
for (let x = 0; x < urls.length; x++) {
if (!/https:\/\//.test(urls[x])) continue
const url = new URL(urls[x])
let image = await fetch(url.toString(), { headers: { referer: url.origin } })
if (!image.ok) continue
const type = image.headers.get('content-type')
if (!/image/.test(type)) continue
image = Buffer.from(await image.arrayBuffer())
if (/(gif|webp)$/.test(type)) image = await sharp(image).png().toBuffer()
doc.image(image, 0, 0, { fit: [595.28, 841.89], align: 'center', valign: 'center' })
if (urls.length != x + 1) doc.addPage()
}
doc.on('data', (chunk) => buffs.push(chunk))
doc.on('end', () => resolve(Buffer.concat(buffs)))
doc.on('error', (err) => reject(err))
doc.end()
})
}