mirror of
https://github.com/natsukagami/youmubot.git
synced 2025-04-20 01:08: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},
|
macros::{command, group},
|
||||||
Args, CommandResult,
|
Args, CommandResult,
|
||||||
},
|
},
|
||||||
model::channel::Message,
|
model::{channel::Message, guild::Member},
|
||||||
utils::MessageBuilder,
|
utils::MessageBuilder,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, sync::Arc, time::Duration};
|
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<_>>()
|
||||||
})
|
})
|
||||||
.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() {
|
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?;
|
.await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let ranks = Arc::new(ranks);
|
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(
|
paginate_reply_fn(
|
||||||
move |page, ctx, msg| {
|
move |page, ctx, msg| {
|
||||||
let contest = contest.clone();
|
let contest = contest.clone();
|
||||||
|
@ -395,23 +420,8 @@ pub async fn contestranks(ctx: &Context, m: &Message, mut args: Args) -> Command
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
ctx,
|
ctx,
|
||||||
m,
|
reply_to,
|
||||||
Duration::from_secs(60),
|
Duration::from_secs(60),
|
||||||
)
|
)
|
||||||
.await?;
|
.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(())
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub async fn watch_contest(
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let http = data.get::<CFClient>().unwrap();
|
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?;
|
Contest::standings(&*http.borrow().await?, contest_id, |f| f.limit(1, 1)).await?;
|
||||||
|
|
||||||
msg.edit(&ctx, |e| {
|
msg.edit(&ctx, |e| {
|
||||||
|
@ -76,6 +76,7 @@ pub async fn watch_contest(
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
msg.pin(ctx).await.ok();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if let Ok(messages) =
|
if let Ok(messages) =
|
||||||
|
@ -103,38 +104,13 @@ pub async fn watch_contest(
|
||||||
.filter_map(|(_, m)| {
|
.filter_map(|(_, m)| {
|
||||||
let member = m.member;
|
let member = m.member;
|
||||||
let handle = m.handle;
|
let handle = m.handle;
|
||||||
m.row.map(|row| ((handle, member), row))
|
m.row.map(|row| (member, handle, row))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
ranks.sort_by(|(_, a), (_, b)| a.rank.cmp(&b.rank));
|
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?;
|
|
||||||
|
|
||||||
|
msg.unpin(ctx).await.ok();
|
||||||
|
crate::contest_rank_table(&ctx, &msg, contest, problems, ranks).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue