use crate::{post::Post, signalboost::Person}; use anyhow::Result; use comrak::{markdown_to_html, ComrakOptions}; use serde::Deserialize; use std::{fs, path::PathBuf}; #[derive(Clone, Deserialize)] pub struct Config { #[serde(rename = "clackSet")] clack_set: Vec, signalboost: Vec, port: u16, #[serde(rename = "resumeFname")] resume_fname: PathBuf, } pub fn markdown(inp: &str) -> String { let mut options = ComrakOptions::default(); options.extension.autolink = true; options.extension.table = true; options.extension.description_lists = true; options.extension.superscript = true; options.extension.strikethrough = true; options.extension.footnotes = true; options.render.unsafe_ = true; markdown_to_html(inp, &options) } pub const ICON: &'static str = "https://christine.website/static/img/avatar.png"; pub struct State { pub cfg: Config, pub signalboost: Vec, pub resume: String, pub blog: Vec, pub gallery: Vec, pub talks: Vec, pub everything: Vec, pub jf: jsonfeed::Feed, } pub fn init(cfg: PathBuf) -> Result { let cfg: Config = serde_dhall::from_file(cfg).parse()?; let sb = cfg.signalboost.clone(); let resume = fs::read_to_string(cfg.resume_fname.clone())?; let resume: String = markdown(&resume); let blog = crate::post::load("blog")?; let gallery = crate::post::load("gallery")?; let talks = crate::post::load("talks")?; let mut everything: Vec = vec![]; { let blog = blog.clone(); let gallery = gallery.clone(); let talks = talks.clone(); everything.extend(blog.iter().cloned()); everything.extend(gallery.iter().cloned()); everything.extend(talks.iter().cloned()); }; everything.sort(); everything.reverse(); let mut jfb = jsonfeed::Feed::builder() .title("Christine Dodrill's Blog") .description("My blog posts and rants about various technology things.") .author( jsonfeed::Author::new() .name("Christine Dodrill") .url("https://christine.website") .avatar(ICON), ) .feed_url("https://christine.website/blog.json") .user_comment("This is a JSON feed of my blogposts. For more information read: https://jsonfeed.org/version/1") .icon(ICON) .favicon(ICON); for post in &everything { let post = post.clone(); jfb = jfb.item(post.into()); } Ok(State { cfg: cfg, signalboost: sb, resume: resume, blog: blog, gallery: gallery, talks: talks, everything: everything, jf: jfb.build(), }) } #[cfg(test)] mod tests { use anyhow::Result; #[test] fn init() -> Result<()> { super::init("./config.dhall".into())?; Ok(()) } }