From 89722ebd6dcdc7067277050a431fbb7b9ea1dcf5 Mon Sep 17 00:00:00 2001 From: "Adam T. Carpenter" Date: Wed, 7 Oct 2020 09:37:41 -0400 Subject: sorted out image repo, error handling --- dichroism/.gitignore | 2 +- dichroism/Cargo.lock | 10 ++++ dichroism/Cargo.toml | 11 +--- .../2020-10-04-235458_create_images/up.sql | 2 +- dichroism/src/bin/dichroismd.rs | 44 ---------------- dichroism/src/config.rs | 33 +++++------- dichroism/src/constants.rs | 4 +- dichroism/src/error.rs | 3 +- dichroism/src/handlers.rs | 1 + dichroism/src/image_api.rs | 4 ++ dichroism/src/image_repo.rs | 31 ++++++++++-- dichroism/src/lib.rs | 16 ------ dichroism/src/main.rs | 59 ++++++++++++++++++++++ dichroism/src/models.rs | 9 +++- 14 files changed, 130 insertions(+), 99 deletions(-) delete mode 100644 dichroism/src/bin/dichroismd.rs delete mode 100644 dichroism/src/lib.rs create mode 100644 dichroism/src/main.rs diff --git a/dichroism/.gitignore b/dichroism/.gitignore index b213475..2f29843 100644 --- a/dichroism/.gitignore +++ b/dichroism/.gitignore @@ -1,6 +1,6 @@ -*.env *.jpeg *.jpg *.png *.webp +Dichroism.toml target/ diff --git a/dichroism/Cargo.lock b/dichroism/Cargo.lock index 03afc5e..746457d 100644 --- a/dichroism/Cargo.lock +++ b/dichroism/Cargo.lock @@ -732,6 +732,7 @@ dependencies = [ "regex", "serde", "serde_json", + "toml", ] [[package]] @@ -2112,6 +2113,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + [[package]] name = "tracing" version = "0.1.21" diff --git a/dichroism/Cargo.toml b/dichroism/Cargo.toml index 0e19889..3ecf4cb 100644 --- a/dichroism/Cargo.toml +++ b/dichroism/Cargo.toml @@ -4,19 +4,11 @@ version = "0.1.0" authors = ["Adam T. Carpenter "] edition = "2018" -[lib] -name = "dichroism" -path = "src/lib.rs" - -[[bin]] -name = "dichroismd" -path = "src/bin/dichroismd.rs" - [dependencies] actix-web = "3" async-std = "1" base64 = "0.13" -diesel = { version = "1.4", features = [ "sqlite", "r2d2" ] } +diesel = { version = "1", features = [ "sqlite", "r2d2" ] } env_logger = "0.7" image = "0.23" listenfd = "0.3" @@ -25,3 +17,4 @@ once_cell = "1" regex = "1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +toml = "0.5" diff --git a/dichroism/migrations/2020-10-04-235458_create_images/up.sql b/dichroism/migrations/2020-10-04-235458_create_images/up.sql index 7e92e57..ba3b4c6 100644 --- a/dichroism/migrations/2020-10-04-235458_create_images/up.sql +++ b/dichroism/migrations/2020-10-04-235458_create_images/up.sql @@ -1,5 +1,5 @@ CREATE TABLE "images" ( "id" INTEGER NOT NULL, - "path" TEXT NOT NULL, + "path" TEXT NOT NULL UNIQUE, PRIMARY KEY("id") ) diff --git a/dichroism/src/bin/dichroismd.rs b/dichroism/src/bin/dichroismd.rs deleted file mode 100644 index 2dc059d..0000000 --- a/dichroism/src/bin/dichroismd.rs +++ /dev/null @@ -1,44 +0,0 @@ -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::::new(config.db_url); - let manager = ConnectionManager::::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 c3dec51..c1c42f0 100644 --- a/dichroism/src/config.rs +++ b/dichroism/src/config.rs @@ -1,31 +1,24 @@ -use crate::constants::*; -use crate::error::DichroismError; +use crate::constants::DEFAULT_CONFIG; use crate::result::Result; -use async_std::fs::metadata; -use async_std::path::PathBuf; -use std::env; +use serde::Deserialize; +use std::env::var; +use std::fs::File; +use std::io::prelude::*; use std::net::SocketAddr; +use toml::from_str; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Deserialize)] pub struct Config { pub db_url: String, - pub img_root: PathBuf, + pub img_root: String, pub bind_addr: SocketAddr, } impl Config { - pub async fn new_from_env() -> Result { - 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()?, - }) + pub fn from_toml() -> Result { + let path = var("DICHROISM_CONFIG").unwrap_or_else(|_| String::from(DEFAULT_CONFIG)); + let mut config = String::new(); + File::open(path)?.read_to_string(&mut config)?; + Ok(from_str(&config)?) } } diff --git a/dichroism/src/constants.rs b/dichroism/src/constants.rs index fe45c1e..87d0442 100644 --- a/dichroism/src/constants.rs +++ b/dichroism/src/constants.rs @@ -1,3 +1 @@ -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"; +pub const DEFAULT_CONFIG: &str = "./Dichroism.toml"; diff --git a/dichroism/src/error.rs b/dichroism/src/error.rs index 5e00abc..17c0024 100644 --- a/dichroism/src/error.rs +++ b/dichroism/src/error.rs @@ -8,6 +8,7 @@ impl std::error::Error for DichroismError {} impl std::fmt::Display for DichroismError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Dichroism Error: {}", self) + write!(f, "{}", self) } } + diff --git a/dichroism/src/handlers.rs b/dichroism/src/handlers.rs index e4ea6a0..0e2b2c3 100644 --- a/dichroism/src/handlers.rs +++ b/dichroism/src/handlers.rs @@ -19,6 +19,7 @@ async fn get_images(pool: web::Data) -> Result { eprintln!("{}", e); HttpResponse::InternalServerError().finish() })?; + dbg!(&images); Ok(HttpResponse::Ok().json(images)) } diff --git a/dichroism/src/image_api.rs b/dichroism/src/image_api.rs index 97faead..3eff88e 100644 --- a/dichroism/src/image_api.rs +++ b/dichroism/src/image_api.rs @@ -16,6 +16,10 @@ pub fn generate_images(data: &str) -> Result<()> { let _thumb = img.thumbnail(200, 200); //thumb.save("test_thumbnail.jpg")?; Ok(()) + + // TODO: gather and return related images as a tuple. then in another function, write them + // out to the filesystem and return NewImages using the resulting paths. The pathnames + // *probably* need to be UUIDs. } pub fn extract_data(uri: &str) -> Result<&str> { diff --git a/dichroism/src/image_repo.rs b/dichroism/src/image_repo.rs index c36f94e..e0f420b 100644 --- a/dichroism/src/image_repo.rs +++ b/dichroism/src/image_repo.rs @@ -1,4 +1,4 @@ -use super::models::ProductImg; +use super::models::{NewProductImg, ProductImg}; use diesel::prelude::*; use diesel::result::Error; @@ -10,8 +10,33 @@ pub fn read_images(conn: &DBConn) -> Result, Error> { Ok(results) } -pub fn create_image() { - todo!() +fn read_images_by_path(conn: &DBConn, path: &str) -> Result, Error> { + use crate::schema::images::dsl::*; + let results = images.filter(path.eq(path)).load::(conn)?; + Ok(results) +} + +pub fn read_image_by_path(conn: &DBConn, path: &str) -> Result, Error> { + use crate::schema::images::dsl::*; + let results = images + .filter(path.eq(path)) + .limit(1) + .load::(conn)?; + Ok(results.first().cloned()) +} + +pub fn read_image_by_id(conn: &DBConn, id: i32) -> Result, Error> { + use crate::schema::images::dsl::*; + let results = images.filter(id.eq(id)).limit(1).load::(conn)?; + Ok(results.first().cloned()) +} + +pub fn create_image(conn: &DBConn, new_image: NewProductImg) -> Result, Error> { + use super::schema::images; + diesel::insert_into(images::table) + .values(&new_image) + .execute(conn)?; + read_image_by_path(conn, &new_image.path) } pub fn update_image() { diff --git a/dichroism/src/lib.rs b/dichroism/src/lib.rs deleted file mode 100644 index e3842d3..0000000 --- a/dichroism/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[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 new file mode 100644 index 0000000..57ac652 --- /dev/null +++ b/dichroism/src/main.rs @@ -0,0 +1,59 @@ +#[macro_use] +extern crate serde; +#[macro_use] +extern crate diesel; + +use actix_web::{App, HttpServer}; +use config::Config; +use diesel::prelude::SqliteConnection; +use diesel::r2d2::ConnectionManager; +use diesel::r2d2::Pool; +use listenfd::ListenFd; +use result::Result; + +mod config; +mod constants; +mod error; +mod handlers; +mod image_api; +mod image_repo; +mod models; +mod product_repo; +mod result; +mod schema; +mod types; + +#[actix_web::main] +async fn main() -> Result<()> { + // Gather config. + let config = Config::from_toml()?; + let bind_addr = config.bind_addr; + + // Initialize DB connection pool. + let manager = ConnectionManager::::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_images) + }); + + 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/models.rs b/dichroism/src/models.rs index 5516688..0485237 100644 --- a/dichroism/src/models.rs +++ b/dichroism/src/models.rs @@ -1,5 +1,12 @@ -#[derive(Debug, Queryable, Serialize)] +#[derive(Debug, Queryable, Serialize, Clone)] pub struct ProductImg { pub id: i32, pub path: String, } + +use super::schema::images; +#[table_name = "images"] +#[derive(Debug, Insertable)] +pub struct NewProductImg { + pub path: String, +} -- cgit v1.2.3