summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJokler <jokler.contact@gmail.com>2017-10-29 23:23:12 +0100
committerJokler <jokler.contact@gmail.com>2017-10-29 23:23:12 +0100
commitcb07b259950d4762ceb609266cd1e8ae0ef60dad (patch)
treec7bdd86b5bed18ce4d16a6bacde9647f0dfc6de3
parent04e195af65b209e4812b1a076dd04e2f5a8ec21c (diff)
parent45f70129ce94c0511fc5cd2cbdc625f8ef00ea4b (diff)
downloadfrippy-cb07b259950d4762ceb609266cd1e8ae0ef60dad.tar.gz
frippy-cb07b259950d4762ceb609266cd1e8ae0ef60dad.zip
Merge branch 'dev'v0.3.0
-rw-r--r--.gitignore4
-rw-r--r--Cargo.lock195
-rw-r--r--Cargo.toml7
-rw-r--r--bin/main.rs23
-rw-r--r--configs/config.toml (renamed from config.toml)2
-rw-r--r--src/lib.rs210
-rw-r--r--src/plugin.rs140
-rw-r--r--src/plugins/currency.rs58
-rw-r--r--src/plugins/emoji.rs74
-rw-r--r--src/plugins/help.rs34
-rw-r--r--src/plugins/mod.rs9
11 files changed, 484 insertions, 272 deletions
diff --git a/.gitignore b/.gitignore
index f2e972d..fdcd3a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,10 @@
# Generated by Cargo
# will have compiled files and executables
/target/
+/plugin_derive/target/
+
+# The top level Cargo.lock should handle everything
+/plugin_derive/Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
diff --git a/Cargo.lock b/Cargo.lock
index 51aaac8..239bad5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,15 +1,20 @@
[root]
name = "frippy"
-version = "0.1.0"
+version = "0.2.0"
dependencies = [
- "clippy 0.0.165 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clippy 0.0.166 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"irc 0.12.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"plugin_derive 0.1.0",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode_names 0.1.7 (git+https://github.com/Jokler/unicode_names?branch=update-to-latest-unicode)",
]
@@ -32,7 +37,7 @@ name = "aho-corasick"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -40,7 +45,7 @@ name = "backtrace"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "backtrace-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -51,10 +56,10 @@ dependencies = [
[[package]]
name = "backtrace-sys"
-version = "0.1.14"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -83,6 +88,11 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "build_const"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "byteorder"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -101,14 +111,14 @@ name = "cargo_metadata"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cc"
-version = "1.0.0"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -127,16 +137,16 @@ dependencies = [
[[package]]
name = "clippy"
-version = "0.0.165"
+version = "0.0.166"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "clippy_lints 0.0.165 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clippy_lints 0.0.166 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clippy_lints"
-version = "0.0.165"
+version = "0.0.166"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -146,18 +156,11 @@ dependencies = [
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "conv"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -178,6 +181,20 @@ dependencies = [
]
[[package]]
+name = "crc"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crc-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crc-core"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "crypt32-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -187,11 +204,6 @@ dependencies = [
]
[[package]]
-name = "custom_derive"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
name = "dbghelp-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -207,7 +219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "either"
-version = "1.2.0"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -303,7 +315,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-cpupool"
-version = "0.1.6"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -316,6 +328,11 @@ version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "glob"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "httparse"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -328,11 +345,11 @@ dependencies = [
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -388,9 +405,9 @@ dependencies = [
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-mockstream 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -404,7 +421,7 @@ name = "itertools"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "either 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -443,11 +460,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libflate"
-version = "0.1.11"
+version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crc 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -456,30 +474,13 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "magenta"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "magenta-sys"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "matches"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -487,7 +488,7 @@ dependencies = [
[[package]]
name = "mime"
-version = "0.3.4"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicase 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -498,7 +499,7 @@ name = "mime_guess"
version = "2.0.0-alpha.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -506,16 +507,16 @@ dependencies = [
[[package]]
name = "mio"
-version = "0.6.10"
+version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
+ "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -538,7 +539,7 @@ name = "native-tls"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "openssl 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)",
"schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -599,22 +600,22 @@ dependencies = [
[[package]]
name = "openssl"
-version = "0.9.19"
+version = "0.9.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
- "openssl-sys 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "openssl-sys 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl-sys"
-version = "0.9.19"
+version = "0.9.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -712,7 +713,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -740,12 +741,12 @@ dependencies = [
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libflate 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -840,12 +841,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
-version = "1.0.15"
+version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
-version = "1.0.15"
+version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -864,13 +865,13 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.3"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -880,7 +881,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -964,7 +965,7 @@ dependencies = [
"futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1039,7 +1040,7 @@ name = "toml"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1151,27 +1152,28 @@ dependencies = [
"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a"
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum backtrace 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99f2ce94e22b8e664d95c57fff45b98a966c2252b60691d0b7aeeccd88d70983"
-"checksum backtrace-sys 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "c63ea141ef8fdb10409d0f5daf30ac51f84ef43bff66f16627773d2a292cd189"
+"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
+"checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9"
"checksum byteorder 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff81738b726f5d099632ceaffe7fb65b90212e8dce59d518729e7e8634032d3d"
"checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6"
"checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b"
-"checksum cc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7db2f146208d7e0fbee761b09cd65a7f51ccc38705d4e7262dad4d73b12a76b1"
+"checksum cc 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ef4019bdb99c0c1ddd56c12c2f507c174d729c6915eca6bd9d27c42f3d93b0f4"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9"
-"checksum clippy 0.0.165 (registry+https://github.com/rust-lang/crates.io-index)" = "88f67cdb6697a5d357f8f70cffdf65f4dcb6ec8bb5069f2bc347589b3869cbe8"
-"checksum clippy_lints 0.0.165 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f37194e4a7cb36daeeb5727eac96e32c82965e4ae8b119817885377ddb6715"
-"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
+"checksum clippy 0.0.166 (registry+https://github.com/rust-lang/crates.io-index)" = "86c1e9a7fd08987104fcca0ce1ab0a627006ed955ce14a87ffa32754c947fccb"
+"checksum clippy_lints 0.0.166 (registry+https://github.com/rust-lang/crates.io-index)" = "cbde64e1942d299a8ebe242d54567654db22aa06bdaae7aa3eb392db275172e0"
"checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67"
"checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d"
+"checksum crc 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fba69ea0e15e720f7e1cfe1cf3bc55007fbd41e32b8ae11cfa343e7e5961e79a"
+"checksum crc-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "003d1170779d405378223470f5864b41b79a91969be1260e4de7b4ec069af69c"
"checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec"
-"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
-"checksum either 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cbee135e9245416869bf52bd6ccc9b59e2482651510784e089b874272f02a252"
+"checksum either 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e311a7479512fbdf858fb54d91ec59f3b9f85bc0113659f46bba12b199d273ce"
"checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
"checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91"
"checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81"
@@ -1184,8 +1186,9 @@ dependencies = [
"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
"checksum futures 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "05a23db7bd162d4e8265968602930c476f688f0c180b44bdaf55e0cb2c687558"
-"checksum futures-cpupool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "77d49e7de8b91b20d6fda43eea906637eff18b96702eb6b2872df8bfab1ad2b5"
+"checksum futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e86f49cc0d92fe1b97a5980ec32d56208272cbb00f15044ea9e2799dde766fdf"
"checksum getopts 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "65922871abd2f101a2eb0eaebadc66668e54a87ad9c3dd82520b5f86ede5eff9"
+"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07"
"checksum hyper 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b45eac8b696d59491b079bd04fcb0f3488c0f6ed62dcb36bcfea8a543e9cdc3"
"checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985"
@@ -1199,15 +1202,13 @@ dependencies = [
"checksum lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9e5e58fa1a4c3b915a561a78a22ee0cac6ab97dca2504428bc1cb074375f8d5"
"checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b"
"checksum libc 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)" = "56cce3130fd040c28df6f495c8492e5ec5808fb4c9093c310df02b0c8f030148"
-"checksum libflate 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a2aa04ec0100812d31a5366130ff9e793291787bc31da845bede4a00ea329830"
+"checksum libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ae46bcdafa496981e996e57c5be82c0a7f130a071323764c6faa4803619f1e67"
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
-"checksum magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf0336886480e671965f794bc9b6fce88503563013d1bfb7a502c81fe3ac527"
-"checksum magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40d014c7011ac470ae28e2f76a02bfea4a8480f73e701353b49ad7a8d75f4699"
"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
-"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
-"checksum mime 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e3d709ffbb330e1566dc2f2a3c9b58a5ad4a381f740b810cd305dc3f089bc160"
+"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
+"checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd"
"checksum mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27a5e6679a0614e25adc14c6434ba84e41632b765a6d9cb2031a0cca682699ae"
-"checksum mio 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "dbd91d3bfbceb13897065e97b2ef177a09a438cb33612b2d371bf568819a9313"
+"checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5"
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
@@ -1216,8 +1217,8 @@ dependencies = [
"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01"
"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0"
"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
-"checksum openssl 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)" = "816914b22eb15671d62c73442a51978f311e911d6a6f6cbdafa6abce1b5038fc"
-"checksum openssl-sys 0.9.19 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4c63a7d559c1e5afa6d6a9e6fa34bbc5f800ffc9ae08b72c605420b0c4f5e8"
+"checksum openssl 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf434ff6117485dc16478d77a4f5c84eccc9c3645c4da8323b287ad6a15a638"
+"checksum openssl-sys 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0ad395f1cee51b64a8d07cc8063498dc7554db62d5f3ca87a67f4eed2791d0c8"
"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
"checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
"checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
@@ -1244,10 +1245,10 @@ dependencies = [
"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7046c9d4c6c522d10b2d098f9bebe2bef227e0e74044d8c1bfcf6b476af799"
-"checksum serde_derive 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "1afcaae083fd1c46952a315062326bc9957f182358eb7da03b57ef1c688f7aa9"
+"checksum serde 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "e11a631f964d4e6572712ea12075fb1d65eeef42b0058884195b430ac1e26809"
+"checksum serde_derive 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "1a51d54c805fbc8e12b603d1ba51eaed3195862976be468888ab0e4995d0000e"
"checksum serde_derive_internals 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd381f6d01a6616cdba8530492d453b7761b456ba974e98768a18cad2cd76f58"
-"checksum serde_json 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d243424e06f9f9c39e3cd36147470fd340db785825e367625f79298a6ac6b7ac"
+"checksum serde_json 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ee28c1d94a7745259b767ca9e5b95d55bafbd3205ca3acb978cad84a6ed6bc62"
"checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480"
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
diff --git a/Cargo.toml b/Cargo.toml
index f07b67c..4c6928e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "frippy"
-version = "0.2.0"
+version = "0.3.0"
authors = ["Jokler <jokler.contact@gmail.com>"]
repository = "https://github.com/Mavulp/frippy"
readme = "README.md"
@@ -20,11 +20,16 @@ doc = false
[dependencies]
irc = "0.12.5"
+tokio-core = "0.1.10"
+futures = "0.1.16"
+log = "0.3.8"
+time = "0.1"
reqwest = "0.8.0"
regex = "0.2.2"
lazy_static = "0.2.9"
serde = "1.0.15"
serde_json = "1.0.3"
+glob = "0.2"
plugin_derive = { path = "plugin_derive" }
unicode_names = { git = 'https://github.com/Jokler/unicode_names', branch = 'update-to-latest-unicode' }
diff --git a/bin/main.rs b/bin/main.rs
index b974405..18f362e 100644
--- a/bin/main.rs
+++ b/bin/main.rs
@@ -1,5 +1,28 @@
extern crate frippy;
+extern crate log;
+extern crate time;
+
+use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata};
+
+struct Logger;
+
+impl log::Log for Logger {
+ fn enabled(&self, metadata: &LogMetadata) -> bool {
+ metadata.level() <= LogLevel::Info
+ }
+
+ fn log(&self, record: &LogRecord) {
+ if self.enabled(record.metadata()) {
+ println!("[{}]({}) {}", time::now().rfc822(), record.level(), record.args());
+ }
+ }
+}
fn main() {
+ log::set_logger(|max_log_level| {
+ max_log_level.set(LogLevelFilter::Info);
+ Box::new(Logger)
+ }).unwrap();
+
frippy::run();
}
diff --git a/config.toml b/configs/config.toml
index dc5da29..510e1ae 100644
--- a/config.toml
+++ b/configs/config.toml
@@ -12,7 +12,7 @@ encoding = "UTF-8"
channels = ["#frippy"]
umodes = "+B"
user_info = "IRC Bot"
-version = "frippy v0.1.0"
+version = "frippy v0.3.0"
source = "https://github.com/Mavulp/frippy"
#ping_time = 180
#ping_timeout = 10
diff --git a/src/lib.rs b/src/lib.rs
index e1ca7e3..324e273 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,42 +4,40 @@
//! Frippy is an IRC bot that runs plugins on each message
//! received.
//!
-//! # Example
+//! ## Example
//! ```no_run
//! extern crate frippy;
//!
//! frippy::run();
//! ```
+//!
+//! # Logging
+//! Frippy uses the [log](https://docs.rs/log) crate so you can log events
+//! which might be of interest.
#[macro_use]
-extern crate lazy_static;
+extern crate log;
#[macro_use]
extern crate plugin_derive;
extern crate irc;
-extern crate regex;
+extern crate tokio_core;
+extern crate futures;
+extern crate glob;
mod plugin;
mod plugins;
-use std::thread::spawn;
-use std::sync::{Arc, Mutex};
-use regex::Regex;
+use std::sync::Arc;
+
use irc::client::prelude::*;
-use irc::proto::Command::PRIVMSG;
use irc::error::Error as IrcError;
-use plugin::*;
+use tokio_core::reactor::Core;
+use futures::future;
+use glob::glob;
-// Lock the mutex and ignore if it is poisoned
-macro_rules! lock_plugin {
- ($e:expr) => {
- match $e.lock() {
- Ok(plugin) => plugin,
- Err(poisoned) => poisoned.into_inner(),
- }
- }
-}
+use plugin::*;
/// Runs the bot
///
@@ -47,136 +45,98 @@ macro_rules! lock_plugin {
///
/// This blocks the current thread while the bot is running
pub fn run() {
- let server = IrcServer::new("config.toml").unwrap();
- server.identify().unwrap();
- // The list of plugins in use
- let plugins: Vec<Arc<Mutex<Plugin>>> =
- vec![Arc::new(Mutex::new(plugins::emoji::Emoji::new())),
- Arc::new(Mutex::new(plugins::currency::Currency::new()))];
-
- // We need the plugins' names to make sure the user gets a response
- // if they use an incorrect plugin name
- let plugin_names: Vec<String> = plugins
- .iter()
- .map(|p| p.lock().unwrap().name().to_lowercase())
- .collect();
-
- // The main loop over received messages
- server
- .for_each_incoming(|message| {
- let message = Arc::new(message);
- // Check for possible command and save the result for later
- let command = get_command(&server.current_nickname().to_lowercase(), &message);
-
- // Check if the first token of the command is valid
- if let Some(ref c) = command {
- if c.tokens.is_empty() {
- let help = format!("Use \"{} help\" to get help", server.current_nickname());
- server.send_notice(&c.source, &help).unwrap();
-
- } else if "help" == &c.tokens[0].to_lowercase() {
- send_help_message(&server, c).unwrap();
-
- } else if !plugin_names.contains(&c.tokens[0].to_lowercase()) {
-
- let help = format!("\"{} {}\" is not a command, \
- try \"{0} help\" instead.",
- server.current_nickname(),
- c.tokens[0]);
-
- server.send_notice(&c.source, &help).unwrap();
+ // Load all toml files in the configs directory
+ let mut configs = Vec::new();
+ for toml in glob("configs/*.toml").unwrap() {
+ match toml {
+ Ok(path) => {
+ info!("Loading {}", path.to_str().unwrap());
+ match Config::load(path) {
+ Ok(v) => configs.push(v),
+ Err(e) => error!("Incorrect config file {}", e),
}
}
+ Err(e) => error!("Failed to read path {}", e),
+ }
+ }
- for plugin in plugins.clone() {
- // Send the message to the plugin if the plugin needs it
- if lock_plugin!(plugin).is_allowed(&server, &message) {
-
- // Clone everything before the move
- // The server uses an Arc internally too
- let plugin = Arc::clone(&plugin);
- let message = Arc::clone(&message);
- let server = server.clone();
+ // Without configs the bot would just idle
+ if configs.is_empty() {
+ error!("No config file found");
+ return;
+ }
- // Execute the plugin in another thread
- spawn(move || { lock_plugin!(plugin).execute(&server, &message).unwrap(); });
+ // The list of plugins in use
+ let mut plugins = ThreadedPlugins::new();
+ plugins.add(plugins::Help::new());
+ plugins.add(plugins::Emoji::new());
+ plugins.add(plugins::Currency::new());
+ info!("Plugins loaded: {}", plugins);
+
+ // Create an event loop to run the connections on.
+ let mut reactor = Core::new().unwrap();
+
+ // Open a connection and add work for each config
+ for config in configs {
+ let server =
+ match IrcServer::new_future(reactor.handle(), &config).and_then(|f| reactor.run(f)) {
+ Ok(v) => v,
+ Err(e) => {
+ error!("Failed to connect: {}", e);
+ return;
}
+ };
- // Check if the command is for this plugin
- // Clone it for the move
- if let Some(mut c) = command.clone() {
+ info!("Connected to server");
- // Skip empty commands
- if c.tokens.is_empty() { continue; }
+ match server.identify() {
+ Ok(_) => info!("Identified"),
+ Err(e) => error!("Failed to identify: {}", e),
+ };
- if lock_plugin!(plugin).name().to_lowercase() == c.tokens[0].to_lowercase() {
+ // TODO Verify if we actually need to clone plugins twice
+ let plugins = plugins.clone();
- // The first token contains the name of the plugin
- c.tokens.remove(0);
+ let task = server
+ .stream()
+ .for_each(move |message| process_msg(&server, plugins.clone(), message))
+ .map_err(|e| error!("Failed to process message: {}", e));
- // Clone the server for the move - it uses an Arc internally
- let server = server.clone();
- spawn(move || { lock_plugin!(plugin).command(&server, c).unwrap(); });
- }
- }
- }
- })
- .unwrap();
-}
+ reactor.handle().spawn(task);
+ }
-fn send_help_message(server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> {
- server.send_notice(&command.source, "Help has not been added yet.")
+ // Run the main loop forever
+ reactor.run(future::empty::<(), ()>()).unwrap();
}
-fn get_command(nick: &str, message: &Message) -> Option<PluginCommand> {
-
- // Get the actual message out of PRIVMSG
- if let PRIVMSG(_, ref content) = message.command {
-
- // Split content by spaces and filter empty tokens
- let mut tokens: Vec<String> = content
- .split(' ')
- .filter(|&x| !x.is_empty())
- .map(ToOwned::to_owned)
- .collect();
-
- // Check if the message contained notthing but spaces
- if tokens.is_empty() {
- return None;
- }
+fn process_msg(server: &IrcServer,
+ mut plugins: ThreadedPlugins,
+ message: Message)
+ -> Result<(), IrcError> {
- // Only compile the regex once
- // We assume that only ':' and ',' are used as suffixes on IRC
- lazy_static! {
- static ref RE: Regex = Regex::new("^[:,]*?$").unwrap();
+ if let Command::JOIN(ref channel, _, _) = message.command {
+ if message.source_nickname().unwrap() == server.current_nickname() {
+ info!("Joined {}", channel);
}
+ }
- if tokens[0].to_lowercase().starts_with(nick) {
-
- // Remove the bot's name from the first token
- tokens[0].drain(..nick.len());
-
- // If the regex does not match the message is not directed at the bot
- if !RE.is_match(&tokens[0]) {
- return None;
- }
+ // Check for possible command and save the result for later
+ let command = PluginCommand::from(&server.current_nickname().to_lowercase(), &message);
- // The first token contained the name of the bot
- tokens.remove(0);
+ let message = Arc::new(message);
+ plugins.execute_plugins(server, message);
- Some(PluginCommand {
- source: message.source_nickname().unwrap().to_string(),
- target: message.response_target().unwrap().to_string(),
- tokens: tokens,
- })
- } else {
- None
+ // If the message contained a command, handle it
+ if let Some(command) = command {
+ if let Err(e) = plugins.handle_command(server, command) {
+ error!("Failed to handle command: {}", e);
}
- } else {
- None
}
+
+ Ok(())
}
+
#[cfg(test)]
mod tests {}
diff --git a/src/plugin.rs b/src/plugin.rs
index 0a4034d..e0a4ce2 100644
--- a/src/plugin.rs
+++ b/src/plugin.rs
@@ -1,4 +1,8 @@
use std::fmt;
+use std::collections::HashMap;
+use std::thread::spawn;
+use std::sync::{Arc, Mutex};
+
use irc::client::prelude::*;
use irc::error::Error as IrcError;
@@ -18,3 +22,139 @@ pub struct PluginCommand {
pub target: String,
pub tokens: Vec<String>,
}
+
+impl PluginCommand {
+ pub fn from(nick: &str, message: &Message) -> Option<PluginCommand> {
+
+ // Get the actual message out of PRIVMSG
+ if let Command::PRIVMSG(_, ref content) = message.command {
+
+ // Split content by spaces and filter empty tokens
+ let mut tokens: Vec<String> = content.split(' ').map(ToOwned::to_owned).collect();
+
+ // Commands start with our name
+ if tokens[0].to_lowercase().starts_with(nick) {
+
+ // Remove the bot's name from the first token
+ tokens[0].drain(..nick.len());
+
+ // We assume that only ':' and ',' are used as suffixes on IRC
+ // If there are any other chars we assume that it is not ment for the bot
+ tokens[0] = tokens[0]
+ .chars()
+ .filter(|&c| !":,".contains(c))
+ .collect();
+ if !tokens[0].is_empty() {
+ return None;
+ }
+
+ // The first token contained the name of the bot
+ tokens.remove(0);
+
+ Some(PluginCommand {
+ source: message.source_nickname().unwrap().to_string(),
+ target: message.response_target().unwrap().to_string(),
+ tokens: tokens,
+ })
+ } else {
+ None
+ }
+ } else {
+ None
+ }
+ }
+}
+
+// Lock the mutex and ignore if it is poisoned
+macro_rules! lock_plugin {
+ ($e:expr) => {
+ match $e.lock() {
+ Ok(plugin) => plugin,
+ Err(poisoned) => poisoned.into_inner(),
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct ThreadedPlugins {
+ plugins: HashMap<String, Arc<Mutex<Plugin>>>,
+}
+
+impl ThreadedPlugins {
+ pub fn new() -> ThreadedPlugins {
+ ThreadedPlugins { plugins: HashMap::new() }
+ }
+
+ pub fn add<T: Plugin + 'static>(&mut self, plugin: T) {
+ let name = plugin.name().to_lowercase();
+ let safe_plugin = Arc::new(Mutex::new(plugin));
+
+ self.plugins.insert(name, safe_plugin);
+ }
+
+ pub fn execute_plugins(&mut self, server: &IrcServer, message: Arc<Message>) {
+
+ for (name, plugin) in self.plugins.clone() {
+ // Send the message to the plugin if the plugin needs it
+ if lock_plugin!(plugin).is_allowed(server, &message) {
+
+ // Clone everything before the move
+ // The server uses an Arc internally too
+ let plugin = Arc::clone(&plugin);
+ let message = Arc::clone(&message);
+ let server = server.clone();
+
+ // Execute the plugin in another thread
+ spawn(move || {
+ if let Err(e) = lock_plugin!(plugin).execute(&server, &message) {
+ error!("Error in {} - {}", name, e);
+ };
+ });
+ }
+ }
+ }
+
+ pub fn handle_command(&mut self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> {
+
+ if !command.tokens.iter().any(|s| !s.is_empty()) {
+ let help = format!("Use \"{} help\" to get help", server.current_nickname());
+ return server.send_notice(&command.source, &help);
+ }
+
+ // Check if the command is for this plugin
+ if let Some(plugin) = self.plugins.get(&command.tokens[0].to_lowercase()) {
+
+ // The first token contains the name of the plugin
+ let name = command.tokens.remove(0);
+
+ // Clone for the move - the server uses an Arc internally
+ let server = server.clone();
+ let plugin = Arc::clone(plugin);
+ spawn(move || {
+ if let Err(e) = lock_plugin!(plugin).command(&server, command) {
+ error!("Error in {} command - {}", name, e);
+ };
+ });
+
+ Ok(())
+
+ } else {
+ let help = format!("\"{} {}\" is not a command, \
+ try \"{0} help\" instead.",
+ server.current_nickname(),
+ command.tokens[0]);
+
+ server.send_notice(&command.source, &help)
+ }
+ }
+}
+
+impl fmt::Display for ThreadedPlugins {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let plugin_names = self.plugins
+ .iter()
+ .map(|(_, p)| lock_plugin!(p).name().to_string())
+ .collect::<Vec<String>>();
+ write!(f, "{}", plugin_names.join(", "))
+ }
+}
diff --git a/src/plugins/currency.rs b/src/plugins/currency.rs
index bb16cd9..78ae593 100644
--- a/src/plugins/currency.rs
+++ b/src/plugins/currency.rs
@@ -4,8 +4,11 @@ extern crate serde_json;
extern crate regex;
use std::io::Read;
+use std::num::ParseFloatError;
+
use irc::client::prelude::*;
use irc::error::Error as IrcError;
+
use self::reqwest::Client;
use self::reqwest::header::Connection;
use self::serde_json::Value;
@@ -66,25 +69,23 @@ impl Currency {
Currency {}
}
- fn eval_command<'a>(&self, tokens: &'a [String]) -> Option<ConvertionRequest<'a>> {
- let parsed = match tokens[0].parse() {
- Ok(v) => v,
- Err(_) => {
- return None;
- }
- };
-
- Some(ConvertionRequest {
- value: parsed,
- source: &tokens[1],
- target: &tokens[2],
- })
+ fn eval_command<'a>(&self, tokens: &'a [String]) -> Result<ConvertionRequest<'a>, ParseFloatError> {
+ Ok(ConvertionRequest {
+ value: tokens[0].parse()?,
+ source: &tokens[1],
+ target: &tokens[2],
+ })
}
fn convert(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> {
+
+ if command.tokens.len() < 3 {
+ return self.invalid_command(server, &command);
+ }
+
let request = match self.eval_command(&command.tokens) {
- Some(request) => request,
- None => {
+ Ok(request) => request,
+ Err(_) => {
return self.invalid_command(server, &command);
}
};
@@ -103,7 +104,7 @@ impl Currency {
}
}
- fn help(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> {
+ fn help(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> {
let help = format!("usage: {} currency value from_currency to_currency\r\n\
example: 1.5 eur usd\r\n\
available currencies: AUD, BGN, BRL, CAD, \
@@ -111,14 +112,14 @@ impl Currency {
IDR, ILS, INR, JPY, KRW, MXN, MYR, NOK, \
NZD, PHP, PLN, RON, RUB, SEK, SGD, THB, \
TRY, USD, ZAR",
- server.current_nickname());
+ server.current_nickname());
server.send_notice(&command.source, &help)
}
fn invalid_command(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> {
- let help = format!("Incorrect value. \
- Send \"{} help currency\" for help.",
+ let help = format!("Incorrect Command. \
+ Send \"{} currency help\" for help.",
server.current_nickname());
server.send_notice(&command.source, &help)
@@ -131,21 +132,18 @@ impl Plugin for Currency {
}
fn execute(&mut self, _: &IrcServer, _: &Message) -> Result<(), IrcError> {
- Ok(())
+ panic!("Currency does not implement the execute function!")
}
- fn command(&mut self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> {
- if command.tokens.is_empty() {
- self.invalid_command(server, &command)
+ fn command(&mut self, server: &IrcServer, mut command: PluginCommand) -> Result<(), IrcError> {
- } else if command.tokens[0].to_lowercase() == "help" {
- self.help(server, command)
-
- } else if command.tokens.len() >= 3 {
- self.convert(server, command)
+ if command.tokens.is_empty() {
+ return self.invalid_command(server, &command);
+ }
- } else {
- self.invalid_command(server, &command)
+ match command.tokens[0].as_ref() {
+ "help" => self.help(server, &mut command),
+ _ => self.convert(server, command),
}
}
}
diff --git a/src/plugins/emoji.rs b/src/plugins/emoji.rs
index d2ed956..09d5c27 100644
--- a/src/plugins/emoji.rs
+++ b/src/plugins/emoji.rs
@@ -1,43 +1,83 @@
extern crate unicode_names;
+use std::fmt;
+
use irc::client::prelude::*;
use irc::error::Error as IrcError;
use plugin::*;
+struct EmojiHandle {
+ symbol: char,
+ count: i32,
+}
+
+impl fmt::Display for EmojiHandle {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+
+ let name = match unicode_names::name(self.symbol) {
+ Some(sym) => sym.to_string().to_lowercase(),
+ None => String::from("UNKNOWN"),
+ };
+
+ if self.count > 1 {
+ write!(f, "{}x {}", self.count, name)
+ } else {
+ write!(f, "{}", name)
+ }
+ }
+}
+
#[derive(PluginName, Debug)]
pub struct Emoji;
+
impl Emoji {
pub fn new() -> Emoji {
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) {
-
- let name = match unicode_names::name(emoji) {
- Some(v) => format!("{}", v).to_lowercase(),
- None => "UNKNOWN".to_string(),
- };
-
- names.push(name);
- }
+ let names = self.return_emojis(content)
+ .iter()
+ .map(|e| e.to_string())
+ .collect::<Vec<String>>();
server.send_privmsg(target, &names.join(", "))
}
- fn return_emojis(&self, string: &str) -> Vec<char> {
+ fn return_emojis(&self, string: &str) -> Vec<EmojiHandle> {
+ let mut emojis: Vec<EmojiHandle> = Vec::new();
+
+ let mut current = EmojiHandle {
+ symbol: ' ',
+ count: 0,
+ };
- let mut emojis: Vec<char> = Vec::new();
for c in string.chars() {
- if self.is_emoji(&c) {
- emojis.push(c);
+ if !self.is_emoji(&c) {
+ continue;
+ }
+
+ if current.symbol == c {
+ current.count += 1;
+
+ } else {
+ if current.count > 0 {
+ emojis.push(current);
+ }
+
+ current = EmojiHandle {
+ symbol: c,
+ count: 1,
+ }
}
}
+ if current.count > 0 {
+ emojis.push(current);
+ }
+
emojis
}
@@ -67,7 +107,9 @@ impl Plugin for Emoji {
fn execute(&mut self, server: &IrcServer, message: &Message) -> Result<(), IrcError> {
match message.command {
- Command::PRIVMSG(ref target, ref content) => self.emoji(server, content, target),
+ Command::PRIVMSG(_, ref content) => {
+ self.emoji(server, content, message.response_target().unwrap())
+ }
_ => Ok(()),
}
}
diff --git a/src/plugins/help.rs b/src/plugins/help.rs
new file mode 100644
index 0000000..c4ddcd4
--- /dev/null
+++ b/src/plugins/help.rs
@@ -0,0 +1,34 @@
+use irc::client::prelude::*;
+use irc::error::Error as IrcError;
+
+use plugin::*;
+
+#[derive(PluginName, Debug)]
+pub struct Help;
+
+impl Help {
+ pub fn new() -> Help {
+ Help {}
+ }
+
+ fn help(&self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> {
+ server.send_notice(&command.source, "Help has not been added yet.")
+ }
+}
+
+impl Plugin for Help {
+ fn is_allowed(&self, _: &IrcServer, _: &Message) -> bool {
+ false
+ }
+
+ fn execute(&mut self, _: &IrcServer, _: &Message) -> Result<(), IrcError> {
+ panic!("Help does not implement the execute function!")
+ }
+
+ fn command(&mut self, server: &IrcServer, command: PluginCommand) -> Result<(), IrcError> {
+ self.help(server, command)
+ }
+}
+
+#[cfg(test)]
+mod tests {}
diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs
index adf54b2..0dea596 100644
--- a/src/plugins/mod.rs
+++ b/src/plugins/mod.rs
@@ -1,2 +1,7 @@
-pub mod emoji;
-pub mod currency;
+mod help;
+mod emoji;
+mod currency;
+
+pub use self::help::Help;
+pub use self::emoji::Emoji;
+pub use self::currency::Currency;