From c2a15e4447d7535fc3b9f8fabcfacf26947a84d2 Mon Sep 17 00:00:00 2001 From: gennyble Date: Fri, 11 Oct 2024 21:54:58 -0500 Subject: truly i do not know what any of this is; git reinit --- src/atom/mod.rs | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 src/atom/mod.rs (limited to 'src/atom/mod.rs') diff --git a/src/atom/mod.rs b/src/atom/mod.rs new file mode 100644 index 0000000..2020163 --- /dev/null +++ b/src/atom/mod.rs @@ -0,0 +1,154 @@ +mod urn; + +use std::str::FromStr; + +use bempline::{variables, Document, Options}; +use camino::{Utf8Path, Utf8PathBuf}; +use confindent::{let_get, Confindent, Entry, Node}; +use time::{format_description::well_known, OffsetDateTime}; +use urn::Urn; + +use crate::{markup, templated::Templated, timeparse}; + +pub fn main() -> ! { + let awake_conf = Confindent::from_file(std::env::args().nth(2).unwrap()).unwrap(); + + let root: Utf8PathBuf = awake_conf.child_parse("Webroot").unwrap(); + + // Grab the atom config and then grab the atom template + let atom_conf_path = std::env::args().nth(3).unwrap_or(String::from("atom.conf")); + let mut atom_conf = Confindent::from_file(&atom_conf_path).unwrap(); + let atom = Document::from_file( + root.clone() + .join(atom_conf.child_value("Template").unwrap()) + .canonicalize_utf8() + .unwrap(), + Options::default(), + ) + .unwrap(); + + let mut changed = false; + // Go through every feed and create the entries + let feeds = atom_conf.children_mut("Feed"); + for feed in feeds { + make_feed(feed, &mut changed, &root, atom.clone()) + } + + // If the atom has changed, probably because we created an ID + // write it to disk. + if changed { + std::fs::write(atom_conf_path, atom_conf.to_string()); + } + + std::process::exit(0); +} + +pub struct AtomFeed { + /// Where is the atom located in the webroot. (relative to webroot) + relpath: Utf8PathBuf, + /// What unique ID does this Feed have? + id: String, + + title: String, + subtitle: String, + updated: OffsetDateTime, + author_name: String, + author_email: String, + + entries: Vec, +} + +pub struct AtomEntry { + /// What file does this entry direct to? This file will be opened to inspect + /// the frontmatter for information to fill out the entry with. It will also + /// be used to create the link to the entry. + relpath: Utf8PathBuf, + /// What unique ID does this Entry have? + id: String, + + title: String, + published: OffsetDateTime, + updated: OffsetDateTime, +} + +/// Parses all the options of a feed and generates the build job +pub fn make_feed(feed: &mut Entry, changed: &mut bool, root: &Utf8Path, mut atom: Document) { + let_get!( + feed, + relpath: Utf8PathBuf = "Output", + clone id = "Id", + clone title = "Title", + clone subtitle = "Subtitle", + clone updated = "Updated", + ); + + //FIXME: gen- We need to backresolve the feed URL + let feed_link = ""; + let author_name = feed.get("Author/Name").unwrap().to_owned(); + let author_email = feed.get("Author/Email").unwrap().to_owned(); + + let mut atomfeed = AtomFeed { + relpath, + id, + title, + subtitle, + updated: timeparse::parse(&updated).unwrap(), + author_name, + author_email, + entries: vec![], + }; + + let entries = feed.children_mut("Entry"); + for entry in entries { + if !entry.has_child("Id") { + //TODO: gen- Read NID from conf? + let id = Urn::new_random("dreamy"); + entry.push_entry(("Id", id)); + *changed = true; + } + + atomfeed.entries.push(make_entry(entry, &root)); + } +} + +fn make_entry>(entry: &Entry, webroot: P) -> AtomEntry { + let relpath: Utf8PathBuf = entry.parse().unwrap(); + let path = webroot.as_ref().join(&relpath); + + let entry_content = match std::fs::read_to_string(&path) { + Ok(ok) => ok, + Err(e) => { + panic!("failed to get file at {path}: {e}"); + } + }; + let entry_templated = Templated::from_str(&entry_content).unwrap(); + + let conf_or_frontmatter = |conf_key: &str, front_key: &str| -> &str { + entry + .child_value(conf_key) + .unwrap_or_else(|| entry_templated.frontmatter.get(front_key).unwrap()) + }; + + let title = conf_or_frontmatter("Title", "title").to_owned(); + let id = entry.child_value("Id").unwrap().to_owned(); + + let entry_published_raw = conf_or_frontmatter("Published", "published"); + + let updated = timeparse::parse(entry.child_value("Updated").unwrap_or_else(|| { + entry_templated + .frontmatter + .get("updated") + .unwrap_or(entry_published_raw) + })) + .unwrap(); + + let published = timeparse::parse(entry_published_raw).unwrap(); + + AtomEntry { + relpath, + id, + title, + published, + updated, + } +} -- cgit 1.4.1-3-g733a5