diff --git a/Cargo.lock b/Cargo.lock index 732ef8f..bac09c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,12 +15,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ascii" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf56136a5198c7b01a49e3afcbef6cf84597273d298f54432926024107b0109" - [[package]] name = "atty" version = "0.2.14" @@ -165,7 +159,6 @@ dependencies = [ name = "desubot" version = "0.1.0" dependencies = [ - "ascii", "bytes", "env_logger", "futures", @@ -174,7 +167,9 @@ dependencies = [ "hyper-rustls", "hyper-tls", "log 0.4.11", + "markov", "multipart", + "rand 0.7.3", "reqwest", "rusqlite", "serde_json", @@ -187,6 +182,18 @@ dependencies = [ "uuid", ] +[[package]] +name = "dtoa" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "encoding_rs" version = "0.8.26" @@ -221,6 +228,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +[[package]] +name = "fixedbitset" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" + [[package]] name = "fnv" version = "1.0.7" @@ -369,6 +382,15 @@ dependencies = [ "slab", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.1.15" @@ -568,6 +590,15 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.6" @@ -616,6 +647,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" + [[package]] name = "log" version = "0.3.9" @@ -634,6 +671,21 @@ dependencies = [ "cfg-if 0.1.10", ] +[[package]] +name = "markov" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6ad68e26d51a9558f65e93b9795c9422630d0932717a3235668bb9ab71e3fd" +dependencies = [ + "getopts", + "itertools", + "petgraph", + "rand 0.7.3", + "serde", + "serde_derive", + "serde_yaml", +] + [[package]] name = "matches" version = "0.1.8" @@ -862,6 +914,16 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "petgraph" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "phf" version = "0.7.24" @@ -1416,6 +1478,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7" +dependencies = [ + "dtoa", + "linked-hash-map", + "serde", + "yaml-rust", +] + [[package]] name = "sha1" version = "0.6.0" @@ -1727,6 +1801,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + [[package]] name = "unicode-xid" version = "0.2.1" @@ -1973,3 +2053,12 @@ dependencies = [ "winapi 0.2.8", "winapi-build", ] + +[[package]] +name = "yaml-rust" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f0c922f1a334134dc2f7a8b67dc5d25f0735263feec974345ff706bcf20b0d" +dependencies = [ + "linked-hash-map", +] diff --git a/Cargo.toml b/Cargo.toml index f018193..af78a44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,5 +29,6 @@ sha1 = "*" env_logger = "0.7" log = { version = "^0.4.5", features = ["std"] } subprocess = "0.2.6" -ascii = "1.0.0" -serde_json = "1.0" \ No newline at end of file +serde_json = "1.0" +markov = "1.1.0" +rand = "0.7.3" \ No newline at end of file diff --git a/src/commands.rs b/src/commands.rs index 1d2245f..814136a 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1,8 +1,10 @@ use crate::db; +use crate::errors::Error; use html_escape::encode_text; +use markov::Chain; use telegram_bot::prelude::*; use telegram_bot::{Api, Message, ParseMode}; -use crate::errors::Error; +use rand::Rng; pub(crate) async fn here(api: Api, message: Message) -> Result<(), Error> { let members: Vec = db::get_members(message.chat.id()).unwrap(); @@ -39,7 +41,10 @@ pub(crate) async fn top(api: Api, message: Message) -> Result<(), Error> { let mut msg = "Your top using words:\n
".to_string();
     let mut counter = 1;
     for word in top.iter() {
-        msg = format!("{} {} {} - {}\n", msg, counter, word.word, word.count);
+        msg = format!(
+            "{} {} {} - {}\n",
+            msg, counter, word.word, word.count
+        );
         counter += 1;
     }
     msg = format!("{}{}", msg, "
"); @@ -52,4 +57,26 @@ pub(crate) async fn top(api: Api, message: Message) -> Result<(), Error> { } //api.send(message.chat.text("Text to message chat")).await?; //api.send(message.from.text("Private text")).await?; - Ok(())} + Ok(()) +} + +pub(crate) async fn markov_all(api: Api, message: Message) -> Result<(), Error> { + let messages = db::get_random_messages().await?; + let mut chain = Chain::new(); + chain.feed(messages); + let mut sentences = chain.generate(); + let mut msg = String::new(); + for _ in 1..rand::thread_rng().gen_range(2, 10) { + msg = format!("{} {}", msg, sentences.pop().unwrap()); + } + match api + .send(message.text_reply(msg.trim()).parse_mode(ParseMode::Html)) + .await + { + Ok(_) => debug!("/top command sent to {}", message.chat.id()), + Err(_) => warn!("/top command sent failed to {}", message.chat.id()), + } + //api.send(message.chat.text("Text to message chat")).await?; + //api.send(message.from.text("Private text")).await?; + Ok(()) +} diff --git a/src/db.rs b/src/db.rs index 96cb938..7c0a566 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,6 +1,6 @@ use crate::errors; use crate::utils; -use rusqlite::{params, named_params, Connection, Error, Result}; +use rusqlite::{named_params, params, Connection, Error, Result}; use std::time::SystemTime; use telegram_bot::*; @@ -95,6 +95,17 @@ pub(crate) fn get_confs() -> Result> { Ok(confs) } */ +pub(crate) async fn get_random_messages() -> Result, Error> { + let conn = open()?; + let mut stmt = conn.prepare("SELECT text FROM messages ORDER BY RANDOM() LIMIT 50")?; + let mut rows = stmt.query_named(named_params![])?; + let mut messages = Vec::new(); + + while let Some(row) = rows.next()? { + messages.push(row.get(0)?) + } + Ok(messages) +} pub(crate) fn get_members(id: telegram_bot::ChatId) -> Result> { let conn = open()?; diff --git a/src/main.rs b/src/main.rs index 7292883..bfc7d96 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,7 @@ async fn handler(api: Api, message: Message, token: String) -> Result<(), errors "/here" => commands::here(api, message).await?, "/top" => commands::top(api, message).await?, "/stat" => commands::top(api, message).await?, + "/markov_all" => commands::markov_all(api, message).await?, _ => (), } }