mirror of
https://github.com/thedrewen/protojx-manager.git
synced 2026-03-21 09:48:56 +01:00
feat: add canvas dependency and implement uptime bar image generation
- Added 'canvas' dependency to package.json and package-lock.json. - Updated getUpdatedContainer method in StatusService to be asynchronous. - Implemented getStatusImageBar method in StatusService to generate a visual representation of uptime data. - Modified live_status.command.ts and statut.command.ts to await the updated container. - Created test.ts to demonstrate uptime bar generation and save it as an image. - Updated tsconfig.json to target ES2024 and include relevant libraries.
This commit is contained in:
@@ -28,7 +28,7 @@ const cmd : CommandDefinition = {
|
||||
if(channel?.isSendable()) {
|
||||
let message;
|
||||
try {
|
||||
message = await channel.send({components: [statusService.getUpdatedContainer(true)], flags: [MessageFlags.IsComponentsV2]});
|
||||
message = await channel.send({components: [await statusService.getUpdatedContainer(true)], flags: [MessageFlags.IsComponentsV2]});
|
||||
} catch (error) {
|
||||
await interaction.editReply({content: 'An error has occurred. Please check the permissions for the channel.'});
|
||||
return;
|
||||
|
||||
@@ -17,7 +17,7 @@ const cmd : CommandDefinition = {
|
||||
),
|
||||
async execute(interaction : ChatInputCommandInteraction) {
|
||||
await interaction.deferReply();
|
||||
await interaction.editReply({components: [statusService.getUpdatedContainer()], flags: MessageFlags.IsComponentsV2});
|
||||
await interaction.editReply({components: [await statusService.getUpdatedContainer()], flags: MessageFlags.IsComponentsV2});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ import { HostsLog } from "../entity/hostslog.entity";
|
||||
import { Repository } from "typeorm";
|
||||
import { Follow } from "../entity/follow.entity";
|
||||
import { Guild } from "../entity/guild.entity";
|
||||
import dayjs from "dayjs";
|
||||
import dayjs, { Dayjs } from "dayjs";
|
||||
import { stat, writeFile } from "fs";
|
||||
import { Canvas } from "canvas";
|
||||
|
||||
type Nofity = {time: Date, name : string, alive : boolean, type : InfraType, host: string};
|
||||
|
||||
@@ -171,7 +173,7 @@ export class StatusService {
|
||||
const channel = await guild.channels.fetch(gdb.persistent_message_channel_id);
|
||||
if(channel?.isSendable()) {
|
||||
const message = await channel.messages.fetch(gdb.persistent_message_id);
|
||||
await message.edit({components: [this.getUpdatedContainer(true)]});
|
||||
await message.edit({components: [await this.getUpdatedContainer(true)]});
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
@@ -191,6 +193,73 @@ export class StatusService {
|
||||
this.client.user?.setActivity({ name: '💭 Server load and status...' })
|
||||
}
|
||||
|
||||
public async getStatusImageBar(host: string) {
|
||||
|
||||
const datas = await this.hostsLogRepo.createQueryBuilder()
|
||||
.where('created_at > :date', {date: dayjs().subtract(1, 'week').toDate()}).getMany();
|
||||
|
||||
const uptimes : { up: boolean, date: Dayjs }[] = datas.map((log) => {
|
||||
|
||||
return {
|
||||
up: log.status,
|
||||
date: dayjs(log.created_at)
|
||||
}
|
||||
});
|
||||
|
||||
const now = dayjs();
|
||||
const week = now.clone().subtract(1, 'week');
|
||||
|
||||
const canvas = new Canvas(100, 2, "image");
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.fillStyle = "#27FF00";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
const maxTime = (now.unix() - week.unix());
|
||||
const ranges: { min: number, max: number }[] = [];
|
||||
|
||||
let minTime: number | null = null;
|
||||
uptimes.map((element, index) => {
|
||||
const positionForMaxTime = (element.date.unix() - week.unix());
|
||||
const percent = Math.round((positionForMaxTime / maxTime) * 100);
|
||||
|
||||
if (ranges.length == 0 && minTime == null) {
|
||||
if (element.up && minTime == null) {
|
||||
ranges.push({
|
||||
min: 0,
|
||||
max: percent
|
||||
});
|
||||
} else {
|
||||
minTime = percent;
|
||||
}
|
||||
} else {
|
||||
if (!element.up) {
|
||||
minTime = percent;
|
||||
|
||||
if(minTime != null && index == uptimes.length - 1) {
|
||||
ranges.push({
|
||||
min: minTime,
|
||||
max: 100
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (minTime) {
|
||||
ranges.push({
|
||||
min: minTime,
|
||||
max: percent
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
ctx.fillStyle = '#ff0000';
|
||||
ranges.map((value) => {
|
||||
ctx.fillRect(value.min, 0, value.max - value.min, canvas.height);
|
||||
});
|
||||
|
||||
return canvas.toDataURL();
|
||||
}
|
||||
|
||||
private async updateClientStatus() {
|
||||
if (this.client) {
|
||||
const hosts = this.hosts.length;
|
||||
@@ -282,7 +351,7 @@ export class StatusService {
|
||||
}
|
||||
}
|
||||
|
||||
public getUpdatedContainer(live : boolean = false): ContainerBuilder {
|
||||
public async getUpdatedContainer(live : boolean = false): Promise<ContainerBuilder> {
|
||||
const hostTexts = this.hosts.map((s) => {
|
||||
return { type: s.type, value: `- ${s.name} : ${s.alive ? `${process.env.EMOJI_STATUS_ONLINE} Online` : `${process.env.EMOJI_STATUS_OFFLINE} Offline`}` };
|
||||
});
|
||||
@@ -336,6 +405,11 @@ export class StatusService {
|
||||
|
||||
container.addSeparatorComponents((s) => s);
|
||||
|
||||
let status = await this.getStatusImageBar('154.16.254.10');
|
||||
container.addMediaGalleryComponents((m) => m
|
||||
.addItems((i) => i.setURL(status))
|
||||
)
|
||||
|
||||
container.addTextDisplayComponents((text) => text.setContent(`:globe_with_meridians: Website Status : https://statut.protojx.com/\n${live ? 'Last update : ' : ''}<t:${dayjs().unix()}:f> - Receive automatic notifications when there is an outage with /follow !`));
|
||||
|
||||
return container;
|
||||
|
||||
Reference in New Issue
Block a user