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