Use the last contest rating change id, instead of rating change time

This commit is contained in:
Natsu Kagami 2020-02-13 16:34:22 -05:00
parent 20a78c1c14
commit bacb781896
Signed by: nki
GPG key ID: 73376E117CD20735
3 changed files with 30 additions and 25 deletions

View file

@ -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<Vec<ChannelId>> = 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<Utc> = 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();

View file

@ -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<HashMap<UserId, CfUser>>;
pub struct CfUser {
pub handle: String,
pub last_update: DateTime<Utc>,
#[serde(default)]
pub last_contest_id: Option<u64>,
pub rating: Option<i64>,
}
impl Default for CfUser {
fn default() -> Self {
Self {
handle: "".to_owned(),
last_update: Utc::now(),
rating: None,
}
}
}
impl From<User> 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<RatingChange>) -> Self {
Self {
handle: u.handle,
last_update: Utc::now(),
last_contest_id: rc.into_iter().last().map(|v| v.contest_id),
rating: u.rating,
}
}

View file

@ -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));
}
}