diff options
| author | Jokler <jokler.contact@gmail.com> | 2017-10-29 23:23:12 +0100 |
|---|---|---|
| committer | Jokler <jokler.contact@gmail.com> | 2017-10-29 23:23:12 +0100 |
| commit | cb07b259950d4762ceb609266cd1e8ae0ef60dad (patch) | |
| tree | c7bdd86b5bed18ce4d16a6bacde9647f0dfc6de3 | |
| parent | 04e195af65b209e4812b1a076dd04e2f5a8ec21c (diff) | |
| parent | 45f70129ce94c0511fc5cd2cbdc625f8ef00ea4b (diff) | |
| download | frippy-cb07b259950d4762ceb609266cd1e8ae0ef60dad.tar.gz frippy-cb07b259950d4762ceb609266cd1e8ae0ef60dad.zip | |
Merge branch 'dev'v0.3.0
| -rw-r--r-- | .gitignore | 4 | ||||
| -rw-r--r-- | Cargo.lock | 195 | ||||
| -rw-r--r-- | Cargo.toml | 7 | ||||
| -rw-r--r-- | bin/main.rs | 23 | ||||
| -rw-r--r-- | configs/config.toml (renamed from config.toml) | 2 | ||||
| -rw-r--r-- | src/lib.rs | 210 | ||||
| -rw-r--r-- | src/plugin.rs | 140 | ||||
| -rw-r--r-- | src/plugins/currency.rs | 58 | ||||
| -rw-r--r-- | src/plugins/emoji.rs | 74 | ||||
| -rw-r--r-- | src/plugins/help.rs | 34 | ||||
| -rw-r--r-- | src/plugins/mod.rs | 9 |
11 files changed, 484 insertions, 272 deletions
@@ -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 @@ -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" @@ -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 @@ -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; |
