diff --git a/src/commands.rs b/src/commands.rs index 0eccab0..1d2245f 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1,12 +1,13 @@ use crate::db; use html_escape::encode_text; use telegram_bot::prelude::*; -use telegram_bot::{Api, Error, Message, ParseMode, }; +use telegram_bot::{Api, Message, ParseMode}; +use crate::errors::Error; pub(crate) async fn here(api: Api, message: Message) -> Result<(), Error> { let members: Vec = db::get_members(message.chat.id()).unwrap(); for u in &members { - debug!("Found user {:?}", u); + debug!("Found user {:?} in chat {}", u, message.chat.id()); } let mut msg = "I summon you, ".to_string(); for user in members { @@ -25,10 +26,30 @@ pub(crate) async fn here(api: Api, message: Message) -> Result<(), Error> { .send(message.text_reply(msg).parse_mode(ParseMode::Html)) .await { - Ok(_) => debug!("@here command sent to {}", message.from.id), - Err(_) => warn!("@here command sent failed to {}", message.from.id), + Ok(_) => debug!("/here command sent to {}", message.chat.id()), + Err(_) => warn!("/here 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(()) } + +pub(crate) async fn top(api: Api, message: Message) -> Result<(), Error> { + let top = db::get_top(&message).await?; + 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);
+        counter += 1;
+    }
+    msg = format!("{}{}", msg, "
"); + match api + .send(message.text_reply(msg).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 ff8ac2e..96cb938 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,6 +1,6 @@ use crate::errors; use crate::utils; -use rusqlite::{params, Connection, Error, Result}; +use rusqlite::{params, named_params, Connection, Error, Result}; use std::time::SystemTime; use telegram_bot::*; @@ -10,6 +10,11 @@ pub struct Conf { title: String, date: i32, } +#[derive(Debug, Clone)] +pub struct TopWord { + pub word: String, + pub count: i32, +} pub(crate) fn open() -> Result { let path = "./memory.sqlite3"; @@ -250,11 +255,10 @@ pub(crate) async fn add_file( pub(crate) async fn get_file(file_id: String) -> Result { let conn = open()?; let file_rowid = match { conn.prepare("SELECT rowid FROM file WHERE file_id = :file_id")? } - .query_row(params![file_id], |row| row.get(0)) { + .query_row(params![file_id], |row| row.get(0)) + { Ok(id) => Ok(id), - Err(_) => { - Err(errors::Error::FileNotFound) - } + Err(_) => Err(errors::Error::FileNotFound), }; file_rowid @@ -330,8 +334,8 @@ pub(crate) async fn add_sentence(message: &telegram_bot::Message) -> Result<(), Ok(id) => { debug!("Added {}: rowid: {}", &word, id); match add_relation(id, msg_rowid, message).await { - Ok(_) => {}, - Err(e) => panic!("SQLITE3 Error: Relations failed: {:?}", e) + Ok(_) => {} + Err(e) => panic!("SQLITE3 Error: Relations failed: {:?}", e), } } Err(_) => debug!("Word {} is in stop list.", &word), @@ -341,6 +345,39 @@ pub(crate) async fn add_sentence(message: &telegram_bot::Message) -> Result<(), Ok(()) } +pub(crate) async fn get_top( + message: &telegram_bot::Message, +) -> Result, errors::Error> { + let user_id = i64::from(message.from.id); + let conf_id = i64::from(message.chat.id()); + + let conn = open()?; + let mut stmt = conn.prepare(" + SELECT w.word, COUNT(*) as count FROM relations r + LEFT JOIN word w ON w.id = r.word_id + LEFT JOIN `user` u ON u.id = r.user_id + WHERE u.id = :user_id AND + r.conf_id = :conf_id AND + r.id > ( + SELECT IFNULL(MAX(relation_id), 0) FROM reset WHERE user_id = :user_id AND conf_id = :conf_id + ) + GROUP BY w.word + ORDER BY count DESC + LIMIT 10 + ")?; + + let mut rows = stmt.query_named(named_params! {":user_id": user_id, ":conf_id": conf_id})?; + let mut top = Vec::new(); + + while let Some(row) = rows.next()? { + top.push(TopWord { + word: row.get(0)?, + count: row.get(1)?, + }) + } + Ok(top) +} + // SCHEME static SCHEME: &str = " -- diff --git a/src/main.rs b/src/main.rs index 7aa43e2..b711ab5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,13 +26,11 @@ async fn handler(api: Api, message: Message, token: String) -> Result<(), errors db::add_sentence(&message).await?; match data.as_str() { "/here" => commands::here(api, message).await?, + "/top" => commands::top(api, message).await?, _ => (), } } - MessageKind::Photo { - ref caption, - .. - } => { + MessageKind::Photo { ref caption, .. } => { let title = utils::get_title(&message); info!( "<{}({})>[{}({})]: *PHOTO* {}", @@ -114,8 +112,8 @@ async fn handler(api: Api, message: Message, token: String) -> Result<(), errors async fn main() -> Result<(), errors::Error> { env_logger::from_env(Env::default().default_filter_or("info")).init(); match db::update_scheme() { - Ok(_) => {}, - Err(e) => panic!("Database error: {:?}", e) + Ok(_) => {} + Err(e) => panic!("Database error: {:?}", e), } let token = match env::var("TELEGRAM_BOT_TOKEN") { Ok(token) => token, diff --git a/src/utils.rs b/src/utils.rs index 5e5f223..bafdfee 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -9,7 +9,7 @@ use crate::db; use crate::errors; extern crate reqwest; use serde_json::Value; -use subprocess::{Exec, }; +use subprocess::Exec; pub(crate) fn get_title(message: &Message) -> String { match &message.chat { @@ -81,13 +81,12 @@ pub(crate) async fn get_files( hasher.update(&content); let file_hash = hasher.digest().to_string(); match db::get_file(file_hash.clone()).await { - Ok(_) => { - } + Ok(_) => {} Err(_) => { let mut dest = File::create(path.clone())?; match dest.write(&content) { - Ok(_) => {}, - Err(e) => panic!("IO Error: Couldn't save file: {:?}", e) + Ok(_) => {} + Err(e) => panic!("IO Error: Couldn't save file: {:?}", e), } } };