extern crate regex; extern crate rss; use regex::Regex; use rss::{ChannelBuilder, Item}; use std::error; use std::fs; use std::fs::File; use std::io::prelude::*; fn main() -> Result<(), Box> { // create rss channel for mycelial.technology let mut channel = ChannelBuilder::default() .title("mycelial technology") .link("https://mycelial.technology") .description( "glyph's RSS feed. Biophilic musings on carbon-based and silicon-based technologies.", ) .build() .unwrap(); // list template directories containing articles for syndication let bacteria = "./templates/bacteria"; let computers = "./templates/computers"; let fungi = "./templates/fungi"; let plants = "./templates/plants"; // add directories to a vector let mut dirs = Vec::new(); dirs.push(bacteria); dirs.push(computers); dirs.push(fungi); dirs.push(plants); // create vectors for item fields let mut titles = Vec::new(); let mut pub_dates = Vec::new(); let mut urls = Vec::new(); let mut articles = Vec::new(); // loop through template directories and extract item field values for dir in dirs { for entry in fs::read_dir(dir)? { let entry = entry?; let path = entry.path(); // populate item url vector from article filenames let re_url = Regex::new("./templates/(.*).html.tera")?; let caps_url = re_url.captures(&path.to_str().unwrap()); if let Some(url) = caps_url { let article_url = url[1].replace("_", "-"); let full_url = format!("https://mycelial.technology/{}", article_url); urls.push(full_url); }; // open the file (article) and read it to a string let mut file = File::open(path)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; // populate item title vector from article heading let re_h2 = Regex::new("

(.*)

")?; let caps_h2 = re_h2.captures(&contents); if let Some(title) = caps_h2 { titles.push(title[1].to_string()); }; // populate pub_date vector from first italic element in article let re_i = Regex::new("(.*)")?; let caps_i = re_i.captures(&contents); if let Some(date) = caps_i { pub_dates.push(date[1].to_string()); }; // populate article content vector from article element let re_article = Regex::new(r"
[\s\S]*
")?; let caps_article = re_article.captures(&contents); if let Some(content) = caps_article { articles.push(content[0].to_string()); }; } } // get length of titles vector (serves as proxy for total number of articles) let library = titles.len(); // create vector for channel items let mut items = Vec::new(); // loop through vectors of item fields and create items accordingly for x in 0..library { let mut item = Item::default(); item.set_title(titles[x].to_string()); item.set_link(urls[x].to_string()); item.set_pub_date(pub_dates[x].to_string()); item.set_description(articles[x].to_string()); items.push(item) } // add the items to the channel channel.set_items(items); // write the channel to file let rss_file = File::create("static/feed.rss")?; channel.write_to(rss_file)?; Ok(()) }