summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJokler <jokler.contact@gmail.com>2017-10-04 04:35:27 +0200
committerJokler <jokler.contact@gmail.com>2017-10-04 04:35:27 +0200
commit4446aca4055da69daa398ed3103b069e65a7f2c1 (patch)
treef59c0cc4cb5f5d8c1dcfd386cf17f01542c6ff5c
parent298b43631805cbf9fb5ab78fcb5d784a97879d21 (diff)
downloadfrippy-4446aca4055da69daa398ed3103b069e65a7f2c1.tar.gz
frippy-4446aca4055da69daa398ed3103b069e65a7f2c1.zip
Initial bot source
-rw-r--r--.travis.yml8
-rw-r--r--Cargo.toml28
-rw-r--r--bin/main.rs5
-rw-r--r--config.toml14
-rw-r--r--src/lib.rs65
-rw-r--r--src/plugin.rs35
-rw-r--r--src/plugins/emoji.rs98
-rw-r--r--src/plugins/mod.rs1
8 files changed, 254 insertions, 0 deletions
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..8c91a74
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,8 @@
+language: rust
+rust:
+ - stable
+ - beta
+ - nightly
+matrix:
+ allow_failures:
+ - rust: nightly
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..a126b60
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,28 @@
+[package]
+name = "frippy"
+version = "0.1.0"
+authors = ["Jokler <jokler.contact@gmail.com>"]
+repository = "https://github.com/Mavulp/frippy"
+readme = "README.md"
+license = "MIT"
+keywords = ["irc", "bot"]
+categories = ["network-programming"]
+description = "An IRC Bot"
+
+[lib]
+name = "frippy"
+path = "src/lib.rs"
+
+[[bin]]
+name = "frippy"
+path = "bin/main.rs"
+
+[dependencies]
+irc = "0.12.5"
+lazy_static = "0.2.9"
+reqwest = "0.8.0"
+regex = "0.2.2"
+serde = "1.0.15"
+serde_json = "1.0.3"
+
+unicode_names = { git = 'https://github.com/antifuchs/unicode_names', branch = 'fix-for-rust-1-10' }
diff --git a/bin/main.rs b/bin/main.rs
new file mode 100644
index 0000000..b974405
--- /dev/null
+++ b/bin/main.rs
@@ -0,0 +1,5 @@
+extern crate frippy;
+
+fn main() {
+ frippy::run();
+}
diff --git a/config.toml b/config.toml
new file mode 100644
index 0000000..e0f4d57
--- /dev/null
+++ b/config.toml
@@ -0,0 +1,14 @@
+owners = [""]
+nickname = "frippy"
+realname = "frippy"
+server = ""
+port = 6697
+encoding = "UTF-8"
+channels = [""]
+user_info = "IRC Bot"
+version = "irc:git:Rust"
+source = "https://github.com/Mavulp/frippy"
+ping_time = 180
+ping_timeout = 10
+burst_window_length = 8
+max_messages_in_burst = 15
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..37ae19c
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,65 @@
+#![feature(proc_macro)]
+extern crate irc;
+#[macro_use]
+extern crate lazy_static;
+
+#[macro_use]
+mod plugin;
+mod plugins;
+
+use std::thread::spawn;
+use std::sync::{Arc, Mutex};
+use irc::client::prelude::*;
+
+use plugin::Plugin;
+
+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()))];
+
+ server
+ .for_each_incoming(|message| {
+ let message = Arc::new(message);
+
+ for plugin in plugins.clone().into_iter() {
+ let server = server.clone();
+ let message = message.clone();
+
+ spawn(move || {
+ let mut plugin = match plugin.lock() {
+ Ok(plugin) => plugin,
+ Err(poisoned) => poisoned.into_inner(),
+ };
+
+ if plugin.is_allowed(&server, &message) {
+ plugin.execute(&server, &message).unwrap();
+ }
+ });
+ }
+ })
+ .unwrap();
+}
+
+#[cfg(test)]
+mod tests {
+ use irc::client::prelude::*;
+
+ pub fn make_server(cmd: &str) -> IrcServer {
+ let config = Config {
+ nickname: Some(format!("test")),
+ server: Some(format!("irc.test.net")),
+ channels: Some(vec![format!("#test")]),
+ use_mock_connection: Some(true),
+ ..Default::default()
+ };
+
+ IrcServer::from_config(config).unwrap()
+ }
+
+ pub fn get_server_value(server: &IrcServer) -> String {
+ unimplemented!();
+ }
+}
diff --git a/src/plugin.rs b/src/plugin.rs
new file mode 100644
index 0000000..473cab1
--- /dev/null
+++ b/src/plugin.rs
@@ -0,0 +1,35 @@
+use std::fmt;
+use irc::client::prelude::*;
+use irc::error::Error as IrcError;
+
+pub trait Plugin: Send + Sync + fmt::Debug {
+ fn is_allowed(&self, server: &IrcServer, message: &Message) -> bool;
+ fn execute(&mut self, server: &IrcServer, message: &Message) -> Result<(), IrcError>;
+}
+
+#[macro_export]
+macro_rules! register_plugin {
+ ($t:ident) => {
+ #[derive(Debug)]
+ pub struct $t;
+
+ impl $t {
+ pub fn new() -> $t {
+ $t { }
+ }
+ }
+ };
+
+ ($t:ident, $element: ident: $ty: ty) => {
+ #[derive(Debug)]
+ pub struct $t {
+ $element: $ty
+ }
+
+ impl $t {
+ pub fn new() -> $t {
+ $t { $element: <$ty>::new() }
+ }
+ }
+ };
+}
diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs
new file mode 100644
index 0000000..8b56a14
--- /dev/null
+++ b/src/plugins/emoji.rs
@@ -0,0 +1,98 @@
+use irc::client::prelude::*;
+use irc::error::Error as IrcError;
+use plugin::Plugin;
+
+extern crate unicode_names;
+
+register_plugin!(Emoji);
+
+impl Emoji {
+ fn emoji(&self, server: &IrcServer, content: &str, target: &str) -> Result<(), IrcError> {
+
+ let mut names: Vec<String> = Vec::new();
+ for emoji in self.return_emojis(&content) {
+
+ names.push(match unicode_names::name(emoji) {
+ Some(v) => format!("{}", v).to_lowercase(),
+ None => format!("UNKNOWN"),
+ });
+ }
+
+ server.send_privmsg(target, &names.join(", "))
+ }
+
+ fn return_emojis(&self, string: &str) -> Vec<char> {
+
+ let mut emojis: Vec<char> = Vec::new();
+
+ for c in string.chars() {
+ if self.is_emoji(&c) {
+ emojis.push(c);
+ }
+ }
+
+ emojis
+ }
+
+ fn is_emoji(&self, c: &char) -> bool {
+ match *c { '\u{1F600}'...'\u{1F64F}' // Emoticons
+ | '\u{1F300}'...'\u{1F5FF}' // Misc Symbols and Pictographs
+ | '\u{1F680}'...'\u{1F6FF}' // Transport and Map
+ | '\u{2600}' ...'\u{26FF}' // Misc symbols
+ | '\u{2700}' ...'\u{27BF}' // Dingbats
+ | '\u{FE00}' ...'\u{FE0F}' // Variation Selectors
+ | '\u{1F900}'...'\u{1F9FF}' // Supplemental Symbols and Pictographs
+ | '\u{20D0}' ...'\u{20FF}' => true, // Combining Diacritical Marks for Symbols
+ _ => false,
+ }
+ }
+}
+
+impl Plugin for Emoji {
+ fn is_allowed(&self, _: &IrcServer, message: &Message) -> bool {
+ match message.command {
+ Command::PRIVMSG(_, _) => true,
+ _ => false,
+ }
+ }
+
+ fn execute(&mut self, server: &IrcServer, message: &Message) -> Result<(), IrcError> {
+ match message.command {
+ Command::PRIVMSG(ref target, ref content) => self.emoji(server, content, target),
+ _ => Ok(())
+ }
+ }
+}
+
+#[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 :😃\r\n");
+// let mut plugin = Emoji::new();
+//
+// server.for_each_incoming(|message| {
+// assert!(plugin.execute(&server, &message).is_ok());
+// }).unwrap();
+//
+// assert_eq!("PRIVMSG test :smiling fce with open mouth\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
new file mode 100644
index 0000000..35cdb27
--- /dev/null
+++ b/src/plugins/mod.rs
@@ -0,0 +1 @@
+pub mod emoji;