diff options
Diffstat (limited to 'dichroism/src')
| -rw-r--r-- | dichroism/src/bin/dichroismd.rs | 44 | ||||
| -rw-r--r-- | dichroism/src/config.rs | 32 | ||||
| -rw-r--r-- | dichroism/src/constants.rs | 3 | ||||
| -rw-r--r-- | dichroism/src/error.rs | 1 | ||||
| -rw-r--r-- | dichroism/src/handlers.rs | 31 | ||||
| -rw-r--r-- | dichroism/src/image_api.rs | 11 | ||||
| -rw-r--r-- | dichroism/src/image_repo.rs | 32 | ||||
| -rw-r--r-- | dichroism/src/lib.rs | 16 | ||||
| -rw-r--r-- | dichroism/src/main.rs | 35 | ||||
| -rw-r--r-- | dichroism/src/models.rs | 5 | ||||
| -rw-r--r-- | dichroism/src/product_api.rs | 0 | ||||
| -rw-r--r-- | dichroism/src/product_repo.rs | 18 | ||||
| -rw-r--r-- | dichroism/src/schema.rs | 6 | ||||
| -rw-r--r-- | dichroism/src/types.rs | 5 | 
14 files changed, 194 insertions, 45 deletions
| diff --git a/dichroism/src/bin/dichroismd.rs b/dichroism/src/bin/dichroismd.rs new file mode 100644 index 0000000..2dc059d --- /dev/null +++ b/dichroism/src/bin/dichroismd.rs @@ -0,0 +1,44 @@ +use actix_web::{App, HttpServer}; +use dichroism::config; +use dichroism::handlers; +use dichroism::result::Result; +use diesel::prelude::SqliteConnection; +use diesel::r2d2::ConnectionManager; +use diesel::r2d2::Pool; +use listenfd::ListenFd; + +#[actix_web::main] +async fn main() -> Result<()> { +    // Gather config. +    let config = config::Config::new_from_env().await?; +    let bind_addr = config.bind_addr; + +    // Initialize DB connection pool. +    //let manager = ConnectionManager::<SqliteConnection>::new(config.db_url); +    let manager = ConnectionManager::<SqliteConnection>::new(&config.db_url); +    let pool = Pool::builder().build(manager)?; + +    // Initialize application server. +    let mut server = HttpServer::new(move || { +        App::new() +            .data(config.clone()) +            .data(pool.clone()) +            .service(handlers::hello) +            .service(handlers::create_image) +            .service(handlers::get_products) +    }); + +    let mut listenfd = ListenFd::from_env(); +    server = if let Some(l) = listenfd +        .take_tcp_listener(0) +        .expect("Unable to grab TCP listener!") +    { +        // If using listenfd, use it to allow for cargo watch auto-reloading. +        server.listen(l)? +    } else { +        // Bind to config for release. +        server.bind(bind_addr)? +    }; + +    Ok(server.run().await?) +} diff --git a/dichroism/src/config.rs b/dichroism/src/config.rs index e5b4046..c3dec51 100644 --- a/dichroism/src/config.rs +++ b/dichroism/src/config.rs @@ -1 +1,31 @@ -struct Config {} +use crate::constants::*; +use crate::error::DichroismError; +use crate::result::Result; +use async_std::fs::metadata; +use async_std::path::PathBuf; +use std::env; +use std::net::SocketAddr; + +#[derive(Debug, Clone)] +pub struct Config { +    pub db_url: String, +    pub img_root: PathBuf, +    pub bind_addr: SocketAddr, +} + +impl Config { +    pub async fn new_from_env() -> Result<Self> { +        let img_root = PathBuf::from(env::var(ENV_IMG_ROOT)?); +        let meta = metadata(&img_root).await?; + +        if !meta.is_dir() || meta.permissions().readonly() { +            return Err(Box::new(DichroismError::InvalidImageRoot)); +        } + +        Ok(Config { +            db_url: env::var(ENV_DB_URL)?, +            img_root, +            bind_addr: env::var(ENV_BIND_ADDR)?.parse()?, +        }) +    } +} diff --git a/dichroism/src/constants.rs b/dichroism/src/constants.rs new file mode 100644 index 0000000..fe45c1e --- /dev/null +++ b/dichroism/src/constants.rs @@ -0,0 +1,3 @@ +pub const ENV_IMG_ROOT: &str = "DICHROISM_IMG_ROOT"; +pub const ENV_BIND_ADDR: &str = "DICHROISM_BIND_ADDR"; +pub const ENV_DB_URL: &str = "DICHROISM_DB_URL"; diff --git a/dichroism/src/error.rs b/dichroism/src/error.rs index 2f01381..5e00abc 100644 --- a/dichroism/src/error.rs +++ b/dichroism/src/error.rs @@ -1,6 +1,7 @@  #[derive(Debug)]  pub enum DichroismError {      UriDataExtract, +    InvalidImageRoot,  }  impl std::error::Error for DichroismError {} diff --git a/dichroism/src/handlers.rs b/dichroism/src/handlers.rs index 1e0ae28..e4ea6a0 100644 --- a/dichroism/src/handlers.rs +++ b/dichroism/src/handlers.rs @@ -1,13 +1,29 @@ +use super::image_repo; +use super::product_repo; +use super::types::DbPool; +use crate::config::Config;  use crate::image_api; -use actix_web::{get, post, HttpResponse, Responder}; +use actix_web::{get, post, web, Error, HttpResponse, Responder};  #[get("/")]  async fn hello() -> impl Responder {      HttpResponse::Ok().body("Hey, this is an API!")  } +#[get("/images")] +async fn get_images(pool: web::Data<DbPool>) -> Result<HttpResponse, Error> { +    let conn = pool.get().expect("Couldn't get DB connection from pool."); +    let images = web::block(move || image_repo::read_images(&conn)) +        .await +        .map_err(|e| { +            eprintln!("{}", e); +            HttpResponse::InternalServerError().finish() +        })?; +    Ok(HttpResponse::Ok().json(images)) +} +  #[post("/images")] -async fn create_image(req_body: String) -> impl Responder { +async fn create_image(_config: web::Data<Config>, req_body: String) -> impl Responder {      let data = match image_api::extract_data(&req_body) {          Err(e) => return HttpResponse::BadRequest().body(format!("fail: {}", e.to_string())),          Ok(d) => d, @@ -24,6 +40,13 @@ async fn create_image(req_body: String) -> impl Responder {  }  #[get("/products")] -async fn get_products(_req_body: String) -> impl Responder { -    HttpResponse::Ok().body("got products!") +async fn get_products(pool: web::Data<DbPool>) -> Result<HttpResponse, Error> { +    let conn = pool.get().expect("Couldn't get DB connection from pool."); +    let products = web::block(move || product_repo::read_products(&conn)) +        .await +        .map_err(|e| { +            eprintln!("{}", e); +            HttpResponse::InternalServerError().finish() +        })?; +    Ok(HttpResponse::Ok().json(products))  } diff --git a/dichroism/src/image_api.rs b/dichroism/src/image_api.rs index 44effe4..97faead 100644 --- a/dichroism/src/image_api.rs +++ b/dichroism/src/image_api.rs @@ -3,10 +3,11 @@ use crate::result::Result;  use base64::decode;  use regex::Regex; -lazy_static! { -    static ref DATA_URI_RE: Regex = -        Regex::new("^data:image/(png|jpeg);base64,(?P<data>.+)").expect("Couldn't parse Regex!"); -} +use once_cell::sync::Lazy; + +static DATA_URI_RE: Lazy<Regex> = Lazy::new(|| { +    Regex::new("^data:image/(png|jpeg);base64,(?P<data>.+)").expect("Couldn't parse Regex.") +});  pub fn generate_images(data: &str) -> Result<()> {      let bytes = decode(data)?; @@ -24,7 +25,7 @@ pub fn extract_data(uri: &str) -> Result<&str> {      Ok(caps          .name("data") -        .expect("Should never fail if regex succeeded") +        .expect("Should never fail if regex succeeded.")          .as_str())  } diff --git a/dichroism/src/image_repo.rs b/dichroism/src/image_repo.rs new file mode 100644 index 0000000..c36f94e --- /dev/null +++ b/dichroism/src/image_repo.rs @@ -0,0 +1,32 @@ +use super::models::ProductImg; +use diesel::prelude::*; +use diesel::result::Error; + +type DBConn = SqliteConnection; + +pub fn read_images(conn: &DBConn) -> Result<Vec<ProductImg>, Error> { +    use crate::schema::images::dsl::*; +    let results = images.load::<ProductImg>(conn)?; +    Ok(results) +} + +pub fn create_image() { +    todo!() +} + +pub fn update_image() { +    todo!() +} + +pub fn delete_image() { +    todo!() +} + +#[cfg(test)] +mod tests { + +    #[test] +    fn test() -> std::result::Result<(), Box<dyn std::error::Error>> { +        Ok(()) +    } +} diff --git a/dichroism/src/lib.rs b/dichroism/src/lib.rs new file mode 100644 index 0000000..e3842d3 --- /dev/null +++ b/dichroism/src/lib.rs @@ -0,0 +1,16 @@ +#[macro_use] +extern crate serde; +#[macro_use] +extern crate diesel; + +pub mod config; +mod constants; +mod error; +pub mod handlers; +mod image_api; +mod image_repo; +mod models; +mod product_repo; +pub mod result; +mod schema; +pub mod types; diff --git a/dichroism/src/main.rs b/dichroism/src/main.rs deleted file mode 100644 index 442b92d..0000000 --- a/dichroism/src/main.rs +++ /dev/null @@ -1,35 +0,0 @@ -#[macro_use] -extern crate lazy_static; - -use actix_web::{App, HttpServer}; -use listenfd::ListenFd; - -mod config; -mod error; -mod handlers; -mod image_api; -mod result; - -#[actix_web::main] -async fn main() -> std::io::Result<()> { -    let mut listenfd = ListenFd::from_env(); -    let mut server = HttpServer::new(|| { -        App::new() -            .service(handlers::hello) -            .service(handlers::create_image) -            .service(handlers::get_products) -    }); - -    server = if let Some(l) = listenfd -        .take_tcp_listener(0) -        .expect("Unable to grab TCP listener!") -    { -        // "Debug mode" with cargo watch auto-reloading -        server.listen(l)? -    } else { -        // "Release mode" -        server.bind("127.0.0.1:8000")? -    }; - -    server.run().await -} diff --git a/dichroism/src/models.rs b/dichroism/src/models.rs new file mode 100644 index 0000000..5516688 --- /dev/null +++ b/dichroism/src/models.rs @@ -0,0 +1,5 @@ +#[derive(Debug, Queryable, Serialize)] +pub struct ProductImg { +    pub id: i32, +    pub path: String, +} diff --git a/dichroism/src/product_api.rs b/dichroism/src/product_api.rs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/dichroism/src/product_api.rs diff --git a/dichroism/src/product_repo.rs b/dichroism/src/product_repo.rs new file mode 100644 index 0000000..67c5d3e --- /dev/null +++ b/dichroism/src/product_repo.rs @@ -0,0 +1,18 @@ +use super::models::ProductImg; +use diesel::prelude::*; +use diesel::result::Error; + +type DBConn = SqliteConnection; + +pub fn read_products(_conn: &DBConn) -> Result<Vec<ProductImg>, Error> { +    todo!() +} + +#[cfg(test)] +mod tests { + +    #[test] +    fn test() -> std::result::Result<(), Box<dyn std::error::Error>> { +        Ok(()) +    } +} diff --git a/dichroism/src/schema.rs b/dichroism/src/schema.rs new file mode 100644 index 0000000..e1c4408 --- /dev/null +++ b/dichroism/src/schema.rs @@ -0,0 +1,6 @@ +table! { +    images (id) { +        id -> Integer, +        path -> Text, +    } +} diff --git a/dichroism/src/types.rs b/dichroism/src/types.rs new file mode 100644 index 0000000..91aef95 --- /dev/null +++ b/dichroism/src/types.rs @@ -0,0 +1,5 @@ +use diesel::r2d2::ConnectionManager; +use diesel::r2d2::Pool; +use diesel::SqliteConnection; + +pub type DbPool = Pool<ConnectionManager<SqliteConnection>>; |