aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJokler <jokler.contact@gmail.com>2018-05-14 20:46:59 +0200
committerJokler <jokler.contact@gmail.com>2018-05-14 20:46:59 +0200
commite9799560e033c3de59a99946ad3811dff47c8819 (patch)
treef2584dd5ef943a6d996007d4f56fae59dbf02594
parentbef668bce8dc1022e7dde7b0da65fa64bb472cf4 (diff)
downloadfrippy-e9799560e033c3de59a99946ad3811dff47c8819.tar.gz
frippy-e9799560e033c3de59a99946ad3811dff47c8819.zip
Remind: Add Mysql as a possible database
The bot also responds with the id and time of a reminder after creation to allow the creator to delete them. Furthermore the InvalidCommand message was fixed and the unnecessary dotenv dependency was removed.
-rw-r--r--Cargo.lock97
-rw-r--r--Cargo.toml29
-rw-r--r--migrations/2018-05-13-150818_create_events/down.sql1
-rw-r--r--migrations/2018-05-13-150818_create_events/up.sql8
-rw-r--r--src/main.rs3
-rw-r--r--src/plugins/factoids/database.rs3
-rw-r--r--src/plugins/remind/database.rs128
-rw-r--r--src/plugins/remind/mod.rs80
-rw-r--r--src/plugins/remind/parser.rs41
-rw-r--r--src/plugins/tell/database.rs3
10 files changed, 267 insertions, 126 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 427197f..902eb79 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -58,7 +58,7 @@ name = "base64"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -84,7 +84,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
-version = "1.2.2"
+version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -92,7 +92,7 @@ name = "bytes"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -135,19 +135,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clippy"
-version = "0.0.198"
+version = "0.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "clippy_lints 0.0.198 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clippy_lints 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clippy_lints"
-version = "0.0.198"
+version = "0.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -157,7 +157,7 @@ dependencies = [
"matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -236,22 +236,11 @@ dependencies = [
]
[[package]]
-name = "derive-error-chain"
-version = "0.11.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "syntex_fmt_macros 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "diesel"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel_derives 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"mysqlclient-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -296,16 +285,6 @@ dependencies = [
]
[[package]]
-name = "dotenv"
-version = "0.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "derive-error-chain 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "dtoa"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -446,11 +425,10 @@ dependencies = [
"antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"circular-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "clippy 0.0.198 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clippy 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel_infer_schema 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel_migrations 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"frippy_derive 0.1.0",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -462,9 +440,9 @@ dependencies = [
"log4rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r2d2-diesel 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rlua 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rlua 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.55 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -704,7 +682,7 @@ version = "0.1.14"
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.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1108,6 +1086,18 @@ dependencies = [
]
[[package]]
+name = "regex"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "regex-syntax"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1116,6 +1106,14 @@ dependencies = [
]
[[package]]
+name = "regex-syntax"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "relay"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1157,7 +1155,7 @@ dependencies = [
[[package]]
name = "rlua"
-version = "0.12.2"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1265,7 +1263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.13.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.13.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1342,7 +1340,7 @@ dependencies = [
[[package]]
name = "syn"
-version = "0.13.9"
+version = "0.13.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1368,14 +1366,6 @@ dependencies = [
]
[[package]]
-name = "syntex_fmt_macros"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "take"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1777,15 +1767,15 @@ dependencies = [
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
"checksum bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f382711e76b9de6c744cc00d0497baba02fb00a787f088c879f01d09468e32"
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
-"checksum byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "73b5bdfe7ee3ad0b99c9801d58807a9dbc9e09196365b0203853b99889ab3c87"
+"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
"checksum bytes 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "2f1d50c876fb7545f5f289cd8b2aee3f359d073ae819eed5d6373638e2c61e59"
"checksum cargo_metadata 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ebd6272a2ca4fd39dbabbd6611eb03df45c2259b3b80b39a9ff8fbdcf42a4b3"
"checksum cc 1.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0ebb87d1116151416c0cf66a0e3fb6430cccd120fd6300794b4dfaa050ac40ba"
"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
"checksum chrono 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cce36c92cb605414e9b824f866f5babe0a0368e39ea07393b9b63cf3844c0e6"
"checksum circular-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be63960d0419728d75f18d0132e5da310d2db6ef31db808a733a8566afe5545"
-"checksum clippy 0.0.198 (registry+https://github.com/rust-lang/crates.io-index)" = "da3a62431bbcebe5250a1235e022cc61bcc2f32405d8dc08da4011d223c6a4ba"
-"checksum clippy_lints 0.0.198 (registry+https://github.com/rust-lang/crates.io-index)" = "9517a4eee5daa6eaf318a5bd7a4db0bcd5d92e8d8f22c3e341e60cf1746c73a4"
+"checksum clippy 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)" = "927a1f79af10deb103df108347f23c6b7fa1731c953d6fb24d68be1748a0993f"
+"checksum clippy_lints 0.0.200 (registry+https://github.com/rust-lang/crates.io-index)" = "d2432663f6bdb90255dcf9df5ca504f99b575bb471281591138f62f9d31f863b"
"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.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
@@ -1794,13 +1784,11 @@ dependencies = [
"checksum crossbeam-epoch 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b4e2817eb773f770dcb294127c011e22771899c21d18fce7dd739c0b9832e81"
"checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b"
"checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a"
-"checksum derive-error-chain 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4450afbe280461e78299b39182a085b70e3e71be049cf4a588ad72f1e44d33"
"checksum diesel 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24815a0c2094f2c8dafe74ab3b9e975892f44acbb94b4d4b4898025a7615efa4"
"checksum diesel_derives 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6471a2b637b414d3ee1504cf230409a550381c79204282f8fe06c527e4ae56be"
"checksum diesel_infer_schema 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7ca3b65de2209668e7de12cb0b771e39bd37fbd652aa560d9843b730dbc17bd9"
"checksum diesel_migrations 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "992026fb46e684eaede3d9d05737de34bdcdcb7f97b389b3c0fa7999389d504e"
"checksum dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d6f0e2bb24d163428d8031d3ebd2d2bd903ad933205a97d0f18c7c1aade380f3"
-"checksum dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70de3c590ce18df70743cace1cf12565637a0b26fd8b04ef10c7d33fdc66cdc"
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
@@ -1893,11 +1881,13 @@ dependencies = [
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
+"checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
+"checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b"
"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "241faa9a8ca28a03cbbb9815a5d085f271d4c0168a19181f106aa93240c22ddb"
-"checksum rlua 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4d6a9d2d1da31dd5cb4878789b924e46a600bdca4895b30f2efd6370d0dfc80e"
+"checksum rlua 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f4876476bf0ac0bb596c60153c5ba11ddfc5738df991baa9ec35b303dffb1ff"
"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
"checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a"
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
@@ -1921,10 +1911,9 @@ dependencies = [
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97c05b8ebc34ddd6b967994d5c6e9852fa92f8b82b3858c39451f97346dcce5"
-"checksum syn 0.13.9 (registry+https://github.com/rust-lang/crates.io-index)" = "505550dded6ff93eb63bd9d0ada380ffccd9f51c046a5e80a3078d53fcef0038"
+"checksum syn 0.13.10 (registry+https://github.com/rust-lang/crates.io-index)" = "77961dcdac942fa8bc033c16f3a790b311c8a27d00811b878ebd8cf9b7ba39d5"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd"
-"checksum syntex_fmt_macros 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e5386bdc48758d136af85b3880548e1f3a9fad8d7dc2b38bdb48c36a9cdefc0"
"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
diff --git a/Cargo.toml b/Cargo.toml
index 75c9abe..feab256 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,23 +18,22 @@ mysql = [
"diesel",
"diesel_infer_schema",
"diesel_migrations",
- "dotenv",
"r2d2",
"r2d2-diesel"
]
[dependencies]
-irc = "0.13"
+irc = "0.13.5"
log = "0.4.1"
-time = "0.1.39"
-humantime = "1.1.0"
-rlua = "0.12.2"
+time = "0.1.40"
+humantime = "1.1.1"
+rlua = "0.13.0"
reqwest = "0.8.5"
-regex = "0.2.6"
+regex = "1.0.0"
lazy_static = "1.0.0"
-serde = "1.0.27"
-serde_json = "1.0.9"
-chrono = "0.4.0"
+serde = "1.0.55"
+serde_json = "1.0.17"
+chrono = "0.4.2"
glob = "0.2.11"
circular-queue = "0.2.0"
failure = "0.1.1"
@@ -50,17 +49,17 @@ branch = 'update-to-latest-unicode'
[dependencies.diesel]
-version = "1.1.1"
+version = "1.2.2"
optional = true
features = ["mysql", "chrono"]
[dependencies.diesel_infer_schema]
-version = "1.1.0"
+version = "1.2.0"
optional = true
features = ["mysql"]
[dependencies.diesel_migrations]
-version = "1.1.0"
+version = "1.2.0"
optional = true
features = ["mysql"]
@@ -72,10 +71,6 @@ optional = true
version = "1.0.0"
optional = true
-[dependencies.dotenv]
-version = "0.11.0"
-optional = true
-
[dependencies.clippy]
-version = "*"
+version = "0.0.200"
optional = true
diff --git a/migrations/2018-05-13-150818_create_events/down.sql b/migrations/2018-05-13-150818_create_events/down.sql
new file mode 100644
index 0000000..858bcc0
--- /dev/null
+++ b/migrations/2018-05-13-150818_create_events/down.sql
@@ -0,0 +1 @@
+DROP TABLE events
diff --git a/migrations/2018-05-13-150818_create_events/up.sql b/migrations/2018-05-13-150818_create_events/up.sql
new file mode 100644
index 0000000..4e6f14e
--- /dev/null
+++ b/migrations/2018-05-13-150818_create_events/up.sql
@@ -0,0 +1,8 @@
+CREATE TABLE events (
+ id SERIAL PRIMARY KEY,
+ receiver VARCHAR(32) NOT NULL,
+ content TEXT NOT NULL,
+ author VARCHAR(32) NOT NULL,
+ time TIMESTAMP NOT NULL,
+ `repeat` BIGINT UNSIGNED NULL
+)
diff --git a/src/main.rs b/src/main.rs
index 3f56c50..61cc839 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -126,8 +126,7 @@ fn run() -> Result<(), Error> {
let pool = Arc::new(pool);
bot.add_plugin(Factoids::new(pool.clone()));
bot.add_plugin(Tell::new(pool.clone()));
- // TODO Use mysql pool
- bot.add_plugin(Remind::new(HashMap::new()));
+ bot.add_plugin(Remind::new(pool.clone()));
info!("Connected to MySQL server")
}
Err(e) => {
diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs
index 702834f..6cd979e 100644
--- a/src/plugins/factoids/database.rs
+++ b/src/plugins/factoids/database.rs
@@ -1,6 +1,3 @@
-#[cfg(feature = "mysql")]
-extern crate dotenv;
-
use std::collections::HashMap;
#[cfg(feature = "mysql")]
use std::sync::Arc;
diff --git a/src/plugins/remind/database.rs b/src/plugins/remind/database.rs
index c0c127e..e434ec0 100644
--- a/src/plugins/remind/database.rs
+++ b/src/plugins/remind/database.rs
@@ -1,14 +1,30 @@
-#[cfg(feature = "mysql")]
-extern crate dotenv;
-
use std::collections::HashMap;
use std::collections::hash_map::Entry;
use std::fmt;
+#[cfg(feature = "mysql")]
+use std::sync::Arc;
+
+#[cfg(feature = "mysql")]
+use diesel::mysql::MysqlConnection;
+#[cfg(feature = "mysql")]
+use diesel::prelude::*;
+#[cfg(feature = "mysql")]
+use r2d2::Pool;
+#[cfg(feature = "mysql")]
+use r2d2_diesel::ConnectionManager;
+
+#[cfg(feature = "mysql")]
+use failure::ResultExt;
+
use chrono::NaiveDateTime;
use super::error::*;
+#[cfg(feature = "mysql")]
+static LAST_ID_SQL: &'static str = "SELECT LAST_INSERT_ID()";
+
+#[cfg_attr(feature = "mysql", derive(Queryable))]
#[derive(Clone, Debug)]
pub struct Event {
pub id: i64,
@@ -16,7 +32,7 @@ pub struct Event {
pub content: String,
pub author: String,
pub time: NaiveDateTime,
- pub repeat: Option<u64>,
+ pub repeat: Option<i64>,
}
impl fmt::Display for Event {
@@ -29,18 +45,20 @@ impl fmt::Display for Event {
}
}
+#[cfg_attr(feature = "mysql", derive(Insertable))]
+#[cfg_attr(feature = "mysql", table_name = "events")]
#[derive(Debug)]
pub struct NewEvent<'a> {
pub receiver: &'a str,
pub content: &'a str,
pub author: &'a str,
pub time: &'a NaiveDateTime,
- pub repeat: Option<u64>,
+ pub repeat: Option<i64>,
}
pub trait Database: Send + Sync {
- fn insert_event(&mut self, event: &NewEvent) -> Result<(), RemindError>;
- fn update_event_time(&mut self, id: i64, &NaiveDateTime) -> Result<(), RemindError>;
+ fn insert_event(&mut self, event: &NewEvent) -> Result<i64, RemindError>;
+ fn update_event_time(&mut self, id: i64, time: &NaiveDateTime) -> Result<(), RemindError>;
fn get_events_before(&self, time: &NaiveDateTime) -> Result<Vec<Event>, RemindError>;
fn get_user_events(&self, user: &str) -> Result<Vec<Event>, RemindError>;
fn get_event(&self, id: i64) -> Result<Event, RemindError>;
@@ -49,7 +67,7 @@ pub trait Database: Send + Sync {
// HashMap
impl Database for HashMap<i64, Event> {
- fn insert_event(&mut self, event: &NewEvent) -> Result<(), RemindError> {
+ fn insert_event(&mut self, event: &NewEvent) -> Result<i64, RemindError> {
let mut id = 0;
while self.contains_key(&id) {
id += 1;
@@ -65,7 +83,7 @@ impl Database for HashMap<i64, Event> {
};
match self.insert(id, event) {
- None => Ok(()),
+ None => Ok(id),
Some(_) => Err(ErrorKind::Duplicate)?,
}
}
@@ -126,3 +144,95 @@ impl Database for HashMap<i64, Event> {
}
}
}
+
+#[cfg(feature = "mysql")]
+mod schema {
+ table! {
+ events (id) {
+ id -> Bigint,
+ receiver -> Varchar,
+ content -> Text,
+ author -> Varchar,
+ time -> Timestamp,
+ repeat -> Nullable<Bigint>,
+ }
+ }
+}
+
+#[cfg(feature = "mysql")]
+use self::schema::events;
+
+#[cfg(feature = "mysql")]
+impl Database for Arc<Pool<ConnectionManager<MysqlConnection>>> {
+ fn insert_event(&mut self, event: &NewEvent) -> Result<i64, RemindError> {
+ use diesel::{self, dsl::sql, types::Bigint};
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+
+ diesel::insert_into(events::table)
+ .values(event)
+ .execute(conn)
+ .context(ErrorKind::MysqlError)?;
+
+ let id = sql::<Bigint>(LAST_ID_SQL)
+ .get_result(conn)
+ .context(ErrorKind::MysqlError)?;
+
+ Ok(id)
+ }
+
+ fn update_event_time(&mut self, id: i64, time: &NaiveDateTime) -> Result<(), RemindError> {
+ use self::events::columns;
+ use diesel;
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+
+ match diesel::update(events::table.filter(columns::id.eq(id)))
+ .set(columns::time.eq(time))
+ .execute(conn)
+ {
+ Ok(0) => Err(ErrorKind::NotFound)?,
+ Ok(_) => Ok(()),
+ Err(e) => Err(e).context(ErrorKind::MysqlError)?,
+ }
+ }
+
+ fn get_events_before(&self, time: &NaiveDateTime) -> Result<Vec<Event>, RemindError> {
+ use self::events::columns;
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+
+ Ok(events::table
+ .filter(columns::time.lt(time))
+ .load::<Event>(conn)
+ .context(ErrorKind::MysqlError)?)
+ }
+
+ fn get_user_events(&self, user: &str) -> Result<Vec<Event>, RemindError> {
+ use self::events::columns;
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+
+ Ok(events::table
+ .filter(columns::receiver.eq(user))
+ .load::<Event>(conn)
+ .context(ErrorKind::MysqlError)?)
+ }
+
+ fn get_event(&self, id: i64) -> Result<Event, RemindError> {
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+
+ Ok(events::table
+ .find(id)
+ .first(conn)
+ .context(ErrorKind::MysqlError)?)
+ }
+
+ fn delete_event(&mut self, id: i64) -> Result<(), RemindError> {
+ use self::events::columns;
+ use diesel;
+
+ let conn = &*self.get().context(ErrorKind::NoConnection)?;
+ match diesel::delete(events::table.filter(columns::id.eq(id))).execute(conn) {
+ Ok(0) => Err(ErrorKind::NotFound)?,
+ Ok(_) => Ok(()),
+ Err(e) => Err(e).context(ErrorKind::MysqlError)?,
+ }
+ }
+}
diff --git a/src/plugins/remind/mod.rs b/src/plugins/remind/mod.rs
index 8f9b628..71f9d03 100644
--- a/src/plugins/remind/mod.rs
+++ b/src/plugins/remind/mod.rs
@@ -58,12 +58,12 @@ fn run<T: Database>(client: &IrcClient, db: Arc<RwLock<T>>) {
debug!("Sent reminder {:?}", event);
if let Some(repeat) = event.repeat {
- let next_time = event.time + chrono::Duration::seconds(repeat as i64);
+ let next_time = event.time + chrono::Duration::seconds(repeat);
if let Err(e) = db.write().update_event_time(event.id, &next_time) {
error!("Failed to update reminder: {}", e);
} else {
- debug!("Updated time on: {:?}", event);
+ debug!("Updated time");
}
} else if let Err(e) = db.write().delete_event(event.id) {
error!("Failed to delete reminder: {}", e);
@@ -103,33 +103,50 @@ impl<T: 'static + Database> Remind<T> {
}
}
- fn set(&self, command: PluginCommand) -> Result<&str, RemindError> {
- let parser = CommandParser::try_from_tokens(command.tokens)?;
+ fn user_cmd(&self, command: PluginCommand) -> Result<String, RemindError> {
+ let parser = CommandParser::parse_target(command.tokens)?;
+
+ self.set(parser, &command.source)
+ }
+
+ fn me_cmd(&self, command: PluginCommand) -> Result<String, RemindError> {
+ let source = command.source.clone();
+ let parser = CommandParser::with_target(command.tokens, command.source)?;
+
+ self.set(parser, &source)
+ }
+
+ fn set(&self, parser: CommandParser, author: &str) -> Result<String, RemindError> {
debug!("parser: {:?}", parser);
- let mut target = parser.get_target();
- if target == "me" {
- target = &command.source;
- }
+ let target = parser.get_target();
+ let time = parser.get_time(Duration::from_secs(120))?;
let event = database::NewEvent {
receiver: target,
content: &parser.get_message(),
- author: &command.source,
- time: &parser.get_time(Duration::from_secs(120))?,
+ author: author,
+ time: &time,
repeat: parser
- .get_repeat(Duration::from_secs(300))?
- .map(|d| d.as_secs()),
+ .get_repeat(Duration::from_secs(600))?
+ .map(|d| d.as_secs() as i64),
};
debug!("New event: {:?}", event);
- Ok(self.events.write().insert_event(&event).map(|()| "Got it")?)
+ Ok(self.events
+ .write()
+ .insert_event(&event)
+ .map(|id| format!("Created reminder with id {} at {} UTC", id, time))?)
}
fn list(&self, user: &str) -> Result<String, RemindError> {
let mut events = self.events.read().get_user_events(user)?;
+ if events.is_empty() {
+ Err(ErrorKind::NotFound)?;
+ }
+
let mut list = events.remove(0).to_string();
for ev in events {
list.push_str("\r\n");
@@ -145,7 +162,10 @@ impl<T: 'static + Database> Remind<T> {
.remove(0)
.parse::<i64>()
.context(ErrorKind::Parsing)?;
- let event = self.events.read().get_event(id)?;
+ let event = self.events
+ .read()
+ .get_event(id)
+ .context(ErrorKind::NotFound)?;
if event.receiver.eq_ignore_ascii_case(&command.source)
|| event.author.eq_ignore_ascii_case(&command.source)
@@ -169,15 +189,18 @@ impl<T: 'static + Database> Remind<T> {
}
impl<T: Database> Plugin for Remind<T> {
- fn execute(&self, client: &IrcClient, _: &Message) -> ExecutionStatus {
- let mut has_reminder = self.has_reminder.write();
- if !*has_reminder {
- let events = Arc::clone(&self.events);
- let client = client.clone();
+ fn execute(&self, client: &IrcClient, msg: &Message) -> ExecutionStatus {
+ if let Command::JOIN(_, _, _) = msg.command {
+ let mut has_reminder = self.has_reminder.write();
+
+ if !*has_reminder {
+ let events = Arc::clone(&self.events);
+ let client = client.clone();
- spawn(move || run(&client, events));
+ spawn(move || run(&client, events));
- *has_reminder = true;
+ *has_reminder = true;
+ }
}
ExecutionStatus::Done
@@ -198,7 +221,8 @@ impl<T: Database> Plugin for Remind<T> {
let sub_command = command.tokens.remove(0);
let response = match sub_command.as_ref() {
- "user" => self.set(command).map(|s| s.to_owned()),
+ "user" => self.user_cmd(command),
+ "me" => self.me_cmd(command),
"delete" => self.delete(command).map(|s| s.to_owned()),
"list" => self.list(&source),
"help" => Ok(self.help().to_owned()),
@@ -241,7 +265,7 @@ pub mod error {
#[error = "RemindError"]
pub enum ErrorKind {
/// Invalid command error
- #[fail(display = "Incorrect Command. Send \"currency help\" for help.")]
+ #[fail(display = "Incorrect Command. Send \"remind help\" for help.")]
InvalidCommand,
/// Missing message error
@@ -287,5 +311,15 @@ pub mod error {
/// Not found error
#[fail(display = "No events found")]
NotFound,
+
+ /// MySQL error
+ #[cfg(feature = "mysql")]
+ #[fail(display = "Failed to execute MySQL Query")]
+ MysqlError,
+
+ /// No connection error
+ #[cfg(feature = "mysql")]
+ #[fail(display = "No connection to the database")]
+ NoConnection,
}
}
diff --git a/src/plugins/remind/parser.rs b/src/plugins/remind/parser.rs
index 2dbb040..e027aba 100644
--- a/src/plugins/remind/parser.rs
+++ b/src/plugins/remind/parser.rs
@@ -27,20 +27,30 @@ enum ParseState {
}
impl CommandParser {
- pub fn try_from_tokens(tokens: Vec<String>) -> Result<Self, RemindError> {
- if tokens.is_empty() {
- return Err(ErrorKind::MissingReceiver.into());
+ pub fn parse_target(mut tokens: Vec<String>) -> Result<Self, RemindError> {
+ let mut parser = CommandParser::default();
+
+ if let Some(target) = tokens.pop() {
+ parser.target = target;
+ } else {
+ Err(ErrorKind::MissingReceiver)?;
}
+ parser.parse_tokens(tokens)
+ }
+
+ pub fn with_target(tokens: Vec<String>, target: String) -> Result<Self, RemindError> {
let mut parser = CommandParser::default();
- let mut state = ParseState::None;
+ parser.target = target;
- let mut iter = tokens.into_iter();
- parser.target = iter.next()
- .expect("This should be guaranteed by the length check");
+ parser.parse_tokens(tokens)
+ }
+ fn parse_tokens(mut self, tokens: Vec<String>) -> Result<Self, RemindError> {
+ let mut state = ParseState::None;
let mut cur_str = String::new();
- while let Some(token) = iter.next() {
+
+ for token in tokens {
let next_state = match token.as_ref() {
"on" => ParseState::On,
"at" => ParseState::At,
@@ -58,30 +68,31 @@ impl CommandParser {
if next_state != state {
if state != ParseState::None {
- parser = parser.add_string_by_state(&state, cur_str)?;
+ self = self.add_string_by_state(&state, cur_str)?;
cur_str = String::new();
}
state = next_state;
}
}
- parser = parser.add_string_by_state(&state, cur_str)?;
- if parser.message.is_none() {
+ self = self.add_string_by_state(&state, cur_str)?;
+
+ if self.message.is_none() {
return Err(ErrorKind::MissingMessage.into());
}
- if parser.in_duration.is_some() && parser.at_time.is_some()
- || parser.in_duration.is_some() && parser.on_date.is_some()
+ if self.in_duration.is_some() && self.at_time.is_some()
+ || self.in_duration.is_some() && self.on_date.is_some()
{
return Err(ErrorKind::AmbiguousTime.into());
}
- if parser.in_duration.is_none() && parser.at_time.is_none() && parser.on_date.is_none() {
+ if self.in_duration.is_none() && self.at_time.is_none() && self.on_date.is_none() {
return Err(ErrorKind::MissingTime.into());
}
- Ok(parser)
+ Ok(self)
}
fn add_string_by_state(self, state: &ParseState, string: String) -> Result<Self, RemindError> {
diff --git a/src/plugins/tell/database.rs b/src/plugins/tell/database.rs
index 522df5a..75789e4 100644
--- a/src/plugins/tell/database.rs
+++ b/src/plugins/tell/database.rs
@@ -1,6 +1,3 @@
-#[cfg(feature = "mysql")]
-extern crate dotenv;
-
use std::collections::HashMap;
#[cfg(feature = "mysql")]
use std::sync::Arc;