From bacb78189690cfbeb4d26c2f701ee09fbb5d302f Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Thu, 13 Feb 2020 16:34:22 -0500 Subject: [PATCH] Use the last contest rating change id, instead of rating change time --- youmubot-cf/src/announcer.rs | 28 ++++++++++++++++++---------- youmubot-cf/src/db.rs | 21 ++++++++------------- youmubot-cf/src/lib.rs | 6 ++++-- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/youmubot-cf/src/announcer.rs b/youmubot-cf/src/announcer.rs index cefd788..df9146f 100644 --- a/youmubot-cf/src/announcer.rs +++ b/youmubot-cf/src/announcer.rs @@ -1,6 +1,6 @@ use crate::db::{CfSavedUsers, CfUser}; use announcer::MemberToChannels; -use chrono::{DateTime, Utc}; +use chrono::Utc; use codeforces::{RatingChange, User}; use serenity::{ framework::standard::{CommandError, CommandResult}, @@ -53,7 +53,7 @@ fn update_user( }; let mut channels_list: Option> = None; - let last_update = std::mem::replace(&mut cfu.last_update, Utc::now()); + cfu.last_update = Utc::now(); // Update the rating cfu.rating = info.rating; @@ -81,16 +81,24 @@ fn update_user( Ok(()) }; + let rating_changes = match cfu.last_contest_id { + None => rating_changes, + Some(v) => rating_changes + .into_iter() + .take_while(|rc| rc.contest_id != v) + .collect(), + }; + + cfu.last_contest_id = rating_changes + .iter() + .last() + .map(|v| v.contest_id) + .or(cfu.last_contest_id); + // Check for any good announcements to make for rc in rating_changes { - let date: DateTime = DateTime::from_utc( - chrono::NaiveDateTime::from_timestamp(rc.rating_update_time_seconds as i64, 0), - Utc, - ); - if &date > &last_update { - if let Err(v) = send_message(rc) { - dbg!(v); - } + if let Err(v) = send_message(rc) { + dbg!(v); } } after.recv().ok(); diff --git a/youmubot-cf/src/db.rs b/youmubot-cf/src/db.rs index 519c87f..cbd0ab8 100644 --- a/youmubot-cf/src/db.rs +++ b/youmubot-cf/src/db.rs @@ -1,5 +1,5 @@ use chrono::{DateTime, Utc}; -use codeforces::User; +use codeforces::{RatingChange, User}; use serenity::model::id::UserId; use std::collections::HashMap; use youmubot_db::DB; @@ -12,24 +12,19 @@ pub type CfSavedUsers = DB>; pub struct CfUser { pub handle: String, pub last_update: DateTime, + #[serde(default)] + pub last_contest_id: Option, pub rating: Option, } -impl Default for CfUser { - fn default() -> Self { - Self { - handle: "".to_owned(), - last_update: Utc::now(), - rating: None, - } - } -} - -impl From for CfUser { - fn from(u: User) -> Self { +impl CfUser { + /// Save a new user as an internal CFUser. + /// Requires a vector of rating changes because we must rely on the Codeforces rating_changes API's return order to properly announce. + pub(crate) fn save(u: User, rc: Vec) -> Self { Self { handle: u.handle, last_update: Utc::now(), + last_contest_id: rc.into_iter().last().map(|v| v.contest_id), rating: u.rating, } } diff --git a/youmubot-cf/src/lib.rs b/youmubot-cf/src/lib.rs index 9365357..9eb5a64 100644 --- a/youmubot-cf/src/lib.rs +++ b/youmubot-cf/src/lib.rs @@ -16,7 +16,7 @@ mod hook; /// Live-commentating a Codeforces round. mod live; -use db::CfSavedUsers; +use db::{CfSavedUsers, CfUser}; pub use hook::codeforces_info_hook; @@ -97,13 +97,15 @@ pub fn save(ctx: &mut Context, m: &Message, mut args: Args) -> CommandResult { m.reply(&ctx, "cannot find an account with such handle")?; } Some(acc) => { + // Collect rating changes data. + let rating_changes = acc.rating_changes(&http)?; 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()); + db.insert(m.author.id, CfUser::save(acc, rating_changes)); } }