rippanteq7 commited on
Commit
6199537
·
verified ·
1 Parent(s): d6a14cd

Update brat generator (using playwright)

Browse files
Files changed (2) hide show
  1. index.js +81 -41
  2. package.json +1 -0
index.js CHANGED
@@ -6,14 +6,24 @@ import fs from 'fs'
6
  import morgan from 'morgan'
7
  import os from 'os'
8
  import path from 'path'
 
9
  import PDFDocument from 'pdfkit'
10
  import sharp from 'sharp'
11
  import util from 'util'
12
  import yts from 'yt-search'
13
 
14
  const utils = {
 
 
 
 
 
 
 
 
 
15
  // from https://github.com/petersolopov/carbonara
16
- fetchCarbonaraAPI: async (code, output, opts = {}) => {
17
  let resp = await utils.fetchPOST('https://carbonara.solopov.dev/api/cook', JSON.stringify({ code, ...opts }), {
18
  headers: { 'Content-Type': 'application/json' }
19
  })
@@ -22,12 +32,12 @@ const utils = {
22
  if (/json$/.test(content)) {
23
  let json = await resp.json()
24
  throw json.error || 'An error occurred'
25
- } else {
26
- throw resp.statusText
27
  }
 
28
  }
29
 
30
  let img = await resp.arrayBuffer()
 
31
  await fs.promises.writeFile(output, Buffer.from(img))
32
  return output
33
  },
@@ -38,6 +48,23 @@ const utils = {
38
  ).json(),
39
  fetchPOST: (url, body, opts = {}) => fetch(url, { method: 'POST', body, ...opts }),
40
  formatSize: (n) => bytes(+n, { unitSeparator: ' ' }),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  getError: (e) => String(e).startsWith('[object ') ? 'Internal Server Error' : String(e),
42
  isBase64: (str) => {
43
  try {
@@ -121,25 +148,31 @@ app.all('/', (_, res) => {
121
  status['memoryUsage'] = `${utils.formatSize(totalmem - freemem)} / ${utils.formatSize(totalmem)}`
122
 
123
  res.json({
124
- creator: `@${process.env['SPACE_AUTHOR_NAME'] || 'rippanteq7'}`,
125
  message: 'Hello World!',
126
  uptime: new Date(process.uptime() * 1000).toUTCString().split(' ')[4],
127
  status
128
  })
129
  })
130
 
131
- app.all('/carbon', async (req, res) => {
132
  if (!['GET', 'POST'].includes(req.method)) return res.status(405).json({ success: false, message: 'Method Not Allowed' })
133
 
134
  try {
135
  const obj = req.allParams
136
- if (!obj.code) return res.status(400).json({ success: false, message: 'Required parameter \'code\'' })
 
 
 
 
 
137
 
138
- const filePath = `${tmpDir}/${utils.randomName('.png')}`
139
- // nembak API carbonara njir
140
- const image = await utils.fetchCarbonaraAPI(obj.code, filePath, obj)
141
  const resultUrl = `https://${req.hostname}/${image.replace(tmpDir, 'file')}`
142
- utils.isTrue(obj.json) ? res.json({ success: true, result: resultUrl }) : res[utils.isTrue(obj.raw) ? 'send' : 'redirect'](resultUrl)
 
 
143
  } catch (e) {
144
  console.log(e)
145
  res.status(500).json({ error: true, message: utils.getError(e) })
@@ -161,7 +194,9 @@ app.all('/topdf', async (req, res) => {
161
  await fs.promises.writeFile(`${tmpDir}/${fileName}`, bufferPDF)
162
 
163
  const resultUrl = `https://${req.hostname}/file/${fileName}`
164
- utils.isTrue(json) ? res.json({ success: true, result: resultUrl }) : res[utils.isTrue(raw) ? 'send' : 'redirect'](resultUrl)
 
 
165
  } catch (e) {
166
  console.log(e)
167
  res.status(500).json({ error: true, message: utils.getError(e) })
@@ -183,24 +218,29 @@ app.all(/^\/webp2(gif|mp4|png)/, async (req, res) => {
183
  await fs.promises.writeFile(`${tmpDir}/${fileName}`, fileBuffer)
184
 
185
  const resultUrl = `https://${req.hostname}/file/${fileName}`
186
- utils.isTrue(json) ? res.json({ success: true, result: resultUrl }) : res[utils.isTrue(raw) ? 'send' : 'redirect'](resultUrl)
187
- } else {
188
- const fileName = utils.randomName('.webp')
189
- const filePath = `${tmpDir}/${fileName}`
190
- await fs.promises.writeFile(filePath, Buffer.from(file, 'base64'))
191
-
192
- const exec = util.promisify(cp.exec).bind(cp)
193
- await exec(`convert ${filePath} ${filePath.replace('webp', 'gif')}`)
194
-
195
- let resultUrl
196
- if (type === 'gif') resultUrl = `https://${req.hostname}/file/${fileName.replace('webp', 'gif')}`
197
- else {
198
- 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')}`)
199
- resultUrl = `https://${req.hostname}/file/${fileName.replace('webp', 'mp4')}`
200
- }
201
-
202
- utils.isTrue(json) ? res.json({ success: true, result: resultUrl }) : res[utils.isTrue(raw) ? 'send' : 'redirect'](resultUrl)
203
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  } catch (e) {
205
  console.log(e)
206
  res.status(500).json({ error: true, message: utils.getError(e) })
@@ -238,20 +278,20 @@ app.all(/^\/y(outube|t)(\/(d(ownload|l)|search)?)?/, async (req, res) => {
238
  if (result.status === 'error') return res.status(400).json({ success: false, message: 'An error occurred' })
239
  res.redirect(result.url)
240
  return
241
- } else {
242
- if (!obj.query) return res.status(400).json({ success: false, message: 'Required parameter \'query\'' })
243
-
244
- let result = await yts(utils.ytIdRegex.test(obj.query) ? { videoId: utils.ytIdRegex.exec(obj.query)[1] } : obj.query)
245
- result = result.videos ? result.videos[0] : result
246
- if (!result?.url) return res.status(400).json({ success: false, message: 'Video unavailable' })
247
-
248
- const dlUrl = `https://${req.hostname}/yt/dl?url=${result.url}`
249
- const download = { audio: `${dlUrl}&type=audio`, video: `${dlUrl}&type=video` }
250
- res.json({
251
- success: true,
252
- result: { ...result, download }
253
- })
254
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  } catch (e) {
256
  console.log(e)
257
  res.status(500).json({ error: true, message: utils.getError(e) })
 
6
  import morgan from 'morgan'
7
  import os from 'os'
8
  import path from 'path'
9
+ import playwright from 'playwright'
10
  import PDFDocument from 'pdfkit'
11
  import sharp from 'sharp'
12
  import util from 'util'
13
  import yts from 'yt-search'
14
 
15
  const utils = {
16
+ getBrowser: (...opts) => playwright.chromium.launch({
17
+ args: [
18
+ '--incognito', '--single-process',
19
+ '--no-sandbox', '--no-zygote', '--no-cache'
20
+ ],
21
+ executablePath: process.env.CHROME_BIN,
22
+ headless: true,
23
+ ...opts
24
+ }),
25
  // from https://github.com/petersolopov/carbonara
26
+ fetchCarbonaraAPI: async (code, opts = {}) => {
27
  let resp = await utils.fetchPOST('https://carbonara.solopov.dev/api/cook', JSON.stringify({ code, ...opts }), {
28
  headers: { 'Content-Type': 'application/json' }
29
  })
 
32
  if (/json$/.test(content)) {
33
  let json = await resp.json()
34
  throw json.error || 'An error occurred'
 
 
35
  }
36
+ throw resp.statusText
37
  }
38
 
39
  let img = await resp.arrayBuffer()
40
+ const output = `${tmpDir}/${utils.randomName('.png')}`
41
  await fs.promises.writeFile(output, Buffer.from(img))
42
  return output
43
  },
 
48
  ).json(),
49
  fetchPOST: (url, body, opts = {}) => fetch(url, { method: 'POST', body, ...opts }),
50
  formatSize: (n) => bytes(+n, { unitSeparator: ' ' }),
51
+ generateBrat: async (text) => {
52
+ const browser = await utils.getBrowser()
53
+ try {
54
+ const page = await browser.newPage()
55
+ await page.goto('https://www.bratgenerator.com/')
56
+ await page.click('#toggleButtonWhite')
57
+ await page.locator('#textInput').fill(text)
58
+ const output = `${tmpDir}/${utils.randomName('.jpg')}`
59
+ const ss = await page.locator('#textOverlay')
60
+ .screenshot({ path: output })
61
+ return output
62
+ } catch (e) {
63
+ throw e
64
+ } finally {
65
+ await browser.close()
66
+ }
67
+ },
68
  getError: (e) => String(e).startsWith('[object ') ? 'Internal Server Error' : String(e),
69
  isBase64: (str) => {
70
  try {
 
148
  status['memoryUsage'] = `${utils.formatSize(totalmem - freemem)} / ${utils.formatSize(totalmem)}`
149
 
150
  res.json({
 
151
  message: 'Hello World!',
152
  uptime: new Date(process.uptime() * 1000).toUTCString().split(' ')[4],
153
  status
154
  })
155
  })
156
 
157
+ app.all(/^\/(brat|carbon)/, async (req, res) => {
158
  if (!['GET', 'POST'].includes(req.method)) return res.status(405).json({ success: false, message: 'Method Not Allowed' })
159
 
160
  try {
161
  const obj = req.allParams
162
+ const isBrat = req.params[0] === 'brat'
163
+ if (isBrat && !obj.text) {
164
+ return res.status(400).json({ success: false, message: 'Required parameter \'text\'' })
165
+ } else if (!isBrat && !(obj.code || obj.text)) {
166
+ return res.status(400).json({ success: false, message: 'Required parameter \'code\'' })
167
+ }
168
 
169
+ const image = isBrat ?
170
+ await utils.generateBrat(obj.text) :
171
+ utils.fetchCarbonaraAPI(obj.code || obj.text, obj)
172
  const resultUrl = `https://${req.hostname}/${image.replace(tmpDir, 'file')}`
173
+ utils.isTrue(obj.json) ?
174
+ res.json({ success: true, result: resultUrl }) :
175
+ res[utils.isTrue(obj.raw) ? 'send' : 'redirect'](resultUrl)
176
  } catch (e) {
177
  console.log(e)
178
  res.status(500).json({ error: true, message: utils.getError(e) })
 
194
  await fs.promises.writeFile(`${tmpDir}/${fileName}`, bufferPDF)
195
 
196
  const resultUrl = `https://${req.hostname}/file/${fileName}`
197
+ utils.isTrue(json) ?
198
+ res.json({ success: true, result: resultUrl }) :
199
+ res[utils.isTrue(raw) ? 'send' : 'redirect'](resultUrl)
200
  } catch (e) {
201
  console.log(e)
202
  res.status(500).json({ error: true, message: utils.getError(e) })
 
218
  await fs.promises.writeFile(`${tmpDir}/${fileName}`, fileBuffer)
219
 
220
  const resultUrl = `https://${req.hostname}/file/${fileName}`
221
+ utils.isTrue(json) ?
222
+ res.json({ success: true, result: resultUrl }) :
223
+ res[utils.isTrue(raw) ? 'send' : 'redirect'](resultUrl)
224
+ return
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  }
226
+
227
+ const fileName = utils.randomName('.webp')
228
+ const filePath = `${tmpDir}/${fileName}`
229
+ await fs.promises.writeFile(filePath, Buffer.from(file, 'base64'))
230
+
231
+ const exec = util.promisify(cp.exec).bind(cp)
232
+ await exec(`convert ${filePath} ${filePath.replace('webp', 'gif')}`)
233
+
234
+ let resultUrl
235
+ if (type === 'gif') resultUrl = `https://${req.hostname}/file/${fileName.replace('webp', 'gif')}`
236
+ else {
237
+ 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')}`)
238
+ resultUrl = `https://${req.hostname}/file/${fileName.replace('webp', 'mp4')}`
239
+ }
240
+
241
+ utils.isTrue(json) ?
242
+ res.json({ success: true, result: resultUrl }) :
243
+ res[utils.isTrue(raw) ? 'send' : 'redirect'](resultUrl)
244
  } catch (e) {
245
  console.log(e)
246
  res.status(500).json({ error: true, message: utils.getError(e) })
 
278
  if (result.status === 'error') return res.status(400).json({ success: false, message: 'An error occurred' })
279
  res.redirect(result.url)
280
  return
 
 
 
 
 
 
 
 
 
 
 
 
 
281
  }
282
+
283
+ if (!obj.query) return res.status(400).json({ success: false, message: 'Required parameter \'query\'' })
284
+
285
+ let result = await yts(utils.ytIdRegex.test(obj.query) ? { videoId: utils.ytIdRegex.exec(obj.query)[1] } : obj.query)
286
+ result = result.videos ? result.videos[0] : result
287
+ if (!result?.url) return res.status(400).json({ success: false, message: 'Video unavailable' })
288
+
289
+ const dlUrl = `https://${req.hostname}/yt/dl?url=${result.url}`
290
+ const download = { audio: `${dlUrl}&type=audio`, video: `${dlUrl}&type=video` }
291
+ res.json({
292
+ success: true,
293
+ result: { ...result, download }
294
+ })
295
  } catch (e) {
296
  console.log(e)
297
  res.status(500).json({ error: true, message: utils.getError(e) })
package.json CHANGED
@@ -4,6 +4,7 @@
4
  "express": "*",
5
  "morgan": "*",
6
  "pdfkit": "*",
 
7
  "serve-favicon": "*",
8
  "sharp": "*",
9
  "yt-search": "*"
 
4
  "express": "*",
5
  "morgan": "*",
6
  "pdfkit": "*",
7
+ "playwright": "*",
8
  "serve-favicon": "*",
9
  "sharp": "*",
10
  "yt-search": "*"