From 8e6467fd17600befd60322aa2f418319051be59e Mon Sep 17 00:00:00 2001 From: "Ean Milligan (Bastion)" Date: Sun, 26 Jun 2022 20:18:41 -0400 Subject: [PATCH] Continued work on heatmap --- README.md | 2 + config.example.ts | 1 + src/api.ts | 219 ++++++++++++++-------------- src/commands/heatmap.ts | 35 +++-- src/commands/help.ts | 5 + src/commands/stats.ts | 6 +- src/endpoints/_index.ts | 2 + src/endpoints/gets/heatmap-base.png | Bin 0 -> 58111 bytes src/endpoints/gets/heatmapPng.ts | 16 ++ src/intervals.ts | 10 +- 10 files changed, 170 insertions(+), 126 deletions(-) create mode 100644 src/endpoints/gets/heatmap-base.png create mode 100644 src/endpoints/gets/heatmapPng.ts diff --git a/README.md b/README.md index 7589dee..df465de 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ The Artificer comes with a few supplemental commands to the main rolling command * If bot is given the permission `Manage Messages`, the bot will remove the message requesting the emote. * `[[stats` or `[[s` * Prints out how many users, channels, and servers the bot is currently serving. +* `[[heatmap` or `[[hm` + * Heatmap of when the roll command is run the most. * `[[report` or `[[r [command that failed]` * People aren't perfect, but this bot is trying to be. * If you encounter a command that errors out or returns something unexpected, please use this command to alert the developers of the problem. diff --git a/config.example.ts b/config.example.ts index b984208..d878025 100644 --- a/config.example.ts +++ b/config.example.ts @@ -12,6 +12,7 @@ export const config = { }, "api": { // Setting for the built-in API "enable": false, // Leave this off if you have no intention of using this/supporting it + "publicDomain": 'http://example.com/', // Public domain that the API is behind, should end with a / "port": 8080, // Port for the API to listen on "supportURL": "your_support_url_for_api_abuse", // Fill this in with the way you wish to be contacted when somebody needs to report API key abuse "rateLimitTime": 10000, // Time range for how often the API rate limits will be lifted (time in ms) diff --git a/src/api.ts b/src/api.ts index a187a81..bd0549e 100644 --- a/src/api.ts +++ b/src/api.ts @@ -91,114 +91,121 @@ const start = async (): Promise => { }); } - if (authenticated) { - // Handle the authenticated request - switch (request.method) { - case 'GET': - switch (path.toLowerCase()) { - case '/key': - case '/key/': - endpoints.get.apiKeyAdmin(requestEvent, query, apiUserid); - break; - case '/channel': - case '/channel/': - endpoints.get.apiChannel(requestEvent, query, apiUserid); - break; - case '/roll': - case '/roll/': - endpoints.get.apiRoll(requestEvent, query, apiUserid); - break; - default: - // Alert API user that they messed up - requestEvent.respondWith(stdResp.NotFound('Auth Get')); - break; - } - break; - case 'POST': - switch (path.toLowerCase()) { - case '/channel/add': - case '/channel/add/': - endpoints.post.apiChannelAdd(requestEvent, query, apiUserid); - break; - default: - // Alert API user that they messed up - requestEvent.respondWith(stdResp.NotFound('Auth Post')); - break; - } - break; - case 'PUT': - switch (path.toLowerCase()) { - case '/key/ban': - case '/key/ban/': - case '/key/unban': - case '/key/unban/': - case '/key/activate': - case '/key/activate/': - case '/key/deactivate': - case '/key/deactivate/': - endpoints.put.apiKeyManage(requestEvent, query, apiUserid, path); - break; - case '/channel/ban': - case '/channel/ban/': - case '/channel/unban': - case '/channel/unban/': - endpoints.put.apiChannelManageBan(requestEvent, query, apiUserid, path); - break; - case '/channel/activate': - case '/channel/activate/': - case '/channel/deactivate': - case '/channel/deactivate/': - endpoints.put.apiChannelManageActive(requestEvent, query, apiUserid, path); - break; - default: - // Alert API user that they messed up - requestEvent.respondWith(stdResp.NotFound('Auth Put')); - break; - } - break; - case 'DELETE': - switch (path.toLowerCase()) { - case '/key/delete': - case '/key/delete/': - endpoints.delete.apiKeyDelete(requestEvent, query, apiUserid, apiUserEmail, apiUserDelCode); - break; - default: - // Alert API user that they messed up - requestEvent.respondWith(stdResp.NotFound('Auth Del')); - break; - } - break; - default: - // Alert API user that they messed up - requestEvent.respondWith(stdResp.MethodNotAllowed('Auth')); - break; - } + if (path) { + if (authenticated) { + // Handle the authenticated request + switch (request.method) { + case 'GET': + switch (path.toLowerCase()) { + case '/key': + case '/key/': + endpoints.get.apiKeyAdmin(requestEvent, query, apiUserid); + break; + case '/channel': + case '/channel/': + endpoints.get.apiChannel(requestEvent, query, apiUserid); + break; + case '/roll': + case '/roll/': + endpoints.get.apiRoll(requestEvent, query, apiUserid); + break; + default: + // Alert API user that they messed up + requestEvent.respondWith(stdResp.NotFound('Auth Get')); + break; + } + break; + case 'POST': + switch (path.toLowerCase()) { + case '/channel/add': + case '/channel/add/': + endpoints.post.apiChannelAdd(requestEvent, query, apiUserid); + break; + default: + // Alert API user that they messed up + requestEvent.respondWith(stdResp.NotFound('Auth Post')); + break; + } + break; + case 'PUT': + switch (path.toLowerCase()) { + case '/key/ban': + case '/key/ban/': + case '/key/unban': + case '/key/unban/': + case '/key/activate': + case '/key/activate/': + case '/key/deactivate': + case '/key/deactivate/': + endpoints.put.apiKeyManage(requestEvent, query, apiUserid, path); + break; + case '/channel/ban': + case '/channel/ban/': + case '/channel/unban': + case '/channel/unban/': + endpoints.put.apiChannelManageBan(requestEvent, query, apiUserid, path); + break; + case '/channel/activate': + case '/channel/activate/': + case '/channel/deactivate': + case '/channel/deactivate/': + endpoints.put.apiChannelManageActive(requestEvent, query, apiUserid, path); + break; + default: + // Alert API user that they messed up + requestEvent.respondWith(stdResp.NotFound('Auth Put')); + break; + } + break; + case 'DELETE': + switch (path.toLowerCase()) { + case '/key/delete': + case '/key/delete/': + endpoints.delete.apiKeyDelete(requestEvent, query, apiUserid, apiUserEmail, apiUserDelCode); + break; + default: + // Alert API user that they messed up + requestEvent.respondWith(stdResp.NotFound('Auth Del')); + break; + } + break; + default: + // Alert API user that they messed up + requestEvent.respondWith(stdResp.MethodNotAllowed('Auth')); + break; + } - // Update rate limit details - if (updateRateLimitTime) { - const apiTimeNow = new Date().getTime(); - rateLimitTime.set(apiUseridStr, apiTimeNow); - } - } else if (!authenticated) { - // Handle the unathenticated request - switch (request.method) { - case 'GET': - switch (path.toLowerCase()) { - case '/key': - case '/key/': - endpoints.get.apiKey(requestEvent, query); - break; - default: - // Alert API user that they messed up - requestEvent.respondWith(stdResp.NotFound('NoAuth Get')); - break; - } - break; - default: - // Alert API user that they messed up - requestEvent.respondWith(stdResp.MethodNotAllowed('NoAuth')); - break; + // Update rate limit details + if (updateRateLimitTime) { + const apiTimeNow = new Date().getTime(); + rateLimitTime.set(apiUseridStr, apiTimeNow); + } + } else if (!authenticated) { + // Handle the unathenticated request + switch (request.method) { + case 'GET': + switch (path.toLowerCase()) { + case '/key': + case '/key/': + endpoints.get.apiKey(requestEvent, query); + break; + case '/heatmap.png': + endpoints.get.heatmapPng(requestEvent); + break; + default: + // Alert API user that they messed up + requestEvent.respondWith(stdResp.NotFound('NoAuth Get')); + break; + } + break; + default: + // Alert API user that they messed up + requestEvent.respondWith(stdResp.MethodNotAllowed('NoAuth')); + break; + } } + } else { + requestEvent.respondWith(stdResp.Forbidden('What are you trying to do?')); } } else if (authenticated && rateLimited) { // Alert API user that they are doing this too often diff --git a/src/commands/heatmap.ts b/src/commands/heatmap.ts index 23f193d..c851e34 100644 --- a/src/commands/heatmap.ts +++ b/src/commands/heatmap.ts @@ -3,25 +3,34 @@ import { // Discordeno deps DiscordenoMessage, } from '../../deps.ts'; -import { } from '../commandUtils.ts'; -import { compilingStats } from '../commonEmbeds.ts'; +import config from '../../config.ts'; +import { LOCALMODE } from '../../flags.ts'; +import { failColor, infoColor2 } from '../commandUtils.ts'; import utils from '../utils.ts'; export const heatmap = async (message: DiscordenoMessage) => { // Light telemetry to see how many times a command is being run dbClient.execute(queries.callIncCnt('heatmap')).catch((e) => utils.commonLoggers.dbError('heatmap.ts:14', 'call sproc INC_CNT on', e)); - try { - const m = await message.send(compilingStats); + if (config.api.enable) { + const m = await message.send({ + embeds: [{ + title: 'Roll Heatmap', + color: infoColor2, + image: { + url: `${config.api.publicDomain}api/heatmap.png`, + }, + }], + }).catch((e) => utils.commonLoggers.messageSendError('heatmap.ts:21', message, e)); - // Calculate how many times commands have been run - const hmQuery = await dbClient.query(`SELECT * FROM roll_time_heatmap`).catch((e) => utils.commonLoggers.dbError('heatmap.ts:20', 'query', e)); - console.log(hmQuery); - - m.edit('').catch((e: Error) => - utils.commonLoggers.messageEditError('heatmap.ts:21', m, e) - ); - } catch (e) { - utils.commonLoggers.messageSendError('heatmap.ts:24', message, e); + console.log(m); + } else { + message.send({ + embeds: [{ + title: 'Roll Heatmap Disabled', + description: 'This command requires the bot\'s API to be enabled. If you are the host of this bot, check your `config.ts` file to enable it.', + color: failColor, + }], + }).catch((e) => utils.commonLoggers.messageSendError('heatmap.ts:21', message, e)); } }; diff --git a/src/commands/help.ts b/src/commands/help.ts index e91eaa4..a6ed395 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -66,6 +66,11 @@ export const help = (message: DiscordenoMessage) => { value: 'Statistics on the bot', inline: true, }, + { + name: `\`${config.prefix}heatmap\``, + value: 'Heatmap of when the roll command is run the most', + inline: true, + }, { name: `\`${config.prefix}xdydzracsq!${config.postfix}\` ...`, value: diff --git a/src/commands/stats.ts b/src/commands/stats.ts index 1e26cd5..9aeb3af 100644 --- a/src/commands/stats.ts +++ b/src/commands/stats.ts @@ -27,9 +27,9 @@ export const stats = async (message: DiscordenoMessage) => { const cachedGuilds = await cacheHandlers.size('guilds'); const cachedChannels = await cacheHandlers.size('channels'); const cachedMembers = await cacheHandlers.size('members'); - m.edit(generateStats(cachedGuilds + cache.dispatchedGuildIds.size, cachedChannels + cache.dispatchedChannelIds.size, cachedMembers, rolls, (total - rolls), rollRate, (totalRate - rollRate))).catch((e: Error) => - utils.commonLoggers.messageEditError('stats.ts:38', m, e) - ); + m.edit(generateStats(cachedGuilds + cache.dispatchedGuildIds.size, cachedChannels + cache.dispatchedChannelIds.size, cachedMembers, rolls, total - rolls, rollRate, totalRate - rollRate)).catch(( + e: Error, + ) => utils.commonLoggers.messageEditError('stats.ts:38', m, e)); } catch (e) { utils.commonLoggers.messageSendError('stats.ts:41', message, e); } diff --git a/src/endpoints/_index.ts b/src/endpoints/_index.ts index 8fc0bcf..c621ed7 100644 --- a/src/endpoints/_index.ts +++ b/src/endpoints/_index.ts @@ -3,6 +3,7 @@ import { apiKey } from './gets/apiKey.ts'; import { apiRoll } from './gets/apiRoll.ts'; import { apiKeyAdmin } from './gets/apiKeyAdmin.ts'; import { apiChannel } from './gets/apiChannel.ts'; +import { heatmapPng } from './gets/heatmapPng.ts'; import { apiChannelAdd } from './posts/apiChannelAdd.ts'; import { apiKeyManage } from './puts/apiKeyManage.ts'; import { apiChannelManageBan } from './puts/apiChannelManageBan.ts'; @@ -17,6 +18,7 @@ export default { apiRoll, apiKeyAdmin, apiChannel, + heatmapPng, }, post: { apiChannelAdd, diff --git a/src/endpoints/gets/heatmap-base.png b/src/endpoints/gets/heatmap-base.png new file mode 100644 index 0000000000000000000000000000000000000000..68a5cc728437f438eb0e240927049ee9218f3a4c GIT binary patch literal 58111 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 literal 0 HcmV?d00001 diff --git a/src/endpoints/gets/heatmapPng.ts b/src/endpoints/gets/heatmapPng.ts new file mode 100644 index 0000000..352d429 --- /dev/null +++ b/src/endpoints/gets/heatmapPng.ts @@ -0,0 +1,16 @@ +import { + // httpd deps + Status, + STATUS_TEXT, +} from '../../../deps.ts'; + +export const heatmapPng = async (requestEvent: Deno.RequestEvent) => { + const file = Deno.readFileSync('./src/endpoints/gets/heatmap.png'); + // Send basic OK to indicate key has been sent + requestEvent.respondWith( + new Response(file, { + status: Status.OK, + statusText: STATUS_TEXT.get(Status.OK), + }), + ); +}; diff --git a/src/intervals.ts b/src/intervals.ts index e0c9b7e..5426b5d 100644 --- a/src/intervals.ts +++ b/src/intervals.ts @@ -63,7 +63,7 @@ const updateListStatistics = (botID: bigint, serverCount: number): void => { // Keep one week of data const hoursToKeep = 7 * 24; -const previousHours: Array> = [] +const previousHours: Array> = []; // updateHourlyRates() returns nothing // Updates the hourlyRate for command usage const updateHourlyRates = async () => { @@ -73,7 +73,7 @@ const updateHourlyRates = async () => { if (previousHours.length > 1) { const oldestHour = previousHours[0]; - const computedDiff: Array = [] + const computedDiff: Array = []; for (let i = 0; i < newestHour.length; i++) { computedDiff.push({ command: newestHour[i].command, @@ -85,7 +85,9 @@ const updateHourlyRates = async () => { // Update DB computedDiff.forEach(async (cmd) => { log(LT.LOG, `Updating hourlyRate | Storing to DB: ${JSON.stringify(cmd)}`); - await dbClient.execute(`UPDATE command_cnt SET hourlyRate = ? WHERE command = ?`, [(cmd.count / previousHours.length), cmd.command]).catch((e) => utils.commonLoggers.dbError('intervals.ts:88', 'update', e)); + await dbClient.execute(`UPDATE command_cnt SET hourlyRate = ? WHERE command = ?`, [cmd.count / previousHours.length, cmd.command]).catch((e) => + utils.commonLoggers.dbError('intervals.ts:88', 'update', e) + ); }); } @@ -93,7 +95,7 @@ const updateHourlyRates = async () => { previousHours.unshift(); } } catch (e) { - log(LT.ERROR, `Something went wrong in previousHours interval | Error: ${e.name} - ${e.message}`) + log(LT.ERROR, `Something went wrong in previousHours interval | Error: ${e.name} - ${e.message}`); } };