use std::io; use std::io::prelude::*; use std::fs::File; extern crate telegram_bot; use telegram_bot::{Api, Message, MessageType, ParseMode}; extern crate time; extern crate regex; use self::regex::Regex; use super::rustc_serialize::json; use feature::FeatureResult; use feature::Feature; #[derive(RustcDecodable)] pub struct Anime { name: String, score: f64, } pub struct TopAnime { animes: Vec, last_update: f64, } impl Feature for TopAnime { fn name(&self) -> &'static str { "TopAnime" } fn init(&mut self) {} fn handle(&mut self, a: Api, m: Message) -> Result { if let MessageType::Text(s) = m.msg { let re = Regex::new(r"(?i)luggas top ([0-9]{1,3}) anime").unwrap(); let cap = re.captures(&s); let s_num = match cap { Some(s) => s.at(1), None => return Ok(FeatureResult::Skip), }; let s_num = match s_num { Some(s) => s, None => return Ok(FeatureResult::Skip), }; // parse to int let num = match s_num.parse::() { Ok(n) => n, Err(e) => { println!("{}", e); return Ok(FeatureResult::Skip); } }; let start = time::precise_time_ns(); if let Err(e) = self.update_animes() { println!("{}", e); return Ok(FeatureResult::Skip); } println!("(benchm) updating animes: {}ms", (time::precise_time_ns() - start) / 1000000); let mut msg = String::new(); for i in 0..num { let i = i as usize; if self.animes.len() <= i { break; } let mut pref = ""; if i % 2 == 0 { pref = "*"; } msg.push_str(&format!("{}{}. {} ({}%){}\n", pref, i + 1, self.animes[i].name, self.animes[i].score, pref)); } println!("(benchm) anime before send: {}ms", (time::precise_time_ns() - start) / 1000000); if let Err(e) = a.send_message(m.chat.id(), msg, Some(ParseMode::Markdown), None, Some(m.message_id), None) { println!("{}", e); } println!("(benchm) anime: {}ms", (time::precise_time_ns() - start) / 1000000); return Ok(FeatureResult::Handled); } Ok(FeatureResult::Skip) } } impl TopAnime { pub fn new() -> TopAnime { let mut t = TopAnime { animes: vec![], last_update: 0f64, }; t.init(); t } fn update_animes(&mut self) -> Result<(), io::Error> { let now = time::precise_time_s(); if now - self.last_update < 3600.0f64 { return Ok(()); } let mut f = try!(File::open("data/animescore.json")); let mut buf = String::new(); try!(f.read_to_string(&mut buf)); let v: Vec = match json::decode(&buf) { Ok(v) => v, Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, format!("{}", e))), }; self.animes = v; self.last_update = now; Ok(()) } }