about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml8
-rw-r--r--src/database/mod.rs6
-rw-r--r--src/lib.rs50
-rw-r--r--src/main.rs50
4 files changed, 93 insertions, 21 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 3974d9c..3f93407 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,6 +7,7 @@ edition = "2018"
 [features]
 default = ["util"]
 util = ["anyhow"]
+redis = ["mobc", "mobc-redis"]
 
 [[bin]]
 name = "kittybox-bulk-import"
@@ -16,7 +17,7 @@ required-features = ["util"]
 [[bin]]
 name = "pyindieblog-export"
 path = "src/bin/pyindieblog_to_kittybox.rs"
-required-features = ["util"]
+required-features = ["util", "redis"]
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dev-dependencies]
@@ -39,7 +40,6 @@ lazy_static = "^1.4.0"       # A macro for declaring lazily evaluated statics in
 log = "^0.4.14"              # A lightweight logging facade for Rust
 markdown = "^0.3.0"          # Native Rust library for parsing Markdown and (outputting HTML)
 markup = "^0.12.0"           # HTML templating engine... ok also very funny about markdown and markup... i just realized the pun...
-mobc = "^0.7.2"              # A generic connection pool with async/await support
 newbase60 = "^0.1.3"         # A library that implements Tantek Çelik's New Base 60
 retainer = "^0.2.2"          # Minimal async cache in Rust with support for key expirations
 serde_json = "^1.0.64"       # A JSON serialization file format
@@ -54,8 +54,12 @@ features = ["attributes", "unstable"]
 [dependencies.chrono]        # Date and time library for Rust
 version = "^0.4.19"
 features = ["serde"]
+[dependencies.mobc]          # A generic connection pool with async/await support
+version = "^0.7.2"
+optional = true
 [dependencies.mobc-redis]    # Redis support for the mobc connection pool
 version = "^0.7.0"
+optional = true
 features = ["async-std-comp"]
 default-features = false
 [dependencies.prometheus]    # Prometheus instrumentation library for Rust applications
diff --git a/src/database/mod.rs b/src/database/mod.rs
index e6873b0..a1f5861 100644
--- a/src/database/mod.rs
+++ b/src/database/mod.rs
@@ -3,10 +3,14 @@ use crate::indieauth::User;
 use async_trait::async_trait;
 use serde::{Deserialize, Serialize};
 
+#[cfg(redis)]
 mod redis;
+#[cfg(redis)]
 pub use crate::database::redis::RedisStorage;
+#[cfg(redis)]
 #[cfg(test)]
 pub use redis::tests::{get_redis_instance, RedisInstance};
+
 mod file;
 pub use crate::database::file::FileStorage;
 
@@ -184,6 +188,7 @@ pub trait Storage: Clone + Send + Sync {
 
 #[cfg(test)]
 mod tests {
+    #[cfg(redis)]
     use super::redis::tests::get_redis_instance;
     use super::{MicropubChannel, Storage};
     use serde_json::json;
@@ -352,6 +357,7 @@ mod tests {
     macro_rules! redis_test {
         ($func_name:expr) => {
             paste! {
+                #[cfg(redis)]
                 #[async_std::test]
                 async fn [<redis_ $func_name>] () {
                     test_logger::ensure_env_logger_initialized();
diff --git a/src/lib.rs b/src/lib.rs
index 77a6c11..1c6394a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -67,6 +67,7 @@ where
     app
 }
 
+#[cfg(redis)]
 pub async fn get_app_with_redis(
     token_endpoint: surf::Url,
     authorization_endpoint: surf::Url,
@@ -86,7 +87,46 @@ pub async fn get_app_with_redis(
     equip_app(app)
 }
 
+pub async fn get_app_with_file(
+    token_endpoint: surf::Url,
+    authorization_endpoint: surf::Url,
+    backend_uri: String,
+    media_endpoint: Option<String>,
+    internal_token: Option<String>,
+) -> App<database::FileStorage> {
+    let app = tide::with_state(ApplicationState {
+        token_endpoint,
+        media_endpoint,
+        authorization_endpoint,
+        internal_token,
+        storage: database::FileStorage::new(todo!()).await.unwrap(),
+        http_client: surf::Client::new(),
+    });
+
+    equip_app(app)
+}
+
 #[cfg(test)]
+pub async fn get_app_with_test_file(token_endpoint: surf::Url) -> (
+    tempdir::TempDir,
+    database::FileStorage,
+    App<database::FileStorage>
+) {
+    use surf::Url;
+    let tempdir = tempdir::TempDir::new("file").expect("Failed to create tempdir");
+    let backend = database::FileStorage::new(tempdir.path().to_path_buf()).await.unwrap();
+    let app = tide::with_state(ApplicationState {
+        token_endpoint,
+        media_endpoint: None,
+        authorization_endpoint: Url::parse("https://indieauth.com/auth").unwrap(),
+        storage: backend.clone(),
+        internal_token: None,
+        http_client: surf::Client::new()
+    });
+    (tempdir, backend, equip_app(app))
+}
+
+#[cfg(all(redis, test))]
 pub async fn get_app_with_test_redis(
     token_endpoint: surf::Url,
 ) -> (
@@ -122,18 +162,18 @@ mod tests {
 
     // Helpers
     async fn create_app() -> (
-        database::RedisStorage,
-        App<database::RedisStorage>,
-        database::RedisInstance,
+        database::FileStorage,
+        App<database::FileStorage>,
+        tempdir::TempDir,
     ) {
         //get_app_with_memory_for_testing(surf::Url::parse(&*mockito::server_url()).unwrap()).await
         let (r, b, a) =
-            get_app_with_test_redis(surf::Url::parse(&*mockito::server_url()).unwrap()).await;
+            get_app_with_test_file(surf::Url::parse(&*mockito::server_url()).unwrap()).await;
         (b, a, r)
     }
 
     async fn post_json(
-        app: &App<database::RedisStorage>,
+        app: &App<database::FileStorage>,
         json: serde_json::Value,
     ) -> surf::Response {
         let request = app
diff --git a/src/main.rs b/src/main.rs
index 0e57ed5..e91476b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -10,14 +10,14 @@ async fn main() -> Result<(), std::io::Error> {
 
     info!("Starting the kittybox server...");
 
-    let redis_uri: String;
-    match env::var("REDIS_URI") {
+    let backend_uri: String;
+    match env::var("BACKEND_URI") {
         Ok(val) => {
-            debug!("Redis connection: {}", val);
-            redis_uri = val
+            debug!("Backend URI: {}", val);
+            backend_uri = val
         }
         Err(_) => {
-            error!("REDIS_URI is not set, cannot find a database");
+            error!("BACKEND_URI is not set, cannot find a database");
             std::process::exit(1);
         }
     };
@@ -63,13 +63,35 @@ async fn main() -> Result<(), std::io::Error> {
     let host = env::var("SERVE_AT")
         .ok()
         .unwrap_or_else(|| "0.0.0.0:8080".to_string());
-    let app = kittybox::get_app_with_redis(
-        token_endpoint,
-        authorization_endpoint,
-        redis_uri,
-        media_endpoint,
-        internal_token,
-    )
-    .await;
-    app.listen(host).await
+
+    if backend_uri.starts_with("redis") {
+        #[cfg(redis)]
+        {
+            let app = kittybox::get_app_with_redis(
+                token_endpoint,
+                authorization_endpoint,
+                backend_uri,
+                media_endpoint,
+                internal_token,
+            ).await;
+            app.listen(host).await
+        }
+        #[cfg(not(redis))]
+        {
+            println!("The Redis backend was disabled at build-time. Please recompile the package with --features=redis.");
+            std::process::exit(1);
+        }
+    } else if backend_uri.starts_with("file") {
+        let app = kittybox::get_app_with_file(
+            token_endpoint,
+            authorization_endpoint,
+            backend_uri,
+            media_endpoint,
+            internal_token
+        ).await;
+        app.listen(host).await
+    } else {
+        println!("Unknown backend, not starting.");
+        std::process::exit(1);
+    }
 }