summaryrefslogtreecommitdiff
path: root/dichroism/src
diff options
context:
space:
mode:
Diffstat (limited to 'dichroism/src')
-rw-r--r--dichroism/src/config.rs62
-rw-r--r--dichroism/src/constants.rs1
-rw-r--r--dichroism/src/main.rs99
-rw-r--r--dichroism/src/migrations/photo_sets.sql8
-rw-r--r--dichroism/src/migrations/products.sql12
-rw-r--r--dichroism/src/result.rs2
6 files changed, 98 insertions, 86 deletions
diff --git a/dichroism/src/config.rs b/dichroism/src/config.rs
index 2031ecc..225ee4c 100644
--- a/dichroism/src/config.rs
+++ b/dichroism/src/config.rs
@@ -1,32 +1,48 @@
-use crate::constants::DEFAULT_CONFIG;
use crate::result::Result;
-use once_cell::sync::Lazy;
-use serde::Deserialize;
-use std::env::var;
-use std::fs::File;
-use std::io::prelude::*;
-use std::net::SocketAddr;
-use toml::from_str;
+use anyhow::{anyhow, Context};
+use std::{env::var, net::SocketAddr, path::PathBuf};
-pub static CONFIG_INSTANCE: Lazy<Config> = Lazy::new(|| {
- Config::from_toml().unwrap_or_else(|e| {
- eprintln!("Error parsing config: {}", e.to_string());
- std::process::exit(1);
- })
-});
-
-#[derive(Debug, Clone, Deserialize)]
+#[derive(Debug, Clone)]
pub struct Config {
- pub db_url: String,
- pub img_root: String,
pub bind_addr: SocketAddr,
+ pub db_path: PathBuf,
+ pub img_path: PathBuf,
}
impl Config {
- pub fn from_toml() -> Result<Self> {
- 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)?)
+ pub fn from_env() -> Result<Self> {
+ let config = Self {
+ bind_addr: var("GL_BIND_ADDR")
+ .with_context(|| "Bind address missing.")?
+ .parse()
+ .with_context(|| "Failed to parse bind address.")?,
+ db_path: var("GL_DB_PATH")
+ .with_context(|| "Database path missing.")?
+ .parse()
+ .with_context(|| "Failed to parse database path.")?,
+ img_path: var("GL_IMG_PATH")
+ .with_context(|| "Image store path missing.")?
+ .parse()
+ .with_context(|| "Failed to parse image store path.")?,
+ };
+
+ if config.db_path.is_dir() {
+ Err(anyhow!(format!(
+ "Database path {:?} is not a regular file",
+ config.db_path
+ )))
+ } else if !config.img_path.is_dir() {
+ Err(anyhow!(format!(
+ "Image store path {:?} is not a directory.",
+ config.img_path
+ )))
+ } else if config.img_path.read_dir().is_err() {
+ Err(anyhow!(format!(
+ "Image store path {:?} is not readable.",
+ config.img_path
+ )))
+ } else {
+ Ok(config)
+ }
}
}
diff --git a/dichroism/src/constants.rs b/dichroism/src/constants.rs
index 72a8de9..a973f3d 100644
--- a/dichroism/src/constants.rs
+++ b/dichroism/src/constants.rs
@@ -1,4 +1,3 @@
-pub const DEFAULT_CONFIG: &str = "./Dichroism.toml";
pub const PHOTO_FULLSIZE_XY: u32 = 1000;
pub const PHOTO_BASE_XY: u32 = 640;
pub const PHOTO_THUMBNAIL_XY: u32 = 300;
diff --git a/dichroism/src/main.rs b/dichroism/src/main.rs
index 6c76f0a..86de76f 100644
--- a/dichroism/src/main.rs
+++ b/dichroism/src/main.rs
@@ -1,66 +1,43 @@
-#[macro_use]
-extern crate serde;
-#[macro_use]
-extern crate diesel;
-
-use actix_cors::Cors;
-use actix_web::{middleware::Logger, App, HttpServer};
-use config::CONFIG_INSTANCE as CONFIG;
-use diesel::prelude::SqliteConnection;
-use diesel::r2d2::ConnectionManager;
-use diesel::r2d2::Pool;
-use listenfd::ListenFd;
-use result::Result;
+use anyhow::Context;
+use axum::{http::StatusCode, routing::get_service, Router};
+use r2d2::Pool;
+use r2d2_sqlite::SqliteConnectionManager;
+use rusqlite::params;
+use std::io::Error;
+use tower_http::services::ServeDir;
mod config;
-mod constants;
-mod dtos;
-mod error;
-mod handlers;
-mod image_service;
-mod models;
-mod repo;
mod result;
-mod schema;
-mod types;
-
-#[actix_web::main]
-async fn main() -> Result<()> {
- // Init logging
- std::env::set_var("RUST_LOG", "actix_web=info");
- env_logger::init();
-
- // Init DB connection pool
- let manager = ConnectionManager::<SqliteConnection>::new(&CONFIG.db_url);
- let pool = Pool::builder().build(manager)?;
-
- // Init application server
- let mut server = HttpServer::new(move || {
- // Init CORS policy
- let cors = Cors::permissive();
-
- App::new()
- .data(pool.clone())
- .wrap(cors)
- .wrap(Logger::default())
- .service(handlers::hello)
- .service(handlers::get_products)
- .service(handlers::patch_product)
- .service(handlers::post_product)
- .service(handlers::post_photo)
- });
-
- // If using listenfd, bind to it instead of the configured address to allow for cargo watch
- // auto-reloading
- let mut listenfd = ListenFd::from_env();
- server = if let Some(l) = listenfd
- .take_tcp_listener(0)
- .expect("Unable to grab TCP listener!")
- {
- server.listen(l)?
- } else {
- server.bind(CONFIG.bind_addr)?
- };
- Ok(server.run().await?)
+#[tokio::main]
+async fn main() -> result::Result<()> {
+ // read config from environment
+ let config = config::Config::from_env()?;
+
+ // start db connection pool
+ let manager = SqliteConnectionManager::file(&config.db_path);
+ let pool = Pool::new(manager).with_context(|| "Failed to create database connection pool.")?;
+
+ // migrate/init db if empty
+ pool.get()?
+ .execute(include_str!("./migrations/photo_sets.sql"), params![])?;
+ pool.get()?
+ .execute(include_str!("./migrations/products.sql"), params![])?;
+
+ let app = Router::new().nest(
+ "/static",
+ get_service(ServeDir::new("/zroot/gl/images")).handle_error(|error: Error| async move {
+ (
+ StatusCode::INTERNAL_SERVER_ERROR,
+ format!("Unhandled internal error: {}", error),
+ )
+ }),
+ );
+
+ axum::Server::bind(&config.bind_addr)
+ .serve(app.into_make_service())
+ .await
+ .with_context(|| "Server error!")?;
+
+ Ok(())
}
diff --git a/dichroism/src/migrations/photo_sets.sql b/dichroism/src/migrations/photo_sets.sql
new file mode 100644
index 0000000..a27c8ab
--- /dev/null
+++ b/dichroism/src/migrations/photo_sets.sql
@@ -0,0 +1,8 @@
+CREATE TABLE IF NOT EXISTS "photo_sets" (
+ "id" INTEGER NOT NULL,
+ "base" TEXT NOT NULL,
+ "fullsize" TEXT NOT NULL,
+ "thumbnail" TEXT NOT NULL,
+ "original" TEXT NOT NULL,
+ PRIMARY KEY("id")
+); \ No newline at end of file
diff --git a/dichroism/src/migrations/products.sql b/dichroism/src/migrations/products.sql
new file mode 100644
index 0000000..0603a5c
--- /dev/null
+++ b/dichroism/src/migrations/products.sql
@@ -0,0 +1,12 @@
+CREATE TABLE IF NOT EXISTS "products" (
+ "id" INTEGER NOT NULL,
+ "photo_set" INTEGER NOT NULL,
+ "cents" INTEGER NOT NULL,
+ "quantity" INTEGER NOT NULL,
+ "name" TEXT NOT NULL,
+ "description" TEXT NOT NULL,
+ "featured" INTEGER NOT NULL,
+ "category" TEXT NOT NULL,
+ PRIMARY KEY("id"),
+ FOREIGN KEY("photo_set") REFERENCES "photo_sets"("id")
+); \ No newline at end of file
diff --git a/dichroism/src/result.rs b/dichroism/src/result.rs
index 708451d..88e89cd 100644
--- a/dichroism/src/result.rs
+++ b/dichroism/src/result.rs
@@ -1 +1 @@
-pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
+pub type Result<T> = anyhow::Result<T>;