2023-01-23 23:36:03 +01:00
|
|
|
use anyhow::Result;
|
|
|
|
use diesel::{
|
|
|
|
prelude::*,
|
|
|
|
r2d2::{ConnectionManager, Pool, PooledConnection},
|
|
|
|
};
|
|
|
|
use lettre::{Message, SmtpTransport, Transport};
|
|
|
|
use std::{env, thread::park_timeout};
|
|
|
|
use time::{Duration, OffsetDateTime};
|
|
|
|
use tracing::{debug, info, trace};
|
|
|
|
|
2023-01-24 00:46:25 +01:00
|
|
|
mod config;
|
2023-01-23 23:36:03 +01:00
|
|
|
mod models;
|
|
|
|
mod schema;
|
|
|
|
|
2023-01-24 00:46:25 +01:00
|
|
|
use config::Config;
|
2023-01-23 23:36:03 +01:00
|
|
|
use models::{NewReminder, Reminder};
|
|
|
|
|
|
|
|
fn remind(
|
|
|
|
db: &mut PooledConnection<ConnectionManager<PgConnection>>,
|
|
|
|
mailer: &SmtpTransport,
|
|
|
|
) -> Result<()> {
|
2023-01-24 00:46:25 +01:00
|
|
|
info!("checking for reminders");
|
2023-01-23 23:36:03 +01:00
|
|
|
|
|
|
|
for reminder in schema::reminders::dsl::reminders
|
|
|
|
.filter(schema::reminders::executed.is_null())
|
|
|
|
.order(schema::reminders::planned.asc())
|
|
|
|
.load::<Reminder>(db)?
|
|
|
|
{
|
|
|
|
trace!(?reminder, "checking reminder");
|
|
|
|
if reminder.planned <= OffsetDateTime::now_utc() {
|
|
|
|
let email = Message::builder()
|
|
|
|
.from("whakarite@localhost".parse()?)
|
|
|
|
.to(reminder.receiver.parse()?)
|
|
|
|
.subject(&reminder.title)
|
|
|
|
.body(reminder.message.to_string())?;
|
|
|
|
|
|
|
|
mailer.send(&email)?;
|
|
|
|
|
|
|
|
diesel::update(&reminder)
|
|
|
|
.set(schema::reminders::executed.eq(Some(OffsetDateTime::now_utc())))
|
|
|
|
.execute(db)?;
|
|
|
|
|
|
|
|
debug!("email sent to {}", reminder.receiver);
|
|
|
|
} else {
|
2023-01-24 00:46:25 +01:00
|
|
|
let duration = reminder.planned - OffsetDateTime::now_utc();
|
|
|
|
info!(?duration, "parking reminder");
|
|
|
|
|
|
|
|
park_timeout(<std::time::Duration>::try_from(duration)?);
|
2023-01-23 23:36:03 +01:00
|
|
|
}
|
2023-01-24 00:46:25 +01:00
|
|
|
// Check for another remind job if none dont loop forever
|
2023-01-23 23:36:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() -> Result<()> {
|
|
|
|
tracing_subscriber::fmt::init();
|
|
|
|
|
|
|
|
info!(
|
|
|
|
"{} {} started",
|
|
|
|
env!("CARGO_BIN_NAME"),
|
|
|
|
env!("CARGO_PKG_VERSION")
|
|
|
|
);
|
|
|
|
|
2023-01-24 00:46:25 +01:00
|
|
|
let config_path = "./config.toml";
|
|
|
|
|
|
|
|
let config: Config = toml::from_str(&std::fs::read_to_string(config_path)?)?;
|
|
|
|
|
|
|
|
trace!(?config, config_path, "loaded config");
|
|
|
|
|
|
|
|
let db_pool = Pool::builder().build(ConnectionManager::<PgConnection>::new(format!(
|
|
|
|
"postgresql://{}:{}@{}:{}/{}",
|
|
|
|
config.database.user,
|
|
|
|
config.database.pass,
|
|
|
|
config.database.host,
|
|
|
|
config.database.port,
|
|
|
|
config.database.name
|
|
|
|
)))?;
|
2023-01-23 23:36:03 +01:00
|
|
|
|
|
|
|
let test_reminder = NewReminder {
|
|
|
|
created: OffsetDateTime::now_utc(),
|
|
|
|
planned: (OffsetDateTime::now_utc() + Duration::MINUTE),
|
|
|
|
title: "Test title",
|
|
|
|
message: "Test message",
|
|
|
|
receiver: "finga@localhost",
|
|
|
|
};
|
|
|
|
|
|
|
|
diesel::insert_into(schema::reminders::table)
|
|
|
|
.values(&test_reminder)
|
|
|
|
.execute(&mut db_pool.get()?)?;
|
|
|
|
|
|
|
|
let mailer = SmtpTransport::unencrypted_localhost();
|
|
|
|
|
|
|
|
loop {
|
|
|
|
remind(&mut db_pool.get()?, &mailer)?;
|
|
|
|
}
|
|
|
|
}
|