about summary refs log tree commit diff
path: root/src
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
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')
-rw-r--r--src/atom/mod.rs154
-rw-r--r--src/atom/urn.rs49
-rwxr-xr-x[-rw-r--r--]src/atomizer.rs0
-rwxr-xr-x[-rw-r--r--]src/error.rs0
-rwxr-xr-x[-rw-r--r--]src/fs.rs0
-rwxr-xr-x[-rw-r--r--]src/ifc.rs0
-rwxr-xr-x[-rw-r--r--]src/main.rs12
-rwxr-xr-x[-rw-r--r--]src/markup.rs0
-rwxr-xr-x[-rw-r--r--]src/settings.rs0
-rwxr-xr-x[-rw-r--r--]src/templated.rs0
-rwxr-xr-x[-rw-r--r--]src/timeparse.rs0
-rwxr-xr-x[-rw-r--r--]src/util.rs0
12 files changed, 209 insertions, 6 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,
+	}
+}
diff --git a/src/atom/urn.rs b/src/atom/urn.rs
new file mode 100644
index 0000000..9ec73ae
--- /dev/null
+++ b/src/atom/urn.rs
@@ -0,0 +1,49 @@
+use core::fmt;
+
+use rand::{rngs::OsRng, Rng};
+
+//TODO: gen- Check URN are valid
+// https://www.rfc-editor.org/rfc/rfc2141#section-2.1
+pub struct Urn {
+	/// Namespace Identifier
+	nid: String,
+	/// Namespace Specific string. This is the unique part of the identifier
+	nss: String,
+}
+
+impl Urn {
+	/// awake specific function for generating a URN in the form of:
+	/// `urn:NID:1234-5678`
+	/// Where 1234-5678 is a randomly generated eight digit ID broken in two.
+	pub fn new_random<S: Into<String>>(nid: S) -> Self {
+		let first = random_base58(4);
+		let second = random_base58(4);
+
+		Self {
+			nid: nid.into(),
+			nss: format!("{first}-{second}"),
+		}
+	}
+}
+
+impl fmt::Display for Urn {
+	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+		let Urn { nid, nss } = self;
+
+		write!(f, "urn:{nid}:{nss}")
+	}
+}
+
+const BASE58: &'static [u8] = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
+const USER_ID_LENGTH: usize = 6;
+const SESSION_ID_LENGTH: usize = 12;
+
+/// Random Base58 string, `count` characters long, using OsRng which is assumed
+/// to be secure
+/// > assumed that system always provides high-quality cryptographically secure random data
+fn random_base58(count: usize) -> String {
+	let mut rng = OsRng::default();
+	std::iter::from_fn(|| Some(BASE58[rng.gen_range(0..BASE58.len())] as char))
+		.take(count)
+		.collect()
+}
diff --git a/src/atomizer.rs b/src/atomizer.rs
index e6a147b..e6a147b 100644..100755
--- a/src/atomizer.rs
+++ b/src/atomizer.rs
diff --git a/src/error.rs b/src/error.rs
index 56539d0..56539d0 100644..100755
--- a/src/error.rs
+++ b/src/error.rs
diff --git a/src/fs.rs b/src/fs.rs
index 831aa86..831aa86 100644..100755
--- a/src/fs.rs
+++ b/src/fs.rs
diff --git a/src/ifc.rs b/src/ifc.rs
index d0a9f5f..d0a9f5f 100644..100755
--- a/src/ifc.rs
+++ b/src/ifc.rs
diff --git a/src/main.rs b/src/main.rs
index 0c61389..5784588 100644..100755
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,4 @@
-mod atomizer;
+mod atom;
 mod error;
 mod fs;
 mod ifc;
@@ -20,7 +20,7 @@ use axum::{
 };
 use bempline::{variables, Document, Options};
 use camino::Utf8PathBuf;
-use confindent::Confindent;
+use confindent::{Confindent, Node};
 pub use error::RuntimeError;
 use fs::Filesystem;
 use settings::Settings;
@@ -36,7 +36,7 @@ use crate::{
 #[tokio::main]
 async fn main() {
 	match std::env::args().nth(1).as_deref() {
-		Some("atomizer") => atomizer::main(),
+		Some("atomizer") => atom::main(),
 		/* fallthrough*/
 		Some("serve") => (),
 		_ => (),
@@ -250,7 +250,7 @@ async fn send_template(
 	for style in templated.frontmatter.get_many("style") {
 		let mut pat = style_pattern.clone();
 		pat.set("style", style);
-		template.set_pattern("styles", pat);
+		template.set_pattern(pat);
 	}
 
 	// path to the file for navigation
@@ -285,7 +285,7 @@ async fn send_template(
 		let mut pat = path_pattern.clone();
 		pat.set("path_link", "/");
 		pat.set("path_name", "home");
-		template.set_pattern("path", pat);
+		template.set_pattern(pat);
 
 		for part in path {
 			link.push(part);
@@ -293,7 +293,7 @@ async fn send_template(
 			let mut pat = path_pattern.clone();
 			pat.set("path_link", &link);
 			pat.set("path_name", part);
-			template.set_pattern("path", pat);
+			template.set_pattern(pat);
 		}
 	}
 
diff --git a/src/markup.rs b/src/markup.rs
index a1516f4..a1516f4 100644..100755
--- a/src/markup.rs
+++ b/src/markup.rs
diff --git a/src/settings.rs b/src/settings.rs
index 06abc18..06abc18 100644..100755
--- a/src/settings.rs
+++ b/src/settings.rs
diff --git a/src/templated.rs b/src/templated.rs
index c6daac8..c6daac8 100644..100755
--- a/src/templated.rs
+++ b/src/templated.rs
diff --git a/src/timeparse.rs b/src/timeparse.rs
index f4eaca5..f4eaca5 100644..100755
--- a/src/timeparse.rs
+++ b/src/timeparse.rs
diff --git a/src/util.rs b/src/util.rs
index a3cc064..a3cc064 100644..100755
--- a/src/util.rs
+++ b/src/util.rs