import fetch from "flumm-fetch-cookies"; import { promises as fs } from "fs"; import { exec } from "child_process"; import cfg from "../config.mjs"; import sql from "../sql.mjs"; import lib from "../lib.mjs"; const cleanTags = async () => { const tags = await sql("tags") .leftJoin("tags_assign", "tags_assign.tag_id", "tags.id") .whereNull("tags_assign.item_id"); if(tags.length === 0) return 0; let deleteTag = sql("tags"); let dtags = 0; tags.forEach(tag => { if(["sfw", "nsfw"].includes(tag.tag.toLowerCase())) return dtags; deleteTag = deleteTag.orWhere("id", tag.id); dtags++; }); await deleteTag.del(); return dtags; }; export default async bot => { return [{ name: "f0ck", call: /^\!f0ck .*/i, active: true, level: 100, f: async e => { switch(e.args[0]) { case "stats": const dirs = { b: await fs.readdir("./public/b"), t: await fs.readdir("./public/t"), ca: await fs.readdir("./public/ca") }; const sizes = { b: lib.formatSize((await Promise.all(dirs.b.map( async file => (await fs.stat(`./public/b/${file}`)).size)) ).reduce((a, b) => b + a)), t: lib.formatSize((await Promise.all(dirs.t.map( async file => (await fs.stat(`./public/t/${file}`)).size)) ).reduce((a, b) => b + a)), ca: lib.formatSize((await Promise.all(dirs.ca.map(async file => (await fs.stat(`./public/ca/${file}`)).size))).reduce((a, b) => b + a)), }; return e.reply(`${dirs.b.length} f0cks: ${sizes.b}, ${dirs.t.length} thumbnails: ${sizes.t}, ${dirs.ca.length} coverarts: ${sizes.ca}`); case "limit": return e.reply(`up to ${lib.formatSize(cfg.main.maxfilesize)} (${lib.formatSize(cfg.main.maxfilesize * cfg.main.adminmultiplier)} for admins)`); case "thumb": const rows = await sql("items").select("id"); const dir = (await fs.readdir("./public/t")).filter(d => d.endsWith(".png")).map(e => +e.split(".")[0]); const tmp = []; for(let row of rows) !dir.includes(row.id) ? tmp.push(row.id) : null; e.reply(`${tmp.length}, ${rows.length}, ${dir.length}`); break; case "cache": cfg.websrv.cache = !cfg.websrv.cache; return e.reply(`Cache is ${cfg.websrv.cache ? "enabled" : "disabled"}`); case "uptime": exec('sudo systemctl status f0ck', (err, stdout) => { if(!err) return e.reply(stdout.split('\n')[2].trim().replace("Active: active (running)", "i'm active")); }); break; case "restart": e.reply("hay hay patron, hemen!"); exec("sudo systemctl restart f0ck"); break; case "cleanTags": const tags = await cleanTags(); e.reply(tags + " tags removed"); break; case "clearTmp": await Promise.all((await fs.readdir("./tmp")).filter(d => d !== ".empty").map(async d => fs.unlink(`./tmp/${d}`))); e.reply("cleared lol"); break; case "status": const tmpc = await lib.countf0cks(); e.reply(`tagged: ${tmpc.tagged}; untagged: ${tmpc.untagged}; sfw: ${tmpc.sfw}; nsfw: ${tmpc.nsfw}; total: ${tmpc.total}`); break; case "autotagger": const body = { headers: { Authorization: `Basic ${cfg.tagger.btoa}` } }; const res = await (await fetch(`${cfg.tagger.endpoint}/usage`, body)).json(); if(res) { const processed = res.result.monthly_processed; const limit = res.result.monthly_limit; return e.reply(`autotagger: usage/limit: ${processed}/${limit}`); } return; break; /*case "renameTag": const origTag = e.args.slice(1).join(' '); if(origTag.length <= 1) return e.reply("absichtliche Provokation!"); const origTagID = (await sql('tags').where('tag', origTag))[0].id; const affected = (await sql('tags_assign') .update({ 'tag_id': sql.raw('(select id from tags where tag = ?)', [ origTag ]) }) .whereIn('tag_id', sql.raw('select id from tags where normalized = slugify(?)', [ origTag ])) ).toString(); const deleted = (await sql('tags') .where('normalized', sql.raw('slugify(?)', [ origTag ])) .andWhereNot('id', origTagID) .del() ); e.reply(JSON.stringify({ affected, deleted })); break;*/ case "help": e.reply("cmds: stats, limit, thumb, cache, uptime, restart, cleanTags, clearTmp, status"); break; default: return; } } }] };