about summary refs log tree commit diff
path: root/src/atom/mod.rs
diff options
context:
space:
mode:
authorgennyble <gen@nyble.dev>2024-10-11 21:54:58 -0500
committergennyble <gen@nyble.dev>2024-10-11 21:54:58 -0500
commitc2a15e4447d7535fc3b9f8fabcfacf26947a84d2 (patch)
tree4b566334c8e55518fdf5fb2b0af58eaf49b37d69 /src/atom/mod.rs
parentb0f6242b8b936d47b32c227cab5b18b4902cf9c4 (diff)
downloadawake-c2a15e4447d7535fc3b9f8fabcfacf26947a84d2.tar.gz
awake-c2a15e4447d7535fc3b9f8fabcfacf26947a84d2.zip
truly i do not know what any of this is; git reinit
Diffstat (limited to 'src/atom/mod.rs')
-rw-r--r--src/atom/mod.rs154
1 files changed, 154 insertions, 0 deletions
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<AtomEntry>,
+}
+
+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<P: AsRef<Utf8Path>>(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,
+	}
+}