siputzx commited on
Commit
b399b6c
·
verified ·
1 Parent(s): bfa0169

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +61 -7
app.js CHANGED
@@ -4,16 +4,55 @@ 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
  const utils = {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  async createBrowserInstance() {
18
  const browser = await chromium.launch({ headless: true });
19
  const context = await browser.newContext({
@@ -41,23 +80,25 @@ const utils = {
41
  return { browser, page };
42
  },
43
 
44
- async generateBrat(text) {
45
  const { browser, page } = await this.createBrowserInstance();
46
 
47
  try {
48
  await page.fill('#textInput', text);
49
  const overlay = page.locator('#textOverlay');
50
 
51
- // Take screenshot
52
  const pngBuffer = await overlay.screenshot({
53
  timeout: 3000,
54
  type: 'png'
55
  });
56
 
57
- // Convert to WebP
58
- return await sharp(pngBuffer)
59
  .webp({ quality: 80 })
60
  .toBuffer();
 
 
 
61
  } finally {
62
  await browser.close();
63
  }
@@ -70,7 +111,7 @@ app.use(cors());
70
 
71
  app.get('*', async (req, res) => {
72
  try {
73
- const { q } = req.query;
74
  if (!q) {
75
  return res.json({
76
  name: 'HD Bart Generator API',
@@ -83,10 +124,23 @@ app.get('*', async (req, res) => {
83
  cpuCount: os.cpus().length,
84
  uptime: `${os.uptime()} seconds`,
85
  memoryUsage: `${Math.round((os.totalmem() - os.freemem()) / 1024 / 1024)} MB used of ${Math.round(os.totalmem() / 1024 / 1024)} MB`
 
 
 
 
 
86
  }
87
  });
88
  }
89
- const imageBuffer = await utils.generateBrat(q);
 
 
 
 
 
 
 
 
90
  res.set('Content-Type', 'image/webp');
91
  res.send(imageBuffer);
92
  } catch (error) {
 
4
  import dotenv from 'dotenv';
5
  import os from 'os';
6
  import sharp from 'sharp';
7
+ import path from 'path';
8
+ import fs from 'fs';
9
+ import crypto from 'crypto';
10
+ import { tmpdir } from 'os';
11
+ import webp from 'node-webpmux';
12
 
13
  dotenv.config();
14
 
15
  const config = {
16
  maxTextLength: 100,
17
  viewport: { width: 1920, height: 1080 },
18
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
19
+ metadata: {
20
+ packname: "HD Bart Generator",
21
+ author: "API",
22
+ categories: ["meme"]
23
+ }
24
  };
25
 
26
  const utils = {
27
+ async addExifMetadata(buffer, metadata) {
28
+ const tmpFileIn = path.join(tmpdir(), `${crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`);
29
+ const tmpFileOut = path.join(tmpdir(), `${crypto.randomBytes(6).readUIntLE(0, 6).toString(36)}.webp`);
30
+
31
+ fs.writeFileSync(tmpFileIn, buffer);
32
+
33
+ const img = new webp.Image();
34
+ const json = {
35
+ "sticker-pack-id": `https://github.com/DikaArdnt/Hisoka-Morou`,
36
+ "sticker-pack-name": metadata.packname,
37
+ "sticker-pack-publisher": metadata.author,
38
+ "emojis": metadata.categories || [""]
39
+ };
40
+
41
+ const exifAttr = Buffer.from([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x41, 0x57, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00]);
42
+ const jsonBuff = Buffer.from(JSON.stringify(json), "utf-8");
43
+ const exif = Buffer.concat([exifAttr, jsonBuff]);
44
+ exif.writeUIntLE(jsonBuff.length, 14, 4);
45
+
46
+ await img.load(tmpFileIn);
47
+ fs.unlinkSync(tmpFileIn);
48
+ img.exif = exif;
49
+ await img.save(tmpFileOut);
50
+
51
+ const finalBuffer = fs.readFileSync(tmpFileOut);
52
+ fs.unlinkSync(tmpFileOut);
53
+ return finalBuffer;
54
+ },
55
+
56
  async createBrowserInstance() {
57
  const browser = await chromium.launch({ headless: true });
58
  const context = await browser.newContext({
 
80
  return { browser, page };
81
  },
82
 
83
+ async generateBrat(text, metadata) {
84
  const { browser, page } = await this.createBrowserInstance();
85
 
86
  try {
87
  await page.fill('#textInput', text);
88
  const overlay = page.locator('#textOverlay');
89
 
90
+ // Take screenshot and convert to WebP
91
  const pngBuffer = await overlay.screenshot({
92
  timeout: 3000,
93
  type: 'png'
94
  });
95
 
96
+ const webpBuffer = await sharp(pngBuffer)
 
97
  .webp({ quality: 80 })
98
  .toBuffer();
99
+
100
+ // Add EXIF metadata
101
+ return await this.addExifMetadata(webpBuffer, metadata);
102
  } finally {
103
  await browser.close();
104
  }
 
111
 
112
  app.get('*', async (req, res) => {
113
  try {
114
+ const { q, packname, author } = req.query;
115
  if (!q) {
116
  return res.json({
117
  name: 'HD Bart Generator API',
 
124
  cpuCount: os.cpus().length,
125
  uptime: `${os.uptime()} seconds`,
126
  memoryUsage: `${Math.round((os.totalmem() - os.freemem()) / 1024 / 1024)} MB used of ${Math.round(os.totalmem() / 1024 / 1024)} MB`
127
+ },
128
+ parameters: {
129
+ q: "Teks yang akan ditampilkan (required)",
130
+ packname: "Nama pack sticker (optional)",
131
+ author: "Nama author sticker (optional)"
132
  }
133
  });
134
  }
135
+
136
+ // Create metadata object using query parameters or defaults
137
+ const metadata = {
138
+ packname: packname || config.metadata.packname,
139
+ author: author || config.metadata.author,
140
+ categories: config.metadata.categories
141
+ };
142
+
143
+ const imageBuffer = await utils.generateBrat(q, metadata);
144
  res.set('Content-Type', 'image/webp');
145
  res.send(imageBuffer);
146
  } catch (error) {