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, state: State ) -> impl IntoResponse { let menu: Vec = 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, 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_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 = 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 = 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() }