import { createRequire } from 'module'; import { fileURLToPath } from 'url'; import path from 'path'; import PDFDocument from 'pdfkit'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const require = createRequire(import.meta.url); const { promisify } = require('util'); const express = require('express'); const axios = require('axios'); const cheerio = require('cheerio'); const fs = require('fs'); const { tmpdir } = require('os'); const { join } = require('path'); const nodeID3 = require('node-id3'); const puppeteer = require('puppeteer'); const app = express(); const PORT = 7860; const { format } = require("util"); const os = require("os"); const writeFileAsync = promisify(fs.writeFile); const fss = fs.promises; function generateRandomID(length = 8) { const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; for (let i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * characters.length)); } return result; } async function komiku_download(url) { const instanceID = generateRandomID(); const tempDir = path.join(os.tmpdir(), instanceID); await fss.mkdir(tempDir); // Extracting the title from the URL const title = url.split('/').filter(part => part).pop(); try { const response = await axios.get(url); const html = response.data; const $ = cheerio.load(html); const imgList = []; $('#Baca_Komik img').each((index, element) => { const src = $(element).attr('src'); imgList.push({ path: src }); }); const imagePaths = await downloadImages(imgList, tempDir, instanceID); const pdfPath = await createPDF(imagePaths, instanceID, tempDir); console.log(`PDF berhasil dibuat: ${pdfPath}`); return { path: pdfPath, title: title }; } catch (error) { console.log(error); throw error; } finally { await fss.rmdir(tempDir, { recursive: true }); } } async function downloadImage(image, tempDir, instanceID) { const response = await axios.get(image.path, { responseType: 'arraybuffer' }); const imagePath = path.join(tempDir, `image_${instanceID}_${Date.now()}_${Math.floor(Math.random() * 1000)}.jpg`); await writeFileAsync(imagePath, response.data); return imagePath; } async function downloadImages(imgList, tempDir, instanceID) { const imagePaths = []; for (const img of imgList) { const imagePath = await downloadImage(img, tempDir, instanceID); imagePaths.push(imagePath); } return imagePaths; } async function createPDF(imagePaths, instanceID, tempDir) { const pdfPath = path.join(os.tmpdir(), `${instanceID}.pdf`); const doc = new PDFDocument({ autoFirstPage: false }); doc.pipe(fs.createWriteStream(pdfPath)); for (const imagePath of imagePaths) { const { width, height } = await getImageDimensions(imagePath); doc.addPage({ size: [width, height] }); doc.image(imagePath, 0, 0, { width: width, height: height }); } doc.end(); return pdfPath; } async function getImageDimensions(imagePath) { const { promisify } = require('util'); const sizeOf = promisify(require('image-size')); const dimensions = await sizeOf(imagePath); return dimensions; } app.get('/komikudl', async (req, res) => { const url = req.query.url; if (!url) { return res.status(400).send('URL is required'); } try { const data = await komiku_download(url); res.download(data.path, `${data.title}.pdf`, (err) => { if (err) { console.error(err); } fs.unlinkSync(data.path); // Remove the file after sending it }); } catch (error) { res.status(500).send('An error occurred while generating the PDF'); } }); app.get('/add', async (req, res) => { try { const { url, title, artist, year, imgUrl } = req.query; // Ambil file audio dari URL const response = await axios.get(url, { responseType: 'arraybuffer' }); // Simpan file audio ke dalam buffer const audioBuffer = Buffer.from(response.data); // Buat nama file yang acak const randomFilename = Math.random().toString(36).substring(7) + '.mp3'; // Path untuk menyimpan file sementara const tmpFilePath = join(tmpdir(), randomFilename); // Simpan file audio ke dalam sistem file sementara fs.writeFileSync(tmpFilePath, audioBuffer); // Buat objek tag ID3 const tags = { title: title, artist: artist, year: year // Anda juga dapat menambahkan gambar album (cover) jika diperlukan }; // Jika ada URL untuk cover, ambil gambarnya dan tambahkan ke dalam tag ID3 if (imgUrl) { const coverResponse = await axios.get(imgUrl, { responseType: 'arraybuffer' }); const coverBuffer = Buffer.from(coverResponse.data); tags.image = { mime: 'image/jpeg', // Sesuaikan dengan tipe mime gambar type: { id: 3, // Jenis gambar (3 untuk cover album) name: 'Front Cover' }, description: 'Cover', // Deskripsi (opsional) imageBuffer: coverBuffer }; } // Ubah tag ID3 dari file audio const success = nodeID3.write(tags, tmpFilePath); if (success) { console.log('Tag ID3 berhasil diubah!'); } else { console.error('Gagal mengubah tag ID3.'); } // Kirim link download audio yang sudah diubah const downloadLink = `https://${process.env.SPACE_HOST}/download/${randomFilename}`; res.json({ msg: `Audio berhasil diubah.`, link: downloadLink }); } catch (error) { console.error('Terjadi kesalahan:', error); res.status(500).send('Terjadi kesalahan saat mengubah audio.'); } }); async function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // Route untuk mendownload audio yang sudah diubah app.get('/download/:filename', async (req, res) => { const { filename } = req.params; const filePath = join(tmpdir(), filename); res.download(filePath, () => { // Hapus file setelah berhasil didownload fs.unlinkSync(filePath); }); }); const startTime = new Date(); // Fungsi untuk menghitung waktu berjalan dalam format yang diinginkan function waktuBerjalan() { const sekarang = new Date(); const selisih = sekarang.getTime() - startTime.getTime(); const hari = Math.floor(selisih / (1000 * 60 * 60 * 24)); const jam = Math.floor((selisih % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const menit = Math.floor((selisih % (1000 * 60 * 60)) / (1000 * 60)); const detik = Math.floor((selisih % (1000 * 60)) / 1000); if (hari > 0) { return `${hari} hari ${jam} jam ${menit} menit ${detik} detik`; } else if (jam > 0) { return `${jam} jam ${menit} menit ${detik} detik`; } else if (menit > 0) { return `${menit} menit ${detik} detik`; } else { return `${detik} detik`; } } app.get('/ping', (req, res) => { res.send('Server is up and running!' + waktuBerjalan()); }); const pingServer = async () => { try { const pingResponse = await axios.get(`https://${process.env.SPACE_HOST}` + '/ping'); console.log('Server pinged at:', new Date().toLocaleTimeString()); } catch (error) { console.error('Failed to ping server:', error.message); } }; /*other api*/ async function searchResepPuppeter(query, hal) { let pages = "https://cookpad.com/id/cari/" + query + "?event=search.typed_query" if(hal > 1) { pages += "&page=" + hal; } const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); const page = await browser.newPage(); await page.setUserAgent("Mozilla/5.0 (Linux; Android 10; SM-G965U Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.141 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/420.0.0.32.61;]"); await page.setExtraHTTPHeaders({ 'Referer': pages }); await page.goto(pages); const baseUrl = page.url(); let jason = { list: [], next_page: false }; const liHtmlArray = jason.list; const ulElement = await page.$("#main_contents > div.lg\\:flex.lg\\:items-start > div.relative.lg\\:w-3\\/5 > ul"); if (ulElement) { const listItemsWithId = await ulElement.$$("li[id]"); for (const li of listItemsWithId) { const linkElement = await li.$("div.flex-auto.m-sm > div > div.flex.justify-between > h2 > a"); const imageElement = await li.$("div.flex-none.w-20.xs\\:w-auto.h-auto > picture > img"); const authorElement = await li.$("div.flex-auto.m-sm > div > div.border-t.border-dashed.border-cookpad-gray-400.pt-sm.mt-auto > div > span.break-all.clamp-1 > span"); const li_url = await (await linkElement.getProperty('href')).jsonValue(); const li_text = await (await linkElement.getProperty('innerText')).jsonValue(); const li_img = await (await imageElement.getProperty('src')).jsonValue(); const li_author = await (await authorElement.getProperty('innerText')).jsonValue(); let anu = { url: li_url, title: li_text, thumbnail: li_img, author: li_author }; liHtmlArray.push(anu); } } else { console.error("Element