121 lines
No EOL
4.2 KiB
Rust
121 lines
No EOL
4.2 KiB
Rust
use askama_axum::IntoResponse;
|
|
use axum::extract::{State, Path};
|
|
use axum::http::StatusCode;
|
|
use log::{warn, error};
|
|
|
|
use crate::block_types;
|
|
use crate::{block_types::BlockTypes, AppState};
|
|
use crate::entities::{prelude::*, *};
|
|
use sea_orm::*;
|
|
|
|
use chrono::{Utc, Datelike};
|
|
|
|
use super::{PostTemplate, PostNotFoundTemplate};
|
|
|
|
pub(crate) async fn resolver(
|
|
Path(slug): Path<String>,
|
|
state: State<AppState>
|
|
) -> impl IntoResponse {
|
|
|
|
let menu: Vec<menu_entry::Model> = match Menu::find()
|
|
.filter(menu::Column::Name.eq("primary"))
|
|
.one(&state.db_conn)
|
|
.await
|
|
.expect("Failed to get primary menu! HALTING") {
|
|
Some(menu) => menu,
|
|
None => panic!("Missing \"primary\" menu in database!"),
|
|
}.find_related(MenuEntry)
|
|
.order_by_asc(menu_entry::Column::Order)
|
|
.all(&state.db_conn)
|
|
.await
|
|
.expect("Failed to get primary menu items!");
|
|
|
|
let settings: settings::Model = match Settings::find()
|
|
.filter(settings::Column::Id.eq("current"))
|
|
.one(&state.db_conn)
|
|
.await
|
|
.expect("Failed to get site settings!") {
|
|
Some (settings) => settings,
|
|
None => panic!("Missing \"current\" settings in database!")
|
|
};
|
|
|
|
let post_search: Result<Option<post::Model>, DbErr> = Post::find()
|
|
.filter(post::Column::Slug.eq(&slug))
|
|
.one(&state.db_conn)
|
|
.await;
|
|
|
|
let post_meta: post::Model = match post_search {
|
|
Ok(post_result) => {
|
|
match post_result {
|
|
Some(post_result) => post_result,
|
|
None => return (StatusCode::NOT_FOUND, PostNotFoundTemplate { slug, year: Utc::now().date_naive().year().to_string(), menu, settings }).into_response(),
|
|
}
|
|
},
|
|
Err(e) => {
|
|
error!("{}", e);
|
|
return (StatusCode::INTERNAL_SERVER_ERROR, ()).into_response();
|
|
},
|
|
};
|
|
|
|
let blocks: Vec<post_block::Model> = post_meta.find_related(PostBlock)
|
|
.order_by_asc(post_block::Column::Order)
|
|
.all(&state.db_conn)
|
|
.await
|
|
.expect("Failed to get post blocks! HALTING");
|
|
|
|
let mut content_blocks: Vec<BlockTypes> = vec![];
|
|
|
|
for block in blocks {
|
|
content_blocks.push(
|
|
match block.r#type.as_str() {
|
|
"HR" => BlockTypes::HR,
|
|
"PARAGRAPH" => BlockTypes::PARAGRAPH { text: block.content },
|
|
"MARKDOWN" => BlockTypes::MARKDOWN { content: block.content },
|
|
"HEADER" => {
|
|
let deserde: block_types::Header = serde_json::from_str(&block.content.as_str()).expect("Incorrect HEADER blockormatting");
|
|
|
|
BlockTypes::HEADER { text: deserde.text, size: deserde.size }
|
|
},
|
|
"HTML" => BlockTypes::HTML { content: block.content },
|
|
"IMAGE" => BlockTypes::IMAGE { content: {
|
|
Image::find_by_id(block.content)
|
|
.one(&state.db_conn)
|
|
.await
|
|
.expect("Failed to get image! HALTING")
|
|
}},
|
|
_ => {
|
|
warn!("Unsupported block type! ({})", block.r#type.as_str());
|
|
BlockTypes::UNSUPPORTED
|
|
}
|
|
});
|
|
}
|
|
|
|
let last_updated = match post_meta.clone().updated {
|
|
Some(updated) => Some(updated.to_string()),
|
|
None => None,
|
|
};
|
|
|
|
let featured_image: Option<image::Model> = match post_meta.clone().featured_image {
|
|
Some(featured_image) => {
|
|
Image::find()
|
|
.filter(image::Column::Id.eq(featured_image))
|
|
.one(&state.db_conn)
|
|
.await
|
|
.expect("Failed to get image! HALTING")
|
|
},
|
|
None => None,
|
|
};
|
|
|
|
(StatusCode::FOUND, PostTemplate {
|
|
draft: post_meta.clone().draft,
|
|
title: post_meta.clone().title,
|
|
summary: post_meta.clone().summary,
|
|
publish_date: post_meta.clone().published.to_string(),
|
|
last_updated,
|
|
content_blocks,
|
|
year: Utc::now().date_naive().year().to_string(),
|
|
menu,
|
|
settings,
|
|
featured_image,
|
|
}).into_response()
|
|
} |