summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJokler <jokler.contact@gmail.com>2017-10-06 01:14:39 +0200
committerJokler <jokler.contact@gmail.com>2017-10-11 15:41:32 +0200
commit76a5131bd9e8acd32ea8c382c0c608e57022512e (patch)
tree5e3064cdfc0ef731424cc98755031447871e6da5
parent3d22bb82e6bf9851b361346a17d36aaffdf0fb98 (diff)
downloadfrippy-76a5131bd9e8acd32ea8c382c0c608e57022512e.tar.gz
frippy-76a5131bd9e8acd32ea8c382c0c608e57022512e.zip
Add fixed currency plugin
-rw-r--r--src/lib.rs4
-rw-r--r--src/plugins/currency.rs165
-rw-r--r--src/plugins/emoji.rs58
-rw-r--r--src/plugins/mod.rs1
4 files changed, 198 insertions, 30 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 5f9bcaa..f7d0971 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -16,7 +16,9 @@ pub fn run() {
let server = IrcServer::new("config.toml").unwrap();
server.identify().unwrap();
- let plugins: Vec<Arc<Mutex<Plugin>>> = vec![Arc::new(Mutex::new(plugins::emoji::Emoji::new()))];
+ let plugins: Vec<Arc<Mutex<Plugin>>> =
+ vec![Arc::new(Mutex::new(plugins::emoji::Emoji::new())),
+ Arc::new(Mutex::new(plugins::currency::Currency::new()))];
server
.for_each_incoming(|message| {
diff --git a/src/plugins/currency.rs b/src/plugins/currency.rs
new file mode 100644
index 0000000..71b943a
--- /dev/null
+++ b/src/plugins/currency.rs
@@ -0,0 +1,165 @@
+extern crate reqwest;
+extern crate serde;
+extern crate serde_json;
+extern crate regex;
+
+use std::io::Read;
+use irc::client::prelude::*;
+use irc::error::Error as IrcError;
+use self::regex::Regex;
+use plugin::Plugin;
+use self::reqwest::Client;
+use self::reqwest::header::Connection;
+use self::serde_json::Value;
+
+register_plugin!(Currency);
+
+lazy_static! {
+ static ref RE: Regex = Regex::new(r"([0-9]+) ([A-Za-z]+) (?i)(to) ([A-Za-z]+)").unwrap();
+}
+
+struct ConvertionRequest<'a> {
+ value: f64,
+ source: &'a str,
+ target: &'a str,
+}
+
+macro_rules! try_option {
+ ($e:expr) => {
+ match $e {
+ Some(v) => v,
+ None => { return None; }
+ }
+ }
+}
+
+impl<'a> ConvertionRequest<'a> {
+ fn send(&self) -> Option<f64> {
+
+ let response = Client::new()
+ .get("https://api.fixer.io/latest")
+ .form(&[("base", self.source)])
+ .header(Connection::close())
+ .send();
+
+ match response {
+ Ok(mut response) => {
+ let mut body = String::new();
+ try_option!(response.read_to_string(&mut body).ok());
+ println!("{}", body);
+
+ let convertion_rates: Result<Value, _> = serde_json::from_str(&body);
+ match convertion_rates {
+ Ok(convertion_rates) => {
+
+ let rates: &Value = try_option!(convertion_rates.get("rates"));
+ let target_rate: &Value = try_option!(rates.get(self.target.to_uppercase()));
+ Some(self.value * try_option!(target_rate.as_f64()))
+ }
+ Err(_) => None,
+ }
+ }
+ Err(_) => None,
+ }
+ }
+}
+
+impl Currency {
+ fn grep_request<'a>(&self, msg: &'a str) -> Option<ConvertionRequest<'a>> {
+ match RE.captures(msg) {
+ Some(captures) => {
+ Some(ConvertionRequest {
+ value: {
+ let capture = try_option!(captures.get(1)).as_str();
+ try_option!(capture.parse().ok())
+ },
+ source: try_option!(captures.get(2)).as_str(),
+ target: try_option!(captures.get(4)).as_str(), // 3 is to/TO
+ })
+ }
+ None => None,
+ }
+ }
+
+ fn convert(&self,
+ server: &IrcServer,
+ _: &Message,
+ target: &str,
+ msg: &str)
+ -> Result<(), IrcError> {
+ let request = match self.grep_request(msg) {
+ Some(request) => request,
+ None => {
+ return Ok(());
+ }
+ };
+
+ match request.send() {
+ Some(response) => {
+ server.send_privmsg(target,
+ &*format!("{} {} => {:.4} {}",
+ request.value,
+ request.source,
+ response / 1.00000000,
+ request.target))
+ }
+ None => server.send_privmsg(target, "Error while converting given currency"),
+ }
+ }
+}
+
+impl Plugin for Currency {
+ fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool {
+ match message.command {
+ Command::PRIVMSG(_, ref msg) => RE.is_match(msg),
+ _ => false,
+ }
+ }
+
+ fn execute(&mut self, server: &IrcServer, message: &Message) -> Result<(), IrcError> {
+ match message.command {
+ Command::PRIVMSG(ref target, ref msg) => self.convert(server, message, target, msg),
+ _ => Ok(()),
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use tests::{make_server, get_server_value};
+
+ use irc::client::prelude::*;
+
+ use plugin::Plugin;
+ use regex::Regex;
+ use super::Currency;
+
+ #[test]
+ fn test_big_jpy_to_eur() {
+ let server = make_server("PRIVMSG test :5000000 JPY to EUR\r\n");
+ let mut plugin = Currency::new();
+
+ for message in server.iter() {
+ let message = message.unwrap();
+ assert!(plugin.is_allowed(&server, &message));
+ assert!(plugin.execute(&server, &message).is_ok());
+ }
+
+ let regex = Regex::new(r"=> ([0-9]{2})").unwrap();
+ let msg = get_server_value(&server);
+ let captures = regex.captures(&*msg).unwrap();
+ assert!(captures.at(0).is_some());
+
+ let result = captures
+ .at(0)
+ .unwrap()
+ .split_whitespace()
+ .last()
+ .unwrap()
+ .parse::<i32>();
+ assert!(result.is_ok());
+
+ let value = result.unwrap();
+ assert!(value > 10 && value < 100);
+ }
+}
diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs
index 75fc863..6c24584 100644
--- a/src/plugins/emoji.rs
+++ b/src/plugins/emoji.rs
@@ -66,33 +66,33 @@ impl Plugin for Emoji {
#[cfg(test)]
mod tests {
-// use ::tests::{make_server, get_server_value};
-//
-// use irc::client::prelude::*;
-//
-// use plugin::Plugin;
-// use super::Emoji;
-//
-// #[test]
-// fn emoji_message() {
-// let server = make_server("PRIVMSG test :emoji\r\n");
-// let mut plugin = Emoji::new();
-//
-// server.for_each_incoming(|message| {
-// assert!(plugin.execute(&server, &message).is_ok());
-// }).unwrap();
-//
-// assert_eq!("PRIVMSG test :emoji name\r\n", &*get_server_value(&server));
-// }
-//
-// #[test]
-// fn no_emoji_message() {
-// let server = make_server("PRIVMSG test :test\r\n");
-// let mut plugin = Emoji::new();
-//
-// server.for_each_incoming(|message| {
-// assert!(plugin.execute(&server, &message).is_ok());
-// }).unwrap();
-// assert_eq!("", &*get_server_value(&server));
-// }
+ //use ::tests::{make_server, get_server_value};
+ //
+ //use irc::client::prelude::*;
+ //
+ //use plugin::Plugin;
+ //use super::Emoji;
+ //
+ //#[test]
+ //fn emoji_message() {
+ // let server = make_server("PRIVMSG test :emoji\r\n");
+ // let mut plugin = Emoji::new();
+ //
+ // server.for_each_incoming(|message| {
+ // assert!(plugin.execute(&server, &message).is_ok());
+ // }).unwrap();
+ //
+ // assert_eq!("PRIVMSG test :emoji name\r\n", &*get_server_value(&server));
+ //}
+ //
+ //#[test]
+ //fn no_emoji_message() {
+ // let server = make_server("PRIVMSG test :test\r\n");
+ // let mut plugin = Emoji::new();
+ //
+ // server.for_each_incoming(|message| {
+ // assert!(plugin.execute(&server, &message).is_ok());
+ // }).unwrap();
+ // assert_eq!("", &*get_server_value(&server));
+ //}
}
diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs
index 35cdb27..adf54b2 100644
--- a/src/plugins/mod.rs
+++ b/src/plugins/mod.rs
@@ -1 +1,2 @@
pub mod emoji;
+pub mod currency;