summary refs log tree commit diff
path: root/api/src/routes/guilds/#guild_id/widget.png.ts
diff options
context:
space:
mode:
Diffstat (limited to 'api/src/routes/guilds/#guild_id/widget.png.ts')
-rw-r--r--api/src/routes/guilds/#guild_id/widget.png.ts111
1 files changed, 0 insertions, 111 deletions
diff --git a/api/src/routes/guilds/#guild_id/widget.png.ts b/api/src/routes/guilds/#guild_id/widget.png.ts
deleted file mode 100644

index 4c82b740..00000000 --- a/api/src/routes/guilds/#guild_id/widget.png.ts +++ /dev/null
@@ -1,111 +0,0 @@ -import { Request, Response, Router } from "express"; -import { Guild } from "@fosscord/util"; -import { HTTPError } from "lambert-server"; -import { route } from "@fosscord/api"; -import fs from "fs"; -import path from "path"; - -const router: Router = Router(); - -// TODO: use svg templates instead of node-canvas for improved performance and to change it easily - -// https://discord.com/developers/docs/resources/guild#get-guild-widget-image -// TODO: Cache the response -router.get("/", route({}), async (req: Request, res: Response) => { - const { guild_id } = req.params; - - const guild = await Guild.findOneOrFail({ id: guild_id }); - if (!guild.widget_enabled) throw new HTTPError("Unknown Guild", 404); - - // Fetch guild information - const icon = guild.icon; - const name = guild.name; - const presence = guild.presence_count + " ONLINE"; - - // Fetch parameter - const style = req.query.style?.toString() || "shield"; - if (!["shield", "banner1", "banner2", "banner3", "banner4"].includes(style)) { - throw new HTTPError("Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').", 400); - } - - // Setup canvas - const { createCanvas } = require("canvas"); - const { loadImage } = require("canvas"); - const sizeOf = require("image-size"); - - // TODO: Widget style templates need Fosscord branding - const source = path.join(__dirname, "..", "..", "..", "..", "assets", "widget", `${style}.png`); - if (!fs.existsSync(source)) { - throw new HTTPError("Widget template does not exist.", 400); - } - - // Create base template image for parameter - const { width, height } = await sizeOf(source); - const canvas = createCanvas(width, height); - const ctx = canvas.getContext("2d"); - const template = await loadImage(source); - ctx.drawImage(template, 0, 0); - - // Add the guild specific information to the template asset image - switch (style) { - case "shield": - ctx.textAlign = "center"; - await drawText(ctx, 73, 13, "#FFFFFF", "thin 10px Verdana", presence); - break; - case "banner1": - if (icon) await drawIcon(ctx, 20, 27, 50, icon); - await drawText(ctx, 83, 51, "#FFFFFF", "12px Verdana", name, 22); - await drawText(ctx, 83, 66, "#C9D2F0FF", "thin 11px Verdana", presence); - break; - case "banner2": - if (icon) await drawIcon(ctx, 13, 19, 36, icon); - await drawText(ctx, 62, 34, "#FFFFFF", "12px Verdana", name, 15); - await drawText(ctx, 62, 49, "#C9D2F0FF", "thin 11px Verdana", presence); - break; - case "banner3": - if (icon) await drawIcon(ctx, 20, 20, 50, icon); - await drawText(ctx, 83, 44, "#FFFFFF", "12px Verdana", name, 27); - await drawText(ctx, 83, 58, "#C9D2F0FF", "thin 11px Verdana", presence); - break; - case "banner4": - if (icon) await drawIcon(ctx, 21, 136, 50, icon); - await drawText(ctx, 84, 156, "#FFFFFF", "13px Verdana", name, 27); - await drawText(ctx, 84, 171, "#C9D2F0FF", "thin 12px Verdana", presence); - break; - default: - throw new HTTPError("Value must be one of ('shield', 'banner1', 'banner2', 'banner3', 'banner4').", 400); - } - - // Return final image - const buffer = canvas.toBuffer("image/png"); - res.set("Content-Type", "image/png"); - res.set("Cache-Control", "public, max-age=3600"); - return res.send(buffer); -}); - -async function drawIcon(canvas: any, x: number, y: number, scale: number, icon: string) { - // @ts-ignore - const img = new require("canvas").Image(); - img.src = icon; - - // Do some canvas clipping magic! - canvas.save(); - canvas.beginPath(); - - const r = scale / 2; // use scale to determine radius - canvas.arc(x + r, y + r, r, 0, 2 * Math.PI, false); // start circle at x, and y coords + radius to find center - - canvas.clip(); - canvas.drawImage(img, x, y, scale, scale); - - canvas.restore(); -} - -async function drawText(canvas: any, x: number, y: number, color: string, font: string, text: string, maxcharacters?: number) { - canvas.fillStyle = color; - canvas.font = font; - if (text.length > (maxcharacters || 0) && maxcharacters) text = text.slice(0, maxcharacters) + "..."; - canvas.fillText(text, x, y); -} - -export default router;