remindrs/src/main.rs
finga 0434505b2d Use standard paths for a possible config location
Check several possible standard paths when there is no path to the
configuration file given as argument. To find the configuration file
following paths are used. The local directory `./config.toml`, the
user global configuration directory
`$XDG_CONFIG_HOME/whakarite/config.toml` and the system wide
configuration directory `/etc/whakarite/config.toml`. Note that in the
later two cases the directory which contains the `config.toml`
receives its name from the `$CARGO_BIN_NAME` environment variable at
compile time.
2023-01-25 22:11:32 +01:00

102 lines
2.8 KiB
Rust

use anyhow::Result;
use clap::Parser;
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};
mod args;
mod config;
mod models;
mod schema;
use args::Args;
use config::Config;
use models::{NewReminder, Reminder};
fn remind(
db: &mut PooledConnection<ConnectionManager<PgConnection>>,
mailer: &SmtpTransport,
) -> Result<()> {
info!("checking for reminders");
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 {
let duration = reminder.planned - OffsetDateTime::now_utc();
info!(?duration, "parking reminder");
park_timeout(<std::time::Duration>::try_from(duration)?);
}
// Check for another remind job if none dont loop forever
}
Ok(())
}
fn main() -> Result<()> {
let args = Args::parse();
if env::var("RUST_LOG").is_err() {
env::set_var("RUST_LOG", format!("{}", args.log_level));
}
tracing_subscriber::fmt::init();
info!(
"{} {} started",
env!("CARGO_BIN_NAME"),
env!("CARGO_PKG_VERSION")
);
let config = Config::load_config(args.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
)))?;
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)?;
}
}