M .gitignore => .gitignore +1 -0
@@ 5,3 5,4 @@
/blogs
/pages
/template.html.hbs
+/config.toml
M Cargo.lock => Cargo.lock +145 -0
@@ 21,6 21,19 @@ dependencies = [
]
[[package]]
+name = "atom_syndication"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91a85f2ee28cbd1ecf91288460f6dc74661fd99b4e9a559836a667ccf63aa38c"
+dependencies = [
+ "chrono",
+ "derive_builder",
+ "diligent-date-parser",
+ "never",
+ "quick-xml",
+]
+
+[[package]]
name = "autocfg"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 172,6 185,72 @@ dependencies = [
]
[[package]]
+name = "darling"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "derive_builder"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
+dependencies = [
+ "derive_builder_macro",
+]
+
+[[package]]
+name = "derive_builder_core"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "derive_builder_macro"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
+dependencies = [
+ "derive_builder_core",
+ "syn 1.0.109",
+]
+
+[[package]]
name = "digest"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 182,6 261,15 @@ dependencies = [
]
[[package]]
+name = "diligent-date-parser"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6cf7fe294274a222363f84bcb63cdea762979a0443b4cf1f4f8fd17c86b1182"
+dependencies = [
+ "chrono",
+]
+
+[[package]]
name = "emojicons"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 193,6 281,21 @@ dependencies = [
]
[[package]]
+name = "encoding_rs"
+version = "0.8.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 262,6 365,12 @@ dependencies = [
]
[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
name = "indexmap"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 336,6 445,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
+name = "never"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c96aba5aa877601bb3f6dd6a63a969e1f82e60646e81e71b14496995e9853c91"
+
+[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 464,6 579,16 @@ dependencies = [
]
[[package]]
+name = "quick-xml"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffc053f057dd768a56f62cd7e434c42c831d296968997e9ac1f76ea7c2d14c41"
+dependencies = [
+ "encoding_rs",
+ "memchr 2.5.0",
+]
+
+[[package]]
name = "quote"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 607,6 732,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
[[package]]
+name = "rss"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14816ec8b4e58b34a36adba66dcadd3e1e221dcb0fb2fd83e7c5129ea1a72458"
+dependencies = [
+ "atom_syndication",
+ "derive_builder",
+ "never",
+ "quick-xml",
+]
+
+[[package]]
name = "ryu"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 682,6 819,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ 919,8 1062,10 @@ dependencies = [
"emojicons",
"handlebars",
"pulldown-cmark",
+ "rss",
"serde",
"serde_derive",
+ "serde_json",
"toml",
"walkdir",
]
M Cargo.toml => Cargo.toml +2 -0
@@ 10,7 10,9 @@ chrono = "0.4.24"
emojicons = "1.0.1"
handlebars = "4.3.6"
pulldown-cmark = "0.9.2"
+rss = "2.0.2"
serde = "1.0.157"
serde_derive = "1.0.157"
+serde_json = "1.0.94"
toml = "0.7.3"
walkdir = "2.3.3"
M src/main.rs => src/main.rs +69 -3
@@ 1,11 1,12 @@
use chrono::NaiveDate;
use handlebars::Handlebars;
-use serde_derive::Serialize;
+use serde_derive::{Serialize, Deserialize};
use std::fs::{self, File};
use std::io::Write;
use std::path::{Path, PathBuf};
use toml::{Table, Value};
use walkdir::WalkDir;
+use rss::{Item, Guid, ChannelBuilder};
#[derive(Clone, Serialize)]
struct Blog {
@@ 21,11 22,39 @@ struct BlogPage {
after: Option<usize>,
}
+#[derive(Serialize)]
+struct Jsonfeed {
+ version: String,
+ title: String,
+ items: Vec<JsonfeedItems>,
+ icon: String,
+ home_page_url: String,
+ feed_url: String
+}
+
+#[derive(Serialize)]
+struct JsonfeedItems {
+ id: String,
+ url: String,
+ title: String,
+ content_html: String,
+ date_published: String,
+}
+
+#[derive(Deserialize)]
+struct Config {
+ name: String,
+ home_page: String,
+ icon: String,
+}
+
fn main() {
// make public folder
let _ = fs::remove_dir_all("public");
fs::create_dir("public").expect("could not make the folder \"public\"");
+ let config: Config = toml::from_str(&fs::read_to_string("config.toml").expect("could not read file config.toml")).expect("Cant convert your config to toml");
+
//copy all static
for e in WalkDir::new("static").into_iter().filter_map(|e| e.ok()) {
if e.metadata().unwrap().is_file() {
@@ 163,8 192,45 @@ fn main() {
before,
after,
}
- });
- for (x, i) in blog_pages.enumerate() {
+ }).collect::<Vec<_>>();
+ let json_blogs = serde_json::to_string(&Jsonfeed {
+ version: "https://jsonfeed.org/version/1".to_string(),
+ title: format!("{}'s Blog", config.name),
+ icon: config.icon,
+ home_page_url: config.home_page.clone(),
+ feed_url: format!("{}/blogs.json", config.home_page),
+ items: blog_pages.first().expect("cant get the first blog page").blogs.iter().map(|x| JsonfeedItems {
+ id: format!("{}/blogs/{}", config.home_page.clone(), x.path.display()),
+ url: format!("{}/blogs/{}", config.home_page, x.path.display()),
+ title: x.config["title"].as_str().expect("cant get the title of the blog").to_string(),
+ content_html: x.config["content"].as_str().expect("cant get the content of a blog (should never happen)").to_string(),
+ date_published: format!("{}T00:00:00+00:00", x.config["date"].as_str().expect("no date on blog"))
+ }).collect()
+ }).expect("Cant write the json blogs");
+ let rss_blogs = ChannelBuilder::default()
+ .title(format!("{}'s Blog", config.name))
+ .link(format!("{}/blogs", config.home_page))
+ .items(blog_pages.first().expect("cant get the first blog page").blogs.iter().map(|x| {
+ let mut item = Item::default();
+ item.set_guid({
+ let mut guid = Guid::default();
+ guid.set_permalink(true);
+ guid.set_value(format!("{}/blogs/{}", config.home_page.clone(), x.path.display()));
+ guid
+ });
+ item.set_title(x.config["title"].as_str().expect("Cant get the title of a blog").to_string());
+ item.set_link(format!("{}/blogs/{}", config.home_page.clone(), x.path.display()));
+ item.set_description(x.config["content"].as_str().expect("cant get the content of a blog (should never happen)").to_string());
+ item.set_pub_date(NaiveDate::parse_from_str(x.config["date"].as_str().expect("no date on blog"), "%Y-%m-%d").expect("Cant read date").format("%a, %d %b %Y 00:00:00 +0000").to_string());
+ item
+ }).collect::<Vec<_>>()).build();
+
+ let mut file = File::create("public/blogs.json").expect("Cant make blogs.json");
+ file.write_all(json_blogs.as_bytes()).expect("Cant write to blogs.json");
+ let mut file = File::create("public/blogs.rss").expect("Cant make blogs.rss");
+ file.write_all(rss_blogs.to_string().as_bytes()).expect("Cant write to blogs.rss");
+
+ for (x, i) in blog_pages.iter().enumerate() {
let path_name = format!("public/blogs-{x}.html");
let path = Path::new(&path_name);
let mut file =