summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaweł Dybiec <pawel@dybiec.info>2022-12-27 15:39:23 +0000
committerPaweł Dybiec <pawel@dybiec.info>2022-12-27 15:39:23 +0000
commit96a9ee11414d8468f91e28619b14d41650fbdcb1 (patch)
treea8fa0dec196ff41652fd76d8e5251427ded5e2ec
parentAdd basic model for messages + parsing (diff)
Use db for static strings
-rw-r--r--Cargo.lock31
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs76
3 files changed, 103 insertions, 5 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0588ad8..175aac8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -928,6 +928,36 @@ dependencies = [
 ]
 
 [[package]]
+name = "sqlite"
+version = "0.30.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12e072cb5fb89b3fe5e9c9584676348feb503f9fb3ae829d9868171bc5372d48"
+dependencies = [
+ "libc",
+ "sqlite3-sys",
+]
+
+[[package]]
+name = "sqlite3-src"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1815a7a02c996eb8e5c64f61fcb6fd9b12e593ce265c512c5853b2513635691"
+dependencies = [
+ "cc",
+ "pkg-config",
+]
+
+[[package]]
+name = "sqlite3-sys"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d47c99824fc55360ba00caf28de0b8a0458369b832e016a64c13af0ad9fbb9ee"
+dependencies = [
+ "libc",
+ "sqlite3-src",
+]
+
+[[package]]
 name = "syn"
 version = "1.0.107"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1217,6 +1247,7 @@ dependencies = [
  "reqwest",
  "serde",
  "serde_json",
+ "sqlite",
  "tokio",
  "tokio-macros",
  "tracing",
diff --git a/Cargo.toml b/Cargo.toml
index 43bc0e4..32d2dcb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,6 +13,7 @@ futures-util = { version = "0.3.25", features = ["tokio-io"] }
 reqwest = { version = "0.11.13", features = ["serde_json", "json"] }
 serde = { version = "1.0.151", features = ["serde_derive"] }
 serde_json = "1.0.91"
+sqlite = "0.30.3"
 tokio = { version = "1.23.0", features = ["full"] }
 tokio-macros = "1.8.2"
 tracing = "0.1.37"
diff --git a/src/main.rs b/src/main.rs
index b735100..c2d2be3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,9 +1,30 @@
 mod mattermost;
+use std::path::Path;
+
 use anyhow::anyhow;
 use tokio::{self};
-use tracing::debug;
+use tracing::{debug, warn};
 
-struct Vav {}
+struct Vav {
+    db_connection: Option<sqlite::ConnectionWithFullMutex>
+}
+impl Vav{
+    fn new<T:AsRef<Path>>(path:Option<T>) -> Self {
+        let ret = Self{
+            db_connection:path.and_then(|path|sqlite::Connection::open_with_full_mutex(path).ok()),
+        };
+        if let Some(connection) = &ret.db_connection{
+            let create_table_res=connection.execute("CREATE TABLE keyval (key text NOT NULL PRIMARY KEY, value text NOT NULL)");
+            if let Err(err) = create_table_res{
+                warn!("Error while creating db {err}");
+            }      
+        }
+        ret
+    }
+}
+const INSERT_STATEMENT:&str = "INSERT INTO keyval (key,value) VALUES (?,?)";
+const SELECT_ONE:&str = "SELECT key,value FROM keyval where key=?";
+const SELECT_ALL:&str = "SELECT key,value FROM keyval";
 #[async_trait::async_trait]
 impl mattermost::Handler for Vav {
     async fn handle(
@@ -21,9 +42,53 @@ impl mattermost::Handler for Vav {
         if !message.starts_with('!') {
             return Ok(());
         }
-        let message = message.strip_prefix('!').unwrap();
+        let message=message.strip_prefix('!').unwrap();
+        let (message,rest) = message.split_once(' ').unwrap_or((message,""));
         match message{
-            "adres" => client.reply_to(posted.post, "Uniwersytet Wrocławski Instytut Informatyki; pl. Frederyka Joliot-Curie 15; 50-383 Wrocław".to_owned()).await?,
+            "store" =>{
+                let message = rest;
+                let (name,value) =message.split_once(' ').ok_or(anyhow::anyhow!("missing value in command store"))?;
+                if let Some(connection) = &self.db_connection{
+                    let mut statement = connection.prepare(INSERT_STATEMENT)?;
+                    statement.bind((1,name))?;
+                    statement.bind((2,value))?;
+                    if let Err(err) = statement.next(){
+                        warn!("Error while writing to db {err}");
+                    }      
+                }
+        
+            }
+            "lookup" =>{
+                let name = rest;
+                let response =if let Some(connection) = &self.db_connection{
+                    let mut statement = connection.prepare(SELECT_ONE)?;
+                    statement.bind((1,name))?;
+                    match statement.next(){
+                        Ok(sqlite::State::Done) => {
+                            "no entry under that name".to_owned()
+                        },
+                        Ok(sqlite::State::Row) => {
+                            statement.read::<String,_>(1)?
+                        },
+                        Err(err) => {
+                        warn!("Error while writing to db {err}");
+                        return Err(err.into())},
+                    }
+                } else {"uggh, no db".to_owned()};
+                client.reply_to(posted.post,response).await?;
+            }
+            "list" =>{
+                let response =if let Some(connection) = &self.db_connection{
+                    let mut statement = connection.prepare(SELECT_ALL)?;
+                    let mut res =vec!["Stored keys:".to_owned()];
+                    while let Ok(result) =  statement.next(){
+                            if result == sqlite::State::Done{ break;}
+                            res.push(statement.read::<String,_>(0)?)
+                    }
+                    res.join("\n")
+                } else {"uggh, no db".to_owned()};
+                client.reply_to(posted.post,response).await?;
+            }
             _ => return Err(anyhow!("Unrecognized command {message}")),
         }
         Ok(())
@@ -35,9 +100,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
     tracing_subscriber::fmt::init();
     let login = std::env::var("USER_MAIL")?;
     let password = std::env::var("USER_PASSWORD")?;
+    let db = std::env::var("SQLITE_PATH").ok();
     let auth = mattermost::AuthData { login, password };
     let mut client = mattermost::Client::new(auth, "https://mattermost.continuum.ii.uni.wroc.pl");
     client.update_bearer_token().await?;
-    client.handle_websocket_stream(Vav {}).await?;
+    client.handle_websocket_stream(Vav::new(db)).await?;
     Ok(())
 }