From 5f0c06b6cfd4431a6b07d6eea51454284c127ab0 Mon Sep 17 00:00:00 2001 From: viridian Date: Sat, 20 Apr 2024 22:22:59 +0200 Subject: [PATCH] Add config and some code for atom feeds --- Cargo.lock | 7 +++++ Cargo.toml | 1 + src/config.rs | 14 ++++++++++ src/lib.rs | 1 + src/main.rs | 3 ++ src/syndication/atom.rs | 62 +++++++++++++++++++++++++++++++++++++++++ src/syndication/mod.rs | 1 + 7 files changed, 89 insertions(+) create mode 100644 src/syndication/atom.rs create mode 100644 src/syndication/mod.rs diff --git a/Cargo.lock b/Cargo.lock index f823a3b..86dbd0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -519,6 +519,7 @@ dependencies = [ "serde_json", "tera", "toml", + "xml-builder", ] [[package]] @@ -1432,6 +1433,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "xml-builder" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efc4f1a86af7800dfc4056c7833648ea4515ae21502060b5c98114d828f5333b" + [[package]] name = "zerocopy" version = "0.7.32" diff --git a/Cargo.toml b/Cargo.toml index 1379000..a11a235 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,4 @@ chrono = "0.4" derive_more = "0.99" scraper = "0.19" serde_json = "1.0" +xml-builder = "0.5" diff --git a/src/config.rs b/src/config.rs index febcd58..63cf390 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,8 +7,21 @@ pub struct Config { pub src_dir: String, pub templates_dir: String, pub emoji_config: Option, + pub syndication: Option, +} +#[derive(Deserialize, Serialize, Debug)] +pub struct Syndication { + pub title: String, + pub link: String, + pub icon: Option, + pub subtitle: Option, + pub atom: Option, } +#[derive(Deserialize, Serialize, Debug)] +pub struct AtomConfig { + pub enabled: bool, +} #[derive(Deserialize, Serialize, Debug)] pub struct EmojiConfig { pub emoji_web_directory: String, @@ -22,6 +35,7 @@ impl Default for Config { src_dir: "md_src".to_string(), templates_dir: "templates".to_string(), emoji_config: None, + syndication: None, } } } diff --git a/src/lib.rs b/src/lib.rs index 73b69b1..ea00765 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ #![feature(str_split_remainder)] + use chrono::prelude::*; use derive_more::Constructor; use markdown::{to_html_with_options, CompileOptions, Options}; diff --git a/src/main.rs b/src/main.rs index f697889..42336ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,9 @@ +#![feature(ascii_char)] use std::fs::read_to_string; pub mod config; pub mod emoji; pub mod index; +pub mod syndication; use mlem::*; use std::env; @@ -45,6 +47,7 @@ fn generate() { format!("{}.html", file.file_name.to_str().unwrap()), )); } + let index = index::generate(post_index, &config.templates_dir); std::fs::write(format!("{}/index.html", config.output_dir), index) diff --git a/src/syndication/atom.rs b/src/syndication/atom.rs new file mode 100644 index 0000000..0b54153 --- /dev/null +++ b/src/syndication/atom.rs @@ -0,0 +1,62 @@ +use xml_builder::{XMLBuilder, XMLElement, XMLVersion}; + +pub fn generate( + config: crate::config::Syndication, + post_index: &Vec, +) -> String { + let mut xml = XMLBuilder::new() + .version(XMLVersion::XML1_1) + .encoding("UTF-8".into()) + .build(); + + let mut feed = XMLElement::new("feed"); + feed.add_attribute("xmlns", "http://www.w3.org/2005/Atom"); + + let mut id = XMLElement::new("id"); + id.add_text(config.link).unwrap(); + feed.add_child(id).unwrap(); + + let mut title = XMLElement::new("title"); + title.add_text(config.title).unwrap(); + feed.add_child(title).unwrap(); + + let mut updated = XMLElement::new("updated"); + let last_update = chrono::DateTime::from_timestamp(last_update(post_index), 0).unwrap(); + updated.add_text(last_update.to_rfc3339()).unwrap(); + feed.add_child(updated).unwrap(); + + if config.subtitle.is_some() { + let mut subtitle = XMLElement::new("subtitle"); + subtitle.add_text(config.subtitle.unwrap()).unwrap(); + feed.add_child(subtitle).unwrap(); + } + + if config.icon.is_some() { + let mut icon = XMLElement::new("icon"); + icon.add_text(config.icon.unwrap()).unwrap(); + feed.add_child(icon).unwrap(); + } + + xml.set_root_element(feed); + let mut writer: Vec = Vec::new(); + xml.generate(&mut writer).unwrap(); + + let mut output_xml = String::new(); + + for e in writer { + output_xml += &e.as_ascii().unwrap().to_string(); + } + + output_xml +} + +fn last_update(post_index: &Vec) -> i64 { + let mut last_timestamp: i64 = i64::MIN; + + for post in post_index { + if post.sort_date > last_timestamp { + last_timestamp = post.sort_date; + } + } + last_timestamp +} diff --git a/src/syndication/mod.rs b/src/syndication/mod.rs new file mode 100644 index 0000000..856b895 --- /dev/null +++ b/src/syndication/mod.rs @@ -0,0 +1 @@ +pub mod atom;