commit - 30dde916b02b22cd1840d13fb35276990bceeb53
commit + ccb62d531454eb4b79b334d3d72be07aa85f4101
blob - /dev/null
blob + 85c1ee63806afb4fcefa06f257000848678997ee (mode 644)
--- /dev/null
+++ src/config.rs
+use serde::Deserialize;
+use std::fs::File;
+use anyhow::Context;
+use std::{io::Read, path::Path};
+
+#[derive(Debug, Deserialize)]
+pub struct Config {
+ pub(crate) to: String,
+ pub(crate) from: String,
+ pub(crate) smtp: SmtpConfig,
+}
+
+#[derive(Debug, Deserialize)]
+pub struct SmtpConfig {
+ pub(crate) user: String,
+ pub(crate) password: String,
+ pub(crate) server: String,
+ pub(crate) port: u16,
+}
+
+impl Config {
+ pub fn new(config_path: impl AsRef<Path>) -> anyhow::Result<Config> {
+ let mut string = String::new();
+ File::open(config_path.as_ref())
+ .context(format!(
+ "File {:?} does not exist",
+ &config_path.as_ref()
+ ))?
+ .read_to_string(&mut string)?;
+ let config: Config = toml::de::from_str(&string)?;
+
+ Ok(config)
+ }
+}
blob - c5901238843b8aa956544d407f87f932190b9b83
blob + 3e3c0785340d6941347d6763d076362cb20d4381
--- src/main.rs
+++ src/main.rs
extern crate diesel_migrations;
pub mod cli;
+pub mod config;
pub mod db;
+pub mod mail;
pub mod models;
pub mod rss;
pub mod schema;
use self::diesel::prelude::*;
use anyhow::Context;
+use config::Config;
use schema::posts::dsl::*;
-use serde::Deserialize;
-use std::fs::File;
-use std::io::BufRead;
-use std::io::BufReader;
-use std::io::Read;
+use std::{
+ fs::File,
+ io::{BufRead, BufReader},
+};
+use crate::mail::{get_mailer, send_email};
-#[derive(Debug, Deserialize)]
-struct Config<'a> {
- to: &'a str,
- from: &'a str,
- smtp: SmtpConfig<'a>,
-}
-
-#[derive(Debug, Deserialize)]
-struct SmtpConfig<'a> {
- user: &'a str,
- password: &'a str,
- server: &'a str,
- port: u16,
-}
-
fn main() -> anyhow::Result<()> {
diesel_migrations::embed_migrations!("migrations/");
env_logger::init();
let args = cli::Cli::build_app()?;
- let mut string = String::new();
- File::open(args.config_path.as_ref().unwrap())
- .context(format!(
- "File {:?} does not exist",
- &args.config_path.unwrap()
- ))?
- .read_to_string(&mut string)?;
- let config: Config = toml::de::from_str(&string)?;
+ let config = Config::new(args.config_path.unwrap())?;
dbg!(&config);
let urls = BufReader::new(
}
fn send_posts(config: &Config, items: Vec<models::Post>, dry_run: bool) -> anyhow::Result<()> {
+ let mailer = get_mailer(config)?;
for mut post in items {
if !dry_run {
let subject = post.title.unwrap_or_else(|| "No title found".to_string());
// TODO: always append url instead
// https://todo.sr.ht/~witcher/rss-email/7
let body = post.content.unwrap_or_else(|| post.url.unwrap());
- send_email(config, subject, body)?;
+ send_email(config, subject, body, &mailer)?;
}
post.sent = true;
}
+ // TODO: mark posts as sent in database, too
Ok(())
}
-
-fn send_email<S, I>(config: &Config, subject: S, body: I) -> anyhow::Result<()>
-where
- S: AsRef<str>,
- I: Into<String>,
-{
- use lettre::{
- message::Message,
- transport::{
- smtp::{
- authentication::Credentials,
- client::{Tls, TlsParameters},
- SmtpTransport,
- },
- Transport,
- },
- };
-
- let email = Message::builder()
- .from(config.from.parse()?)
- .to(config.to.parse()?)
- .subject(subject.as_ref())
- .body(body.into())?;
-
- let creds = Credentials::new(
- config.smtp.user.to_string(),
- config.smtp.password.to_string(),
- );
-
- let tls = TlsParameters::builder(config.smtp.server.to_string())
- .dangerous_accept_invalid_certs(true)
- .build()?;
-
- let mailer = SmtpTransport::relay(config.smtp.server)?
- .tls(Tls::Opportunistic(tls))
- .credentials(creds)
- .port(config.smtp.port)
- .build();
-
- // TODO: extract mailer to only be constructed once and reused
- // https://todo.sr.ht/~witcher/rss-email/9
- // TODO: allow TLS, specify via config?
- // https://todo.sr.ht/~witcher/rss-email/8
- mailer.send(&email)?;
-
- Ok(())
-}
blob - /dev/null
blob + 98c81d0675870c295c157e7fb817f9132755c138 (mode 644)
--- /dev/null
+++ src/mail.rs
+use crate::config::Config;
+use lettre::{
+ message::Message,
+ transport::smtp::{
+ authentication::Credentials,
+ client::{Tls, TlsParameters},
+ SmtpTransport,
+ },
+ Transport,
+};
+
+pub fn get_mailer(config: &Config) -> anyhow::Result<SmtpTransport> {
+ let creds = Credentials::new(
+ config.smtp.user.to_string(),
+ config.smtp.password.to_string(),
+ );
+
+ // TODO: allow TLS, specify via config?
+ // https://todo.sr.ht/~witcher/rss-email/8
+ let tls = TlsParameters::builder(config.smtp.server.to_string())
+ .dangerous_accept_invalid_certs(true)
+ .build()?;
+
+ let mailer = SmtpTransport::relay(&config.smtp.server)?
+ .tls(Tls::Opportunistic(tls))
+ .credentials(creds)
+ .port(config.smtp.port)
+ .build();
+
+ Ok(mailer)
+}
+
+pub fn send_email<S, I>(
+ config: &Config,
+ subject: S,
+ body: I,
+ mailer: &SmtpTransport,
+) -> anyhow::Result<()>
+where
+ S: AsRef<str>,
+ I: Into<String>,
+{
+ let email = Message::builder()
+ .from(config.from.parse()?)
+ .to(config.to.parse()?)
+ .subject(subject.as_ref())
+ .body(body.into())?;
+
+ mailer.send(&email)?;
+
+ Ok(())
+}