···7070 let resume = fs::read_to_string(cfg.resume_fname.clone())?;
7171 let resume: String = markdown::render(&resume)?;
7272 let mi = mi::Client::new(cfg.mi_token.clone(), crate::APPLICATION_NAME.to_string())?;
7373- let blog = crate::post::load("blog", Some(&mi)).await?;
7474- let gallery = crate::post::load("gallery", None).await?;
7575- let talks = crate::post::load("talks", None).await?;
7373+ let blog = crate::post::load("blog").await?;
7474+ let gallery = crate::post::load("gallery").await?;
7575+ let talks = crate::post::load("talks").await?;
7676 let mut everything: Vec<Post> = vec![];
77777878 {
+47-38
src/post/mod.rs
···11use chrono::prelude::*;
22use color_eyre::eyre::{eyre, Result, WrapErr};
33use glob::glob;
44-use std::{cmp::Ordering, fs};
44+use std::{cmp::Ordering, path::PathBuf};
55+use tokio::fs;
5667pub mod frontmatter;
78···7071 }
7172}
72737373-pub async fn load(dir: &str, mi: Option<&mi::Client>) -> Result<Vec<Post>> {
7474- let mut result: Vec<Post> = vec![];
7474+async fn read_post(dir: &str, fname: PathBuf) -> Result<Post> {
7575+ let body = fs::read_to_string(fname.clone())
7676+ .await
7777+ .wrap_err_with(|| format!("can't read {:?}", fname))?;
7878+ let (front_matter, content_offset) = frontmatter::Data::parse(body.clone().as_str())
7979+ .wrap_err_with(|| format!("can't parse frontmatter of {:?}", fname))?;
8080+ let body = &body[content_offset..];
8181+ let date = NaiveDate::parse_from_str(&front_matter.clone().date, "%Y-%m-%d")
8282+ .map_err(|why| eyre!("error parsing date in {:?}: {}", fname, why))?;
8383+ let link = format!("{}/{}", dir, fname.file_stem().unwrap().to_str().unwrap());
8484+ let body_html = crate::app::markdown::render(&body)
8585+ .wrap_err_with(|| format!("can't parse markdown for {:?}", fname))?;
8686+ let body = body.to_string();
8787+ let date: DateTime<FixedOffset> =
8888+ DateTime::<Utc>::from_utc(NaiveDateTime::new(date, NaiveTime::from_hms(0, 0, 0)), Utc)
8989+ .with_timezone(&Utc)
9090+ .into();
75917676- for path in glob(&format!("{}/*.markdown", dir))?.filter_map(Result::ok) {
7777- log::debug!("loading {:?}", path);
7878- let body =
7979- fs::read_to_string(path.clone()).wrap_err_with(|| format!("can't read {:?}", path))?;
8080- let (fm, content_offset) = frontmatter::Data::parse(body.clone().as_str())
8181- .wrap_err_with(|| format!("can't parse frontmatter of {:?}", path))?;
8282- let markup = &body[content_offset..];
8383- let date = NaiveDate::parse_from_str(&fm.clone().date, "%Y-%m-%d")
8484- .map_err(|why| eyre!("error parsing date in {:?}: {}", path, why))?;
8585- let link = format!("{}/{}", dir, path.file_stem().unwrap().to_str().unwrap());
8686- let mentions: Vec<mi::WebMention> = match mi {
8787- None => vec![],
8888- Some(mi) => mi
8989- .mentioners(format!("https://christine.website/{}", link))
9090- .await
9191- .map_err(|why| tracing::error!("error: can't load mentions for {}: {}", link, why))
9292- .unwrap_or(vec![]),
9393- };
9292+ let mentions: Vec<mi::WebMention> = match std::env::var("MI_TOKEN") {
9393+ Ok(token) => mi::Client::new(token.to_string(), crate::APPLICATION_NAME.to_string())?
9494+ .mentioners(format!("https://christine.website/{}", link))
9595+ .await
9696+ .map_err(|why| tracing::error!("error: can't load mentions for {}: {}", link, why))
9797+ .unwrap_or(vec![]),
9898+ Err(_) => vec![],
9999+ };
941009595- result.push(Post {
9696- front_matter: fm,
9797- link: link,
9898- body: markup.to_string(),
9999- body_html: crate::app::markdown::render(&markup)
100100- .wrap_err_with(|| format!("can't parse markdown for {:?}", path))?,
101101- date: {
102102- DateTime::<Utc>::from_utc(
103103- NaiveDateTime::new(date, NaiveTime::from_hms(0, 0, 0)),
104104- Utc,
105105- )
106106- .with_timezone(&Utc)
107107- .into()
108108- },
109109- mentions: mentions,
110110- })
111111- }
101101+ Ok(Post {
102102+ front_matter,
103103+ link,
104104+ body,
105105+ body_html,
106106+ date,
107107+ mentions,
108108+ })
109109+}
110110+111111+pub async fn load(dir: &str) -> Result<Vec<Post>> {
112112+ let futs = glob(&format!("{}/*.markdown", dir))?
113113+ .filter_map(Result::ok)
114114+ .map(|fname| read_post(dir, fname));
115115+116116+ let mut result: Vec<Post> = futures::future::join_all(futs)
117117+ .await
118118+ .into_iter()
119119+ .map(Result::unwrap)
120120+ .collect();
112121113122 if result.len() == 0 {
114123 Err(eyre!("no posts loaded"))