Add heatmap.png generator
This commit is contained in:
parent
42cb268a58
commit
a7cdd91969
|
@ -1,3 +1,4 @@
|
||||||
config.ts
|
config.ts
|
||||||
**/**/Thumbs.db
|
**/**/Thumbs.db
|
||||||
logs
|
logs
|
||||||
|
src/endpoints/gets/heatmap.png
|
||||||
|
|
2
deps.ts
2
deps.ts
|
@ -18,3 +18,5 @@ export { Status, STATUS_TEXT } from "https://deno.land/std@0.137.0/http/http_sta
|
||||||
export { nanoid } from "https://deno.land/x/nanoid@v3.0.0/mod.ts";
|
export { nanoid } from "https://deno.land/x/nanoid@v3.0.0/mod.ts";
|
||||||
|
|
||||||
export { LogTypes as LT, initLog, log } from "https://raw.githubusercontent.com/Burn-E99/Log4Deno/V1.1.1/mod.ts";
|
export { LogTypes as LT, initLog, log } from "https://raw.githubusercontent.com/Burn-E99/Log4Deno/V1.1.1/mod.ts";
|
||||||
|
|
||||||
|
export * as is from "https://deno.land/x/imagescript@v1.2.13/mod.ts";
|
||||||
|
|
7
mod.ts
7
mod.ts
|
@ -79,11 +79,18 @@ startBot({
|
||||||
intervals.updateHourlyRates();
|
intervals.updateHourlyRates();
|
||||||
}, 3600000);
|
}, 3600000);
|
||||||
|
|
||||||
|
// Interval to update heatmap.png every hour
|
||||||
|
setInterval(() => {
|
||||||
|
log(LT.LOG, 'Updating heatmap.png');
|
||||||
|
intervals.updateHeatmapPng();
|
||||||
|
}, 3600000);
|
||||||
|
|
||||||
// setTimeout added to make sure the startup message does not error out
|
// setTimeout added to make sure the startup message does not error out
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
LOCALMODE && editBotNickname(config.devServer, `LOCAL - ${config.name}`);
|
LOCALMODE && editBotNickname(config.devServer, `LOCAL - ${config.name}`);
|
||||||
LOCALMODE ? log(LT.INFO, 'updateListStatistics not running') : intervals.updateListStatistics(botId, cache.guilds.size);
|
LOCALMODE ? log(LT.INFO, 'updateListStatistics not running') : intervals.updateListStatistics(botId, cache.guilds.size);
|
||||||
intervals.updateHourlyRates();
|
intervals.updateHourlyRates();
|
||||||
|
intervals.updateHeatmapPng();
|
||||||
editBotStatus({
|
editBotStatus({
|
||||||
activities: [{
|
activities: [{
|
||||||
name: 'Booting Complete',
|
name: 'Booting Complete',
|
||||||
|
|
|
@ -10,7 +10,7 @@ export const dbClient = await new Client().connect({
|
||||||
password: config.db.password,
|
password: config.db.password,
|
||||||
});
|
});
|
||||||
|
|
||||||
const weekDays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
|
export const weekDays = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
|
||||||
|
|
||||||
export const queries = {
|
export const queries = {
|
||||||
insertRollLogCmd: (api: number, error: number) => `INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,${api},${error})`,
|
insertRollLogCmd: (api: number, error: number) => `INSERT INTO roll_log(input,result,resultid,api,error) values(?,?,?,${api},${error})`,
|
||||||
|
|
112
src/intervals.ts
112
src/intervals.ts
|
@ -8,12 +8,14 @@ import {
|
||||||
// Discordeno deps
|
// Discordeno deps
|
||||||
cache,
|
cache,
|
||||||
cacheHandlers,
|
cacheHandlers,
|
||||||
|
// imagescript
|
||||||
|
is,
|
||||||
// Log4Deno deps
|
// Log4Deno deps
|
||||||
log,
|
log,
|
||||||
LT,
|
LT,
|
||||||
} from '../deps.ts';
|
} from '../deps.ts';
|
||||||
import { PastCommandCount } from './mod.d.ts';
|
import { PastCommandCount } from './mod.d.ts';
|
||||||
import { dbClient } from './db.ts';
|
import { dbClient, weekDays } from './db.ts';
|
||||||
import utils from './utils.ts';
|
import utils from './utils.ts';
|
||||||
import config from '../config.ts';
|
import config from '../config.ts';
|
||||||
|
|
||||||
|
@ -41,7 +43,7 @@ const getRandomStatus = async (): Promise<string> => {
|
||||||
return status;
|
return status;
|
||||||
};
|
};
|
||||||
|
|
||||||
// updateListStatistics(bot ID, current guild count) returns nothing
|
// updateListStatistics(bot ID, current guild count) returns nothing, posts to botlists
|
||||||
// Sends the current server count to all bot list sites we are listed on
|
// Sends the current server count to all bot list sites we are listed on
|
||||||
const updateListStatistics = (botID: bigint, serverCount: number): void => {
|
const updateListStatistics = (botID: bigint, serverCount: number): void => {
|
||||||
config.botLists.forEach(async (e) => {
|
config.botLists.forEach(async (e) => {
|
||||||
|
@ -64,11 +66,11 @@ const updateListStatistics = (botID: bigint, serverCount: number): void => {
|
||||||
// Keep one week of data
|
// Keep one week of data
|
||||||
const hoursToKeep = 7 * 24;
|
const hoursToKeep = 7 * 24;
|
||||||
const previousHours: Array<Array<PastCommandCount>> = [];
|
const previousHours: Array<Array<PastCommandCount>> = [];
|
||||||
// updateHourlyRates() returns nothing
|
// updateHourlyRates() returns nothing, updates DB directly
|
||||||
// Updates the hourlyRate for command usage
|
// Updates the hourlyRate for command usage
|
||||||
const updateHourlyRates = async () => {
|
const updateHourlyRates = async () => {
|
||||||
try {
|
try {
|
||||||
const newestHour = await dbClient.query(`SELECT command, count FROM command_cnt ORDER BY command;`).catch((e) => utils.commonLoggers.dbError('intervals.ts:71', 'query', e));
|
const newestHour = await dbClient.query('SELECT command, count FROM command_cnt ORDER BY command;').catch((e) => utils.commonLoggers.dbError('intervals.ts:71', 'query', e));
|
||||||
previousHours.push(newestHour);
|
previousHours.push(newestHour);
|
||||||
if (previousHours.length > 1) {
|
if (previousHours.length > 1) {
|
||||||
const oldestHour = previousHours[0];
|
const oldestHour = previousHours[0];
|
||||||
|
@ -99,4 +101,104 @@ const updateHourlyRates = async () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default { getRandomStatus, updateListStatistics, updateHourlyRates };
|
// getPercentOfRange(min, max, val) returns number
|
||||||
|
// Gets a percent value of where val lies in the min-max range
|
||||||
|
const getPercentOfRange = (minVal: number, maxVal: number, val: number): number => {
|
||||||
|
const localMax = maxVal - minVal;
|
||||||
|
const localVal = val - minVal;
|
||||||
|
|
||||||
|
return localVal / localMax;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pixel locations in heatmap-base.png, pixel locations are 0 based
|
||||||
|
// dayPixels holds the left and right (AKA X Coord) pixel locations for each col (ex: [leftPX, rightPX])
|
||||||
|
const dayPixels: Array<Array<number>> = [
|
||||||
|
[72, 159],
|
||||||
|
[163, 260],
|
||||||
|
[264, 359],
|
||||||
|
[363, 497],
|
||||||
|
[501, 608],
|
||||||
|
[612, 686],
|
||||||
|
[690, 800],
|
||||||
|
];
|
||||||
|
// hourPixels holds the top and bottom (AKA Y Coord) pixel locations for each row (ex: [topPX, botPX])
|
||||||
|
const hourPixels: Array<Array<number>> = [
|
||||||
|
[29, 49],
|
||||||
|
[51, 72],
|
||||||
|
[74, 95],
|
||||||
|
[97, 118],
|
||||||
|
[120, 141],
|
||||||
|
[143, 164],
|
||||||
|
[166, 187],
|
||||||
|
[189, 209],
|
||||||
|
[211, 232],
|
||||||
|
[234, 254],
|
||||||
|
[256, 277],
|
||||||
|
[279, 299],
|
||||||
|
[301, 322],
|
||||||
|
[324, 345],
|
||||||
|
[347, 368],
|
||||||
|
[370, 391],
|
||||||
|
[393, 413],
|
||||||
|
[415, 436],
|
||||||
|
[438, 459],
|
||||||
|
[461, 482],
|
||||||
|
[484, 505],
|
||||||
|
[507, 528],
|
||||||
|
[530, 550],
|
||||||
|
[552, 572],
|
||||||
|
];
|
||||||
|
// updateHeatmap() returns nothing, creates new heatmap.png
|
||||||
|
// Updates the heatmap image with latest data from the db
|
||||||
|
const updateHeatmapPng = async () => {
|
||||||
|
const baseHeatmap = Deno.readFileSync('./src/endpoints/gets/heatmap-base.png');
|
||||||
|
const heatmap = await is.decode(baseHeatmap);
|
||||||
|
if (heatmap instanceof is.Image) {
|
||||||
|
// Get latest data from DB
|
||||||
|
const heatmapData = await dbClient.query('SELECT * FROM roll_time_heatmap ORDER BY hour;').catch((e) => utils.commonLoggers.dbError('intervals.ts:148', 'query', e));
|
||||||
|
|
||||||
|
let minRollCnt = Infinity;
|
||||||
|
let maxRollCnt = 0;
|
||||||
|
// determine min and max values
|
||||||
|
for (let hour = 0; hour < heatmapData.length; hour++) {
|
||||||
|
for (let day = 0; day < weekDays.length; day++) {
|
||||||
|
const rollCnt = heatmapData[hour][weekDays[day]];
|
||||||
|
log(LT.LOG, `updateHeatmapPng | finding min/max | min: ${minRollCnt} max: ${maxRollCnt} curr: ${rollCnt}`);
|
||||||
|
if (rollCnt > maxRollCnt) {
|
||||||
|
maxRollCnt = rollCnt;
|
||||||
|
}
|
||||||
|
if (rollCnt < minRollCnt) {
|
||||||
|
minRollCnt = rollCnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply values to image
|
||||||
|
for (let hour = 0; hour < heatmapData.length; hour++) {
|
||||||
|
for (let day = 0; day < weekDays.length; day++) {
|
||||||
|
log(LT.LOG, `updateHeatmapPng | putting ${weekDays[day]} ${hour}:00 into image`);
|
||||||
|
const percent = getPercentOfRange(minRollCnt, maxRollCnt, heatmapData[hour][weekDays[day]]);
|
||||||
|
heatmap.drawBox(
|
||||||
|
dayPixels[day][0] + 1,
|
||||||
|
hourPixels[hour][0] + 1,
|
||||||
|
dayPixels[day][1] - dayPixels[day][0] + 1,
|
||||||
|
hourPixels[hour][1] - hourPixels[hour][0] + 1,
|
||||||
|
is.Image.rgbToColor(
|
||||||
|
255 * (1 - percent),
|
||||||
|
255 * percent,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Deno.writeFileSync('./src/endpoints/gets/heatmap.png', await heatmap.encode());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getRandomStatus,
|
||||||
|
updateListStatistics,
|
||||||
|
updateHourlyRates,
|
||||||
|
updateHeatmapPng,
|
||||||
|
};
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
deno run --allow-write=./logs/ --allow-read=./src/solver/ --allow-net .\mod.ts
|
deno run --allow-write=./logs/,./src/endpoints/gets/heatmap.png --allow-read=./src/solver/,./src/endpoints/gets/heatmap-base.png --allow-net .\mod.ts
|
Loading…
Reference in New Issue