From 99dabd3f2f81ffcf0b6f2b59e13ebb4502b2ccac Mon Sep 17 00:00:00 2001 From: "Adam T. Carpenter" Date: Thu, 22 Oct 2020 17:44:38 -0400 Subject: Added product migration, better organization of DTOs, Entities, and Domain Models. Also made config loading/photo generation easier. --- dichroism/src/models/photo.rs | 24 ++++++++++++- dichroism/src/models/photo_set.rs | 72 +++++++++++++++++++++++++++++++++++---- dichroism/src/models/product.rs | 26 ++++---------- 3 files changed, 95 insertions(+), 27 deletions(-) (limited to 'dichroism/src/models') diff --git a/dichroism/src/models/photo.rs b/dichroism/src/models/photo.rs index 2e8b3bf..dee6288 100644 --- a/dichroism/src/models/photo.rs +++ b/dichroism/src/models/photo.rs @@ -1,5 +1,27 @@ +use crate::config::CONFIG_INSTANCE; +use crate::error::DichroismError; +use crate::result::Result; +use image::DynamicImage; +use std::path::PathBuf; +use uuid::Uuid; + #[derive(Debug, Queryable, Serialize, Clone)] pub struct Photo { - pub id: i32, pub path: String, } + +impl Photo { + pub fn from_image(image: &DynamicImage) -> Result { + let base_name = Uuid::new_v3(&Uuid::NAMESPACE_OID, &image.to_bytes()) + .to_hyphenated() + .to_string(); + let mut path = PathBuf::from(&CONFIG_INSTANCE.img_root); + path.push(base_name); + path.set_extension("jpg"); + image.save(&path)?; + + Ok(Self { + path: path.to_str().ok_or(DichroismError::ImageWrite)?.to_string(), + }) + } +} diff --git a/dichroism/src/models/photo_set.rs b/dichroism/src/models/photo_set.rs index 2f6c128..84fe0e1 100644 --- a/dichroism/src/models/photo_set.rs +++ b/dichroism/src/models/photo_set.rs @@ -1,8 +1,68 @@ -#[derive(Debug, Queryable, Clone)] +use super::photo::Photo; +use crate::constants::{PHOTO_BASE_XY, PHOTO_FULLSIZE_XY, PHOTO_THUMBNAIL_XY}; +use crate::error::DichroismError; +use crate::result::Result; +use base64::decode; +use image::imageops::FilterType; +use image::GenericImageView; +use once_cell::sync::Lazy; +use regex::Regex; + +static DATA_URI_RE: Lazy = Lazy::new(|| { + Regex::new("^data:image/(png|jpeg);base64,(?P.+)") + .expect("Couldn't parse data URI Regex.") +}); + pub struct PhotoSet { - pub id: i32, - pub base: i32, - pub fullsize: i32, - pub thumbnail: i32, - pub original: i32, + pub original: Photo, // original, just for safe-keeping + pub fullsize: Photo, // full-size, "zoomed" view + pub base: Photo, // basic viewing + pub thumbnail: Photo, // tiny, square thumbnail +} + +impl PhotoSet { + pub fn from_data_uri(uri: &str) -> Result { + let data = DATA_URI_RE + .captures(uri) + .ok_or(DichroismError::UriDataExtract)? + .name("data") + .ok_or(DichroismError::UriDataExtract)? + .as_str(); + let original = image::load_from_memory(&decode(data)?)?; + let fullsize = original.resize(PHOTO_FULLSIZE_XY, PHOTO_FULLSIZE_XY, FilterType::Lanczos3); + let base = original.resize(PHOTO_BASE_XY, PHOTO_BASE_XY, FilterType::Lanczos3); + + let (width, height) = original.dimensions(); + let thumbnail = if width > height { + let offset = (width - height) / 2; + original.crop_imm(offset, 0, width - offset * 2, height) + } else { + let offset = (height - width) / 2; + original.crop_imm(0, offset, width, height - offset * 2) + } + .resize(PHOTO_THUMBNAIL_XY, PHOTO_THUMBNAIL_XY, FilterType::Lanczos3); + + Ok(Self { + original: Photo::from_image(&original)?, + fullsize: Photo::from_image(&fullsize)?, + base: Photo::from_image(&base)?, + thumbnail: Photo::from_image(&thumbnail)?, + }) + } +} + +#[cfg(test)] +mod tests { + //use super::*; + + const TEST_DATA_URI: &str = include_str!("../unit_test_data/img_data_uri.txt"); + const TEST_DATA_BASE64: &str = include_str!("../unit_test_data/test_data_base64.txt"); + + #[test] + fn test_gen_product_images() { + // PhotoSet::from_data_uri(TEST_DATA_URI.trim()) + // .unwrap() + // .commit(".") + // .unwrap(); + } } diff --git a/dichroism/src/models/product.rs b/dichroism/src/models/product.rs index 9b81b8a..be0a5ec 100644 --- a/dichroism/src/models/product.rs +++ b/dichroism/src/models/product.rs @@ -1,26 +1,12 @@ -#[derive(Debug, Clone, Queryable, Serialize)] +use super::PhotoSet; + pub struct Product { - pub id: i32, + pub id: u32, pub name: String, - pub quantity: i32, - pub cents: i32, pub description: String, + pub cents: u32, + pub quantity: u32, pub featured: bool, - pub category_path: String, pub photo_set: PhotoSet, -} - -#[derive(Debug, Clone, Serialize)] -pub struct PhotoSet { - pub id: i32, - pub base: i32, - pub fullsize: i32, - pub thumbnail: i32, - pub original: i32, -} - -#[derive(Debug, Clone, Serialize)] -pub struct Photo { - pub id: i32, - pub path: String, + pub category: String, } -- cgit v1.2.3