Update app.js
Browse files
app.js
CHANGED
|
@@ -4,6 +4,8 @@ import cors from 'cors';
|
|
| 4 |
import axios from 'axios';
|
| 5 |
import fetch from 'node-fetch';
|
| 6 |
import * as cheerio from 'cheerio';
|
|
|
|
|
|
|
| 7 |
import dotenv from 'dotenv';
|
| 8 |
import os from 'os';
|
| 9 |
import { io } from "socket.io-client";
|
|
@@ -293,6 +295,126 @@ app.get("/y232", async (req, res) => {
|
|
| 293 |
|
| 294 |
});
|
| 295 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
const PORT = process.env.PORT || 7860;
|
| 297 |
|
| 298 |
app.listen(PORT, async () => {
|
|
|
|
| 4 |
import axios from 'axios';
|
| 5 |
import fetch from 'node-fetch';
|
| 6 |
import * as cheerio from 'cheerio';
|
| 7 |
+
import fakeUa from 'fake-useragent';
|
| 8 |
+
import { FormData } from 'formdata-node';
|
| 9 |
import dotenv from 'dotenv';
|
| 10 |
import os from 'os';
|
| 11 |
import { io } from "socket.io-client";
|
|
|
|
| 295 |
|
| 296 |
});
|
| 297 |
|
| 298 |
+
class Luluvdo {
|
| 299 |
+
async download(url, output = 'json') {
|
| 300 |
+
try {
|
| 301 |
+
console.log(`[LOG] Memulai proses untuk URL: ${url}`);
|
| 302 |
+
const idMatch = url.match(/(?:\/[de])\/([a-zA-Z0-9_-]+)/);
|
| 303 |
+
const id = idMatch?.[1];
|
| 304 |
+
if (!id) throw new Error('Invalid URL: ID not found');
|
| 305 |
+
|
| 306 |
+
console.log(`[LOG] Mengambil form dari halaman: https://luluvdo.com/d/${id}_h`);
|
| 307 |
+
|
| 308 |
+
const browser = await chromium.launch({ headless: true });
|
| 309 |
+
const page = await browser.newPage();
|
| 310 |
+
await page.setUserAgent(fakeUa());
|
| 311 |
+
|
| 312 |
+
// Navigate to the page
|
| 313 |
+
await page.goto(`https://luluvdo.com/d/${id}_h`);
|
| 314 |
+
|
| 315 |
+
let formResult;
|
| 316 |
+
do {
|
| 317 |
+
// Get form data using Playwright
|
| 318 |
+
formResult = new FormData();
|
| 319 |
+
const formData = await page.$$eval('form#F1 input', (inputs) => {
|
| 320 |
+
return inputs.map(input => ({
|
| 321 |
+
name: input.name,
|
| 322 |
+
value: input.value
|
| 323 |
+
}));
|
| 324 |
+
});
|
| 325 |
+
|
| 326 |
+
formData.forEach(({ name, value }) => {
|
| 327 |
+
if (name && value) formResult.append(name, value);
|
| 328 |
+
});
|
| 329 |
+
|
| 330 |
+
console.log(`[LOG] Form yang diambil: ${JSON.stringify(formResult, null, 2)}`);
|
| 331 |
+
|
| 332 |
+
if (!formResult.has('hash')) {
|
| 333 |
+
console.log('[LOG] Form tidak valid, mencoba lagi...');
|
| 334 |
+
await page.reload();
|
| 335 |
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
| 336 |
+
}
|
| 337 |
+
} while (!formResult.has('hash'));
|
| 338 |
+
|
| 339 |
+
console.log('[LOG] Form berhasil diambil, mengirimkan permintaan untuk mendapatkan link unduhan');
|
| 340 |
+
|
| 341 |
+
// Use Axios to submit the form data (POST request)
|
| 342 |
+
const axiosClient = axios.create({
|
| 343 |
+
headers: { 'User-Agent': fakeUa() },
|
| 344 |
+
withCredentials: true,
|
| 345 |
+
});
|
| 346 |
+
|
| 347 |
+
let result;
|
| 348 |
+
do {
|
| 349 |
+
// Post the form data using Axios
|
| 350 |
+
const { data: postData } = await axiosClient.post(`https://luluvdo.com/d/${id}_h`, formResult);
|
| 351 |
+
|
| 352 |
+
const $$ = cheerio.load(postData);
|
| 353 |
+
|
| 354 |
+
result = {
|
| 355 |
+
size: $$('table tr:nth-child(1) td:nth-child(2)').text().trim() || 'N/A',
|
| 356 |
+
bytes: $$('table tr:nth-child(2) td:nth-child(2)').text().trim() || 'N/A',
|
| 357 |
+
ip: $$('table tr:nth-child(3) td:nth-child(2)').text().trim() || 'N/A',
|
| 358 |
+
link: $$('a.btn.btn-gradient.submit-btn').attr('href') || 'N/A',
|
| 359 |
+
expired: $$('div.text-center.text-danger').text().trim() || 'N/A',
|
| 360 |
+
};
|
| 361 |
+
|
| 362 |
+
console.log(`[LOG] Hasil: ${JSON.stringify(result, null, 2)}`);
|
| 363 |
+
|
| 364 |
+
if (result.link === 'N/A') {
|
| 365 |
+
console.log('[LOG] Link unduhan belum tersedia, mencoba lagi...');
|
| 366 |
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
| 367 |
+
}
|
| 368 |
+
} while (result.link === 'N/A');
|
| 369 |
+
|
| 370 |
+
console.log(`[LOG] Link unduhan berhasil ditemukan: ${result.link}`);
|
| 371 |
+
|
| 372 |
+
let media = null;
|
| 373 |
+
if (output === 'file') {
|
| 374 |
+
console.log('[LOG] Mengunduh file...');
|
| 375 |
+
const { data: buffer, headers } = await axiosClient.get(result.link, {
|
| 376 |
+
headers: {
|
| 377 |
+
Referer: `https://luluvdo.com/d/${id}_h`,
|
| 378 |
+
'X-Forwarded-For': result.ip,
|
| 379 |
+
},
|
| 380 |
+
responseType: 'arraybuffer',
|
| 381 |
+
});
|
| 382 |
+
|
| 383 |
+
media = {
|
| 384 |
+
buffer: Buffer.from(buffer),
|
| 385 |
+
contentType: headers['content-type'] || 'application/octet-stream',
|
| 386 |
+
fileName: result.link.split('/').pop() || 'downloaded_file',
|
| 387 |
+
};
|
| 388 |
+
console.log('[LOG] File berhasil diunduh');
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
await browser.close();
|
| 392 |
+
return media ? { ...result, ...media } : result;
|
| 393 |
+
} catch (error) {
|
| 394 |
+
console.error(`[ERROR] Proses gagal: ${error.message}`);
|
| 395 |
+
throw new Error(`Download failed: ${error.message}`);
|
| 396 |
+
}
|
| 397 |
+
}
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
|
| 401 |
+
app.get('/luluvdo', async (req, res) => {
|
| 402 |
+
const { url, output } = req.query;
|
| 403 |
+
const luluvdo = new Luluvdo();
|
| 404 |
+
|
| 405 |
+
if (!url) {
|
| 406 |
+
return res.status(400).json({ error: 'URL is required' });
|
| 407 |
+
}
|
| 408 |
+
|
| 409 |
+
try {
|
| 410 |
+
const result = await luluvdo.download(url, output || 'json');
|
| 411 |
+
res.status(200).json(result);
|
| 412 |
+
} catch (error) {
|
| 413 |
+
console.error(`[ERROR] Download failed: ${error.message}`);
|
| 414 |
+
res.status(500).json({ error: error.message });
|
| 415 |
+
}
|
| 416 |
+
});
|
| 417 |
+
|
| 418 |
const PORT = process.env.PORT || 7860;
|
| 419 |
|
| 420 |
app.listen(PORT, async () => {
|