Spaces:
No application file
No application file
Commit Β·
41d0a4b
1
Parent(s): 6a51d12
update
Browse files- services/brat.js +30 -0
- services/browser.js +25 -0
- services/editimg.js +51 -0
- services/function.js +25 -0
- services/run-playwright.js +27 -0
- services/screenshot.js +35 -0
- services/tes.js +37 -0
- services/uploader.js +29 -0
- services/upscaler.js +227 -0
services/brat.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const path = require('path');
|
| 2 |
+
const { getBrowser } = require('./browser');
|
| 3 |
+
|
| 4 |
+
const generateBrat = async (text) => {
|
| 5 |
+
const browser = await getBrowser();
|
| 6 |
+
const context = await browser.newContext({
|
| 7 |
+
viewport: { width: 1536, height: 695 },
|
| 8 |
+
});
|
| 9 |
+
|
| 10 |
+
const page = await context.newPage();
|
| 11 |
+
const filePath = path.join(__dirname, '../site/index.html');
|
| 12 |
+
|
| 13 |
+
await page.goto(`file://${filePath}`);
|
| 14 |
+
await page.click('#toggleButtonWhite');
|
| 15 |
+
await page.click('#textOverlay');
|
| 16 |
+
await page.click('#textInput');
|
| 17 |
+
await page.fill('#textInput', text);
|
| 18 |
+
|
| 19 |
+
const element = await page.$('#textOverlay');
|
| 20 |
+
const box = await element.boundingBox();
|
| 21 |
+
|
| 22 |
+
const screenshot = await page.screenshot({
|
| 23 |
+
clip: { x: box.x, y: box.y, width: 500, height: 500 },
|
| 24 |
+
});
|
| 25 |
+
|
| 26 |
+
await context.close();
|
| 27 |
+
return screenshot;
|
| 28 |
+
};
|
| 29 |
+
|
| 30 |
+
module.exports = { generateBrat };
|
services/browser.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const { chromium } = require('playwright');
|
| 2 |
+
|
| 3 |
+
let browser;
|
| 4 |
+
|
| 5 |
+
const launchBrowser = async () => {
|
| 6 |
+
if (!browser) {
|
| 7 |
+
browser = await chromium.launch();
|
| 8 |
+
}
|
| 9 |
+
};
|
| 10 |
+
|
| 11 |
+
const getBrowser = async () => {
|
| 12 |
+
if (!browser) {
|
| 13 |
+
await launchBrowser();
|
| 14 |
+
}
|
| 15 |
+
return browser;
|
| 16 |
+
};
|
| 17 |
+
|
| 18 |
+
const closeBrowser = async () => {
|
| 19 |
+
if (browser) {
|
| 20 |
+
await browser.close();
|
| 21 |
+
browser = null;
|
| 22 |
+
}
|
| 23 |
+
};
|
| 24 |
+
|
| 25 |
+
module.exports = { launchBrowser, getBrowser, closeBrowser };
|
services/editimg.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Tambahkan fungsi getRandom ke Array
|
| 2 |
+
Array.prototype.getRandom = function() {
|
| 3 |
+
return this[Math.floor(Math.random() * this.length)];
|
| 4 |
+
};
|
| 5 |
+
|
| 6 |
+
const { GoogleGenerativeAI } = require("@google/generative-ai");
|
| 7 |
+
|
| 8 |
+
// Daftar API Key
|
| 9 |
+
let apikey = [
|
| 10 |
+
'AIzaSyD4Hh71PpZCIWbGMNhjwllenHuAQupYwKQ',
|
| 11 |
+
'AIzaSyCp6ElMZX1hZPrkRAQdCNTQzL1TOQshg4Y'
|
| 12 |
+
];
|
| 13 |
+
|
| 14 |
+
// Inisialisasi GoogleGenerativeAI dengan API Key acak
|
| 15 |
+
const genAI = new GoogleGenerativeAI(apikey.getRandom());
|
| 16 |
+
|
| 17 |
+
async function generateImage(prompt, image = null) {
|
| 18 |
+
const contents = [{ text: prompt }];
|
| 19 |
+
|
| 20 |
+
if (image) {
|
| 21 |
+
const base64Image = image.toString("base64");
|
| 22 |
+
contents.push({
|
| 23 |
+
inlineData: {
|
| 24 |
+
mimeType: "image/png",
|
| 25 |
+
data: base64Image
|
| 26 |
+
}
|
| 27 |
+
});
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
const model = genAI.getGenerativeModel({
|
| 31 |
+
model: "gemini-2.0-flash-exp-image-generation",
|
| 32 |
+
generationConfig: {
|
| 33 |
+
responseModalities: ['image', 'text'],
|
| 34 |
+
responseMimeType: "text/plain"
|
| 35 |
+
}
|
| 36 |
+
});
|
| 37 |
+
|
| 38 |
+
try {
|
| 39 |
+
const response = await model.generateContent(contents);
|
| 40 |
+
|
| 41 |
+
const imageData =
|
| 42 |
+
response?.response?.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
|
| 43 |
+
|
| 44 |
+
return imageData ? Buffer.from(imageData, "base64") : null;
|
| 45 |
+
} catch (error) {
|
| 46 |
+
console.error("Error generating image:", error);
|
| 47 |
+
return error.message;
|
| 48 |
+
}
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
module.exports = { generateImage }
|
services/function.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const axios = require("axios");
|
| 2 |
+
|
| 3 |
+
async function urlToBuffer(url) {
|
| 4 |
+
try {
|
| 5 |
+
const response = await axios.get(url, {
|
| 6 |
+
responseType: "arraybuffer",
|
| 7 |
+
});
|
| 8 |
+
return Buffer.from(response.data, "binary");
|
| 9 |
+
} catch (error) {
|
| 10 |
+
console.error("Terjadi kesalahan:", error);
|
| 11 |
+
throw error;
|
| 12 |
+
}
|
| 13 |
+
}
|
| 14 |
+
|
| 15 |
+
async function upload(url) {
|
| 16 |
+
try {
|
| 17 |
+
let buff = await urlToBuffer(url);
|
| 18 |
+
let hasil = await Upload(buff);
|
| 19 |
+
return hasil;
|
| 20 |
+
} catch (e) {
|
| 21 |
+
return e;
|
| 22 |
+
}
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
module.exports = { urlToBuffer };
|
services/run-playwright.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const { exec } = require('child_process');
|
| 2 |
+
const fs = require('fs');
|
| 3 |
+
const path = require('path');
|
| 4 |
+
const { randomUUID } = require('crypto');
|
| 5 |
+
|
| 6 |
+
const executePlaywright = async (userCode) => {
|
| 7 |
+
return new Promise((resolve) => {
|
| 8 |
+
const scriptName = `playwright_script_${randomUUID()}.mjs`;
|
| 9 |
+
const scriptPath = path.join(__dirname, scriptName);
|
| 10 |
+
|
| 11 |
+
// Simpan kode ke file sementara
|
| 12 |
+
fs.writeFileSync(scriptPath, userCode);
|
| 13 |
+
|
| 14 |
+
// Jalankan kode dengan node
|
| 15 |
+
exec(`node ${scriptPath}`, { timeout: 30000 }, (error, stdout, stderr) => {
|
| 16 |
+
// Hapus file setelah eksekusi
|
| 17 |
+
fs.unlinkSync(scriptPath);
|
| 18 |
+
|
| 19 |
+
if (error) {
|
| 20 |
+
return resolve({ success: false, error: stderr || error.message });
|
| 21 |
+
}
|
| 22 |
+
resolve({ success: true, output: stdout });
|
| 23 |
+
});
|
| 24 |
+
});
|
| 25 |
+
};
|
| 26 |
+
|
| 27 |
+
module.exports = { executePlaywright };
|
services/screenshot.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const { getBrowser } = require('./browser');
|
| 2 |
+
const { devices } = require('playwright');
|
| 3 |
+
|
| 4 |
+
const takeScreenshot = async (url, device) => {
|
| 5 |
+
const browser = await getBrowser();
|
| 6 |
+
|
| 7 |
+
let deviceOptions;
|
| 8 |
+
switch (device?.toLowerCase()) {
|
| 9 |
+
case 'iphone':
|
| 10 |
+
deviceOptions = devices['iPhone 13'];
|
| 11 |
+
break;
|
| 12 |
+
case 'ipad':
|
| 13 |
+
deviceOptions = devices['iPad Pro 11'];
|
| 14 |
+
break;
|
| 15 |
+
case 'desktop':
|
| 16 |
+
deviceOptions = {
|
| 17 |
+
viewport: { width: 1920, height: 1080 },
|
| 18 |
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36',
|
| 19 |
+
};
|
| 20 |
+
break;
|
| 21 |
+
default:
|
| 22 |
+
throw new Error("Parameter `device` harus 'iphone', 'ipad', atau 'desktop'");
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
const context = await browser.newContext(deviceOptions);
|
| 26 |
+
const page = await context.newPage();
|
| 27 |
+
await page.goto(url, { timeout: 30000 });
|
| 28 |
+
|
| 29 |
+
const screenshot = await page.screenshot({ fullPage: true });
|
| 30 |
+
await context.close();
|
| 31 |
+
|
| 32 |
+
return screenshot;
|
| 33 |
+
};
|
| 34 |
+
|
| 35 |
+
module.exports = { takeScreenshot };
|
services/tes.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const { chromium } = require('playwright');
|
| 2 |
+
|
| 3 |
+
async function tes() {
|
| 4 |
+
// Inisialisasi browser
|
| 5 |
+
const browser = await chromium.launch({ headless: false }); // Gunakan headless: true jika ingin tanpa UI
|
| 6 |
+
const context = await browser.newContext();
|
| 7 |
+
|
| 8 |
+
// Atur cookie
|
| 9 |
+
await context.addCookies([
|
| 10 |
+
{
|
| 11 |
+
name: '__session',
|
| 12 |
+
value: encodeURIComponent(`{"user_id":"01eff777-9400-603a-9104-0242ac120006","token":"v4.public.eyJhdWQiOiJpemFuYW1pLWFwcHMiLCJlbWFpbCI6ImNpZnVtb29naXdhcmFAZ21haWwuY29tIiwiZXhwIjoiMjAyNS0wMy0xMlQwNjowMToxM1oiLCJpYXQiOiIyMDI1LTAzLTExVDA2OjAxOjEzWiIsImlzcyI6Iml6YW5hbWktYXBpIiwianRpIjoiMDFlZmY3NzctOTQwMC02MDNhLTkxMDQtMDI0MmFjMTIwMDA2IiwibmJmIjoiMjAyNS0wMy0xMVQwNjowMToxM1oiLCJyZXF1ZXN0SVAiOiIiLCJzdWIiOiIwMWVmZjc3Ny05NDAwLTYwM2EtOTEwNC0wMjQyYWMxMjAwMDYiLCJ1c2VyQWdlbnQiOiIifRkMEjJZh4M60f179S9BvautqJaYFFsLA-X_RCxDem_eD73MLf_4Z2y9trX7EKCwJ3hFT6FhuMtygtU4rvJVGgE","username":"cifumo ogiwara","email":"cifumoogiwara@gmail.com","avatar_image_url":"https://lh3.googleusercontent.com/a/ACg8ocIGlKJt2X5_0faMYeUwRYkC0_xmtyqk2XN6-reP71yDLyORQh8=s96-c","is_premium":false,"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJvYXV0aCIsInRpbWVzdGFtcCI6MTc0MTY3MjYwMH1dLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJnb29nbGUiLCJwcm92aWRlcnMiOlsiZ29vZ2xlIl19LCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZW1haWwiOiJjaWZ1bW9vZ2l3YXJhQGdtYWlsLmNvbSIsImV4cCI6MTc0MTY3NjIwMCwiaWF0IjoxNzQxNjcyNjAwLCJpc19hbm9ueW1vdXMiOmZhbHNlLCJpc3MiOiJodHRwczovL2F1dGguc2hpbmlnYW1pLmdnL2F1dGgvdjEiLCJwaG9uZSI6IiIsInJvbGUiOiJhdXRoZW50aWNhdGVkIiwic2Vzc2lvbl9pZCI6IjljMjRjZGQ3LWY4OTktNDNiOS04ZjZhLTczMTA3OWJjNWFjMiIsInN1YiI6IjRjZTFlNjIxLWRkZDYtNDI4Ni1iZmE3LTAyZWUwNDYwYTE2MiIsInVzZXJfbWV0YWRhdGEiOnsiYXZhdGFyX3VybCI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FDZzhvY0lHbEtKdDJYNV8wZmFNWWVVd1JZa0MwX3htdHlxazJYTjYtcmVQNzF5REx5T1JRaDg9czk2LWMiLCJlbWFpbCI6ImNpZnVtb29naXdhcmFAZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImZ1bGxfbmFtZSI6ImNpZnVtbyBvZ2l3YXJhIiwiaXNzIjoiaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tIiwibmFtZSI6ImNpZnVtbyBvZ2l3YXJhIiwicGhvbmVfdmVyaWZpZWQiOmZhbHNlLCJwaWN0dXJlIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EvQUNnOG9jSUdsS0p0Mlg1XzBmYU1ZZVV3UllrQzBfeG10eXFrMlhONi1yZVA3MXlETHlPUlFoOD1zOTYtYyIsInByb3ZpZGVyX2lkIjoiMTE0NTI0NDcyOTc5NDAzOTMyMDk1Iiwic3ViIjoiMTE0NTI0NDcyOTc5NDAzOTMyMDk1In19.CVorldNlebRldcIh7r2sRGZfWe72EKk5Eg04XD2BhLc","refresh_token":"wkbA8YebwI8rvz2Zjuddqg","expires_at":1741676200,"expired_at_moment":"1970-01-21 10:47:56"}`),
|
| 13 |
+
domain: 'app.shinigami.asia',
|
| 14 |
+
path: '/',
|
| 15 |
+
httpOnly: false,
|
| 16 |
+
secure: true
|
| 17 |
+
}
|
| 18 |
+
]);
|
| 19 |
+
|
| 20 |
+
// Membuka halaman
|
| 21 |
+
const page = await context.newPage();
|
| 22 |
+
await page.goto('https://app.shinigami.asia/chapter/8e53d781-39f4-4683-b3bf-cd260b9b01d2', {
|
| 23 |
+
waitUntil: 'domcontentloaded'
|
| 24 |
+
});
|
| 25 |
+
|
| 26 |
+
// Tunggu 5 detik agar halaman termuat sempurna
|
| 27 |
+
await page.waitForTimeout(5000);
|
| 28 |
+
|
| 29 |
+
// Ambil isi HTML dari halaman
|
| 30 |
+
const htmlContent = await page.content();
|
| 31 |
+
return htmlContent
|
| 32 |
+
|
| 33 |
+
// Tutup browser
|
| 34 |
+
await browser.close();
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
module.exports = { tes };
|
services/uploader.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const FormData = require('form-data');
|
| 2 |
+
const crypto = require('crypto');
|
| 3 |
+
const path = require('path');
|
| 4 |
+
const fetch = require('node-fetch');
|
| 5 |
+
|
| 6 |
+
module.exports = async function (buffer, originalFilename = 'iyah') {
|
| 7 |
+
// Ambil ekstensi dari file asli
|
| 8 |
+
const ext = path.extname(originalFilename);
|
| 9 |
+
// Generate nama file random
|
| 10 |
+
const randomFilename = crypto.randomBytes(8).toString('hex') + ext;
|
| 11 |
+
|
| 12 |
+
const form = new FormData();
|
| 13 |
+
form.append('file', buffer, { filename: randomFilename });
|
| 14 |
+
|
| 15 |
+
try {
|
| 16 |
+
const response = await fetch('https://upload.cifumo.xyz/api/upload', {
|
| 17 |
+
method: 'POST',
|
| 18 |
+
body: form,
|
| 19 |
+
headers: form.getHeaders()
|
| 20 |
+
});
|
| 21 |
+
|
| 22 |
+
const result = await response.json();
|
| 23 |
+
console.log('Upload Success:', result);
|
| 24 |
+
return result.url;
|
| 25 |
+
} catch (error) {
|
| 26 |
+
console.error('Upload Failed:', error);
|
| 27 |
+
return null;
|
| 28 |
+
}
|
| 29 |
+
};
|
services/upscaler.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const axios = require('axios')
|
| 2 |
+
const FormData = require('form-data')
|
| 3 |
+
|
| 4 |
+
const bigjpg = {
|
| 5 |
+
api: {
|
| 6 |
+
base: 'https://bigjpg.com',
|
| 7 |
+
endpoint: {
|
| 8 |
+
task: '/task',
|
| 9 |
+
free: '/free'
|
| 10 |
+
}
|
| 11 |
+
},
|
| 12 |
+
|
| 13 |
+
available: {
|
| 14 |
+
styles: {
|
| 15 |
+
'art': 'Artwork',
|
| 16 |
+
'photo': 'Foto'
|
| 17 |
+
},
|
| 18 |
+
noise: {
|
| 19 |
+
'-1': 'Ninguno',
|
| 20 |
+
'0': 'Bajo',
|
| 21 |
+
'1': 'Medio',
|
| 22 |
+
'2': 'Alto',
|
| 23 |
+
'3': 'El mΓ‘s alto'
|
| 24 |
+
}
|
| 25 |
+
},
|
| 26 |
+
|
| 27 |
+
headers: {
|
| 28 |
+
'origin': 'https://bigjpg.com',
|
| 29 |
+
'referer': 'https://bigjpg.com/',
|
| 30 |
+
'user-agent': 'Postify/1.0.0',
|
| 31 |
+
'x-requested-with': 'XMLHttpRequest'
|
| 32 |
+
},
|
| 33 |
+
|
| 34 |
+
isValid: (style, noise) => {
|
| 35 |
+
if (!style && !noise) {
|
| 36 |
+
return {
|
| 37 |
+
valid: true,
|
| 38 |
+
style: 'art',
|
| 39 |
+
noise: '-1'
|
| 40 |
+
};
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
if (style && !bigjpg.available.styles[style]) {
|
| 44 |
+
return {
|
| 45 |
+
valid: false,
|
| 46 |
+
error: `Stylenya kagak valid bree.. Pilih salah satunya yak: ${Object.keys(bigjpg.available.styles).join(', ')} πΏ`
|
| 47 |
+
};
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
if (noise && !bigjpg.available.noise[noise]) {
|
| 51 |
+
return {
|
| 52 |
+
valid: false,
|
| 53 |
+
error: `Noise levelnya kagak valid bree.. Pilih salah satunya yak: ${Object.keys(bigjpg.available.noise).join(', ')} π`
|
| 54 |
+
};
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
return {
|
| 58 |
+
valid: true,
|
| 59 |
+
style: style || 'art',
|
| 60 |
+
noise: noise || '-1'
|
| 61 |
+
};
|
| 62 |
+
},
|
| 63 |
+
|
| 64 |
+
getImageInfo: async (img) => {
|
| 65 |
+
if (!img) {
|
| 66 |
+
return {
|
| 67 |
+
valid: false,
|
| 68 |
+
error: "Hadeh, gini bree... lu kasih link image nya yak πΏ Jangan kosong begini, aelah π"
|
| 69 |
+
};
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
try {
|
| 73 |
+
const response = await axios.get(img, {
|
| 74 |
+
responseType: 'arraybuffer'
|
| 75 |
+
});
|
| 76 |
+
|
| 77 |
+
const fileSize = parseInt(response.headers['content-length'] || response.data.length);
|
| 78 |
+
const width = Math.floor(Math.random() * (2000 - 800 + 1)) + 800;
|
| 79 |
+
const height = Math.floor(Math.random() * (2000 - 800 + 1)) + 800;
|
| 80 |
+
|
| 81 |
+
let fileName = img.split('/').pop().split('#')[0].split('?')[0] || 'image.jpg';
|
| 82 |
+
if (fileName.endsWith('.webp')) {
|
| 83 |
+
fileName = fileName.replace('.webp', '.jpg');
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
if (fileSize > 5 * 1024 * 1024) {
|
| 87 |
+
return {
|
| 88 |
+
valid: false,
|
| 89 |
+
error: "Size imagenya kegedean bree.. Max 5MB yak π"
|
| 90 |
+
};
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
return {
|
| 94 |
+
valid: true,
|
| 95 |
+
info: {
|
| 96 |
+
fileName,
|
| 97 |
+
fileSize,
|
| 98 |
+
width,
|
| 99 |
+
height
|
| 100 |
+
}
|
| 101 |
+
};
|
| 102 |
+
|
| 103 |
+
} catch (err) {
|
| 104 |
+
return {
|
| 105 |
+
valid: false,
|
| 106 |
+
error: "Link imagenya error bree.. Coba link yang lain yak π"
|
| 107 |
+
};
|
| 108 |
+
}
|
| 109 |
+
},
|
| 110 |
+
|
| 111 |
+
upscale: async (img, options = {}) => {
|
| 112 |
+
const validation = await bigjpg.getImageInfo(img);
|
| 113 |
+
if (!validation.valid) {
|
| 114 |
+
return {
|
| 115 |
+
success: false,
|
| 116 |
+
code: 400,
|
| 117 |
+
result: {
|
| 118 |
+
error: validation.error
|
| 119 |
+
}
|
| 120 |
+
};
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
const inputx = bigjpg.isValid(options.style, options.noise);
|
| 124 |
+
if (!inputx.valid) {
|
| 125 |
+
return {
|
| 126 |
+
success: false,
|
| 127 |
+
code: 400,
|
| 128 |
+
result: {
|
| 129 |
+
error: inputx.error
|
| 130 |
+
}
|
| 131 |
+
};
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
const config = {
|
| 135 |
+
x2: '2',
|
| 136 |
+
style: inputx.style,
|
| 137 |
+
noise: inputx.noise,
|
| 138 |
+
file_name: validation.info.fileName,
|
| 139 |
+
files_size: validation.info.fileSize,
|
| 140 |
+
file_height: validation.info.height,
|
| 141 |
+
file_width: validation.info.width,
|
| 142 |
+
input: img
|
| 143 |
+
};
|
| 144 |
+
|
| 145 |
+
try {
|
| 146 |
+
const params = new URLSearchParams();
|
| 147 |
+
params.append('conf', JSON.stringify(config));
|
| 148 |
+
|
| 149 |
+
const taskx = await axios.post(
|
| 150 |
+
`${bigjpg.api.base}${bigjpg.api.endpoint.task}`,
|
| 151 |
+
params,
|
| 152 |
+
{ headers: bigjpg.headers }
|
| 153 |
+
);
|
| 154 |
+
|
| 155 |
+
if (taskx.data.status !== 'ok') {
|
| 156 |
+
return {
|
| 157 |
+
success: false,
|
| 158 |
+
code: 400,
|
| 159 |
+
result: {
|
| 160 |
+
error: "Error euy ππ»"
|
| 161 |
+
}
|
| 162 |
+
};
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
const taskId = taskx.data.info;
|
| 166 |
+
let attempts = 0;
|
| 167 |
+
const maxAttempts = 20;
|
| 168 |
+
|
| 169 |
+
while (attempts < maxAttempts) {
|
| 170 |
+
const res = await axios.get(
|
| 171 |
+
`${bigjpg.api.base}${bigjpg.api.endpoint.free}?fids=${JSON.stringify([taskId])}`,
|
| 172 |
+
{ headers: bigjpg.headers }
|
| 173 |
+
);
|
| 174 |
+
|
| 175 |
+
const result = res.data[taskId];
|
| 176 |
+
|
| 177 |
+
if (result[0] === 'success') {
|
| 178 |
+
return {
|
| 179 |
+
success: true,
|
| 180 |
+
code: 200,
|
| 181 |
+
result: {
|
| 182 |
+
info: validation.info,
|
| 183 |
+
url: result[1],
|
| 184 |
+
size: result[2],
|
| 185 |
+
config: {
|
| 186 |
+
style: config.style,
|
| 187 |
+
styleName: bigjpg.available.styles[config.style],
|
| 188 |
+
noise: config.noise,
|
| 189 |
+
noiseName: bigjpg.available.noise[config.noise]
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
};
|
| 193 |
+
} else if (result[0] === 'error') {
|
| 194 |
+
return {
|
| 195 |
+
success: false,
|
| 196 |
+
code: 400,
|
| 197 |
+
result: {
|
| 198 |
+
error: "Upscalenya gagal bree.. Coba lagi nanti yak π"
|
| 199 |
+
}
|
| 200 |
+
};
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
await new Promise(resolve => setTimeout(resolve, 15000));
|
| 204 |
+
attempts++;
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
return {
|
| 208 |
+
success: false,
|
| 209 |
+
code: 400,
|
| 210 |
+
result: {
|
| 211 |
+
error: "Timeout bree.. π"
|
| 212 |
+
}
|
| 213 |
+
};
|
| 214 |
+
|
| 215 |
+
} catch (err) {
|
| 216 |
+
return {
|
| 217 |
+
success: false,
|
| 218 |
+
code: 400,
|
| 219 |
+
result: {
|
| 220 |
+
error: err.message || "Error euy πΏ"
|
| 221 |
+
}
|
| 222 |
+
};
|
| 223 |
+
}
|
| 224 |
+
}
|
| 225 |
+
};
|
| 226 |
+
|
| 227 |
+
module.exports = { bigjpg };
|