1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
pub mod atom;
pub mod helper;
use self::helper::{article_metadata, get_articles};
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()))
}
#[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(ARTICLE_ROOT).unwrap()).await?;
Ok(Scaffold {
title: "blog index".to_string(),
content: markup::new! {
h2 { "The Weblog" }
p { i { "Articles in reverse-chronological order." } }
p { a[href=uri!(r_blog_atom())]{ "Atom feed" } }
ul {
@for a in &articles {
li {
@a.date.to_string() ": "
a[href=uri!(r_blog_article(&a.canonical_name))] { @a.title }
}
}
}
},
})
}
#[get("/blog/<name>")]
pub async fn r_blog_article(name: &str) -> MyResult<DynScaffold<'static>> {
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?;
let text = read_to_string(apath).await?;
let html = markdown::to_html_with_options(
&text,
&markdown::Options {
parse: markdown::ParseOptions {
constructs: markdown::Constructs {
math_flow: true,
math_text: true,
..Default::default()
},
..Default::default()
},
compile: markdown::CompileOptions {
..Default::default()
},
},
)
.map_err(|e| anyhow!("the server had trouble compiling markdown: {e}"))?;
Ok(Scaffold {
title: a.title,
content: markup::new! {
@markup::raw(&html)
p{i{ "Article written by metamuffin, text licenced under CC BY-ND 4.0, non-trivial code blocks under GPL-3.0-only except where indicated otherwise" }}
},
})
}
|