From e0c11a09fb984c70daf7fe45d4126d83deb9cf67 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Wed, 10 Feb 2021 16:32:28 +0900 Subject: [PATCH] Improve cf live commands --- youmubot-cf/src/lib.rs | 56 ++++++++++++++++++++++++----------------- youmubot-cf/src/live.rs | 36 +++++--------------------- 2 files changed, 39 insertions(+), 53 deletions(-) diff --git a/youmubot-cf/src/lib.rs b/youmubot-cf/src/lib.rs index 067737a..b9eda5d 100644 --- a/youmubot-cf/src/lib.rs +++ b/youmubot-cf/src/lib.rs @@ -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::>() }) .collect::>(); + 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, + 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 } diff --git a/youmubot-cf/src/live.rs b/youmubot-cf/src/live.rs index 14a03a5..ee69c4c 100644 --- a/youmubot-cf/src/live.rs +++ b/youmubot-cf/src/live.rs @@ -56,7 +56,7 @@ pub async fn watch_contest( .await; let http = data.get::().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::>(); - 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::>().join("/"), - row.successful_hack_count, - row.unsuccessful_hack_count, - )).collect::>().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(()) }