summaryrefslogtreecommitdiff
path: root/src/blog/helper.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/blog/helper.rs')
-rw-r--r--src/blog/helper.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/blog/helper.rs b/src/blog/helper.rs
new file mode 100644
index 0000000..6dea529
--- /dev/null
+++ b/src/blog/helper.rs
@@ -0,0 +1,71 @@
+use anyhow::{anyhow, Context};
+use futures::future::join_all;
+use std::{
+ path::{Path, PathBuf},
+ process::Stdio,
+};
+use tokio::{
+ fs::File,
+ io::{AsyncBufReadExt, BufReader},
+ process::Command,
+};
+
+pub struct ArticleMeta {
+ pub title: String,
+ pub canonical_name: String,
+ pub date: iso8601::Date,
+}
+
+pub async fn article_metadata(path: PathBuf) -> anyhow::Result<ArticleMeta> {
+ let f = File::open(&path).await.context("article not found")?;
+ let mut f = BufReader::new(f);
+ let mut buf = String::new();
+ f.read_line(&mut buf).await.context("cant read the file")?; // assume the 1st line has the title
+ Ok(ArticleMeta {
+ title: String::from(buf[2..].trim()),
+ canonical_name: path
+ .file_stem()
+ .ok_or(anyhow!("no file stem"))?
+ .to_str()
+ .ok_or(anyhow!("this file's name is broken"))?
+ .to_string(),
+ date: iso8601::date(
+ &path
+ .file_name()
+ .ok_or(anyhow!("file has no name"))?
+ .to_str()
+ .ok_or(anyhow!("this file's name is broken"))?[0..10],
+ )
+ .map_err(|e| anyhow!("file date wrong: {e}"))?,
+ })
+}
+
+pub async fn get_articles(blog_root: &Path) -> anyhow::Result<Vec<ArticleMeta>> {
+ let mut a = join_all(
+ std::fs::read_dir(blog_root)?
+ .map(|e| e.unwrap())
+ .map(|e| article_metadata(e.path())),
+ )
+ .await
+ .into_iter()
+ .collect::<anyhow::Result<Vec<_>>>()?;
+ a.sort_by_cached_key(|e| -match e.date {
+ iso8601::Date::YMD { year, month, day } => day as i32 + month as i32 * 100 + year * 10000,
+ _ => unreachable!(),
+ });
+ Ok(a)
+}
+
+// TODO use this somewhere
+pub async fn file_history(filename: &str) -> String {
+ String::from_utf8(
+ Command::new("/usr/bin/git")
+ .args(&["log", "--follow", "--pretty=tformat:%as %h %s", filename])
+ .stdout(Stdio::piped())
+ .output()
+ .await
+ .unwrap()
+ .stdout,
+ )
+ .unwrap()
+}