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() }) }