Add timing information for processing messages.

Also did some clean up of some debugging, reordered use statements, tried to short circuit out some processing if the bot isn't mentioned, made weather command support locid and pws locations (specifically to support Sudden Valley).
This commit is contained in:
Darren VanBuren 2016-08-01 19:40:42 -07:00
parent 3d97df6f57
commit 606db75101

View file

@ -5,10 +5,11 @@ extern crate regex;
#[macro_use] extern crate lazy_static; #[macro_use] extern crate lazy_static;
use std::io::Read; use std::io::Read;
use irc::client::prelude::*; use std::time::{Instant};
use hyper::{Client}; use hyper::{Client};
use rustc_serialize::json::{self}; use irc::client::prelude::*;
use regex::Regex; use regex::Regex;
use rustc_serialize::json::{self};
static WEATHER_API_BASE: &'static str = "http://api.wunderground.com/api/"; static WEATHER_API_BASE: &'static str = "http://api.wunderground.com/api/";
@ -21,7 +22,6 @@ fn main() {
let mentions_regex = Regex::new(&format!("({}(:|,) )(.+)$", my_nick)).unwrap(); let mentions_regex = Regex::new(&format!("({}(:|,) )(.+)$", my_nick)).unwrap();
for message in server.iter() { for message in server.iter() {
let message = message.unwrap(); let message = message.unwrap();
//println!("Received message: {}", message);
match message.command { match message.command {
Command::PRIVMSG(ref target, ref msg) => handle_privmsg(target, msg, &message, &mentions_regex, &server), Command::PRIVMSG(ref target, ref msg) => handle_privmsg(target, msg, &message, &mentions_regex, &server),
_ => (), _ => (),
@ -30,53 +30,84 @@ fn main() {
} }
fn handle_privmsg(target: &String, message_body: &String, message_obj: &Message, mentions_regex: &Regex, server: &IrcServer) { fn handle_privmsg(target: &String, message_body: &String, message_obj: &Message, mentions_regex: &Regex, server: &IrcServer) {
let now = Instant::now();
println!("Received message in {} from {}: {}", target, message_obj.source_nickname().unwrap(), message_body); println!("Received message in {} from {}: {}", target, message_obj.source_nickname().unwrap(), message_body);
let source_nick = message_obj.source_nickname().unwrap(); let source_nick = message_obj.source_nickname().unwrap();
let mut inner_message = String::new(); let mut inner_message = String::new();
match mentions_regex.captures(message_body) { match mentions_regex.captures(message_body) {
Some(capture) => match capture.at(3) { Some(capture) => match capture.at(3) {
Some(inner_message_match) => {inner_message = String::from(inner_message_match); println!("mentioned_message: {}", inner_message)}, Some(inner_message_match) => inner_message = String::from(inner_message_match),
_ => (), _ => (),
}, },
_ => (), _ => (),
} }
println!("mentioned_message: {}", inner_message);
if inner_message == String::from("test") { // This code only triggers if the bot is mentioned.
server.send_privmsg(target, &format!("{}: Hello!", source_nick)).unwrap(); if !inner_message.is_empty() {
} else if inner_message.starts_with("weather") { println!("Mentioned message inner message: {}", inner_message);
// Weather
lazy_static! {static ref WEATHER_REGEX: Regex = Regex::new("(weather )(.+), (\\w+)$").unwrap(); }
match server.config().options {
None => println!("Options not configured!"),
Some(ref options) => match options.get("wunderground_api_key") {
None => println!("wunderground_api_key not configured!"),
Some(api_key) => {
let mut location_city = String::new();
let mut location_area = String::new();
match WEATHER_REGEX.captures(&inner_message) {
Some(capture) => {match capture.at(2) {
Some(city_match) => location_city = String::from(city_match),
None => (),
};
match capture.at(3) {
Some(area_match) => location_area = String::from(area_match),
None => (),
};
server.send_privmsg(target, &format!("{}: {}", source_nick, &test_get_weather(api_key, &location_city, &location_area))).unwrap();
},
None => (),
}
}, if inner_message == String::from("test") {
server.send_privmsg(target, &format!("{}: Hello!", source_nick)).unwrap();
} else if inner_message.starts_with("weather") {
// Weather regular expressions
lazy_static! { static ref WEATHER_REGEX: Regex = Regex::new("(weather )(.+), (\\w+)$").unwrap(); }
lazy_static! { static ref WEATHER_LOCID_REGEX: Regex = Regex::new("(weather )(\\w+):(\\w+)$").unwrap(); }
// Make sure necessary options are configured.
match server.config().options {
None => println!("Options not configured!"),
Some(ref options) => match options.get("wunderground_api_key") {
None => println!("wunderground_api_key not configured!"),
Some(api_key) => {
// First try to match using WEATHER_REGEX, in the form of weather City, ST or City, Country
let mut location_city = String::new();
let mut location_area = String::new();
match WEATHER_REGEX.captures(&inner_message) {
Some(capture) => {
match capture.at(2) {
Some(city_match) => location_city = String::from(city_match),
None => (),
};
match capture.at(3) {
Some(area_match) => location_area = String::from(area_match),
None => (),
};
server.send_privmsg(target, &format!("{}: {}", source_nick, &get_weather(api_key, &location_city, &location_area))).unwrap();
},
None => {
// Failing this, try to match using WEATHER_LOCID_REGEX, in the form of weather locid:USWA0741 or pws:KCATAHOE2
let mut locid = String::new();
let mut locid_type = String::new();
match WEATHER_LOCID_REGEX.captures(&inner_message) {
Some(capture) => {
match capture.at(2) {
Some(locid_type_match) => locid_type = String::from(locid_type_match),
None => (),
}
match capture.at(3) {
Some(locid_match) => locid = String::from(locid_match),
None => (),
}
server.send_privmsg(target, &format!("{}: {}", source_nick, &get_weather_locid(api_key, &locid_type, &locid))).unwrap();
},
None => (),
}
},
}
},
}
}
} else if inner_message.starts_with("bot-quit") {
if server.config().is_owner(source_nick) {
std::process::exit(0);
} }
} }
} else if message_body.contains("bot-quit") {
std::process::exit(0);
} }
println!("Processing message took {} seconds, {} milliseconds", now.elapsed().as_secs(), now.elapsed().subsec_nanos()/1000000);
} }
fn test_get_weather(api_key: &String, location_city: &String, location_area: &String) -> String { fn get_weather(api_key: &String, location_city: &String, location_area: &String) -> String {
let client = Client::new(); let client = Client::new();
let data_type = "conditions"; let data_type = "conditions";
let url = &format!("{}{}/{}/q/{}/{}.json", WEATHER_API_BASE, api_key, data_type, location_area, location_city); let url = &format!("{}{}/{}/q/{}/{}.json", WEATHER_API_BASE, api_key, data_type, location_area, location_city);
@ -106,3 +137,34 @@ fn test_get_weather(api_key: &String, location_city: &String, location_area: &St
} }
reply_message reply_message
} }
fn get_weather_locid(api_key: &String, locid_type: &String, locid: &String) -> String {
let client = Client::new();
let data_type = "conditions";
let url = &format!("{}{}/{}/q/{}:{}.json", WEATHER_API_BASE, api_key, data_type, locid_type, locid);
println!("Attempting to fetch {}", url);
let mut response = match client.get(url).send() {
Ok(response) => response,
Err(_) => panic!("Error fetching JSON!"),
};
let mut response_body = String::new();
match response.read_to_string(&mut response_body) {
Ok(_) => (),
Err(_) => panic!("Error reading to buffer"),
};
let mut reply_message = String::new();
if let Ok(parsed_response) = json::Json::from_str(&response_body) {
if let Some(ref current_observation) = parsed_response.find("current_observation") {
let ref display_location = current_observation.find("display_location").unwrap();
let display_location_string = display_location.find("full").unwrap().as_string().unwrap();
let temperature_string = current_observation.find("temperature_string").unwrap().as_string().unwrap();
let weather = current_observation.find("weather").unwrap().as_string().unwrap();
let wind_string = current_observation.find("wind_string").unwrap().as_string().unwrap();
let humidity = current_observation.find("relative_humidity").unwrap().as_string().unwrap();
let observation_time = current_observation.find("observation_time").unwrap().as_string().unwrap();
reply_message = format!("It is {} and {} in {}. Wind: {}, Humidity: {}, {}",
weather, temperature_string, display_location_string, wind_string, humidity, observation_time);
}
}
reply_message
}