Add missing options to build-feed
continuous-integration/drone/push Build is passing Details

Signed-off-by: Jacob Kiers <jacob@jacobkiers.net>
This commit is contained in:
Jacob Kiers 2022-08-07 23:17:41 +02:00
parent f529e0ceb6
commit 802b2a81b8
3 changed files with 54 additions and 25 deletions

View File

@ -29,9 +29,14 @@ pub(crate) enum Command {
},
/// Build an ATOM feed containing the full contents of the email
BuildFeed {
/// Host name hosting the feed
hostname: String,
/// Feed file
#[clap(value_parser, default_value = "output/feed.atom")]
filename: PathBuf,
/// Create an HTML file for each message
#[clap(short, long, value_parser, default_value_t = false)]
include_html: bool,
},
/// Exports the emails as HTML files
ExportHtml {

View File

@ -3,11 +3,17 @@ use crate::Message;
use atom_syndication::{
ContentBuilder, Entry, EntryBuilder, Feed, FeedBuilder, Generator, LinkBuilder, Person,
};
use chrono::{DateTime, Utc, TimeZone};
use chrono::{DateTime, TimeZone, Utc};
use mail_parser::HeaderValue;
pub(crate) fn add_entry_to_feed(feed: &mut Feed, message: &Message, processed_html: &String) {
pub(crate) fn add_entry_to_feed(
feed: &mut Feed,
message: &Message,
processed_html: &String,
hostname: &String,
include_html: bool,
) {
let parsed = message.get_parsed().unwrap();
let date = parsed.get_date().expect("Could not extract date");
let from = match parsed.get_from() {
@ -17,7 +23,7 @@ pub(crate) fn add_entry_to_feed(feed: &mut Feed, message: &Message, processed_ht
let path = crate::get_path(&parsed, message);
let url = format!("https://newsletters.kiers.eu/{}", &path);
let url = format!("https://{}/{}", hostname, &path);
let mut entry: Entry = Newsletter {
author: Person {
@ -41,26 +47,29 @@ pub(crate) fn add_entry_to_feed(feed: &mut Feed, message: &Message, processed_ht
content: Some(processed_html.clone()),
id: url.clone(),
published: Utc.timestamp(date.to_timestamp(), 0), //(format!("{}{}", &date.to_iso8601(), "+00:00").as_str()).`unwrap(),
url: url,
url: match include_html {
true => url,
false => "".to_string(),
},
}
.into();
entry.set_updated(Utc.timestamp(date.to_timestamp(), 0));
feed.entries.push(entry);
}
pub(crate) fn build_atom_feed() -> Feed {
pub(crate) fn build_atom_feed(hostname: &String) -> Feed {
FeedBuilder::default()
.title("JJKiers Newsletters")
.id("https://newsletters.kiers.eu/feed.atom")
.id(format!("https://{}/feed.atom", hostname))
.link(
LinkBuilder::default()
.href("https://newsletters.kiers.eu/")
.href(format!("https://{}/", hostname))
.rel("alternate")
.build(),
)
.link(
LinkBuilder::default()
.href("https://newsletters.kiers.eu/feed.atom")
.href(format!("https://{}/feed.atom", hostname))
.rel("self")
.build(),
)
@ -91,18 +100,23 @@ impl From<Newsletter> for Entry {
.build()
});
EntryBuilder::default()
.title(post.title)
let mut eb = EntryBuilder::default();
eb.title(post.title)
.id(post.id)
.published(Some(post.published.clone().into()))
.author(post.author.into())
.content(content)
.link(
.content(content);
if post.url.len() > 1 {
eb.link(
LinkBuilder::default()
.href(post.url)
.rel("alternate")
.build(),
)
.build()
);
}
eb.build()
}
}

View File

@ -35,7 +35,7 @@ fn main() -> Result<(), Box<dyn Error>> {
username.to_owned(),
password.to_owned(),
),
cli::Command::BuildFeed { filename } => build_feed(&filename),
cli::Command::BuildFeed { filename , hostname, include_html } => build_feed(&filename, hostname.to_owned(), *include_html),
_ => unimplemented!("This method is not yet implemented."),
};
@ -50,7 +50,7 @@ fn create_directory<P: AsRef<Path>>(dir: P) -> Result<(), std::io::Error> {
Ok(())
}
fn build_feed(filename: &PathBuf) -> Result<(), Box<dyn Error>> {
fn build_feed(filename: &PathBuf, hostname: String, include_html: bool) -> Result<(), Box<dyn Error>> {
let dir = filename.parent().ok_or(format!(
"Could not get parent directory of {}",
filename.display()
@ -64,7 +64,7 @@ fn build_feed(filename: &PathBuf) -> Result<(), Box<dyn Error>> {
create_directory(dir)?;
let mut feed = feed::build_atom_feed();
let mut feed = feed::build_atom_feed(&hostname);
let mut reader = DataDirectoryMessageReader::new((&Path::new("data")).to_path_buf());
@ -91,7 +91,12 @@ fn build_feed(filename: &PathBuf) -> Result<(), Box<dyn Error>> {
let html_body = parsed.get_html_body(0).expect("Could not read html body");
let processed_html = process_html(&html_body).expect("Could not process the HTML");
feed::add_entry_to_feed(&mut feed, &msg, &processed_html);
if include_html {
let path : PathBuf = [dir, Path::new(&get_path(&parsed, &msg))].iter().collect();
write_file(&path, processed_html.as_bytes())?;
}
feed::add_entry_to_feed(&mut feed, &msg, &processed_html, &hostname, include_html);
}
if feed.entries.len() > 0 {
@ -156,18 +161,14 @@ fn fetch_from_imap(
println!("Storing to {}", &html_path.display());
OpenOptions::new()
.write(true)
.create(true)
.open(&html_path)
.expect(format!("Could not open file '{}' for writing", &html_path.display()).as_str())
.write_all(msg.get_data())
.expect(format!("Could not write html to file '{}'.", &html_path.display()).as_str());
write_file(&html_path, msg.get_data())?;
}
Ok(())
}
fn get_path(parsed: &ParsedMessage, msg: &Message) -> String {
let date = parsed.get_date().expect("Could not extract date");
let date_str = format!(
@ -189,3 +190,12 @@ fn get_path(parsed: &ParsedMessage, msg: &Message) -> String {
fn process_html(input: &str) -> Result<String, ()> {
Ok(input.replace("src", "data-source"))
}
fn write_file(html_path: &PathBuf, data: &[u8]) -> Result<(), std::io::Error> {
OpenOptions::new()
.write(true)
.create(true)
.open(&html_path)
.expect(format!("Could not open file '{}' for writing", &html_path.display()).as_str())
.write_all(data)
}