From 757edd214f841e8d95e4c5430d7ead7a0e8fecbb Mon Sep 17 00:00:00 2001 From: Jokler Date: Thu, 30 Jan 2020 15:55:41 +0100 Subject: Spawn actix-web server with access to the bot Additionally replace all Mutexes with RwLocks. Hopefully this makes it possible for the web server to serve many requests at once since they would just hold read locks. --- Cargo.lock | 622 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 600 insertions(+), 22 deletions(-) (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index fe0ea26..e5b821c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,298 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "actix" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4af87564ff659dee8f9981540cac9418c45e910c8072fdedd643a262a38fcaf" +dependencies = [ + "actix-http", + "actix-rt", + "actix_derive", + "bitflags", + "bytes 0.5.3", + "crossbeam-channel", + "derive_more 0.99.2", + "futures 0.3.1", + "lazy_static", + "log", + "parking_lot 0.10.0", + "pin-project", + "smallvec 1.1.0", + "tokio 0.2.7", + "tokio-util", + "trust-dns-proto 0.18.0-alpha.2", + "trust-dns-resolver 0.18.0-alpha.2", +] + +[[package]] +name = "actix-codec" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09e55f0a5c2ca15795035d90c46bd0e73a5123b72f68f12596d6ba5282051380" +dependencies = [ + "bitflags", + "bytes 0.5.3", + "futures-core", + "futures-sink", + "log", + "tokio 0.2.7", + "tokio-util", +] + +[[package]] +name = "actix-connect" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c95cc9569221e9802bf4c377f6c18b90ef10227d787611decf79fd47d2a8e76c" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "derive_more 0.99.2", + "either", + "futures 0.3.1", + "http 0.2.0", + "log", + "trust-dns-proto 0.18.0-alpha.2", + "trust-dns-resolver 0.18.0-alpha.2", +] + +[[package]] +name = "actix-http" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c16664cc4fdea8030837ad5a845eb231fb93fc3c5c171edfefb52fad92ce9019" +dependencies = [ + "actix-codec", + "actix-connect", + "actix-rt", + "actix-service", + "actix-threadpool", + "actix-utils", + "base64 0.11.0", + "bitflags", + "brotli2", + "bytes 0.5.3", + "chrono", + "copyless", + "derive_more 0.99.2", + "either", + "encoding_rs", + "failure", + "flate2", + "futures-channel", + "futures-core", + "futures-util", + "fxhash", + "h2 0.2.1", + "http 0.2.0", + "httparse", + "indexmap", + "language-tags", + "lazy_static", + "log", + "mime", + "percent-encoding 2.1.0", + "pin-project", + "rand 0.7.3", + "regex", + "serde", + "serde_json", + "serde_urlencoded 0.6.1", + "sha1", + "slab", + "time", +] + +[[package]] +name = "actix-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21705adc76bbe4bc98434890e73a89cd00c6015e5704a60bb6eea6c3b72316b6" +dependencies = [ + "quote 1.0.2", + "syn 1.0.13", +] + +[[package]] +name = "actix-router" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d7a10ca4d94e8c8e7a87c5173aba1b97ba9a6563ca02b0e1cd23531093d3ec8" +dependencies = [ + "bytestring", + "http 0.2.0", + "log", + "regex", + "serde", +] + +[[package]] +name = "actix-rt" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6a0a55507046441a496b2f0d26a84a65e67c8cafffe279072412f624b5fb6d" +dependencies = [ + "actix-macros", + "actix-threadpool", + "copyless", + "futures 0.3.1", + "tokio 0.2.7", +] + +[[package]] +name = "actix-server" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d3455eaac03ca3e49d7b822eb35c884b861f715627254ccbe4309d08f1841a" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "futures 0.3.1", + "log", + "mio", + "mio-uds", + "net2", + "num_cpus", + "slab", +] + +[[package]] +name = "actix-service" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e4fc95dfa7e24171b2d0bb46b85f8ab0e8499e4e3caec691fc4ea65c287564" +dependencies = [ + "futures-util", + "pin-project", +] + +[[package]] +name = "actix-testing" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48494745b72d0ea8ff0cf874aaf9b622a3ee03d7081ee0c04edea4f26d32c911" +dependencies = [ + "actix-macros", + "actix-rt", + "actix-server", + "actix-service", + "futures 0.3.1", + "log", + "net2", +] + +[[package]] +name = "actix-threadpool" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4082192601de5f303013709ff84d81ca6a1bc4af7fb24f367a500a23c6e84e" +dependencies = [ + "derive_more 0.99.2", + "futures-channel", + "lazy_static", + "log", + "num_cpus", + "parking_lot 0.10.0", + "threadpool", +] + +[[package]] +name = "actix-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e5b4faaf105e9a6d389c606c298dcdb033061b00d532af9df56ff3a54995a8" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "derive_more 0.99.2", + "either", + "futures 0.3.1", + "log", +] + +[[package]] +name = "actix-utils" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf8f5631bf01adec2267808f00e228b761c60c0584cc9fa0b5364f41d147f4e" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "bitflags", + "bytes 0.5.3", + "either", + "futures 0.3.1", + "log", + "pin-project", + "slab", +] + +[[package]] +name = "actix-web" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3158e822461040822f0dbf1735b9c2ce1f95f93b651d7a7aded00b1efbb1f635" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-testing", + "actix-threadpool", + "actix-tls", + "actix-utils", + "actix-web-codegen", + "awc", + "bytes 0.5.3", + "derive_more 0.99.2", + "encoding_rs", + "futures 0.3.1", + "fxhash", + "log", + "mime", + "net2", + "pin-project", + "regex", + "serde", + "serde_json", + "serde_urlencoded 0.6.1", + "time", + "url 2.1.0", +] + +[[package]] +name = "actix-web-codegen" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0878b30e62623770a4713a6338329fd0119703bafc211d3e4144f4d4a7bdd5" +dependencies = [ + "proc-macro2 1.0.7", + "quote 1.0.2", + "syn 1.0.13", +] + +[[package]] +name = "actix_derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95aceadaf327f18f0df5962fedc1bde2f870566a0b9f65c89508a3b1f79334c" +dependencies = [ + "proc-macro2 1.0.7", + "quote 1.0.2", + "syn 1.0.13", +] + [[package]] name = "adler32" version = "1.0.4" @@ -98,6 +391,17 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +[[package]] +name = "async-trait" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8df72488e87761e772f14ae0c2480396810e51b2c2ade912f97f0f7e5b95e3c" +dependencies = [ + "proc-macro2 1.0.7", + "quote 1.0.2", + "syn 1.0.13", +] + [[package]] name = "atty" version = "0.2.14" @@ -115,6 +419,29 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" +[[package]] +name = "awc" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7601d4d1d7ef2335d6597a41b5fe069f6ab799b85f53565ab390e7b7065aac5" +dependencies = [ + "actix-codec", + "actix-http", + "actix-rt", + "actix-service", + "base64 0.11.0", + "bytes 0.5.3", + "derive_more 0.99.2", + "futures-core", + "log", + "mime", + "percent-encoding 2.1.0", + "rand 0.7.3", + "serde", + "serde_json", + "serde_urlencoded 0.6.1", +] + [[package]] name = "backtrace" version = "0.3.40" @@ -146,6 +473,12 @@ dependencies = [ "byteorder", ] +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + [[package]] name = "bit-vec" version = "0.5.1" @@ -178,6 +511,26 @@ dependencies = [ "generic-array", ] +[[package]] +name = "brotli-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "brotli2" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" +dependencies = [ + "brotli-sys", + "libc", +] + [[package]] name = "bstr" version = "0.2.8" @@ -225,6 +578,15 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10004c15deb332055f7a4a208190aed362cf9a7c2f6ab70a305fba50e1105f38" +[[package]] +name = "bytestring" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc267467f58ef6cc8874064c62a0423eb0d099362c8a23edd1c6d044f46eead4" +dependencies = [ + "bytes 0.5.3", +] + [[package]] name = "c2-chacha" version = "0.2.3" @@ -345,6 +707,12 @@ dependencies = [ "url 1.7.2", ] +[[package]] +name = "copyless" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff9c56c9fb2a49c05ef0e431485a22400af20d33226dc0764d891d09e724127" + [[package]] name = "core-foundation" version = "0.6.4" @@ -370,6 +738,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" +dependencies = [ + "crossbeam-utils 0.7.0", +] + [[package]] name = "crossbeam-deque" version = "0.7.2" @@ -500,6 +877,17 @@ dependencies = [ "syn 0.15.44", ] +[[package]] +name = "derive_more" +version = "0.99.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8" +dependencies = [ + "proc-macro2 1.0.7", + "quote 1.0.2", + "syn 1.0.13", +] + [[package]] name = "digest" version = "0.8.1" @@ -575,6 +963,18 @@ dependencies = [ "syn 0.15.44", ] +[[package]] +name = "enum-as-inner" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900a6c7fbe523f4c2884eaf26b57b81bb69b6810a01a236390a7ac021d09492e" +dependencies = [ + "heck", + "proc-macro2 1.0.7", + "quote 1.0.2", + "syn 1.0.13", +] + [[package]] name = "error-chain" version = "0.12.1" @@ -853,6 +1253,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "generic-array" version = "0.12.3" @@ -1067,7 +1476,7 @@ dependencies = [ "bytes 0.4.12", "fnv", "futures 0.1.29", - "http", + "http 0.1.21", "indexmap", "log", "slab", @@ -1075,6 +1484,25 @@ dependencies = [ "tokio-io", ] +[[package]] +name = "h2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9433d71e471c1736fd5a61b671fc0b148d7a2992f666c958d03cd8feb3b88d1" +dependencies = [ + "bytes 0.5.3", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.0", + "indexmap", + "log", + "slab", + "tokio 0.2.7", + "tokio-util", +] + [[package]] name = "heck" version = "0.3.1" @@ -1114,6 +1542,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b" +dependencies = [ + "bytes 0.5.3", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.1.0" @@ -1122,7 +1561,7 @@ checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" dependencies = [ "bytes 0.4.12", "futures 0.1.29", - "http", + "http 0.1.21", "tokio-buf", ] @@ -1156,8 +1595,8 @@ dependencies = [ "bytes 0.4.12", "futures 0.1.29", "futures-cpupool", - "h2", - "http", + "h2 0.1.26", + "http 0.1.21", "http-body", "httparse", "iovec", @@ -1276,6 +1715,12 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "language-tags" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" + [[package]] name = "lazy_static" version = "1.4.0" @@ -1686,6 +2131,16 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "parking_lot" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e98c49ab0b7ce5b222f2cc9193fc4efe11c6d0bd4f648e374684a6857b1cfc" +dependencies = [ + "lock_api 0.3.3", + "parking_lot_core 0.7.0", +] + [[package]] name = "parking_lot_core" version = "0.2.14" @@ -1726,6 +2181,20 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "parking_lot_core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7582838484df45743c8434fbff785e8edf260c28748353d44bc0da32e0ceabf1" +dependencies = [ + "cfg-if", + "cloudabi", + "libc", + "redox_syscall", + "smallvec 1.1.0", + "winapi 0.3.8", +] + [[package]] name = "paste" version = "0.1.6" @@ -1760,6 +2229,26 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pin-project" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7804a463a8d9572f13453c516a5faea534a2403d7ced2f0c7e100eeff072772c" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" +dependencies = [ + "proc-macro2 1.0.7", + "quote 1.0.2", + "syn 1.0.13", +] + [[package]] name = "pin-project-lite" version = "0.1.2" @@ -1782,6 +2271,9 @@ checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" name = "pokebot" version = "0.1.1" dependencies = [ + "actix", + "actix-rt", + "actix-web", "byte-slice-cast", "futures 0.1.29", "futures-preview", @@ -2155,14 +2647,14 @@ version = "0.9.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" dependencies = [ - "base64", + "base64 0.10.1", "bytes 0.4.12", "cookie", "cookie_store", "encoding_rs", "flate2", "futures 0.1.29", - "http", + "http 0.1.21", "hyper", "hyper-tls", "log", @@ -2171,7 +2663,7 @@ dependencies = [ "native-tls", "serde", "serde_json", - "serde_urlencoded", + "serde_urlencoded 0.5.5", "time", "tokio 0.1.22", "tokio-executor", @@ -2199,7 +2691,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" dependencies = [ - "base64", + "base64 0.10.1", "blake2b_simd", "crossbeam-utils 0.6.6", ] @@ -2336,6 +2828,18 @@ dependencies = [ "url 1.7.2", ] +[[package]] +name = "serde_urlencoded" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" +dependencies = [ + "dtoa", + "itoa", + "serde", + "url 2.1.0", +] + [[package]] name = "serde_yaml" version = "0.8.11" @@ -2348,6 +2852,12 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" + [[package]] name = "signal-hook" version = "0.1.12" @@ -2632,6 +3142,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "threadpool" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" +dependencies = [ + "num_cpus", +] + [[package]] name = "time" version = "0.1.42" @@ -2675,11 +3194,17 @@ checksum = "e61fe9bd8b36108a3c679bb6de916e39595a7a7f18c5e314c0014bb1b6ba13f7" dependencies = [ "bytes 0.5.3", "fnv", + "futures-core", "iovec", "lazy_static", + "libc", "memchr", "mio", + "mio-uds", "pin-project-lite", + "signal-hook-registry", + "slab", + "winapi 0.3.8", ] [[package]] @@ -2887,6 +3412,20 @@ dependencies = [ "tokio-reactor", ] +[[package]] +name = "tokio-util" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930" +dependencies = [ + "bytes 0.5.3", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio 0.2.7", +] + [[package]] name = "toml" version = "0.5.5" @@ -2909,7 +3448,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5559ebdf6c2368ddd11e20b11d6bbaf9e46deb803acd7815e93f5a7b4a6d2901" dependencies = [ "byteorder", - "enum-as-inner", + "enum-as-inner 0.2.1", "failure", "futures 0.1.29", "idna 0.1.5", @@ -2927,6 +3466,26 @@ dependencies = [ "url 1.7.2", ] +[[package]] +name = "trust-dns-proto" +version = "0.18.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a7f3a2ab8a919f5eca52a468866a67ed7d3efa265d48a652a9a3452272b413f" +dependencies = [ + "async-trait", + "enum-as-inner 0.3.0", + "failure", + "futures 0.3.1", + "idna 0.2.0", + "lazy_static", + "log", + "rand 0.7.3", + "smallvec 1.1.0", + "socket2", + "tokio 0.2.7", + "url 2.1.0", +] + [[package]] name = "trust-dns-resolver" version = "0.11.1" @@ -2944,7 +3503,26 @@ dependencies = [ "smallvec 0.6.13", "tokio 0.1.22", "tokio-executor", - "trust-dns-proto", + "trust-dns-proto 0.7.4", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.18.0-alpha.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f90b1502b226f8b2514c6d5b37bafa8c200d7ca4102d57dc36ee0f3b7a04a2f" +dependencies = [ + "cfg-if", + "failure", + "futures 0.3.1", + "ipconfig", + "lazy_static", + "log", + "lru-cache", + "resolv-conf", + "smallvec 1.1.0", + "tokio 0.2.7", + "trust-dns-proto 0.18.0-alpha.2", ] [[package]] @@ -2967,9 +3545,9 @@ name = "ts-bookkeeping" version = "0.1.0" source = "git+https://github.com/ReSpeak/tsclientlib#7d82374088c11d3d3171ed07bfef16f4d9482b26" dependencies = [ - "base64", + "base64 0.10.1", "chrono", - "derive_more", + "derive_more 0.14.1", "failure", "heck", "itertools", @@ -2986,11 +3564,11 @@ name = "tsclientlib" version = "0.1.0" source = "git+https://github.com/ReSpeak/tsclientlib#7d82374088c11d3d3171ed07bfef16f4d9482b26" dependencies = [ - "base64", + "base64 0.10.1", "bytes 0.4.12", "chashmap", "chrono", - "derive_more", + "derive_more 0.14.1", "failure", "futures 0.1.29", "futures 0.3.1", @@ -3009,8 +3587,8 @@ dependencies = [ "tokio 0.1.22", "tokio 0.2.7", "tokio-threadpool", - "trust-dns-proto", - "trust-dns-resolver", + "trust-dns-proto 0.7.4", + "trust-dns-resolver 0.11.1", "ts-bookkeeping", "tsproto", "tsproto-packets", @@ -3024,13 +3602,13 @@ source = "git+https://github.com/ReSpeak/tsclientlib#7d82374088c11d3d3171ed07bfe dependencies = [ "aes", "arrayref", - "base64", + "base64 0.10.1", "bitflags", "byteorder", "bytes 0.4.12", "chrono", "curve25519-dalek", - "derive_more", + "derive_more 0.14.1", "eax", "failure", "flakebi-ring", @@ -3061,11 +3639,11 @@ version = "0.1.0" source = "git+https://github.com/ReSpeak/tsclientlib#7d82374088c11d3d3171ed07bfef16f4d9482b26" dependencies = [ "arrayref", - "base64", + "base64 0.10.1", "bitflags", "byteorder", "bytes 0.4.12", - "derive_more", + "derive_more 0.14.1", "failure", "nom", "num-derive", @@ -3080,7 +3658,7 @@ name = "tsproto-structs" version = "0.1.0" source = "git+https://github.com/ReSpeak/tsclientlib#7d82374088c11d3d3171ed07bfef16f4d9482b26" dependencies = [ - "base64", + "base64 0.10.1", "csv", "heck", "lazy_static", @@ -3095,7 +3673,7 @@ name = "tsproto-types" version = "0.1.0" source = "git+https://github.com/ReSpeak/tsclientlib#7d82374088c11d3d3171ed07bfef16f4d9482b26" dependencies = [ - "base64", + "base64 0.10.1", "bitflags", "chrono", "heck", -- cgit v1.2.3-70-g09d2 From 2831c2b60cb61a14c7efee4ab5c0389eb3ad5469 Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 2 Feb 2020 19:50:33 +0100 Subject: Add a very basic template using available info --- Cargo.lock | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 8 ++-- src/audio_player.rs | 29 ++++++++++++- src/bot/master.rs | 22 +++++++--- src/bot/music.rs | 32 +++++++++++++- src/playlist.rs | 10 +++++ src/web_server.rs | 63 +++++++++++++++++++-------- src/youtube_dl.rs | 28 ++++++++++++ static/.gitkeep | 0 templates/base.htm | 14 ++++++ templates/index.htm | 27 ++++++++++++ templates/song.htm | 10 +++++ 12 files changed, 334 insertions(+), 32 deletions(-) create mode 100644 static/.gitkeep create mode 100644 templates/base.htm create mode 100644 templates/index.htm create mode 100644 templates/song.htm (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index e5b821c..13ef6a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,6 +59,26 @@ dependencies = [ "trust-dns-resolver 0.18.0-alpha.2", ] +[[package]] +name = "actix-files" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301482841d3d74483a446ead63cb7d362e187d2c8b603f13d91995621ea53c46" +dependencies = [ + "actix-http", + "actix-service", + "actix-web", + "bitflags", + "bytes 0.5.3", + "derive_more 0.99.2", + "futures 0.3.1", + "log", + "mime", + "mime_guess", + "percent-encoding 2.1.0", + "v_htmlescape", +] + [[package]] name = "actix-http" version = "1.0.1" @@ -391,6 +411,54 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +[[package]] +name = "askama" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a1fb9e41eb366cbcd267da2094be5b7e62fdbca9f82091e7503e80f885050d" +dependencies = [ + "actix-web", + "askama_derive", + "askama_escape", + "askama_shared", + "bytes 0.5.3", + "futures 0.3.1", + "mime", + "mime_guess", +] + +[[package]] +name = "askama_derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1012c270085fa35ece6a48a569544fde85b6d9ee41074c7b706cc912a03f939" +dependencies = [ + "askama_shared", + "nom 5.1.0", + "proc-macro2 1.0.7", + "quote 1.0.2", + "syn 1.0.13", +] + +[[package]] +name = "askama_escape" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a577aeba5fec1aafb9f195d98cfcc38a78b588e4ebf9b15f62ca1c7aa33795a" + +[[package]] +name = "askama_shared" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee517f4e33c27b129928e71d8a044d54c513e72e0b72ec5c4f5f1823e9de353" +dependencies = [ + "askama_escape", + "humansize", + "num-traits", + "serde", + "toml", +] + [[package]] name = "async-trait" version = "0.1.22" @@ -1571,6 +1639,12 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" +[[package]] +name = "humansize" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" + [[package]] name = "humantime" version = "1.3.0" @@ -1972,6 +2046,16 @@ dependencies = [ "version_check 0.1.5", ] +[[package]] +name = "nom" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c433f4d505fe6ce7ff78523d2fa13a0b9f2690e181fc26168bcbe5ccc5d14e07" +dependencies = [ + "memchr", + "version_check 0.1.5", +] + [[package]] name = "num-bigint" version = "0.2.4" @@ -2272,8 +2356,10 @@ name = "pokebot" version = "0.1.1" dependencies = [ "actix", + "actix-files", "actix-rt", "actix-web", + "askama", "byte-slice-cast", "futures 0.1.29", "futures-preview", @@ -3077,7 +3163,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58898aa9e9462043aa48c62021ba284a6906d210bde13602e65be8329c364d33" dependencies = [ - "nom", + "nom 4.2.3", "proc-macro2 0.4.30", "quote 0.6.13", "syn 0.15.44", @@ -3645,7 +3731,7 @@ dependencies = [ "bytes 0.4.12", "derive_more 0.14.1", "failure", - "nom", + "nom 4.2.3", "num-derive", "num-traits", "rental", @@ -3796,6 +3882,37 @@ dependencies = [ "rand 0.6.5", ] +[[package]] +name = "v_escape" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "660b101c07b5d0863deb9e7fb3138777e858d6d2a79f9e6049a27d1cc77c6da6" +dependencies = [ + "v_escape_derive", +] + +[[package]] +name = "v_escape_derive" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ca2a14bc3fc5b64d188b087a7d3a927df87b152e941ccfbc66672e20c467ae" +dependencies = [ + "nom 4.2.3", + "proc-macro2 1.0.7", + "quote 1.0.2", + "syn 1.0.13", +] + +[[package]] +name = "v_htmlescape" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33e939c0d8cf047514fb6ba7d5aac78bc56677a6938b2ee67000b91f2e97e41" +dependencies = [ + "cfg-if", + "v_escape", +] + [[package]] name = "vcpkg" version = "0.2.8" @@ -3926,7 +4043,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" dependencies = [ - "nom", + "nom 4.2.3", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1fdb258..15b80f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,9 @@ gstreamer-audio = "0.15.0" byte-slice-cast = "0.3.5" serde_json = "1.0.44" serde = "1.0.104" -rand = { version = "0.7.3", features = ["small_rng"] } -actix-web = "2.0.0" -actix-rt = "1.0.0" actix = "0.9.0" +actix-rt = "1.0.0" +actix-web = "2.0.0" +actix-files = "0.2.1" +askama = { version = "0.9.0", features = ["with-actix-web"] } +rand = { version = "0.7.3", features = ["small_rng"] } diff --git a/src/audio_player.rs b/src/audio_player.rs index cdb04d7..4df213f 100644 --- a/src/audio_player.rs +++ b/src/audio_player.rs @@ -13,6 +13,8 @@ use log::{debug, error, info, warn}; use std::sync::{Arc, RwLock}; use tokio02::sync::mpsc::UnboundedSender; +use crate::youtube_dl::AudioMetadata; + static GST_INIT: Once = Once::new(); #[derive(Copy, Clone, Debug)] @@ -33,8 +35,10 @@ pub struct AudioPlayer { bus: gst::Bus, http_src: gst::Element, + volume_f64: RwLock, volume: gst::Element, sender: Arc>>, + currently_playing: RwLock>, } fn make_element(factoryname: &str, display_name: &str) -> Result { @@ -111,8 +115,10 @@ impl AudioPlayer { bus, http_src, + volume_f64: RwLock::new(0.0), volume, sender, + currently_playing: RwLock::new(None), }) } @@ -173,7 +179,16 @@ impl AudioPlayer { Ok((audio_bin, volume, ghost_pad)) } - pub fn set_source_url(&self, location: String) -> Result<(), AudioPlayerError> { + pub fn set_metadata(&self, data: AudioMetadata) -> Result<(), AudioPlayerError> { + self.set_source_url(data.url.clone())?; + + let mut currently_playing = self.currently_playing.write().unwrap(); + *currently_playing = Some(data); + + Ok(()) + } + + fn set_source_url(&self, location: String) -> Result<(), AudioPlayerError> { info!("Setting location URI: {}", location); self.http_src.set_property("location", &location)?; @@ -181,6 +196,7 @@ impl AudioPlayer { } pub fn set_volume(&self, volume: f64) -> Result<(), AudioPlayerError> { + *self.volume_f64.write().unwrap() = volume; let db = 50.0 * volume.log10(); info!("Setting volume: {} -> {} dB", volume, db); @@ -203,9 +219,20 @@ impl AudioPlayer { } } + pub fn volume(&self) -> f64 { + *self.volume_f64.read().unwrap() + } + + pub fn currently_playing(&self) -> Option { + self.currently_playing.read().unwrap().clone() + } + pub fn reset(&self) -> Result<(), AudioPlayerError> { info!("Setting pipeline state to null"); + let mut currently_playing = self.currently_playing.write().unwrap(); + *currently_playing = None; + self.pipeline.set_state(gst::State::Null)?; Ok(()) diff --git a/src/bot/master.rs b/src/bot/master.rs index bc38cca..10a7572 100644 --- a/src/bot/master.rs +++ b/src/bot/master.rs @@ -213,14 +213,24 @@ impl MasterBot { Ok(()) } - pub fn names(&self) -> Vec { + pub fn bot_datas(&self) -> Vec { let music_bots = self.music_bots.read().unwrap(); - music_bots - .connected_bots - .iter() - .map(|(_, b)| b.name().to_owned()) - .collect() + let len = music_bots.connected_bots.len(); + let mut result = Vec::with_capacity(len); + for (name, bot) in &music_bots.connected_bots { + let bot_data = crate::web_server::BotData { + name: name.clone(), + state: bot.state(), + volume: bot.volume(), + currently_playing: bot.currently_playing(), + playlist: bot.playlist_to_vec(), + }; + + result.push(bot_data); + } + + result } pub fn quit(&self, reason: String) { diff --git a/src/bot/music.rs b/src/bot/music.rs index 920f1cb..d53e4a8 100644 --- a/src/bot/music.rs +++ b/src/bot/music.rs @@ -44,7 +44,7 @@ fn parse_seek(mut amount: &str) -> Result { } } -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum State { Playing, Paused, @@ -52,6 +52,18 @@ pub enum State { EndOfStream, } +impl std::fmt::Display for State { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + match self { + State::Playing => write!(fmt, "Playing"), + State::Paused => write!(fmt, "Paused"), + State::Stopped | State::EndOfStream => write!(fmt, "Stopped"), + }?; + + Ok(()) + } +} + #[derive(Debug)] pub enum MusicBotMessage { TextMessage(Message), @@ -176,7 +188,7 @@ impl MusicBot { self.send_message(&format!("Playing {}", ts::underline(&metadata.title))); self.set_description(&format!("Currently playing '{}'", metadata.title)); self.player.reset().unwrap(); - self.player.set_source_url(metadata.url).unwrap(); + self.player.set_metadata(metadata).unwrap(); self.player.play().unwrap(); } @@ -211,6 +223,22 @@ impl MusicBot { &self.name } + pub fn state(&self) -> State { + *self.state.read().expect("RwLock was not poisoned") + } + + pub fn volume(&self) -> f64 { + self.player.volume() + } + + pub fn currently_playing(&self) -> Option { + self.player.currently_playing() + } + + pub fn playlist_to_vec(&self) -> Vec { + self.playlist.read().unwrap().to_vec() + } + pub fn my_channel(&self) -> ChannelId { self.teamspeak .as_ref() diff --git a/src/playlist.rs b/src/playlist.rs index 87c1c98..445f8a5 100644 --- a/src/playlist.rs +++ b/src/playlist.rs @@ -28,6 +28,16 @@ impl Playlist { res } + pub fn to_vec(&self) -> Vec { + let (a, b) = self.data.as_slices(); + + let mut res = a.to_vec(); + res.extend_from_slice(b); + res.reverse(); + + res + } + pub fn is_empty(&self) -> bool { self.data.is_empty() } diff --git a/src/web_server.rs b/src/web_server.rs index 1edbc50..94f043a 100644 --- a/src/web_server.rs +++ b/src/web_server.rs @@ -1,21 +1,12 @@ use std::sync::Arc; use actix::{Actor, Addr, Handler, Message, SyncArbiter, SyncContext}; -use actix_web::{get, middleware::Logger, web, App, HttpResponse, HttpServer, Responder}; +use actix_web::{get, middleware::Logger, web, App, HttpServer, Responder}; +use askama::actix_web::TemplateIntoResponse; +use askama::Template; use crate::bot::MasterBot; - -struct GetNames; - -impl Message for GetNames { - type Result = Result, ()>; -} - -#[get("/")] -async fn index(bot: web::Data>) -> impl Responder { - let names = bot.send(GetNames).await.unwrap().unwrap(); - HttpResponse::Ok().body(&format!("Music bots connected: {}", names.join(", "))) -} +use crate::youtube_dl::AudioMetadata; pub struct WebServerArgs { pub domain: String, @@ -33,6 +24,7 @@ pub async fn start(args: WebServerArgs) -> std::io::Result<()> { .data(bot_addr.clone()) .wrap(Logger::default()) .service(index) + .service(actix_files::Files::new("/static", "static/")) }) .bind(args.bind_address)? .run() @@ -49,12 +41,49 @@ impl Actor for BotExecutor { type Context = SyncContext; } -impl Handler for BotExecutor { - type Result = Result, ()>; +impl Handler for BotExecutor { + type Result = Result, ()>; - fn handle(&mut self, _: GetNames, _: &mut Self::Context) -> Self::Result { + fn handle(&mut self, _: PlaylistRequest, _: &mut Self::Context) -> Self::Result { let bot = &self.0; - Ok(bot.names()) + Ok(bot.bot_datas()) + } +} + +struct PlaylistRequest; + +impl Message for PlaylistRequest { + type Result = Result, ()>; +} + +#[derive(Template)] +#[template(path = "index.htm")] +struct PlaylistTemplate<'a> { + bots: &'a [BotData], +} + +#[derive(Debug)] +pub struct BotData { + pub name: String, + pub state: crate::bot::State, + pub volume: f64, + pub currently_playing: Option, + pub playlist: Vec, +} + +#[get("/")] +async fn index(bot: web::Data>) -> impl Responder { + let bot_datas = match bot.send(PlaylistRequest).await.unwrap() { + Ok(data) => data, + Err(_) => { + //error!("Playlist error: {}", e); + Vec::with_capacity(0) + } + }; + + PlaylistTemplate { + bots: &bot_datas[..], } + .into_response() } diff --git a/src/youtube_dl.rs b/src/youtube_dl.rs index b62d4b3..99e50e7 100644 --- a/src/youtube_dl.rs +++ b/src/youtube_dl.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use futures::compat::Future01CompatExt; use std::process::{Command, Stdio}; use tokio_process::CommandExt; @@ -9,7 +11,33 @@ use log::debug; #[derive(Serialize, Deserialize, Clone, Debug)] pub struct AudioMetadata { pub url: String, + pub webpage_url: String, pub title: String, + pub thumbnail: Option, + #[serde(default, deserialize_with = "duration_deserialize")] + #[serde(serialize_with = "duration_serialize")] + pub duration: Option, + #[serde(skip)] + pub added_by: String, +} + +fn duration_serialize(d: &Option, s: S) -> Result +where + S: serde::Serializer, +{ + match d { + Some(d) => s.serialize_some(&d.as_secs_f64()), + None => s.serialize_none(), + } +} + +fn duration_deserialize<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let dur: Option = Deserialize::deserialize(deserializer)?; + + Ok(dur.map(|v| Duration::from_secs_f64(v))) } pub async fn get_audio_download_url(uri: String) -> Result { diff --git a/static/.gitkeep b/static/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/templates/base.htm b/templates/base.htm new file mode 100644 index 0000000..7810f21 --- /dev/null +++ b/templates/base.htm @@ -0,0 +1,14 @@ + + + + + + + {% block title %}{{ title }} - PokeBot{% endblock %} + + +
+ {% block content %}{% endblock %} +
+ + diff --git a/templates/index.htm b/templates/index.htm new file mode 100644 index 0000000..2584603 --- /dev/null +++ b/templates/index.htm @@ -0,0 +1,27 @@ +{% extends "base.htm" %} + +{% block title %}Overview{% endblock %} + +{% block content %} +

Bots

+
    + {% for bot in bots %} +

    {{ bot.name }}

    +
    State: {{ bot.state }}
    +
    Volume: {{ bot.volume * 100.0 }}%
    + {% match bot.currently_playing %} + {% when Some with (current) %} + Currently playing: + {% let item = current %} + {% include "song.htm" %} + {% when None %} + {% endmatch %} + + {% for item in bot.playlist %} +
  • + {% include "song.htm" %} +
  • + {% endfor %} + {% endfor %} +
+{% endblock %} diff --git a/templates/song.htm b/templates/song.htm new file mode 100644 index 0000000..93f4fec --- /dev/null +++ b/templates/song.htm @@ -0,0 +1,10 @@ +{{ item.title }} +{% match item.duration %} + {% when Some with (duration) %} + {% let secs = duration.as_secs() %} + {% let mins = secs / 60 %} + {% let submin_secs = secs % 60 %} + ({{ "{:02}"|format(mins) }}:{{ "{:02}"|format(submin_secs) }}) + {% when None %} + (--:--) +{% endmatch %} -- cgit v1.2.3-70-g09d2 From 5eea11a03c11551091b2c72f48590aec7f5410f0 Mon Sep 17 00:00:00 2001 From: Jokler Date: Mon, 3 Feb 2020 01:14:05 +0100 Subject: Add a json /api/bots endpoint for data retrieval --- Cargo.lock | 1 + Cargo.toml | 1 + src/bot/master.rs | 14 +++++++++ src/bot/music.rs | 3 +- src/web_server.rs | 90 ++++++++++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 94 insertions(+), 15 deletions(-) (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index 13ef6a1..9117117 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2361,6 +2361,7 @@ dependencies = [ "actix-web", "askama", "byte-slice-cast", + "derive_more 0.99.2", "futures 0.1.29", "futures-preview", "futures-util", diff --git a/Cargo.toml b/Cargo.toml index 15b80f7..d271d7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,3 +40,4 @@ actix-web = "2.0.0" actix-files = "0.2.1" askama = { version = "0.9.0", features = ["with-actix-web"] } rand = { version = "0.7.3", features = ["small_rng"] } +derive_more = "0.99.2" diff --git a/src/bot/master.rs b/src/bot/master.rs index 10a7572..67867ef 100644 --- a/src/bot/master.rs +++ b/src/bot/master.rs @@ -213,6 +213,20 @@ impl MasterBot { Ok(()) } + pub fn bot_data(&self, name: String) -> Option { + let music_bots = self.music_bots.read().unwrap(); + + let bot = music_bots.connected_bots.get(&name)?; + + Some(crate::web_server::BotData { + name: name, + state: bot.state(), + volume: bot.volume(), + currently_playing: bot.currently_playing(), + playlist: bot.playlist_to_vec(), + }) + } + pub fn bot_datas(&self) -> Vec { let music_bots = self.music_bots.read().unwrap(); diff --git a/src/bot/music.rs b/src/bot/music.rs index d53e4a8..0def280 100644 --- a/src/bot/music.rs +++ b/src/bot/music.rs @@ -5,6 +5,7 @@ use std::thread; use humantime; use log::{debug, info}; +use serde::Serialize; use structopt::StructOpt; use tokio02::sync::mpsc::UnboundedSender; use tsclientlib::{data, ChannelId, ClientId, ConnectOptions, Identity, Invoker, MessageTarget}; @@ -44,7 +45,7 @@ fn parse_seek(mut amount: &str) -> Result { } } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize)] pub enum State { Playing, Paused, diff --git a/src/web_server.rs b/src/web_server.rs index 94f043a..02c57e7 100644 --- a/src/web_server.rs +++ b/src/web_server.rs @@ -1,9 +1,13 @@ use std::sync::Arc; use actix::{Actor, Addr, Handler, Message, SyncArbiter, SyncContext}; -use actix_web::{get, middleware::Logger, web, App, HttpServer, Responder}; +use actix_web::{ + get, middleware::Logger, web, App, HttpResponse, HttpServer, Responder, ResponseError, +}; use askama::actix_web::TemplateIntoResponse; use askama::Template; +use derive_more::Display; +use serde::Serialize; use crate::bot::MasterBot; use crate::youtube_dl::AudioMetadata; @@ -24,6 +28,7 @@ pub async fn start(args: WebServerArgs) -> std::io::Result<()> { .data(bot_addr.clone()) .wrap(Logger::default()) .service(index) + .service(web::scope("/api").service(get_bot_list).service(get_bot)) .service(actix_files::Files::new("/static", "static/")) }) .bind(args.bind_address)? @@ -41,29 +46,47 @@ impl Actor for BotExecutor { type Context = SyncContext; } -impl Handler for BotExecutor { +struct BotDataListRequest; + +impl Message for BotDataListRequest { + // A plain Vec does not work for some reason + type Result = Result, ()>; +} + +impl Handler for BotExecutor { type Result = Result, ()>; - fn handle(&mut self, _: PlaylistRequest, _: &mut Self::Context) -> Self::Result { + fn handle(&mut self, _: BotDataListRequest, _: &mut Self::Context) -> Self::Result { let bot = &self.0; Ok(bot.bot_datas()) } } -struct PlaylistRequest; +struct BotDataRequest(String); -impl Message for PlaylistRequest { - type Result = Result, ()>; +impl Message for BotDataRequest { + type Result = Option; +} + +impl Handler for BotExecutor { + type Result = Option; + + fn handle(&mut self, r: BotDataRequest, _: &mut Self::Context) -> Self::Result { + let name = r.0; + let bot = &self.0; + + bot.bot_data(name) + } } #[derive(Template)] #[template(path = "index.htm")] -struct PlaylistTemplate<'a> { +struct OverviewTemplate<'a> { bots: &'a [BotData], } -#[derive(Debug)] +#[derive(Debug, Serialize)] pub struct BotData { pub name: String, pub state: crate::bot::State, @@ -74,16 +97,55 @@ pub struct BotData { #[get("/")] async fn index(bot: web::Data>) -> impl Responder { - let bot_datas = match bot.send(PlaylistRequest).await.unwrap() { + let bot_datas = match bot.send(BotDataListRequest).await.unwrap() { Ok(data) => data, - Err(_) => { - //error!("Playlist error: {}", e); - Vec::with_capacity(0) - } + Err(_) => Vec::with_capacity(0), }; - PlaylistTemplate { + OverviewTemplate { bots: &bot_datas[..], } .into_response() } + +#[get("/bots")] +async fn get_bot_list(bot: web::Data>) -> impl Responder { + let bot_datas = match bot.send(BotDataListRequest).await.unwrap() { + Ok(data) => data, + Err(_) => Vec::with_capacity(0), + }; + + web::Json(bot_datas) +} + +#[derive(Serialize)] +struct ApiError { + error: String, + description: String, +} + +#[derive(Debug, Display)] +enum ApiErrorKind { + #[display(fmt = "Not Found")] + NotFound, +} + +impl ResponseError for ApiErrorKind { + fn error_response(&self) -> HttpResponse { + match *self { + ApiErrorKind::NotFound => HttpResponse::NotFound().json(ApiError { + error: self.to_string(), + description: String::from("The requested resource was not found"), + }), + } + } +} + +#[get("/bots/{name}")] +async fn get_bot(bot: web::Data>, name: web::Path) -> impl Responder { + if let Some(bot_data) = bot.send(BotDataRequest(name.into_inner())).await.unwrap() { + Ok(web::Json(bot_data)) + } else { + Err(ApiErrorKind::NotFound) + } +} -- cgit v1.2.3-70-g09d2