perf: threads everywhere! (for encryption & decryption)

This commit is contained in:
Isaac
2025-02-12 04:26:15 +00:00
parent 5a908e77a7
commit d99cb202d5
16 changed files with 529 additions and 424 deletions

View File

@@ -5,8 +5,7 @@ const {
} = require('discord.js');
const { isStaff } = require('../../lib/users');
const ExtendedEmbedBuilder = require('../../lib/embed');
const Cryptr = require('cryptr');
const { decrypt } = new Cryptr(process.env.ENCRYPTION_KEY);
const { reusable } = require('../../lib/threads');
module.exports = class TicketsSlashCommand extends SlashCommand {
constructor(client, options) {
@@ -116,33 +115,44 @@ module.exports = class TicketsSlashCommand extends SlashCommand {
},
});
if (open.length >= 1) {
fields.push({
name: getMessage('commands.slash.tickets.response.fields.open.name'),
value: open.map(ticket => {
const topic = ticket.topic ? `- \`${decrypt(ticket.topic).replace(/\n/g, ' ').slice(0, 30)}\`` : '';
return `> <#${ticket.id}> ${topic}`;
}).join('\n'),
});
}
const worker = await reusable('crypto');
try {
if (open.length >= 1) {
fields.push({
name: getMessage('commands.slash.tickets.response.fields.open.name'),
value: (await Promise.all(
open.map(async ticket => {
const getTopic = async () => (await worker.decrypt(ticket.topic)).replace(/\n/g, ' ').substring(0, 30);
const topic = ticket.topic ? `- \`${await getTopic()}\`` : '';
return `> <#${ticket.id}> ${topic}`;
}),
)).join('\n'),
});
}
if (closed.length === 0) {
const newCommand = client.application.commands.cache.find(c => c.name === 'new');
fields.push({
name: getMessage('commands.slash.tickets.response.fields.closed.name'),
value: getMessage(`commands.slash.tickets.response.fields.closed.none.${ownOrOther}`, {
new: `</${newCommand.name}:${newCommand.id}>`,
user: member.user.toString(),
}),
});
} else {
fields.push({
name: getMessage('commands.slash.tickets.response.fields.closed.name'),
value: closed.map(ticket => {
const topic = ticket.topic ? `- \`${decrypt(ticket.topic).replace(/\n/g, ' ').slice(0, 30)}\`` : '';
return `> ${ticket.category.name} #${ticket.number} (\`${ticket.id}\`) ${topic}`;
}).join('\n'),
});
if (closed.length === 0) {
const newCommand = client.application.commands.cache.find(c => c.name === 'new');
fields.push({
name: getMessage('commands.slash.tickets.response.fields.closed.name'),
value: getMessage(`commands.slash.tickets.response.fields.closed.none.${ownOrOther}`, {
new: `</${newCommand.name}:${newCommand.id}>`,
user: member.user.toString(),
}),
});
} else {
fields.push({
name: getMessage('commands.slash.tickets.response.fields.closed.name'),
value: (await Promise.all(
closed.map(async ticket => {
const getTopic = async () => (await worker.decrypt(ticket.topic)).replace(/\n/g, ' ').substring(0, 30);
const topic = ticket.topic ? `- \`${await getTopic()}\`` : '';
return `> ${ticket.category.name} #${ticket.number} (\`${ticket.id}\`) ${topic}`;
}),
)).join('\n'),
});
}
} finally {
await worker.terminate();
}
// TODO: add portal URL to view all (this list is limited to the last 10)

View File

@@ -5,9 +5,8 @@ const {
TextInputBuilder,
TextInputStyle,
} = require('discord.js');
const Cryptr = require('cryptr');
const { decrypt } = new Cryptr(process.env.ENCRYPTION_KEY);
const ExtendedEmbedBuilder = require('../../lib/embed');
const { quick } = require('../../lib/threads');
module.exports = class TopicSlashCommand extends SlashCommand {
constructor(client, options) {
@@ -66,7 +65,8 @@ module.exports = class TopicSlashCommand extends SlashCommand {
.setPlaceholder(getMessage('modals.topic.placeholder'))
.setRequired(true);
if (ticket.topic) field.setValue(decrypt(ticket.topic)); // why can't discord.js accept null or undefined :(
// why can't discord.js accept null or undefined :(
if (ticket.topic) field.setValue(await quick('crypto', w => w.decrypt(ticket.topic)));
await interaction.showModal(
new ModalBuilder()

View File

@@ -7,9 +7,8 @@ const fs = require('fs');
const { join } = require('path');
const Mustache = require('mustache');
const { AttachmentBuilder } = require('discord.js');
const Cryptr = require('cryptr');
const { decrypt } = new Cryptr(process.env.ENCRYPTION_KEY);
const ExtendedEmbedBuilder = require('../../lib/embed');
const { quick } = require('../../lib/threads');
module.exports = class TranscriptSlashCommand extends SlashCommand {
constructor(client, options) {
@@ -61,31 +60,9 @@ module.exports = class TranscriptSlashCommand extends SlashCommand {
/** @type {import("client")} */
const client = this.client;
ticket.claimedBy = ticket.archivedUsers.find(u => u.userId === ticket.claimedById);
ticket.closedBy = ticket.archivedUsers.find(u => u.userId === ticket.closedById);
ticket.createdBy = ticket.archivedUsers.find(u => u.userId === ticket.createdById);
if (ticket.closedReason) ticket.closedReason = decrypt(ticket.closedReason);
if (ticket.feedback?.comment) ticket.feedback.comment = decrypt(ticket.feedback.comment);
if (ticket.topic) ticket.topic = decrypt(ticket.topic).replace(/\n/g, '\n\t');
ticket.archivedUsers.forEach((user, i) => {
if (user.displayName) user.displayName = decrypt(user.displayName);
user.username = decrypt(user.username);
ticket.archivedUsers[i] = user;
});
ticket.archivedMessages.forEach((message, i) => {
message.author = ticket.archivedUsers.find(u => u.userId === message.authorId);
message.content = JSON.parse(decrypt(message.content));
message.text = message.content.content?.replace(/\n/g, '\n\t') ?? '';
message.content.attachments?.forEach(a => (message.text += '\n\t' + a.url));
message.content.embeds?.forEach(() => (message.text += '\n\t[embedded content]'));
message.number = 'M' + String(i + 1).padStart(ticket.archivedMessages.length.toString().length, '0');
ticket.archivedMessages[i] = message;
});
ticket.pinnedMessageIds = ticket.pinnedMessageIds.map(id => ticket.archivedMessages.find(message => message.id === id)?.number);
// TODO: use a pool of multiple threads
// this is still slow for lots of messages
ticket = await quick('transcript', w => w(ticket));
const channelName = ticket.category.channelName
.replace(/{+\s?(user)?name\s?}+/gi, ticket.createdBy?.username)

View File

@@ -3,8 +3,8 @@ const {
ApplicationCommandOptionType,
EmbedBuilder,
} = require('discord.js');
const Cryptr = require('cryptr');
const { decrypt } = new Cryptr(process.env.ENCRYPTION_KEY);
const { quick } = require('../../lib/threads');
module.exports = class TransferSlashCommand extends SlashCommand {
constructor(client, options) {
@@ -71,7 +71,7 @@ module.exports = class TransferSlashCommand extends SlashCommand {
}),
interaction.channel.edit({
name: channelName,
topic: `${member.toString()}${ticket.topic?.length > 0 ? ` | ${decrypt(ticket.topic)}` : ''}`,
topic: `${member.toString()}${ticket.topic && ` | ${await quick('crypto', w => w.decrypt(ticket.topic))}`}`,
}),
interaction.channel.permissionOverwrites.edit(
member,