aseli commited on
Commit
a5afca9
1 Parent(s): 4d47368

Update index.js

Browse files
Files changed (1) hide show
  1. index.js +68 -165
index.js CHANGED
@@ -1,220 +1,129 @@
1
- const express = require('express');
2
- const puppeteer = require('puppeteer-extra');
3
- const StealthPlugin = require('puppeteer-extra-plugin-stealth');
4
- const AnonymizeUA = require('puppeteer-extra-plugin-anonymize-ua');
5
  const QRCode = require('qrcode');
6
  const Jimp = require('jimp');
7
  const QrCodeReader = require('qrcode-reader');
8
-
9
- puppeteer.use(StealthPlugin());
10
- puppeteer.use(AnonymizeUA());
11
 
12
  const app = express();
13
  const port = 7860;
14
 
15
  app.use(express.json());
16
- app.get('/', async (req, res) => {
17
- console.log('request to /')
18
- res.send('halo kontol')
19
- })
 
 
20
  app.post('/screenshot', async (req, res) => {
21
- console.log('request to /screenshot')
22
- const {
23
- ua,
24
- url,
25
- type,
26
- width,
27
- height,
28
- language,
29
- fullpage
30
- } = req.body;
31
- if (!url) return res.send('please input url')
32
- await processScreenshot(req, res, {
33
- ua,
34
- url,
35
- type,
36
- width,
37
- height,
38
- language,
39
- fullpage
40
- });
41
  });
42
 
43
  app.get('/screenshot', async (req, res) => {
44
- console.log('request to /screenshot (get)')
45
- const {
46
- ua,
47
- url,
48
- type,
49
- width,
50
- height,
51
- language,
52
- fullpage
53
- } = req.query;
54
- if (!url) return res.send('please input url')
55
- await processScreenshot(req, res, {
56
- ua,
57
- url,
58
- type,
59
- width,
60
- height,
61
- language,
62
- fullpage
63
- });
64
  });
 
65
  app.get('/qrcode', async (req, res) => {
66
  try {
67
- const {
68
- mode,
69
- url
70
- } = req.query;
71
 
72
  if (!mode || !url) {
73
  return res.status(400).send('what?');
74
  }
75
 
76
  if (mode === 'create') {
77
- // Generate a QR code
78
  QRCode.toDataURL(url, (err, src) => {
79
- if (err) return res.send({
80
- error: 'Error generating QR code'
81
- });
82
  res.type('png').send(Buffer.from(src.split(",")[1], "base64"));
83
  });
84
  } else if (['read', 'scan'].includes(mode)) {
85
- // Fetch the image and read the QR code
86
  const rts = await fetch(url);
87
- if (!rts.ok || rts.status !== 200) return res.send({
88
- status: 400,
89
- message: 'Can\'t buffer url'
90
- })
91
- if (!/image/.test(rts.headers.get('content-type'))) return res.send({
92
- status: 400,
93
- message: 'Only image type'
94
- })
95
  const buffer = Buffer.from(await rts.arrayBuffer());
96
  const image = await Jimp.read(buffer);
97
 
98
- // Preprocess the image to enhance QR code readability
99
- image
100
- .grayscale() // Convert to grayscale
101
- .contrast(1) // Increase contrast
102
- .normalize(); // Normalize the image
103
 
104
  const qrCodeReader = new QrCodeReader();
105
 
106
  qrCodeReader.callback = (err, value) => {
107
- if (err) return res.send({
108
- error: 'Error reading QR code'
109
- });
110
- res.json({
111
- result: value.result
112
- });
113
  };
114
 
115
  const bitmap = image.bitmap;
116
- qrCodeReader.decode({
117
- width: bitmap.width,
118
- height: bitmap.height,
119
- data: bitmap.data
120
- });
121
  } else {
122
  QRCode.toDataURL(url, (err, src) => {
123
- if (err) return res.send({
124
- error: 'Error generating QR code'
125
- });
126
  res.type('png').send(Buffer.from(src.split(",")[1], "base64"));
127
  });
128
  }
129
  } catch (error) {
130
  console.error(error);
131
- res.send({
132
- error: 'Internal Server Error'
133
- });
134
  }
135
  });
136
 
137
- async function processScreenshot(req, res, {
138
- ua,
139
- url,
140
- type,
141
- width,
142
- height,
143
- language,
144
- fullpage
145
- }) {
146
  try {
147
- console.log('process screenshot')
148
- const browser = await puppeteer.launch({
149
- headless: "new",
150
- args: ["--aggressive-tab-discard",
151
- "--disable-accelerated-2d-canvas",
152
- "--disable-application-cache",
153
- "--disable-cache",
154
- "--disable-dev-shm-usage",
155
- "--disable-gpu",
156
- "--disable-offline-load-stale-cache",
157
- "--disable-setuid-sandbox",
158
- "--disable-setuid-sandbox",
159
- "--disk-cache-size=0",
160
- "--ignore-certificate-errors",
161
- "--no-first-run",
162
- "--no-sandbox",
163
- "--no-zygote"
164
- ]
165
  });
166
- const page = await browser.newPage();
167
-
168
- // Set language and user agent
169
- await page.setExtraHTTPHeaders({
170
- 'Accept-Language': language || 'id-ID',
171
- 'User-Agent': ua || 'Mozilla/5.0 (Linux; Android 13; Pixel Build/RPB1.210523.001) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36',
172
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
- await page.goto(url, {
175
- waitUntil: 'networkidle2',
176
- });
177
- let full = fullpage == 1 ? true : false
178
  let screenshotOptions = {
179
- fullPage: true
 
 
180
  };
 
181
  if (type === 'desktop') {
182
- screenshotOptions = {
183
- fullPage: full,
184
- width: 1280,
185
- height: 800
186
- };
187
- await page.setViewport({
188
- width: 1280,
189
- height: 800,
190
  });
191
  } else if (type === 'mobile') {
192
- screenshotOptions = {
193
- fullPage: full,
194
- width: 375,
195
- height: 667
196
- };
197
- await page.setViewport({
198
  width: 375,
199
  height: 667,
200
  });
201
  } else if (type === 'tablet') {
202
- screenshotOptions = {
203
- fullPage: full,
204
- width: 768,
205
- height: 1024
206
- };
207
- await page.setViewport({
208
  width: 768,
209
  height: 1024,
210
  });
211
  } else if (type === 'iphone') {
212
- screenshotOptions = {
213
- fullPage: full,
214
- width: 375,
215
- height: 667
216
- };
217
- await page.setViewport({
218
  width: 375,
219
  height: 667,
220
  });
@@ -233,19 +142,13 @@ async function processScreenshot(req, res, {
233
  });
234
  await browser.close();
235
  }
236
- screenshotOptions = {
237
- fullPage: full,
238
- width: width || 375,
239
- height: height || 667
240
- };
241
- await page.setViewport({
242
  width: Number(width) || 375,
243
  height: Number(height) || 667,
244
  });
245
  }
246
 
247
- // Wait for a few seconds to mimic more natural behavior
248
- await page.waitForTimeout(3000);
249
 
250
  const screenshot = await page.screenshot(screenshotOptions);
251
 
@@ -257,14 +160,14 @@ async function processScreenshot(req, res, {
257
  console.log('process done');
258
  await browser.close();
259
  } catch (e) {
260
- log(e)
261
  return res.json({
262
  status: 400,
263
  message: 'error when take a screenshot'
264
- })
265
  }
266
  }
267
 
268
  app.listen(port, () => {
269
  console.log(`Server is running on port ${port}`);
270
- });
 
1
+ const express = require('express');
2
+ const { chromium } = require('playwright');
 
 
3
  const QRCode = require('qrcode');
4
  const Jimp = require('jimp');
5
  const QrCodeReader = require('qrcode-reader');
6
+ const fetch = require('node-fetch');
 
 
7
 
8
  const app = express();
9
  const port = 7860;
10
 
11
  app.use(express.json());
12
+
13
+ app.get('/', (req, res) => {
14
+ console.log('request to /');
15
+ res.send('halo kontol');
16
+ });
17
+
18
  app.post('/screenshot', async (req, res) => {
19
+ console.log('request to /screenshot');
20
+ const { ua, url, type, width, height, language, fullpage } = req.body;
21
+ if (!url) return res.send('please input url');
22
+ await processScreenshot(req, res, { ua, url, type, width, height, language, fullpage });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  });
24
 
25
  app.get('/screenshot', async (req, res) => {
26
+ console.log('request to /screenshot (get)');
27
+ const { ua, url, type, width, height, language, fullpage } = req.query;
28
+ if (!url) return res.send('please input url');
29
+ await processScreenshot(req, res, { ua, url, type, width, height, language, fullpage });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  });
31
+
32
  app.get('/qrcode', async (req, res) => {
33
  try {
34
+ const { mode, url } = req.query;
 
 
 
35
 
36
  if (!mode || !url) {
37
  return res.status(400).send('what?');
38
  }
39
 
40
  if (mode === 'create') {
 
41
  QRCode.toDataURL(url, (err, src) => {
42
+ if (err) return res.send({ error: 'Error generating QR code' });
 
 
43
  res.type('png').send(Buffer.from(src.split(",")[1], "base64"));
44
  });
45
  } else if (['read', 'scan'].includes(mode)) {
 
46
  const rts = await fetch(url);
47
+ if (!rts.ok || rts.status !== 200) return res.send({ status: 400, message: 'Can\'t buffer url' });
48
+ if (!/image/.test(rts.headers.get('content-type'))) return res.send({ status: 400, message: 'Only image type' });
 
 
 
 
 
 
49
  const buffer = Buffer.from(await rts.arrayBuffer());
50
  const image = await Jimp.read(buffer);
51
 
52
+ image.grayscale().contrast(1).normalize();
 
 
 
 
53
 
54
  const qrCodeReader = new QrCodeReader();
55
 
56
  qrCodeReader.callback = (err, value) => {
57
+ if (err) return res.send({ error: 'Error reading QR code' });
58
+ res.json({ result: value.result });
 
 
 
 
59
  };
60
 
61
  const bitmap = image.bitmap;
62
+ qrCodeReader.decode({ width: bitmap.width, height: bitmap.height, data: bitmap.data });
 
 
 
 
63
  } else {
64
  QRCode.toDataURL(url, (err, src) => {
65
+ if (err) return res.send({ error: 'Error generating QR code' });
 
 
66
  res.type('png').send(Buffer.from(src.split(",")[1], "base64"));
67
  });
68
  }
69
  } catch (error) {
70
  console.error(error);
71
+ res.send({ error: 'Internal Server Error' });
 
 
72
  }
73
  });
74
 
75
+ async function processScreenshot(req, res, { ua, url, type, width, height, language, fullpage }) {
 
 
 
 
 
 
 
 
76
  try {
77
+ console.log('process screenshot');
78
+ const browser = await chromium.launch({
79
+ headless: true,
80
+ args: ["--no-sandbox", "--disable-setuid-sandbox"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  });
82
+ const context = await browser.newContext({
83
+ userAgent: ua || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
84
+ viewport: { width: width || 1280, height: height || 800 },
85
+ deviceScaleFactor: 2
 
 
86
  });
87
+ const page = await context.newPage();
88
+
89
+ if (language) {
90
+ await page.emulateMedia({ colorScheme: language });
91
+ }
92
+
93
+ await page.goto(url, { waitUntil: 'networkidle' });
94
+
95
+ // Handle JavaScript challenges
96
+ await page.waitForLoadState('networkidle');
97
+
98
+ // Example to handle JavaScript challenge
99
+ // This is a placeholder, replace with actual challenge handling if needed
100
+ // await page.evaluate(() => {
101
+ // // Solve any inline JavaScript challenges
102
+ // });
103
 
 
 
 
 
104
  let screenshotOptions = {
105
+ fullPage: fullpage == 1 ? true : false,
106
+ type: 'png',
107
+ omitBackground: false
108
  };
109
+
110
  if (type === 'desktop') {
111
+ await page.setViewportSize({
112
+ width: 1920,
113
+ height: 1080,
 
 
 
 
 
114
  });
115
  } else if (type === 'mobile') {
116
+ await page.setViewportSize({
 
 
 
 
 
117
  width: 375,
118
  height: 667,
119
  });
120
  } else if (type === 'tablet') {
121
+ await page.setViewportSize({
 
 
 
 
 
122
  width: 768,
123
  height: 1024,
124
  });
125
  } else if (type === 'iphone') {
126
+ await page.setViewportSize({
 
 
 
 
 
127
  width: 375,
128
  height: 667,
129
  });
 
142
  });
143
  await browser.close();
144
  }
145
+ await page.setViewportSize({
 
 
 
 
 
146
  width: Number(width) || 375,
147
  height: Number(height) || 667,
148
  });
149
  }
150
 
151
+ await page.waitForTimeout(5000);
 
152
 
153
  const screenshot = await page.screenshot(screenshotOptions);
154
 
 
160
  console.log('process done');
161
  await browser.close();
162
  } catch (e) {
163
+ console.error(e);
164
  return res.json({
165
  status: 400,
166
  message: 'error when take a screenshot'
167
+ });
168
  }
169
  }
170
 
171
  app.listen(port, () => {
172
  console.log(`Server is running on port ${port}`);
173
+ });