Denim-Bot/src/modules/vyhledavac.ts
2023-08-21 23:12:12 +02:00

170 lines
5.7 KiB
TypeScript

import { APIEmbed, CommandInteractionOption, Message, TextBasedChannel } from "discord.js";
import { CClient, Modul } from "../utils/types";
import { createPool } from "mysql";
import { strankovani } from "../utils/utils";
// Připojení do databáze
const pool = createPool({
host: "127.0.0.1",
user: process.env.DBUser,
password: process.env.DBPwd,
database: "zalohaGeneralu",
charset: "utf8mb4_unicode_ci"
});
const zpracovatZpravu = (mes: Message) => new Promise<void>(async (res, rej) => {
if ([6, 7, 8, 9, 10, 11, 18, 23].includes(mes.type)) return res();
if (mes.type != 0 && mes.type != 20 && mes.type != 19) throw new Error("Neznámej message type " + mes.type.toString());
const reference = mes.reference?.messageId;
const attachments: { name: string; file: string; }[] = [];
if (mes.attachments.size != 0) {
for (const [, attachment] of mes.attachments) {
attachments.push({ name: attachment.name, file: attachment.id });
}
}
const sql = `INSERT INTO Zpravy (ID, Content, Author ${reference ? ", Reference" : ""} , Attachments) VALUES (${mes.id}, ?, ${mes.author.id} ${reference ? `,${reference}` : ""} , ?)`;
pool.query({ sql, values: [mes.content, JSON.stringify(attachments)] }, err => {
if (err) rej(err);
res();
});
});
const porovnat = (filtr: CommandInteractionOption): string[] => {
switch (filtr.name) {
case "kontent": return [`Content LIKE ?`, `%${filtr.value}%`];
case "regex": return [`Content REGEXP ?`, `${filtr.value}`];
case "uzivatel": return [`Author=?`, `${filtr.user!.id}`];
case "od":
case "do": {
const datum = new Date(filtr.value as string);
const cislo = (Number(datum) - 1420070400000) * 4194304;
return [`ID ${filtr.name == "od" ? ">" : "<"} ${cislo}`];
}
case "obrasek": return [`${filtr.value ? "" : " NOT"}Attachments REGEXP "\.(png|jpe?g|gif)"`];
case "obrazekOdkaz": return [`${filtr.value ? "" : " NOT"}Content REGEXP "\.(png|jpe?g|gif)"`];
case "link": return [`${filtr.value ? "" : " NOT"}Content REGEXP "https?://"`];
}
return [""];
};
const exp: Modul = {
more_komandy: {
vyhledej: {
run: () => {
const client: CClient = module.exports.client;
return `tuto je novej komand a histmaj mrdal aby to slo i takhle proste pouzij </morevyhledej:${client.slashCommandy["morevyhledej"]}>`;
},
slashRun: async int => {
const moznosti = int.options;
const filtry = moznosti.data;
if (!filtry.length) return "co takhle tam alespon jeden filtr";
// Nelgel kombinace a tak
if (moznosti.get("kontent") && moznosti.get("regex")) return "kontent a regex nejde kombynovat";
const od = moznosti.get("od");
if (od && isNaN(Number(new Date(od.value as string)))) return "od neny platni datum";
const dod = moznosti.get("do");
if (dod && isNaN(Number(new Date(dod.value as string)))) return "do neny platni datum";
const parsedFiltry: string[] = [];
const mista: string[] = [];
let seradit = "DESC";
for (const filtr of filtry) {
if (filtr.name != "seradit") {
const [parsed, misto] = porovnat(filtr);
parsedFiltry.push(parsed);
if (misto) mista.push(misto);
} else {
seradit = filtr.value as string;
}
}
const odpoved = await int.reply("hledam");
const sql = `SELECT CONVERT(ID, CHAR) as idcko, SUBSTRING(Content, 1, 20) AS kontent FROM Zpravy WHERE ${parsedFiltry.join(" AND ")} ORDER BY ID ${seradit}`;
pool.query({ sql, values: mista }, (err, res?: { idcko: string; kontent: string; }[]) => {
if (err) return odpoved.edit(`chyba: ${err}`);
if (!res || !res.length) return odpoved.edit("nic takoviho sem nenasel");
odpoved.edit("nasel sem tuto:");
let celkovadylka = 0;
const stranky: string[][] = [[]];
let aktualniStranka = 0;
for (const row of res) {
const vlozka = `[${row.kontent}] https://discord.com/channels/555779161067749446/555779161067749448/${row.idcko}`;
const dylka = vlozka.length + 3;
celkovadylka += dylka;
if (celkovadylka > 1024 || stranky[aktualniStranka].length == 20) {
aktualniStranka++;
celkovadylka = dylka;
}
const stranka = stranky[aktualniStranka] ??= [];
stranka.push(vlozka);
}
const zacatekNazvu = "visltki";
const embed: APIEmbed = {
color: Math.random() * 16777215,
fields: [{ name: zacatekNazvu, value: `${stranky[0].join("\n• ")}` }]
};
if (stranky.length == 1) return int.channel?.send({ embeds: [embed] });
embed.fields![0].name += ` (1/${stranky.length})`;
strankovani(int.channel!, embed, zacatekNazvu, stranky);
});
}
}
},
on_ready: () => {
const client = module.exports.client as CClient;
client.channels.fetch("555779161067749448")
.then(async ch => {
const channel = ch as TextBasedChannel;
let posledni: string | undefined;
while (true) {
const msgs = await (channel.messages.fetch(posledni ? { before: posledni } : undefined));
for (const [, mes] of msgs) {
try {
await zpracovatZpravu(mes);
} catch {
return;
}
}
posledni = msgs.last()!.id;
// Radši
await new Promise(res => setTimeout(res, 500));
}
});
},
on_messageCreate: (mes: Message) => {
if (mes.channelId == "555779161067749448")
zpracovatZpravu(mes);
}
};
module.exports = exp;