diff --git a/youmubot-cf/src/db.rs b/youmubot-cf/src/db.rs index 62404f8..f5dc974 100644 --- a/youmubot-cf/src/db.rs +++ b/youmubot-cf/src/db.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use codeforces::User; use serenity::model::id::UserId; use std::collections::HashMap; use youmubot_db::DB; @@ -24,3 +25,13 @@ impl Default for CfUser { } } } + +impl From for CfUser { + fn from(u: User) -> Self { + Self { + handle: u.handle, + last_update: Utc::now(), + rating: u.rating, + } + } +} diff --git a/youmubot-cf/src/lib.rs b/youmubot-cf/src/lib.rs index 7271ea2..949692b 100644 --- a/youmubot-cf/src/lib.rs +++ b/youmubot-cf/src/lib.rs @@ -14,7 +14,8 @@ mod hook; // /// Live-commentating a Codeforces round. // pub mod live; -pub use db::CfSavedUsers; +use db::CfSavedUsers; + pub use hook::codeforces_info_hook; /// Sets up the CF databases. @@ -26,7 +27,7 @@ pub fn setup(path: &std::path::Path, data: &mut ShareMap) { #[group] #[prefix = "cf"] #[description = "Codeforces-related commands"] -#[commands(profile)] +#[commands(profile, save)] #[default_command(profile)] pub struct Codeforces; @@ -35,11 +36,28 @@ pub struct Codeforces; #[description = "Get an user's profile"] #[usage = "[handle or tag = yourself]"] #[example = "natsukagami"] -#[num_args(1)] +#[max_args(1)] pub fn profile(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult { - let handle = args.single::()?; + let handle = args + .single::() + .unwrap_or(UsernameArg::mention(m.author.id)); let http = ctx.data.get_cloned::(); + let handle = match handle { + UsernameArg::Raw(s) => s, + UsernameArg::Tagged(u) => { + let db = CfSavedUsers::open(&*ctx.data.read()); + let db = db.borrow()?; + match db.get(&u) { + Some(v) => v.handle.clone(), + None => { + m.reply(&ctx, "no saved account found.")?; + return Ok(()); + } + } + } + }; + let account = codeforces::User::info(&http, &[&handle[..]])? .into_iter() .next(); @@ -57,3 +75,33 @@ pub fn profile(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult Ok(()) } + +#[command] +#[description = "Link your Codeforces account to the Discord account, to enjoy Youmu's tracking capabilities."] +#[usage = "[handle]"] +#[num_args(1)] +pub fn save(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult { + let handle = args.single::()?; + let http = ctx.data.get_cloned::(); + + let account = codeforces::User::info(&http, &[&handle[..]])? + .into_iter() + .next(); + + match account { + None => { + m.reply(&ctx, "cannot find an account with such handle")?; + } + Some(acc) => { + let db = CfSavedUsers::open(&*ctx.data.read()); + let mut db = db.borrow_mut()?; + m.reply( + &ctx, + format!("account `{}` has been linked to your account.", &acc.handle), + )?; + db.insert(m.author.id, acc.into()); + } + } + + Ok(()) +}