mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-04-19 16:58:55 +00:00
Improve cf live commands
This commit is contained in:
parent
537e396140
commit
e0c11a09fb
2 changed files with 39 additions and 53 deletions
|
@ -4,7 +4,7 @@ use serenity::{
|
|||
macros::{command, group},
|
||||
Args, CommandResult,
|
||||
},
|
||||
model::channel::Message,
|
||||
model::{channel::Message, guild::Member},
|
||||
utils::MessageBuilder,
|
||||
};
|
||||
use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||
|
@ -293,18 +293,43 @@ pub async fn contestranks(ctx: &Context, m: &Message, mut args: Args) -> Command
|
|||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
contest_rank_table(ctx, m, contest, problems, ranks).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command]
|
||||
#[description = "Watch a contest and announce any change on the members of the server assigned to the contest."]
|
||||
#[usage = "[the contest id]"]
|
||||
#[num_args(1)]
|
||||
#[required_permissions(MANAGE_CHANNELS)]
|
||||
#[only_in(guilds)]
|
||||
pub async fn watch(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
||||
let contest_id: u64 = args.single()?;
|
||||
|
||||
live::watch_contest(ctx, m.guild_id.unwrap(), m.channel_id, contest_id).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn contest_rank_table(
|
||||
ctx: &Context,
|
||||
reply_to: &Message,
|
||||
contest: Contest,
|
||||
problems: Vec<codeforces::Problem>,
|
||||
ranks: Vec<(Member, String, codeforces::RanklistRow)>,
|
||||
) -> Result<()> {
|
||||
const ITEMS_PER_PAGE: usize = 10;
|
||||
let total_pages = (ranks.len() + ITEMS_PER_PAGE - 1) / ITEMS_PER_PAGE;
|
||||
|
||||
if ranks.is_empty() {
|
||||
m.reply(&ctx, "No one in this server participated in the contest...")
|
||||
reply_to
|
||||
.reply(&ctx, "No one in this server participated in the contest...")
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let ranks = Arc::new(ranks);
|
||||
|
||||
const ITEMS_PER_PAGE: usize = 10;
|
||||
let total_pages = (ranks.len() + ITEMS_PER_PAGE - 1) / ITEMS_PER_PAGE;
|
||||
|
||||
paginate_reply_fn(
|
||||
move |page, ctx, msg| {
|
||||
let contest = contest.clone();
|
||||
|
@ -395,23 +420,8 @@ pub async fn contestranks(ctx: &Context, m: &Message, mut args: Args) -> Command
|
|||
})
|
||||
},
|
||||
ctx,
|
||||
m,
|
||||
reply_to,
|
||||
Duration::from_secs(60),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command]
|
||||
#[description = "Watch a contest and announce any change on the members of the server assigned to the contest."]
|
||||
#[usage = "[the contest id]"]
|
||||
#[num_args(1)]
|
||||
#[required_permissions(MANAGE_CHANNELS)]
|
||||
#[only_in(guilds)]
|
||||
pub async fn watch(ctx: &Context, m: &Message, mut args: Args) -> CommandResult {
|
||||
let contest_id: u64 = args.single()?;
|
||||
|
||||
live::watch_contest(ctx, m.guild_id.unwrap(), m.channel_id, contest_id).await?;
|
||||
|
||||
Ok(())
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ pub async fn watch_contest(
|
|||
.await;
|
||||
|
||||
let http = data.get::<CFClient>().unwrap();
|
||||
let (mut contest, _, _) =
|
||||
let (mut contest, problems, _) =
|
||||
Contest::standings(&*http.borrow().await?, contest_id, |f| f.limit(1, 1)).await?;
|
||||
|
||||
msg.edit(&ctx, |e| {
|
||||
|
@ -76,6 +76,7 @@ pub async fn watch_contest(
|
|||
))
|
||||
})
|
||||
.await?;
|
||||
msg.pin(ctx).await.ok();
|
||||
|
||||
loop {
|
||||
if let Ok(messages) =
|
||||
|
@ -103,38 +104,13 @@ pub async fn watch_contest(
|
|||
.filter_map(|(_, m)| {
|
||||
let member = m.member;
|
||||
let handle = m.handle;
|
||||
m.row.map(|row| ((handle, member), row))
|
||||
m.row.map(|row| (member, handle, row))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
ranks.sort_by(|(_, a), (_, b)| a.rank.cmp(&b.rank));
|
||||
|
||||
if ranks.is_empty() {
|
||||
channel
|
||||
.send_message(&ctx, |e| {
|
||||
e.content(format!(
|
||||
"**{}** has ended, but I can't find anyone in this server on the scoreboard...",
|
||||
contest.name
|
||||
))
|
||||
})
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
channel.send_message(
|
||||
&ctx, |e|
|
||||
e.content(format!(
|
||||
"**{}** has ended, and the rankings in the server is:\n{}", contest.name,
|
||||
ranks.into_iter().map(|((handle, mem), row)| format!(
|
||||
"- **#{}**: {} (**{}**) with **{:.0}** points [{}] and ({} succeeded, {} failed) hacks!",
|
||||
row.rank,
|
||||
mem.mention(),
|
||||
handle,
|
||||
row.points,
|
||||
row.problem_results.iter().map(|p| format!("{:.0}", p.points)).collect::<Vec<_>>().join("/"),
|
||||
row.successful_hack_count,
|
||||
row.unsuccessful_hack_count,
|
||||
)).collect::<Vec<_>>().join("\n")))).await?;
|
||||
ranks.sort_by(|(_, _, a), (_, _, b)| a.rank.cmp(&b.rank));
|
||||
|
||||
msg.unpin(ctx).await.ok();
|
||||
crate::contest_rank_table(&ctx, &msg, contest, problems, ranks).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue