import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js"; import { db } from "../db/db"; import { createEmbed } from "../lib/embed"; import { formatSize } from "../lib/files"; import { StereoFile } from "../types/files"; export const data = new SlashCommandBuilder() .setName("admin") .setDescription("admin commands") .addSubcommand(subcommand => subcommand .setName("stats") .setDescription("view misc stats") ); export const execute = async (interaction: ChatInputCommandInteraction): Promise => { const subcommand = interaction.options.getSubcommand(); if (subcommand === "stats") { const files = await db.all`SELECT * FROM files`; const totalSize = files.reduce((a, b) => a + b.size, 0); const totalFiles = files.length; const mimes: string[] = files.map(file => file.mime); const sortedMimes = mimes.sort((a, b) => mimes.filter(v => v === a).length - mimes.filter(v => v === b).length ); const mostCommonMime = sortedMimes.pop() || "unknown"; const mostCommonType = ("." + mostCommonMime.split("/")[1]) || "unknown"; const mostCommonCount = mimes.filter(v => v === mostCommonMime).length; const uniqueUsers = new Set(files.map(file => file.owner)).size; const uploaderCounts: Record = {}; files.forEach(file => { uploaderCounts[file.owner] = (uploaderCounts[file.owner] || 0) + 1; }); const topUploader = (Object.entries(uploaderCounts).sort((a, b) => b[1] - a[1])[0]) || ["none", 0]; const oldestFile = files.reduce((a, b) => new Date(a.created_at) < new Date(b.created_at) ? a : b); const newestFile = files.reduce((a, b) => new Date(a.created_at) > new Date(b.created_at) ? a : b); const oldestDate = new Date(oldestFile.created_at); const newestDate = new Date(newestFile.created_at); const daysSpan = Math.max(1, Math.ceil((newestDate.getTime() - oldestDate.getTime()) / (1000 * 60 * 60 * 24))); const filesPerDay = (totalFiles / daysSpan).toFixed(2); const embed = createEmbed(interaction.user) .setTitle("stats") .addFields([ { name: "total files", value: `${totalFiles}` }, { name: "total size", value: `${formatSize(totalSize)}` }, { name: "average size", value: `${formatSize(totalSize / totalFiles)}` }, { name: "most common type", value: `${mostCommonType} (${mostCommonCount} files)` }, { name: "files per day", value: `${Math.round(Number(filesPerDay) * 100) / 100} files/day` }, { name: "total users", value: `${uniqueUsers}` }, { name: "top uploader", value: `<@${topUploader[0]}> (${topUploader[1]} files)` } ].map(field => ({ ...field, inline: true }))) .setDescription("here's the global stats for stereo:") await interaction.reply({ embeds: [embed] }); } }; export default [data, execute] as const;