siputzx commited on
Commit
384ae5b
·
verified ·
1 Parent(s): b63582e

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +62 -87
app.js CHANGED
@@ -1,111 +1,86 @@
1
  import express from 'express';
2
- import { chromium } from 'playwright';
3
- import cors from 'cors';
4
- import dotenv from 'dotenv';
5
- import os from 'os';
6
  import sharp from 'sharp';
7
 
8
- dotenv.config();
9
 
10
- const config = {
11
- maxTextLength: 100,
12
- viewport: { width: 1920, height: 1080 },
13
- userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
14
- };
15
-
16
- let browser, page;
17
-
18
- const utils = {
19
- async initialize() {
20
- if (!browser) {
21
- browser = await chromium.launch({ headless: true });
22
- const context = await browser.newContext({
23
- viewport: config.viewport,
24
- userAgent: config.userAgent
25
- });
26
-
27
- await context.route('**/*', (route) => {
28
- const url = route.request().url();
29
- if (url.endsWith('.png') || url.endsWith('.jpg') || url.includes('google-analytics')) {
30
- return route.abort();
31
- }
32
- route.continue();
33
- });
34
 
35
- page = await context.newPage();
36
- await page.goto('https://www.bratgenerator.com/', { waitUntil: 'domcontentloaded', timeout: 10000 });
 
 
 
37
 
38
- try {
39
- await page.click('#onetrust-accept-btn-handler', { timeout: 2000 });
40
- } catch { }
 
 
 
 
 
 
 
 
41
 
42
- await page.evaluate(() => setupTheme('white'));
43
- }
44
- },
45
 
46
- async generateBrat(text) {
 
47
  await page.fill('#textInput', text);
48
- const overlay = page.locator('#textOverlay');
49
- // Ambil screenshot dalam format PNG
50
- const pngBuffer = await overlay.screenshot({
51
- timeout: 3000,
52
- type: 'png'
53
  });
54
 
55
- // Konversi ke WebP menggunakan sharp
56
- return sharp(pngBuffer)
57
- .webp({ quality: 80 })
58
  .toBuffer();
59
- },
60
 
61
  async close() {
62
- if (browser) await browser.close();
63
  }
64
- };
 
 
65
 
66
- const app = express();
67
- app.use(express.json());
68
- app.use(cors());
69
 
70
- app.get('*', async (req, res) => {
71
- try {
72
- const { q } = req.query;
73
- if (!q) {
74
- return res.json({
75
- name: 'HD Bart Generator API',
76
- message: 'Parameter q di perlukan',
77
- version: '2.1.0',
78
- runtime: {
79
- os: os.type(),
80
- platform: os.platform(),
81
- architecture: os.arch(),
82
- cpuCount: os.cpus().length,
83
- uptime: `${os.uptime()} seconds`,
84
- memoryUsage: `${Math.round((os.totalmem() - os.freemem()) / 1024 / 1024)} MB used of ${Math.round(os.totalmem() / 1024 / 1024)} MB`
85
- }
86
- });
87
  }
88
- const imageBuffer = await utils.generateBrat(q);
89
- res.set('Content-Type', 'image/webp');
90
- res.send(imageBuffer);
91
- } catch (error) {
92
- console.error(error);
93
- res.status(500).json({
94
- status: false,
95
- message: 'Error generating image',
96
- error: process.env.NODE_ENV === 'development' ? error.message : undefined
97
- });
98
- }
99
- });
100
 
101
- const PORT = process.env.PORT || 7860;
 
 
102
 
103
- app.listen(PORT, async () => {
104
- console.log(`Server running on port ${PORT}`);
105
- await utils.initialize();
106
- });
 
 
107
 
108
  process.on('SIGINT', async () => {
109
- await utils.close();
110
  process.exit(0);
111
  });
 
1
  import express from 'express';
2
+ import { chromium } from 'playwright-extra';
3
+ import stealth from 'playwright-extra/plugins/stealth';
4
+ import cluster from 'cluster';
5
+ import { cpus } from 'os';
6
  import sharp from 'sharp';
7
 
8
+ chromium.use(stealth());
9
 
10
+ const BROWSERS_COUNT = cpus().length;
11
+ const PORT = process.env.PORT || 7860;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
+ class FastBratGenerator {
14
+ constructor() {
15
+ this.browsers = [];
16
+ this.pages = [];
17
+ }
18
 
19
+ async init() {
20
+ const promises = Array(BROWSERS_COUNT).fill().map(async () => {
21
+ const browser = await chromium.launch({ headless: true });
22
+ const context = await browser.newContext({ viewport: { width: 1920, height: 1080 } });
23
+ const page = await context.newPage();
24
+
25
+ await page.goto('https://www.bratgenerator.com/', { waitUntil: 'domcontentloaded' });
26
+
27
+ this.browsers.push(browser);
28
+ this.pages.push(page);
29
+ });
30
 
31
+ await Promise.all(promises);
32
+ }
 
33
 
34
+ async generate(text) {
35
+ const page = this.pages[Math.floor(Math.random() * this.pages.length)];
36
  await page.fill('#textInput', text);
37
+
38
+ const screenshot = await page.locator('#textOverlay').screenshot({
39
+ type: 'png',
40
+ timeout: 2000
 
41
  });
42
 
43
+ return sharp(screenshot)
44
+ .webp({ quality: 85, speed: 6 })
 
45
  .toBuffer();
46
+ }
47
 
48
  async close() {
49
+ await Promise.all(this.browsers.map(b => b.close()));
50
  }
51
+ }
52
+
53
+ const bratGenerator = new FastBratGenerator();
54
 
55
+ async function startServer() {
56
+ const app = express();
57
+ app.use(express.json());
58
 
59
+ app.get('/', async (req, res) => {
60
+ try {
61
+ const { q } = req.query;
62
+ if (!q) return res.status(400).send('Text required');
63
+
64
+ const imageBuffer = await bratGenerator.generate(q);
65
+ res.contentType('image/webp');
66
+ res.send(imageBuffer);
67
+ } catch (error) {
68
+ res.status(500).send('Generation failed');
 
 
 
 
 
 
 
69
  }
70
+ });
 
 
 
 
 
 
 
 
 
 
 
71
 
72
+ await bratGenerator.init();
73
+ app.listen(PORT, () => console.log(`Running on ${PORT}`));
74
+ }
75
 
76
+ if (cluster.isPrimary) {
77
+ cpus().forEach(() => cluster.fork());
78
+ cluster.on('exit', (worker) => cluster.fork());
79
+ } else {
80
+ startServer();
81
+ }
82
 
83
  process.on('SIGINT', async () => {
84
+ await bratGenerator.close();
85
  process.exit(0);
86
  });