summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Perry <avaglir@gmail.com>2018-04-07 06:09:52 -0400
committerNathan Perry <avaglir@gmail.com>2018-04-07 06:09:52 -0400
commitfdf65962b9610ab0a7b8e91dc1a2d4973f44c169 (patch)
tree137568972c2033bf487a70c92d732a459d82c3d5
parent1e192fc976325f6bbaede91ab25241efa99e4475 (diff)
database-based memeing working
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock101
-rw-r--r--Cargo.toml7
-rw-r--r--migrations/2018-04-07-091602_add_filename/down.sql1
-rw-r--r--migrations/2018-04-07-091602_add_filename/up.sql5
-rw-r--r--src/commands/meme.rs93
-rw-r--r--src/commands/mod.rs18
-rw-r--r--src/commands/playback/mod.rs76
-rw-r--r--src/commands/sound.rs42
-rw-r--r--src/db/mod.rs8
-rw-r--r--src/db/models.rs5
-rw-r--r--src/db/schema.rs1
-rw-r--r--src/main.rs49
13 files changed, 244 insertions, 163 deletions
diff --git a/.gitignore b/.gitignore
index 2d48ea0..7d9c36d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
.env
.vscode
*.log
+Cargo.lock
diff --git a/Cargo.lock b/Cargo.lock
index 07f0b22..a1acbd3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -224,7 +224,7 @@ name = "derive-error-chain"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_fmt_macros 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -232,24 +232,25 @@ dependencies = [
[[package]]
name = "diesel"
-version = "1.1.1"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "diesel_derives 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "diesel_derives 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pq-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "diesel_derives"
-version = "1.1.0"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -336,6 +337,25 @@ dependencies = [
]
[[package]]
+name = "failure"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "fern"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -877,7 +897,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
-version = "0.3.3"
+version = "0.2.3"
+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 = "proc-macro2"
+version = "0.3.5"
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)",
@@ -890,10 +918,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quote"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1092,7 +1128,7 @@ name = "serde_derive"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1103,7 +1139,7 @@ name = "serde_derive_internals"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1132,13 +1168,14 @@ dependencies = [
[[package]]
name = "serenity"
version = "0.5.1"
-source = "git+https://github.com/zeyla/serenity?rev=b71d99#b71d99fde84135fa66f73c4817d340ffbe8bddae"
+source = "git+https://github.com/mammothbane/serenity#813e4a98ae4411587ed4b3c86ab3eff831dad590"
dependencies = [
"base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"evzht9h3nznqzwl 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper-native-tls 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1217,10 +1254,20 @@ dependencies = [
[[package]]
name = "syn"
+version = "0.12.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1234,6 +1281,15 @@ dependencies = [
]
[[package]]
+name = "synstructure"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "syntex_fmt_macros"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1296,17 +1352,18 @@ dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ctrlc 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "diesel 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "diesel 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)",
"dotenv_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "error-chain 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)",
"fern 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mime_guess 1.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.0-pre.0 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serenity 0.5.1 (git+https://github.com/zeyla/serenity?rev=b71d99)",
+ "serenity 0.5.1 (git+https://github.com/mammothbane/serenity)",
"sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1660,8 +1717,8 @@ dependencies = [
"checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b"
"checksum ctrlc 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "653abc99aa905f693d89df4797fadc08085baee379db92be9f2496cefe8a6f2c"
"checksum derive-error-chain 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4450afbe280461e78299b39182a085b70e3e71be049cf4a588ad72f1e44d33"
-"checksum diesel 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925325c57038f2f14c0413bdf6a92ca72acff644959d0a1a9ebf8d19be7e9c01"
-"checksum diesel_derives 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "28e2b2605ac6a3b9a586383f5f8b2b5f1108f07a421ade965b266289d2805e79"
+"checksum diesel 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06b6446da8e5ae24540deeb54b724ca401efd321fb0c77e583df05a086e05a2a"
+"checksum diesel_derives 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6471a2b637b414d3ee1504cf230409a550381c79204282f8fe06c527e4ae56be"
"checksum dotenv 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a70de3c590ce18df70743cace1cf12565637a0b26fd8b04ef10c7d33fdc66cdc"
"checksum dotenv 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eea1395d2df3b5344dc577809296d9578303296e8d105c408aa80ed67d598ef1"
"checksum dotenv_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "106db107983c2d0c10a9601cdd0c88514df87515e18d24df87e7ae0e2a50c3fa"
@@ -1671,6 +1728,8 @@ dependencies = [
"checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d"
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum evzht9h3nznqzwl 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d52f92982af5248fb5062e81529b3e3a316d08689ff7cf421e5997243a7e1be8"
+"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
+"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
"checksum fern 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "de237898aa785d93b869e965132f62a525b90cce5c0bf2a395f03e62e085bc5c"
"checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
@@ -1733,8 +1792,10 @@ dependencies = [
"checksum pq-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4dfb5e575ef93a1b7b2a381d47ba7c5d4e4f73bff37cee932195de769aad9a54"
"checksum proc-macro-hack 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba8d4f9257b85eb6cdf13f055cea3190520aab1409ca2ab43493ea4820c25f0"
"checksum proc-macro-hack-impl 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5cb6f960ad471404618e9817c0e5d10b1ae74cfdf01fab89ea0641fe7fb2892"
-"checksum proc-macro2 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a01eb4338ef7c116cbe3b2913a6ef9f10b0a711aa6a162af184ea81fab38ea72"
+"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0"
+"checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
+"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
"checksum r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9078ca6a8a5568ed142083bb2f7dc9295b69d16f867ddcc9849e51b17d8db46"
"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1"
@@ -1762,7 +1823,7 @@ dependencies = [
"checksum serde_derive_internals 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "89b340a48245bc03ddba31d0ff1709c118df90edc6adabaca4aac77aea181cce"
"checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74"
"checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480"
-"checksum serenity 0.5.1 (git+https://github.com/zeyla/serenity?rev=b71d99)" = "<none>"
+"checksum serenity 0.5.1 (git+https://github.com/mammothbane/serenity)" = "<none>"
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
@@ -1773,8 +1834,10 @@ dependencies = [
"checksum sodiumoxide 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "bc02c0bc77ffed8e8eaef004399b825cf4fd8aa02d0af6e473225affd583ff4d"
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
"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.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59"
"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"
diff --git a/Cargo.toml b/Cargo.toml
index 928939d..a39320b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,7 +8,7 @@ default = ["diesel"]
[dependencies]
lazy_static = "1.0"
-error-chain = "0.11.0"
+failure = "0.1"
log = "0.4"
typemap = "0.3.3"
url = "1.6.0"
@@ -23,10 +23,9 @@ rand = "0.5.0-pre.0"
either = "1.5.0"
reqwest = "0.8"
sha1 = { version = "0.6.0", features = ["std"] }
+mime_guess = "1.8.4"
[dependencies.serenity]
-# version = "~0.5"
default-features = false
features = ["builder", "cache", "client", "framework", "model", "utils", "voice", "standard_framework"]
-git = "https://github.com/zeyla/serenity"
-rev = "b71d99"
+git = "https://github.com/mammothbane/serenity"
diff --git a/migrations/2018-04-07-091602_add_filename/down.sql b/migrations/2018-04-07-091602_add_filename/down.sql
new file mode 100644
index 0000000..76ea6cf
--- /dev/null
+++ b/migrations/2018-04-07-091602_add_filename/down.sql
@@ -0,0 +1 @@
+ALTER TABLE images DROP COLUMN filename;
diff --git a/migrations/2018-04-07-091602_add_filename/up.sql b/migrations/2018-04-07-091602_add_filename/up.sql
new file mode 100644
index 0000000..c5c572e
--- /dev/null
+++ b/migrations/2018-04-07-091602_add_filename/up.sql
@@ -0,0 +1,5 @@
+ALTER TABLE images ADD COLUMN filename VARCHAR;
+
+UPDATE images SET filename = 'unknown.bin';
+
+ALTER TABLE images ALTER COLUMN filename SET NOT NULL;
diff --git a/src/commands/meme.rs b/src/commands/meme.rs
index 4bd8a27..b0f460f 100644
--- a/src/commands/meme.rs
+++ b/src/commands/meme.rs
@@ -3,6 +3,7 @@ use std::time::Duration;
use rand::{thread_rng, distributions::{Weighted, WeightedChoice, Distribution}};
use serenity::http::AttachmentType;
use serenity::builder::CreateMessage;
+use serenity::framework::standard::Args;
use diesel::PgConnection;
use reqwest::{
Client,
@@ -43,10 +44,9 @@ static mut TTS_WEIGHTS: [Weighted<bool>; 2] = [
Weighted { weight: 1, item: true }
];
-command!(meme(ctx, msg, args) {
+pub fn meme(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()> {
if args.len_quoted() == 0 {
- rand_meme(ctx, msg)?;
- return Ok(());
+ return rand_meme(ctx, msg);
}
macro_rules! next { () => { args.single_quoted::<String>()?.to_lowercase() }; }
@@ -76,17 +76,44 @@ command!(meme(ctx, msg, args) {
let conn = connection()?;
- info!("args.len: {}; args: {:?}", args.len(), args);
- while args.len() > 0 {
+ while args.len_quoted() > 0 {
+ info!("args.len_quoted: {}; args: {:?}", args.len_quoted(), args);
match next!().as_ref() {
- "text" => new_meme.content = Some(args.full().to_owned()),
+ "text" => {
+ new_meme.content = Some(args.full().to_owned());
+ break;
+ },
"image" => {
- let url = args.single_quoted::<String>()?;
+ if new_meme.image_id.is_some() {
+ send(msg.channel_id, "ONLY ONE IMAGE YOU FUCK", msg.tts)?;
+ bail!("user tried to supply more than one image");
+ }
+
+ let mut url = args.single_quoted::<String>()?;
+
+ if url.to_lowercase().trim() == "attached" {
+ let res = msg.attachments.first()
+ .ok_or::<Error>(::failure::err_msg("no attachments found"))
+ .and_then(|att| {
+ let data = att.download()?;
+ let image_id = Image::create(&conn, &att.filename, data, msg.author.id.0)?;
+ new_meme.image_id = Some(image_id);
+
+ Ok(())
+ });
+
+ if res.is_err() {
+ send(msg.channel_id, "fix yer gotdang attachments", msg.tts)?;
+ return res;
+ }
+
+ continue;
+ }
+
let resp = client.head(&url).send()?;
if !resp.status().is_success() {
- send(msg.channel_id, "pick a better url next time thanks", msg.tts)?;
- return Ok(());
+ return send(msg.channel_id, "pick a better url next time thanks", msg.tts);
}
let len = resp.headers().get::<ContentLength>()
@@ -98,15 +125,13 @@ command!(meme(ctx, msg, args) {
.unwrap_or(false);
if len > 20_000_000 || !content_type_valid {
- send(msg.channel_id, "yer pushin me over the fuckin line", msg.tts)?;
- return Ok(());
+ return send(msg.channel_id, "yer pushin me over the fuckin line", msg.tts);
}
let mut resp = client.get(&url).send()?;
if !resp.status().is_success() {
- send(msg.channel_id, "pick a better url next time thanks", msg.tts)?;
- return Ok(());
+ return send(msg.channel_id, "bad link reeeeee", msg.tts);
}
let len = resp.headers().get::<ContentLength>()
@@ -118,56 +143,57 @@ command!(meme(ctx, msg, args) {
.unwrap_or(false);
if len > 20_000_000 || !content_type_valid {
- send(msg.channel_id, "are ye fuckin serious", msg.tts)?;
- return Ok(());
- }
-
- if !resp.status().is_success() {
- send(msg.channel_id, "bad link reeeeee", msg.tts)?;
- return Ok(());
+ return send(msg.channel_id, "are ye fuckin serious", msg.tts);
}
let mut data = Vec::with_capacity(len as usize);
::std::io::copy(&mut resp, &mut data)?;
- let image_id = Image::create(&conn, data, msg.author.id.0)?;
+ let ext = resp.headers().get::<ContentType>()
+ .and_then(|typ| ::mime_guess::get_extensions(typ.type_().as_str(), typ.subtype().as_str()))
+ .and_then(|x| x.first())
+ .unwrap_or(&"bin");
+
+ let filename = format!("{}.{}", new_meme.title, *ext);
+
+ let image_id = Image::create(&conn, &filename, data, msg.author.id.0)?;
new_meme.image_id = Some(image_id);
},
"audio" | "sound" => {
let _url = args.single_quoted::<String>()?;
},
_ => {
- send(msg.channel_id, "hueh?", msg.tts)?;
- return Ok(());
+ return send(msg.channel_id, "hueh?", msg.tts);
}
}
}
if new_meme.content.is_none() && new_meme.image_id.is_none() && new_meme.audio_id.is_none() {
- send(msg.channel_id, "haha it's empty lol xdddd", msg.tts)?;
- return Ok(());
+ return send(msg.channel_id, "hahAA it's empty xdddd", msg.tts);
}
new_meme.save(&conn, msg.author.id.0)?;
- send(msg.channel_id, "i hate my job", msg.tts)?;
+ send(msg.channel_id, "i hate my job", msg.tts)?
},
"delete" | "remove" => {
- send(msg.channel_id, "hwaet", msg.tts)?;
+ send(msg.channel_id, "hwaet", msg.tts)?
},
search => {
let conn = connection()?;
let mem = match find_meme(&conn, search) {
Ok(x) => x,
- Err(_) => {
+ Err(e) => {
send(msg.channel_id, "what in ryan's name", msg.tts)?;
- return Ok(());
+ return Err(e)
},
};
send_meme(ctx, &mem, &conn, msg)?;
}
}
-});
+
+ Ok(())
+}
fn rand_meme(ctx: &Context, message: &Message) -> Result<()> {
let conn = connection()?;
@@ -198,7 +224,7 @@ fn rand_meme(ctx: &Context, message: &Message) -> Result<()> {
ctr += 1;
if ctr > 10 {
send(message.channel_id, "yer listenin to somethin else", message.tts)?;
- return Err("looped too many times trying to find a non-audio meme".into());
+ bail!("looped too many times trying to find a non-audio meme");
}
}
@@ -233,7 +259,10 @@ fn send_meme(ctx: &Context, t: &Meme, conn: &PgConnection, msg: &Message) -> Res
};
match image {
- Some(image) => msg.channel_id.send_files(vec!(AttachmentType::Bytes((&image?.data, &t.title))), create_msg)?,
+ Some(image) => {
+ let image = image?;
+ msg.channel_id.send_files(vec!(AttachmentType::Bytes((&image.data, &image.filename))), create_msg)?
+ },
None => msg.channel_id.send_message(create_msg)?,
};
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index d13082f..9ce518b 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -18,41 +18,41 @@ pub fn register_commands(f: StandardFramework) -> StandardFramework {
.command("skip", |c| c
.desc("skip the rest of the current request")
.guild_only(true)
- .cmd(skip))
+ .exec(skip))
.command("pause", |c| c
.desc("pause playback (currently broken)")
.guild_only(true)
- .cmd(pause))
+ .exec(pause))
.command("resume", |c| c
.desc("resume playing (currently broken)")
.guild_only(true)
- .cmd(resume))
+ .exec(resume))
.command("list", |c| c
.known_as("queue")
.desc("list playing and queued requests")
.guild_only(true)
- .cmd(list))
+ .exec(list))
.command("die", |c| c
.batch_known_as(vec!["sudoku", "stop"])
.desc("stop playing and empty the queue")
.guild_only(true)
- .cmd(die))
+ .exec(die))
.command("mute", |c| c
.desc("mute thulani (playback continues)")
.guild_only(true)
- .cmd(mute))
+ .exec(mute))
.command("unmute", |c| c
.desc("unmute thulani")
.guild_only(true)
- .cmd(unmute))
+ .exec(unmute))
.command("play", |c| c
.desc("queue a request")
.guild_only(true)
- .cmd(play))
+ .exec(play))
.command("volume", |c| c
.desc("set playback volume")
.guild_only(true)
- .cmd(volume))
+ .exec(volume))
.unrecognised_command(|ctx, msg, unrec| {
let url = match msg.content.split_whitespace().skip(1).next() {
Some(x) if x.starts_with("http") => x,
diff --git a/src/commands/playback/mod.rs b/src/commands/playback/mod.rs
index a13ad36..f80bb73 100644
--- a/src/commands/playback/mod.rs
+++ b/src/commands/playback/mod.rs
@@ -3,6 +3,7 @@ use serenity::voice::{LockedAudio, ytdl};
use super::*;
pub use self::types::*;
+use serenity::framework::standard::Args;
mod types;
@@ -56,24 +57,20 @@ pub fn _play(ctx: &Context, msg: &Message, url: &str) -> Result<()> {
Ok(())
}
-command!(play(ctx, msg, args) {
+pub fn play(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()> {
if args.len() == 0 {
- _resume(ctx, msg)?;
- return Ok(());
+ return _resume(ctx, msg);
}
let url = match args.single::<String>() {
Ok(url) => url,
- Err(_) => {
- send(msg.channel_id, "BAD LINK", msg.tts)?;
- return Ok(());
- }
+ Err(_) => return send(msg.channel_id, "BAD LINK", msg.tts),
};
- _play(ctx, msg, &url)?;
-});
+ _play(ctx, msg, &url)
+}
-command!(pause(ctx, msg) {
+pub fn pause(ctx: &mut Context, msg: &Message, _: Args) -> Result<()> {
let mut queue_lock = ctx.data.lock().get::<PlayQueue>().cloned().unwrap();
let done = || send(msg.channel_id, "r u srs", msg.tts);
@@ -82,10 +79,7 @@ command!(pause(ctx, msg) {
let current_item = match play_queue.playing {
Some(ref x) => x,
- None => {
- done()?;
- return Ok(());
- },
+ None => return done(),
};
let audio = current_item.audio.lock();
@@ -93,8 +87,7 @@ command!(pause(ctx, msg) {
};
if !playing {
- done()?;
- return Ok(());
+ return done();
}
{
@@ -102,11 +95,13 @@ command!(pause(ctx, msg) {
let ref audio = queue.playing.clone().unwrap().audio;
audio.lock().pause();
}
-});
-command!(resume(ctx, msg) {
- _resume(ctx, msg)?;
-});
+ Ok(())
+}
+
+pub fn resume(ctx: &mut Context, msg: &Message, _: Args) -> Result<()> {
+ _resume(ctx, msg)
+}
fn _resume(ctx: &mut Context, msg: &Message) -> Result<()> {
let queue_lock = ctx.data.lock().get::<PlayQueue>().cloned().unwrap();
@@ -141,7 +136,7 @@ fn _resume(ctx: &mut Context, msg: &Message) -> Result<()> {
Ok(())
}
-command!(skip(ctx, _msg) {
+pub fn skip(ctx: &mut Context, _msg: &Message, _args: Args) -> Result<()> {
let data = ctx.data.lock();
let mut mgr_lock = data.get::<VoiceManager>().cloned().unwrap();
@@ -156,15 +151,17 @@ command!(skip(ctx, _msg) {
} else {
debug!("got skip with no handler attached");
}
-});
-command!(die(ctx, msg) {
+ Ok(())
+}
+
+pub fn die(ctx: &mut Context, msg: &Message, _: Args) -> Result<()> {
let data = ctx.data.lock();
- let mut mgr_lock = data.get::<VoiceManager>().cloned().unwrap();
+ let mgr_lock = data.get::<VoiceManager>().cloned().unwrap();
let mut manager = mgr_lock.lock();
- let mut queue_lock = data.get::<PlayQueue>().cloned().unwrap();
+ let queue_lock = data.get::<PlayQueue>().cloned().unwrap();
{
let mut play_queue = queue_lock.write().unwrap();
@@ -180,11 +177,13 @@ command!(die(ctx, msg) {
send(msg.channel_id, "YOU die", msg.tts)?;
debug!("got die with no handler attached");
}
-});
-command!(list(ctx, msg) {
- let mut queue_lock = ctx.data.lock().get::<PlayQueue>().cloned().unwrap();
- let mut play_queue = queue_lock.read().unwrap();
+ Ok(())
+}
+
+pub fn list(ctx: &mut Context, msg: &Message, _: Args) -> Result<()> {
+ let queue_lock = ctx.data.lock().get::<PlayQueue>().cloned().unwrap();
+ let play_queue = queue_lock.read().unwrap();
let channel_tmp = msg.channel().unwrap().guild().unwrap();
let channel = channel_tmp.read();
@@ -208,12 +207,15 @@ command!(list(ctx, msg) {
},
}
- play_queue.queue.iter().for_each(|info| {
- let playing_info = match info.data {
- Left(ref url) => format!("`{}`", url),
- Right(_) => "meme".to_owned(),
- };
+ play_queue.queue.iter()
+ .for_each(|info| {
+ let playing_info = match info.data {
+ Left(ref url) => format!("`{}`", url),
+ Right(_) => "meme".to_owned(),
+ };
- channel.say(&format!("{} ({})", playing_info, info.initiator)).unwrap();
- });
-});
+ let _ = channel.say(&format!("{} ({})", playing_info, info.initiator));
+ });
+
+ Ok(())
+}
diff --git a/src/commands/sound.rs b/src/commands/sound.rs
index 6cac61d..c25e910 100644
--- a/src/commands/sound.rs
+++ b/src/commands/sound.rs
@@ -1,9 +1,10 @@
use super::*;
+use serenity::framework::standard::Args;
pub const DEFAULT_VOLUME: f32 = 0.05;
-command!(mute(ctx, _msg) {
- let mut mgr_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap();
+pub fn mute(ctx: &mut Context, msg: &Message, _: Args) -> Result<()> {
+ let mgr_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap();
let mut manager = mgr_lock.lock();
manager.get_mut(*TARGET_GUILD_ID)
@@ -15,10 +16,12 @@ command!(mute(ctx, _msg) {
trace!("Muted");
}
});
-});
-command!(unmute(ctx, msg) {
- let mut mgr_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap();
+ Ok(())
+}
+
+pub fn unmute(ctx: &mut Context, msg: &Message, _: Args) -> Result<()> {
+ let mgr_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap();
let mut manager = mgr_lock.lock();
manager.get_mut(*TARGET_GUILD_ID)
@@ -31,9 +34,11 @@ command!(unmute(ctx, msg) {
let _ = send(msg.channel_id, "REEEEEEEEEEEEEE", msg.tts);
}
});
-});
-command!(volume(ctx, msg, args) {
+ Ok(())
+}
+
+pub fn volume(ctx: &mut Context, msg: &Message, mut args: Args) -> Result<()> {
if args.len() == 0 {
let vol = {
let queue_lock = ctx.data.lock().get::<PlayQueue>().cloned().unwrap();
@@ -41,20 +46,13 @@ command!(volume(ctx, msg, args) {
(play_queue.volume / DEFAULT_VOLUME * 100.0) as usize
};
- send(msg.channel_id, &format!("Volume: {}/100", vol), msg.tts)?;
- return Ok(());
+ return send(msg.channel_id, &format!("Volume: {}/100", vol), msg.tts);
}
- let mut vol: usize = match args.single::<f32>() {
- Ok(vol) if vol.is_nan() => {
- send(msg.channel_id, "you're a fuck", msg.tts)?;
- return Ok(());
- },
+ let vol: usize = match args.single::<f32>() {
+ Ok(vol) if vol.is_nan() => return send(msg.channel_id, "you're a fuck", msg.tts),
Ok(vol) => vol as usize,
- Err(_) => {
- send(msg.channel_id, "???????", msg.tts)?;
- return Ok(());
- },
+ Err(_) => return send(msg.channel_id, "???????", msg.tts),
};
let mut vol: f32 = (vol as f32)/100.0; // force aliasing to reasonable values
@@ -67,7 +65,7 @@ command!(volume(ctx, msg, args) {
vol = 0.0;
}
- let mut queue_lock = ctx.data.lock().get::<PlayQueue>().cloned().unwrap();
+ let queue_lock = ctx.data.lock().get::<PlayQueue>().cloned().unwrap();
{
let mut play_queue = queue_lock.write().unwrap();
@@ -84,5 +82,7 @@ command!(volume(ctx, msg, args) {
let mut audio = current_item.audio.lock();
audio.volume(play_queue.volume);
- };
-});
+ }
+
+ Ok(())
+}
diff --git a/src/db/mod.rs b/src/db/mod.rs
index 0862883..ac0e321 100644
--- a/src/db/mod.rs
+++ b/src/db/mod.rs
@@ -22,12 +22,14 @@ pub fn connection() -> Result<PgConnection> {
pub fn find_meme<T: AsRef<str>>(conn: &PgConnection, search: T) -> Result<Meme> {
use diesel::dsl::sql;
+ use diesel::types::Text;
let search = search.as_ref();
let format_search = format!("%{}%", search);
+ // TODO: check for injection
memes::table
- .filter(memes::title.ilike(&format_search).or(sql(&format!("content ILIKE %{}%", search))))
+ .filter(memes::title.ilike(&format_search).or(sql("content ILIKE ").bind::<Text, _>(&format_search)))
.limit(1)
.first::<Meme>(conn)
.map_err(Error::from)
@@ -35,12 +37,14 @@ pub fn find_meme<T: AsRef<str>>(conn: &PgConnection, search: T) -> Result<Meme>
pub fn find_text<T: AsRef<str>>(conn: &PgConnection, search: T) -> Result<Meme> {
use diesel::dsl::sql;
+ use diesel::types::Text;
let search = search.as_ref();
let format_search = format!("%{}%", search);
+ // TODO: check for injection
memes::table
- .filter((memes::title.ilike(&format_search).or(sql(&format!("content ILIKE %{}%", search))))
+ .filter((memes::title.ilike(&format_search).or(sql("content ILIKE ").bind::<Text, _>(&format_search)))
.and(memes::content.is_not_null()))
.limit(1)
.first::<Meme>(conn)
diff --git a/src/db/models.rs b/src/db/models.rs
index 88ee82c..6ac8b18 100644
--- a/src/db/models.rs
+++ b/src/db/models.rs
@@ -105,10 +105,11 @@ pub struct Image {
pub data: Vec<u8>,
pub metadata_id: i32,
pub data_hash: Vec<u8>,
+ pub filename: String,
}
impl Image {
- pub fn create(conn: &PgConnection, data: Vec<u8>, by_user: u64) -> Result<i32> {
+ pub fn create(conn: &PgConnection, filename: &str, data: Vec<u8>, by_user: u64) -> Result<i32> {
let mut data_hash = ::sha1::Sha1::new();
data_hash.update(&data);
let data_hash = data_hash.digest().bytes().to_vec();
@@ -127,6 +128,7 @@ impl Image {
let new_image = NewImage {
data,
data_hash,
+ filename: filename.to_owned(),
metadata_id: metadata.id,
};
@@ -144,6 +146,7 @@ pub struct NewImage {
pub data: Vec<u8>,
pub metadata_id: i32,
pub data_hash: Vec<u8>,
+ pub filename: String,
}
diff --git a/src/db/schema.rs b/src/db/schema.rs
index d4ba0fa..1822204 100644
--- a/src/db/schema.rs
+++ b/src/db/schema.rs
@@ -22,6 +22,7 @@ table! {
data -> Bytea,
metadata_id -> Int4,
data_hash -> Bytea,
+ filename -> Varchar,
}
}
diff --git a/src/main.rs b/src/main.rs
index e09e77a..eaaf1f0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,21 +5,21 @@ extern crate chrono;
extern crate ctrlc;
extern crate dotenv;
#[macro_use] extern crate dotenv_codegen;
-#[macro_use] extern crate error_chain;
+#[macro_use] extern crate failure;
extern crate fern;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
-#[macro_use] extern crate serenity;
+extern crate serenity;
extern crate typemap;
extern crate url;
extern crate rand;
extern crate either;
extern crate reqwest;
extern crate sha1;
+extern crate mime_guess;
use commands::register_commands;
use dotenv::dotenv;
-use errors::*;
use serenity::framework::standard::help_commands;
use serenity::framework::StandardFramework;
use serenity::model::gateway::Ready;
@@ -28,6 +28,9 @@ use serenity::prelude::*;
use std::env;
use std::thread;
use std::time::{Duration, Instant};
+
+use failure::Error;
+
pub use util::*;
cfg_if! {
if #[cfg(feature = "diesel")] {
@@ -39,24 +42,13 @@ cfg_if! {
mod commands;
mod util;
-mod errors {
- error_chain! {
- foreign_links {
- Serenity(::serenity::Error);
- MissingVar(::std::env::VarError);
- DieselConn(::diesel::ConnectionError) #[cfg(feature = "diesel")];
- Diesel(::diesel::result::Error) #[cfg(feature = "diesel")];
- R2D2(::diesel::r2d2::Error) #[cfg(feature = "diesel")];
- }
- }
-}
+pub type Result<T> = ::std::result::Result<T, Error>;
lazy_static! {
static ref TARGET_GUILD: u64 = dotenv!("TARGET_GUILD").parse().expect("unable to parse TARGET_GUILD as u64");
static ref TARGET_GUILD_ID: GuildId = GuildId(*TARGET_GUILD);
}
-
struct Handler;
impl EventHandler for Handler {
fn ready(&self, _: Context, r: Ready) {
@@ -93,25 +85,13 @@ fn run() -> Result<()> {
result
})
- .after(|_ctx, _msg, _cmd, err| {
+ .after(|_ctx, _msg, cmd, err| {
match err {
Ok(()) => {
- trace!("command completed successfully");
+ trace!("command '{}' completed successfully", cmd);
},
Err(e) => {
- match e {
- Error(e) => {
- error!("error encountered handling request: {}", e);
- e.iter().skip(1).for_each(|e| {
- error!("caused by: {}", e);
- });
-
- if let Some(bt) = e.backtrace() {
- error!("backtrace: {:?}", bt);
- }
- }
- e => error!("encountered error: {:?}", e);
- }
+ error!("error encountered handling command '{}': {:?}", cmd, e);
}
}
})
@@ -193,14 +173,7 @@ fn main() {
info!("starting bot");
match run() {
Err(e) => {
- error!("error encountered running client: {}", e);
- e.iter().skip(1).for_each(|e| {
- error!("caused by: {}", e);
- });
-
- if let Some(bt) = e.backtrace() {
- error!("backtrace: {:?}", bt);
- }
+ error!("error encountered running client: {:?}", e);
},
_ => {
// NOTE: we MUST have gotten here through SIGINT/SIGTERM handlers