initial commit
Some checks failed
release-tag / release-image (push) Failing after 1m14s

This commit is contained in:
konchin
2024-10-11 19:49:58 +08:00
commit 2d7361e937
38 changed files with 4029 additions and 0 deletions

124
commands/contests/result.ts Normal file
View File

@@ -0,0 +1,124 @@
import {
CommandInteraction,
TextChannel,
SlashCommandBuilder,
SlashCommandBooleanOption,
CommandInteractionOptionResolver,
} from 'discord.js';
import {writeFileSync} from 'fs';
import {Command} from '../../classes/command';
import {logger} from '../../logger';
import {config} from '../../config';
import {getContest, getProblem, getSession} from '../../functions/database';
function isTextChannel(data: unknown): data is TextChannel{
return (data as TextChannel).name !== undefined;
}
type CIOR = CommandInteractionOptionResolver;
class Result extends Command{
get name(){return "result";}
get description(){return "See the result of a contest.";}
async execute(interaction: CommandInteraction): Promise<void>{
if(!isTextChannel(interaction.channel)){
await interaction.reply({
content: `Channel name doesn't exist!`
});
logger.error(`Channel name doesn't exist`);
return;
}
const contestName = interaction.channel.name;
const channelId = interaction.channel.id;
const markdown = (interaction.options as CIOR).getBoolean('markdown') ?? false;
const contest = await getContest(channelId);
if(contest === null){
await interaction.reply({
content: `The contest in this channel didn't start!`
});
logger.error(`Contest ${contestName} didn't start`);
return;
}
let content: string = '';
content += `# ${contestName}\n\n`
contest.problems.sort(
(a, b) => {
if(a.problemId > b.problemId)
return 1;
if(a.problemId < b.problemId)
return -1;
return 0;
}
);
const getTime = (time: number) => {
if(time === -1) return -1;
return Math.floor((time-contest.startTime)/(1000*60));
};
for(const problem of contest.problems){
const p = await getProblem(problem._id);
if(p === null) continue;
content += `## p${p.problemId}\n`;
if(getTime(p.ac) === -1)
content += "*Problem unsolved!*\n";
else
content += `**AC** at ${getTime(p.ac)} min\n`;
if(p.wa.length !== 0){
content += `**WA** at`;
let isFirst: boolean = true;
for(const wa of p.wa.sort()){
if(isFirst) isFirst = false;
else content += ',';
content += ` ${getTime(wa)}`;
}
content += ' min\n';
}
if(p.read.length === 0)
content += "*Problem unread!*\n";
else{
content += `**Read**:\n`;
for(const session of p.read){
const s = await getSession(session._id);
if(s === null) continue;
content += `- \`${s.name}\` at ${getTime(s.start)} min`;
if(getTime(s.end) !== -1)
content += ` (estimate: ${getTime(s.end)} min)`;
content += '\n';
}
}
if(p.code.length === 0)
content += "*No one have attempted*\n";
else{
content += `**Code**:\n`;
for(const session of p.code){
const s = await getSession(session._id);
if(s === null) continue;
content += `- \`${s.name}\` at ${getTime(s.start)} min`
content += ` (estimate: ${getTime(s.end)} min)\n`;
}
}
content += '\n';
}
if(markdown){
const file = `${config.mdBaseDir}/${channelId}.md`;
logger.log(`Output to ${file}`);
await writeFileSync(file, content, {encoding: 'utf8'});
await interaction.reply({files:[file]});
}else
await interaction.reply({content: content});
logger.log(`Command: result of ${contestName}/${channelId}`);
}
override build(): SlashCommandBuilder |
Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">{
return new SlashCommandBuilder()
.setName(this.name)
.setDescription(this.description)
.addBooleanOption((option: SlashCommandBooleanOption) =>
option
.setName('markdown')
.setDescription('If true then upload markdown file instead.')
)
}
};
export const command = new Result();