/* eslint-disable no-eval */ import Bull from 'bull'; import cron from 'cron'; import { TextableChannel } from 'eris'; import { Client, RichEmbed } from '.'; import { ScoreInterface } from '../models'; import { apply as Apply } from '../commands'; export default class Queue { public client: Client; public queues: { score: Bull.Queue }; constructor(client: Client) { this.client = client; this.queues = { score: new Bull('score', { prefix: 'queue::score' }), }; this.setProcessors(); this.setCronJobs(); } protected setCronJobs() { const historialCommunityReportJob = new cron.CronJob('0 20 * * *', async () => { try { const reports = await this.client.db.Score.find().lean().exec(); const startDate = new Date(); for (const report of reports) { const data = new this.client.db.ScoreHistorical({ userID: report.userID, report, date: startDate, }); // eslint-disable-next-line no-await-in-loop await data.save(); } } catch (err) { this.client.util.handleError(err); } }); historialCommunityReportJob.start(); } public async jobCounts() { const data = { waiting: 0, active: 0, completed: 0, failed: 0, delayed: 0, }; for (const entry of Object.entries(this.queues)) { // eslint-disable-next-line no-await-in-loop const counts = await entry[1].getJobCounts(); data.waiting += counts.waiting; data.active += counts.active; data.completed += counts.completed; data.failed += counts.failed; data.delayed += counts.delayed; } return data; } protected listeners() { this.queues.score.on('active', (job) => { this.client.util.signale.pending(`${job.id} has become active.`); }); this.queues.score.on('completed', (job) => { this.client.util.signale.success(`Job with id ${job.id} has been completed`); }); this.queues.score.on('error', async (err) => { this.client.util.handleError(err); }); } protected setProcessors() { this.queues.score.process('score::update', async (job: Bull.Job<{ score: ScoreInterface, total: number, activity: number, roles: number, moderation: number, cloudServices: number, other: number, staff: number }>) => { await this.client.db.Score.updateOne({ userID: job.data.score.userID }, { $set: { total: job.data.total, activity: job.data.activity, roles: job.data.roles, moderation: job.data.moderation, cloudServices: job.data.cloudServices, other: job.data.other, staff: job.data.staff, lastUpdate: new Date() } }); if (!job.data.score.pin || job.data.score.pin?.length < 1) { await this.client.db.Score.updateOne({ userID: job.data.score.userID }, { $set: { pin: [this.client.util.randomNumber(100, 999), this.client.util.randomNumber(10, 99), this.client.util.randomNumber(1000, 9999)] } }); } }); this.queues.score.process('score::apply', async (job: Bull.Job<{ channelInformation: { messageID: string, guildID: string, channelID: string }, url: string, userID: string, func?: string }>) => { const application = await Apply.apply(this.client, job.data.url, job.data.userID); const guild = this.client.guilds.get(job.data.channelInformation.guildID); const channel = guild.channels.get(job.data.channelInformation.channelID); const message = await channel.getMessage(job.data.channelInformation.messageID); const member = guild.members.get(job.data.userID); await message.delete(); const embed = new RichEmbed(); embed.setTitle('Application Decision'); if (member) { embed.setAuthor(member.username, member.avatarURL); } if (application.decision === 'APPROVED') { embed.setColor('#50c878'); } else if (application.decision === 'DECLINED') { embed.setColor('#fe0000'); } else if (application.decision === 'PRE-DECLINE') { embed.setColor('#ffa500'); } else { embed.setColor('#eeeeee'); } const chan = await this.client.getDMChannel(job.data.userID); if (chan && application.token) { chan.createMessage(`__**Application Decision Document**__\n*This document provides detailed information about the decision given to you by EDS.*\n\nhttps://eds.libraryofcode.org/dec/${application.token}`); } embed.setDescription(`This application was processed by __${application.processedBy}__ on behalf of the vendor, department, or service who operates this application. Please contact the vendor for further information about your application if needed.`); embed.addField('Status', application.decision, true); embed.addField('User ID', job.data.userID, true); embed.addField('Application ID', application.id, true); embed.addField('Job ID', job.id.toString(), true); embed.setFooter(`${this.client.user.username} via Electronic Decision Service [EDS]`, this.client.user.avatarURL); embed.setTimestamp(); await channel.createMessage({ content: `<@${job.data.userID}>`, embed }); if (job.data.func) { const func = eval(job.data.func); if (application.status === 'SUCCESS' && application.decision === 'APPROVED') await func(this.client, job.data.userID); } }); } public updateScore(score: ScoreInterface, total: number, activity: number, roles: number, moderation: number, cloudServices: number, other: number, staff: number) { this.queues.score.add('score::update', { score, total, activity, roles, moderation, cloudServices, other, staff }); } public processApplication(channelInformation: { messageID: string, guildID: string, channelID: string }, url: string, userID: string, func?: string) { return this.queues.score.add('score::apply', { channelInformation, url, userID, func }); } }