summaryrefslogtreecommitdiff
path: root/dichroism/src
diff options
context:
space:
mode:
Diffstat (limited to 'dichroism/src')
-rw-r--r--dichroism/src/bin/dichroismd.rs44
-rw-r--r--dichroism/src/config.rs32
-rw-r--r--dichroism/src/constants.rs3
-rw-r--r--dichroism/src/error.rs1
-rw-r--r--dichroism/src/handlers.rs31
-rw-r--r--dichroism/src/image_api.rs11
-rw-r--r--dichroism/src/image_repo.rs32
-rw-r--r--dichroism/src/lib.rs16
-rw-r--r--dichroism/src/main.rs35
-rw-r--r--dichroism/src/models.rs5
-rw-r--r--dichroism/src/product_api.rs0
-rw-r--r--dichroism/src/product_repo.rs18
-rw-r--r--dichroism/src/schema.rs6
-rw-r--r--dichroism/src/types.rs5
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>>;