From cd8f761fcf753218b9bd9e98ee570702c647c179 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Wed, 8 Apr 2020 20:00:40 +0800 Subject: [PATCH] implement showing blog no rendering yet --- src/blog.rs | 5 +++++ src/lib.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++++- src/sn.rs | 11 +++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/blog.rs b/src/blog.rs index 589aa4c..45b3916 100644 --- a/src/blog.rs +++ b/src/blog.rs @@ -98,6 +98,11 @@ impl Post { store::get_obj(&Self::uuid_to_post_key(uuid)).await } + pub async fn find_by_url(url: &str) -> MyResult { + let uuid = store::get_str(&Self::url_to_mapping_key(url)).await?; + Self::find_by_uuid(&uuid).await + } + // Write the Post to KV storage; this can be a new post or // update to an existing post; either way, the CALLER is // responsible for making sure PostsList is updated with the diff --git a/src/lib.rs b/src/lib.rs index 144a698..f20d690 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,7 +42,52 @@ fn build_routes() -> router::Router { return router; } -async fn default_route(_req: Request, _url: Url) -> MyResult { +async fn default_route(_req: Request, url: Url) -> MyResult { + // We assume that anything that falls into this catch-all handler + // would be either posts or 404 + // If the path doesn't end with `/`, normalize it first + let path = url.pathname(); + if !path.ends_with("/") { + return Response::new_with_opt_str_and_init( + None, + ResponseInit::new() + .status(302) + .headers(headers!{ + "Location" => &format!("{}{}/", url.origin(), path) + }.as_ref()) + ).internal_err(); + } + + // TODO: handle home page and pagination on home page + // Now we can be sure the path ends with `/` + // (and of course it starts with `/` as per standard) + if path.len() > 1 { + let path = &path[1..path.len() - 1]; + if let Ok(post) = blog::Post::find_by_url(path).await { + if post.url != path { + // Redirect to the latest path of the post + return Response::new_with_opt_str_and_init( + None, + ResponseInit::new() + .status(301) + .headers(headers!{ + "Location" => &format!("{}/{}/", url.origin(), post.url) + }.as_ref()) + ).internal_err(); + } else { + // TODO: Actually render the page... + return Response::new_with_opt_str_and_init( + Some(&post.content), + ResponseInit::new() + .status(200) + .headers(headers!{ + "Content-Type" => "text/html" + }.as_ref()) + ).internal_err(); + } + } + } + Err(Error::NotFound("This page is not available".into())) } diff --git a/src/sn.rs b/src/sn.rs index e9b8a01..219cd91 100644 --- a/src/sn.rs +++ b/src/sn.rs @@ -53,6 +53,17 @@ async fn get_actions(_req: Request, url: Url) -> MyResult { access_type: Some(AccessType::Decrypted) }); + if post_exists { + actions.push(Action { + label: "Open Post".into(), + url: format!("{}/{}/", origin, post.unwrap().url), + verb: Verb::Show, + context: Context::Item, + content_types: vec![ContentType::Note], + access_type: None + }) + } + let info = ActionsExtension { identifier: CONFIG.plugin_identifier.clone(), name: CONFIG.title.clone(),