From 37d6c3cd4d056e37b1e862725512acfe30cb9b45 Mon Sep 17 00:00:00 2001 From: Evie Viau Date: Sat, 4 Feb 2023 18:42:08 -0800 Subject: [PATCH] Add page resolver --- Caddyfile | 2 +- src/main.rs | 30 ++++++++++++----- src/routes/mod.rs | 35 +++++++++++++++++-- src/routes/page_resolver.rs | 67 +++++++++++++++++++++++++++++++++++++ templates/notfound.html | 15 +++++++++ templates/post.html | 15 +++++++-- 6 files changed, 150 insertions(+), 14 deletions(-) create mode 100644 src/routes/page_resolver.rs create mode 100644 templates/notfound.html diff --git a/Caddyfile b/Caddyfile index 3d81aea..35dd778 100644 --- a/Caddyfile +++ b/Caddyfile @@ -1,4 +1,4 @@ -*:80 { +127.0.0.1 { route /favicon.ico { file_server { root ./static diff --git a/src/main.rs b/src/main.rs index c11a8f5..b191e26 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use axum::{Router, routing::get}; use log::info; -use sea_orm::{Database, DatabaseConnection}; +use sea_orm::{Database, DatabaseConnection, ConnectOptions}; mod routes; mod entities; @@ -11,7 +11,9 @@ mod block_types; #[tokio::main] async fn main() { - env::set_var("RUST_LOG", "info"); + if env::var("RUST_LOG").is_err() { + env::set_var("RUST_LOG", "info"); + } tracing_subscriber::fmt::init(); dotenvy::dotenv().ok(); @@ -26,7 +28,10 @@ async fn main() { info!("Connecting to the database..."); - let db_conn = Database::connect(db_url) + let mut db_opt = ConnectOptions::new(db_url); + db_opt.sqlx_logging_level(log::LevelFilter::Debug); + + let db_conn = Database::connect(db_opt) .await .expect("Failed to connect to the database! HALTING"); //Migrator::up(&db_conn, None).await.expect("Failed to run migrations! HALTING"); @@ -37,6 +42,8 @@ async fn main() { let app = Router::new() .route("/", get(routes::root)) + .route("/post/:slug", get(not_implemented)) + .route("/:slug", get(routes::page_resolver::resolver)) .with_state(app_state); info!("Attempting to bind to address..."); @@ -48,13 +55,14 @@ async fn main() { match bind { Ok(bind) => { info!("Binded to address successfully!"); - info!("Started!"); - bind.serve(app.into_make_service()) - .await - .unwrap(); + info!("Listening for connections..."); + match bind.serve(app.into_make_service()).await { + Err(e) => panic!("Failed to start server! HALTING {}", e), + _ => (), + } }, - Err(_) => { - panic!("Failed to bind! HALTING") + Err(e) => { + panic!("Failed to bind! HALTING {}", e) }, } } @@ -63,3 +71,7 @@ async fn main() { struct AppState { db_conn: DatabaseConnection, } + +async fn not_implemented() -> &'static str { + "Not Implemented" +} \ No newline at end of file diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 5f577be..66f11bc 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1,9 +1,41 @@ +pub(crate) mod page_resolver; + + use askama::Template; +use crate::{block_types::BlockTypes, AppState}; + +#[derive(Template)] +#[template(path = "page.html")] +pub(crate) struct PageTemplate { + title: String, + description: Option, + show_title: bool, + content_blocks: Vec, + year: String +} + +#[derive(Template)] +#[template(path = "post.html")] +pub(crate) struct PostTemplate { + title: String, + summary: Option, + publish_date: String, + last_updated: Option, + content_blocks: Vec, + year: String, +} + +#[derive(Template)] +#[template(path = "notfound.html")] +pub(crate) struct NotFoundTemplate { + slug: String, + year: String +} + use axum::extract::State; use log::warn; use crate::block_types; -use crate::{block_types::BlockTypes, AppState}; use crate::entities::{prelude::*, *}; use sea_orm::*; @@ -36,7 +68,6 @@ pub(crate) async fn root( .await .expect("Failed to get home page blocks! HALTING"); - // TODO: should move this into its own func, it'll be reused a bit let content_blocks: Vec = blocks.into_iter().map(|f| match f.r#type.as_str() { "HR" => BlockTypes::HR, diff --git a/src/routes/page_resolver.rs b/src/routes/page_resolver.rs new file mode 100644 index 0000000..d5221a5 --- /dev/null +++ b/src/routes/page_resolver.rs @@ -0,0 +1,67 @@ +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 super::{PageTemplate, NotFoundTemplate}; + +pub(crate) async fn resolver( + Path(slug): Path, + state: State + ) -> impl IntoResponse { + let page_search: Result, DbErr> = Page::find() + .filter(page::Column::Slug.eq(&slug)) + .one(&state.db_conn) + .await; + + let page_meta: page::Model = match page_search { + Ok(page_result) => { + match page_result { + Some(page_result) => page_result, + None => return (StatusCode::NOT_FOUND, NotFoundTemplate { slug, year: "2023".to_owned() }).into_response(), + } + }, + Err(e) => { + error!("{}", e); + return (StatusCode::INTERNAL_SERVER_ERROR, ()).into_response(); + }, + }; + + let blocks: Vec = page_meta.find_related(PageBlock) + .order_by_asc(page_block::Column::Order) + .all(&state.db_conn) + .await + .expect("Failed to get home page blocks! HALTING"); + + let content_blocks: Vec = blocks.into_iter().map(|f| + match f.r#type.as_str() { + "HR" => BlockTypes::HR, + "PARAGRAPH" => BlockTypes::PARAGRAPH { text: f.content }, + "MARKDOWN" => BlockTypes::MARKDOWN { content: f.content }, + "HEADER" => { + let deserde: block_types::Header = serde_json::from_str(&f.content.as_str()).expect("Incorrect HEADER formatting"); + + BlockTypes::HEADER { text: deserde.text, size: deserde.size + } + } + _ => { + warn!("Unsupported block type! ({})", f.r#type.as_str()); + BlockTypes::UNSUPPORTED + } + } + + ).collect(); + + (StatusCode::FOUND, PageTemplate { + title: page_meta.clone().title, + description: page_meta.clone().description, + show_title: page_meta.clone().show_title, + content_blocks, + year: "2023".to_string() + }).into_response() +} \ No newline at end of file diff --git a/templates/notfound.html b/templates/notfound.html new file mode 100644 index 0000000..97c2235 --- /dev/null +++ b/templates/notfound.html @@ -0,0 +1,15 @@ +{% extends "base.html" %} + +{% block title %}404{% endblock %} + +{% block description %} + This page wasn't found! +{% endblock %} + +{% block content %} + +

Page not found!

+ +

{{ slug }} was not found! Would you like to go home?

+ +{% endblock %} \ No newline at end of file diff --git a/templates/post.html b/templates/post.html index 7ee429b..9ab5f50 100644 --- a/templates/post.html +++ b/templates/post.html @@ -27,8 +27,19 @@
- {% for block in blocks %} -

block is real

+ {% for content_block in content_blocks %} + {% match content_block %} + {% when BlockTypes::HR %} +
+ {% when BlockTypes::PARAGRAPH { text } %} +

{{ text }}

+ {% when BlockTypes::MARKDOWN { content } %} + {{ content|markdown }} + {% when BlockTypes::HEADER { text, size } %} + {{text}} + {% when BlockTypes::UNSUPPORTED %} + UNSUPPORTED block type here! + {% endmatch %} {% endfor %}