import cfg from "../config.mjs"; import db from "../sql.mjs"; import lib from "../lib.mjs"; import { getLevel } from "../admin.mjs"; import queue from "../queue.mjs"; import fetch from "flumm-fetch"; import fs from "fs"; import path from "path"; const regex = { all: /https?:\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?/gi, yt: /(?:youtube\.com\/\S*(?:(?:\/e(?:mbed))?\/|watch\/?\?(?:\S*?&?v\=))|youtu\.be\/)([a-zA-Z0-9_-]{6,11})/gi, imgur: /^https?:\/\/(\w+\.)?imgur.com\/(\w*\d\w*)+(\.[a-zA-Z]{3,4})?/gi }; export default async bot => { return [{ name: "parser", call: regex.all, active: true, f: e => { const links = e.message.match(regex.all)?.filter(link => !link.includes("f0ck.me")) || []; let repost; if(e.media) links.push(e.media); if(links.length === 0) return false; if(e.message.match(/(!|-)ignore/)) return false; if(!e.channel.includes("f0ck") && !e.message.match(/(!|-)f0ck/i)) return false; console.log(`parsing ${links.length} link${links.length > 1 ? "s" : ""}...`); links.forEach(async link => { if(regex.imgur.test(link)) return await e.reply(`imgur is not supported!`); // check repost (link) repost = await queue.checkrepostlink(link); if(repost) return await e.reply(`repost motherf0cker (link): ${cfg.main.url.full}/${repost}`); // generate uuid const uuid = await queue.genuuid(); const maxfilesize = (getLevel(e.user).level > 50 ? cfg.main.maxfilesize * cfg.main.adminmultiplier : cfg.main.maxfilesize); let ext; // read metadata if(!regex.yt.test(link)) { const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"]; if(!Object.keys(cfg.mimes).includes(tmphead)) return; ext = cfg.mimes[tmphead]; } const msg = await e.reply(`[charging the f0cker] downloading: ${uuid}`, { disable_notification: true }); // download data const start = new Date(); let source = (await queue.exec(`yt-dlp -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath`)).stdout.trim(); if(!source) { if(e.type == 'tg') return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "something went wrong lol"); return await e.reply("something went wrong lol"); } if(source.match(/larger than/)) { if(e.type == 'tg') return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "too large lol"); return await e.reply("too large lol"); } const end = ~~((new Date() - start) / 1e3); // filesize check const size = fs.statSync(source).size; if(size > maxfilesize) { await fs.promises.unlink(source).catch(_=>{}); if(e.type == 'tg') return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `too large lol. (${lib.formatSize(size)} / ${lib.formatSize(maxfilesize)})`); return await e.reply(`too large lol. (${lib.formatSize(size)} / ${lib.formatSize(maxfilesize)})`); } // mime check const mime = (await queue.exec(`file --mime-type -b ${source}`)).stdout.trim(); if(!Object.keys(cfg.mimes).includes(mime)) { if(e.type == 'tg') return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `lol, go f0ck yourself (${mime})`); return await e.reply(`lol, go f0ck yourself (${mime})`); } // generate checksum const checksum = (await queue.exec(`sha256sum ${source}`)).stdout.trim().split(" ")[0]; // check repost (checksum) repost = await queue.checkrepostsum(checksum); if(repost) { await fs.promises.unlink(source).catch(_=>{}); if(e.type == 'tg') return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `repost motherf0cker (checksum): ${cfg.main.url.full}/${repost}`); return await e.reply(`repost motherf0cker (checksum): ${cfg.main.url.full}/${repost}`); } const filename = path.basename(source); await fs.promises.copyFile(source, `./public/b/${filename}`); await fs.promises.unlink(source).catch(_=>{}); await db` insert into items ${ db({ src: e.media ? "" : link, dest: filename, mime: mime, size: size, checksum: checksum, username: e.user.nick || e.user.username, userchannel: e.channel, usernetwork: e.network, stamp: ~~(new Date() / 1000), active: true }, 'src', 'dest', 'mime', 'size', 'checksum', 'username', 'userchannel', 'usernetwork', 'stamp', 'active') } `; const itemid = await queue.getItemID(filename); // generate thumbnail try { await queue.genThumbnail(filename, mime, itemid, link); } catch(err) { await queue.exec(`convert ./mugge.png ./public/t/${itemid}.webp`); } let speed = lib.calcSpeed(size, end); speed = !Number.isFinite(speed) ? "yes" : `${speed.toFixed(2)} Mbit/s`; // autotagger //await queue.tagSFW(itemid); const outputmsgirc = `[f0cked] link: ${cfg.main.url.full}/${itemid} | size: ${lib.formatSize(size)} | speed: ${speed}`; const outputmsgtg = `[f0cked] size: ${lib.formatSize(size)} | speed: ${speed}`; if(e.type == 'tg') { await e.deleteMessage(msg.result.chat.id, msg.result.message_id); await e.reply(outputmsgtg, { reply_markup: JSON.stringify({ inline_keyboard: [[ { text: 'sfw', callback_data: `b_sfw:${itemid}` }, { text: 'nsfw', callback_data: `b_nsfw:${itemid}` }, { text: 'tags', callback_data: `b_tags:${itemid}` }, { text: '❌ delete', callback_data: `b_delete:${itemid}` } ], [ { text: `open f0ck #${itemid}`, url: `${cfg.main.url.full}/${itemid}` } ]] }) }); } else { await e.reply(outputmsgirc); } }); } }]; };