summaryrefslogtreecommitdiff
path: root/src/blog
diff options
context:
space:
mode:
Diffstat (limited to 'src/blog')
-rw-r--r--src/blog/atom.rs75
-rw-r--r--src/blog/mod.rs12
2 files changed, 84 insertions, 3 deletions
diff --git a/src/blog/atom.rs b/src/blog/atom.rs
new file mode 100644
index 0000000..e6b931c
--- /dev/null
+++ b/src/blog/atom.rs
@@ -0,0 +1,75 @@
+use super::{
+ helper::{get_articles, ArticleMeta},
+ rocket_uri_macro_r_blog_article, rocket_uri_macro_r_blog_index, ARTICLE_ROOT,
+};
+use crate::{error::MyResult, uri};
+use rocket::get;
+use std::{path::PathBuf, str::FromStr};
+
+#[get("/blog/feed.atom")]
+pub async fn r_blog_atom() -> MyResult<String> {
+ let entries = get_articles(&PathBuf::from_str(ARTICLE_ROOT).unwrap())
+ .await?
+ .iter()
+ .map(
+ |ArticleMeta {
+ title,
+ date,
+ canonical_name,
+ ..
+ }| {
+ let title = horrible_escape_function(title);
+ let datetime = iso8601::DateTime {
+ date: date.clone(),
+ time: iso8601::Time::default(),
+ };
+ let href = uri!(r_blog_article(canonical_name));
+ format!(
+ r#"
+ <entry>
+ <title>{title}</title>
+ <link href="{href}/{canonical_name}" />
+ <id>tag:metamuffin.org,{date},{title}</id>
+ <published>{datetime}</published>
+ <summary>N/A</summary>
+ <author>
+ <name>metamuffin</name>
+ <email>metamuffin@disroot.org</email>
+ </author>
+ </entry>"#
+ )
+ },
+ )
+ .collect::<Vec<_>>();
+
+ let feed_url = uri!(r_blog_atom());
+ let index_url = uri!(r_blog_index());
+ let now = chrono::Utc::now().to_rfc3339();
+
+ Ok(format!(
+ r#"<?xml version="1.0" encoding="utf-8"?>
+ <feed xmlns="http://www.w3.org/2005/Atom">
+ <title>metamuffin's blog</title>
+ <subtitle>where they post pointless stuff</subtitle>
+ <link href="{feed_url}" rel="self" />
+ <link href="{index_url}" />
+ <id>urn:uuid:3cf2b704-3d94-4f1f-b194-42798ab5b47c</id>
+ <updated>{now}</updated>
+ <author>
+ <name>metamuffin</name>
+ <email>metamuffin@disroot.org</email>
+ </author>
+ {}
+ </feed>
+ "#,
+ entries.join("\n")
+ ))
+}
+
+pub fn horrible_escape_function(text: &str) -> String {
+ text.replace("&", "&amp;")
+ .replace("<", "&lt;")
+ .replace(">", "&gt;")
+ .replace("'", "&#8217;")
+ .replace("\"", "&quot;")
+}
diff --git a/src/blog/mod.rs b/src/blog/mod.rs
index 3ac38eb..23f0721 100644
--- a/src/blog/mod.rs
+++ b/src/blog/mod.rs
@@ -1,3 +1,4 @@
+pub mod atom;
pub mod helper;
use self::helper::{article_metadata, get_articles};
@@ -5,10 +6,14 @@ use crate::error::MyResult;
use crate::layout::{DynScaffold, Scaffold};
use crate::uri;
use anyhow::anyhow;
+pub use atom::r_blog_atom;
+use atom::rocket_uri_macro_r_blog_atom;
use rocket::{get, response::Redirect};
use std::{path::PathBuf, str::FromStr};
use tokio::fs::read_to_string;
+pub const ARTICLE_ROOT: &'static str = "./blog/articles";
+
#[get("/blog")]
pub fn r_blog() -> Redirect {
Redirect::to(rocket::uri!(r_blog_index()))
@@ -17,12 +22,13 @@ pub fn r_blog() -> Redirect {
#[get("/blog/index")]
pub async fn r_blog_index() -> MyResult<DynScaffold<'static>> {
// TODO this is a major performance issue here. requires O(n) syscalls to complete
- let articles = get_articles(&PathBuf::from_str("./blog/articles").unwrap()).await?;
+ let articles = get_articles(&PathBuf::from_str(ARTICLE_ROOT).unwrap()).await?;
Ok(Scaffold {
title: "blog index".to_string(),
content: markup::new! {
h2 { "The Weblog" }
- i { "Articles in reverse-chronological order." }
+ p { i { "Articles in reverse-chronological order." } }
+ p { a[href=uri!(r_blog_atom())]{ "Atom feed" } }
ul {
@for a in &articles {
li {
@@ -37,7 +43,7 @@ pub async fn r_blog_index() -> MyResult<DynScaffold<'static>> {
#[get("/blog/<name>")]
pub async fn r_blog_article(name: &str) -> MyResult<DynScaffold<'static>> {
- let apath = PathBuf::from_str("./blog/articles")
+ let apath = PathBuf::from_str(ARTICLE_ROOT)
.unwrap()
.join(PathBuf::new().with_file_name(name).with_extension("md"));
let a = article_metadata(apath.clone()).await?;