diff --git a/axum_server/src/components/site_header.rs b/axum_server/src/components/site_header.rs
index d485709..d6fb953 100644
--- a/axum_server/src/components/site_header.rs
+++ b/axum_server/src/components/site_header.rs
@@ -3,21 +3,15 @@ pub struct Link {
pub label: String,
}
+#[derive(Default)]
pub struct HeaderProps {
pub back_link: Option,
}
-impl Default for HeaderProps {
- fn default() -> Self {
- Self { back_link: None }
- }
-}
-
impl HeaderProps {
pub fn with_back_link(link: Link) -> Self {
Self {
back_link: Some(link),
- ..Default::default()
}
}
}
diff --git a/axum_server/src/main.rs b/axum_server/src/main.rs
index bf3115d..7ea01f8 100644
--- a/axum_server/src/main.rs
+++ b/axum_server/src/main.rs
@@ -48,7 +48,6 @@ async fn main() {
axum::serve(listener, app).await.unwrap();
}
-// TODO footer
// TODO Display blog posts
// TODO responsive design
// TODO go live pipeline
diff --git a/axum_server/src/pages/blog_post_page.rs b/axum_server/src/pages/blog_post_page.rs
index 3993379..e7dc5f8 100644
--- a/axum_server/src/pages/blog_post_page.rs
+++ b/axum_server/src/pages/blog_post_page.rs
@@ -21,7 +21,7 @@ pub struct BlogPostTemplate {
pub async fn render_blog_post(Path(post_id): Path) -> Result {
let path = format!("../_posts/blog/{}.md", post_id);
- let parse_post = parse_post::(&path);
+ let parse_post = parse_post::(&path, true);
let parsed = parse_post.await?;
Ok(BlogPostTemplate {
diff --git a/axum_server/src/picture_generator/image_generator.rs b/axum_server/src/picture_generator/image_generator.rs
index aba0519..58d5e19 100644
--- a/axum_server/src/picture_generator/image_generator.rs
+++ b/axum_server/src/picture_generator/image_generator.rs
@@ -24,6 +24,7 @@ pub fn generate_images(
.with_extension(format.get_extension());
if save_path.exists() {
+ debug!("Skip generating {save_path:?} - Already exists");
return;
}
diff --git a/axum_server/src/picture_generator/picture_markup_generator.rs b/axum_server/src/picture_generator/picture_markup_generator.rs
index 82218f4..1ca1860 100644
--- a/axum_server/src/picture_generator/picture_markup_generator.rs
+++ b/axum_server/src/picture_generator/picture_markup_generator.rs
@@ -1,12 +1,11 @@
use std::{
cmp::Ordering,
path::{Path, PathBuf},
- str::FromStr as _,
sync::Arc,
};
use anyhow::Context;
-use image::{GenericImageView, ImageReader};
+use image::{image_dimensions, ImageReader};
use super::{export_format::ExportFormat, image_generator::generate_images};
@@ -17,23 +16,27 @@ pub fn generate_picture_markup(
width: u32,
height: u32,
alt_text: &str,
+ generate_image: bool,
) -> Result {
+ if !orig_img_path.starts_with("/") {
+ return Ok(format!(
+ r#""#
+ ));
+ }
+
let exported_formats = get_export_formats(orig_img_path);
let path_to_generated = get_generated_file_name(orig_img_path);
// TODO This should get removed when we move the project structure #move
- let dev_only_img_path = Path::new("../static/").join(orig_img_path.strip_prefix("/").unwrap());
+ let dev_only_img_path =
+ Path::new("../static/").join(orig_img_path.strip_prefix("/").unwrap_or(orig_img_path));
- let orig_img = ImageReader::open(&dev_only_img_path)
- .with_context(|| format!("Failed to read instrs from {:?}", &dev_only_img_path))?
- .decode()?;
- let orig_img_dimensions = orig_img.dimensions();
+ let orig_img_dimensions = image_dimensions(&dev_only_img_path).unwrap();
let resolutions = get_resolutions(orig_img_dimensions, width, height);
- // TODO lets generate images
-
- let orig_img_arc = Arc::new(orig_img);
- let orig_img_clone = Arc::clone(&orig_img_arc);
let path_to_generated_arc = Arc::new(path_to_generated);
let path_to_generated_clone = Arc::clone(&path_to_generated_arc);
let resolutions_arc = Arc::new(resolutions);
@@ -41,18 +44,25 @@ pub fn generate_picture_markup(
let exported_formats_arc = Arc::new(exported_formats);
let exported_formats_clone = Arc::clone(&exported_formats_arc);
- tokio::spawn(async move {
- let orig_img = orig_img_clone.as_ref();
- let path_to_generated = path_to_generated_clone.as_ref();
- let resolutions = resolutions_clone.as_ref();
- let exported_formats = exported_formats_clone.as_ref();
+ if generate_image {
+ rayon::spawn(move || {
+ let orig_img = ImageReader::open(&dev_only_img_path)
+ .with_context(|| format!("Failed to read instrs from {:?}", &dev_only_img_path))
+ .unwrap()
+ .decode()
+ .unwrap();
+ let path_to_generated = path_to_generated_clone.as_ref();
+ let resolutions = resolutions_clone.as_ref();
+ let exported_formats = exported_formats_clone.as_ref();
- let result = generate_images(orig_img, path_to_generated, resolutions, exported_formats)
- .with_context(|| "Failed to generate images".to_string());
- if let Err(e) = result {
- tracing::error!("Error: {}", e);
- }
- });
+ let result =
+ generate_images(&orig_img, path_to_generated, resolutions, exported_formats)
+ .with_context(|| "Failed to generate images".to_string());
+ if let Err(e) = result {
+ tracing::error!("Error: {}", e);
+ }
+ });
+ }
let exported_formats = Arc::clone(&exported_formats_arc);
let path_to_generated = Arc::clone(&path_to_generated_arc);
@@ -232,7 +242,11 @@ fn get_generated_file_name(orig_img_path: &str) -> PathBuf {
.file_stem()
.expect("There should be a name for every img");
let result = Path::new("/generated_images/")
- .join(parent.strip_prefix("/").unwrap())
+ .join(
+ parent
+ .strip_prefix("/")
+ .unwrap_or(Path::new("/generated_images/")),
+ )
.join(file_name);
result
}
@@ -287,7 +301,9 @@ fn test_get_export_formats() {
}
#[test]
fn test_generate_srcset() {
- let orig_img_path = PathBuf::from_str("/generated_images/images/uploads/img_name").unwrap();
+ let orig_img_path =
+ ::from_str("/generated_images/images/uploads/img_name")
+ .unwrap();
let export_format = ExportFormat::Avif;
let resolutions = vec![
(320, 200, 1.),
@@ -325,7 +341,7 @@ fn test_generate_picture_markup() {
>
"#;
assert_eq!(
- generate_picture_markup(orig_img_path, width, height, "Testing image alt")
+ generate_picture_markup(orig_img_path, width, height, "Testing image alt", false)
.expect("picture markup has to be generated"),
result
);
diff --git a/axum_server/src/post_utils/post_listing.rs b/axum_server/src/post_utils/post_listing.rs
index e484007..0aa9c6a 100644
--- a/axum_server/src/post_utils/post_listing.rs
+++ b/axum_server/src/post_utils/post_listing.rs
@@ -22,7 +22,7 @@ pub async fn get_post_list<'de, Metadata: DeserializeOwned>(
let file_path = file.path();
let file_path_str = file_path.to_str().unwrap();
info!(":{}", file_path_str);
- let post = parse_post::(file_path_str).await?;
+ let post = parse_post::(file_path_str, false).await?;
posts.push(post);
}
diff --git a/axum_server/src/post_utils/post_parser.rs b/axum_server/src/post_utils/post_parser.rs
index 99e66c7..4c6a017 100644
--- a/axum_server/src/post_utils/post_parser.rs
+++ b/axum_server/src/post_utils/post_parser.rs
@@ -6,6 +6,9 @@ use gray_matter::{engine::YAML, Matter};
use pulldown_cmark::{Event, Options, Parser, Tag, TagEnd};
use serde::{de::DeserializeOwned, Deserialize, Deserializer};
use tokio::fs;
+use tracing::debug;
+
+use crate::picture_generator::picture_markup_generator::generate_picture_markup;
pub fn deserialize_date<'de, D>(deserializer: D) -> Result, D::Error>
where
@@ -29,6 +32,7 @@ pub struct ParseResult {
pub async fn parse_post<'de, Metadata: DeserializeOwned>(
path: &str,
+ generate_images: bool,
) -> Result, StatusCode> {
let file_contents = fs::read_to_string(path)
.await
@@ -43,7 +47,7 @@ pub async fn parse_post<'de, Metadata: DeserializeOwned>(
StatusCode::INTERNAL_SERVER_ERROR
})?;
- let body = parse_html(&metadata.content);
+ let body = parse_html(&metadata.content, generate_images);
let filename = Path::new(path)
.file_stem()
@@ -59,7 +63,7 @@ pub async fn parse_post<'de, Metadata: DeserializeOwned>(
})
}
-pub fn parse_html(markdown: &str) -> String {
+pub fn parse_html(markdown: &str, generate_images: bool) -> String {
let mut options = Options::empty();
options.insert(Options::ENABLE_TABLES);
options.insert(Options::ENABLE_FOOTNOTES);
@@ -80,22 +84,41 @@ pub fn parse_html(markdown: &str) -> String {
title,
id,
}) => {
- println!(
+ // TODO Get image resolution
+
+ // Place image into the content with scaled reso to a boundary
+ let picture_markup =
+ generate_picture_markup(&dest_url, 500, 500, &title, generate_images).unwrap_or(
+ format!(
+ r#"
+ "#,
+ alt = title,
+ src = dest_url,
+ ),
+ );
+ // let picture_markup = format!(
+ // r#"
+ // "#,
+ // alt = title,
+ // src = dest_url,
+ // );
+
+ debug!(
"Image link_type: {:?} url: {} title: {} id: {}",
link_type, dest_url, title, id
);
- // TODO src set
Event::Html(
format!(
r#"