2021-06-24 15:57:11 +02:00
|
|
|
use crate::config::Config;
|
|
|
|
use anyhow::Context;
|
|
|
|
use rand::{rngs::StdRng, SeedableRng};
|
|
|
|
use sqlx::MySqlPool;
|
|
|
|
use std::sync::Arc;
|
|
|
|
use structopt::StructOpt;
|
|
|
|
use tera::Tera;
|
2021-06-24 16:22:27 +02:00
|
|
|
use tokio::sync::Mutex;
|
2021-06-24 15:57:11 +02:00
|
|
|
use warp::Filter;
|
|
|
|
|
|
|
|
mod config;
|
|
|
|
mod handlers;
|
|
|
|
mod util;
|
|
|
|
|
|
|
|
#[derive(StructOpt)]
|
|
|
|
struct Opt {
|
|
|
|
#[structopt(index = 1, help = "config file to use")]
|
|
|
|
config: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
async fn main() -> anyhow::Result<()> {
|
|
|
|
env_logger::init();
|
|
|
|
let opt = Opt::from_args();
|
|
|
|
|
|
|
|
let config = load_config(&opt.config)
|
|
|
|
.await
|
|
|
|
.context("error loading config")?;
|
|
|
|
|
|
|
|
let pool = MySqlPool::connect(&config.database_url)
|
|
|
|
.await
|
|
|
|
.context("error creating mysql pool")?;
|
|
|
|
|
|
|
|
let mut tera = Tera::default();
|
|
|
|
tera.add_raw_templates(vec![
|
|
|
|
("index.html", include_str!("../assets/index.html.tera")),
|
|
|
|
("success.html", include_str!("../assets/success.html.tera")),
|
2021-06-24 16:22:27 +02:00
|
|
|
("404.html", include_str!("../assets/404.html.tera")),
|
2021-06-24 15:57:11 +02:00
|
|
|
])
|
|
|
|
.context("error adding templates to tera")?;
|
|
|
|
|
|
|
|
let brevo = Arc::new(Brevo {
|
|
|
|
config,
|
|
|
|
pool,
|
|
|
|
tera,
|
|
|
|
rng: Mutex::new(StdRng::from_rng(rand::thread_rng())?),
|
|
|
|
});
|
|
|
|
let brevo_idx = Arc::clone(&brevo);
|
|
|
|
let brevo_submit = Arc::clone(&brevo);
|
|
|
|
let brevo_srv = Arc::clone(&brevo);
|
2021-06-24 16:22:27 +02:00
|
|
|
let brevo_reject = Arc::clone(&brevo);
|
2021-06-24 15:57:11 +02:00
|
|
|
|
|
|
|
let routes = warp::get()
|
|
|
|
.and(
|
|
|
|
warp::path::end()
|
|
|
|
.and_then(move || handlers::index(Arc::clone(&brevo_idx)))
|
|
|
|
.or(warp::path::param::<String>()
|
|
|
|
.and(warp::path::end())
|
|
|
|
.and_then(move |id| handlers::shortened(id, Arc::clone(&brevo)))),
|
|
|
|
)
|
|
|
|
.or(warp::post()
|
|
|
|
.and(warp::body::content_length_limit(1024 * 16))
|
|
|
|
.and(warp::body::form())
|
2021-06-24 16:22:27 +02:00
|
|
|
.and_then(move |form_data| handlers::submit(form_data, Arc::clone(&brevo_submit))))
|
|
|
|
.recover(move |err| handlers::handle_reject(Arc::clone(&brevo_reject), err));
|
2021-06-24 15:57:11 +02:00
|
|
|
|
|
|
|
warp::serve(routes).run(brevo_srv.config.bind_addr).await;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn load_config(path: &str) -> anyhow::Result<Config> {
|
|
|
|
let data = tokio::fs::read(path).await?;
|
|
|
|
Ok(toml::from_slice::<Config>(&data)?)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Brevo {
|
|
|
|
pub config: Config,
|
|
|
|
pub pool: MySqlPool,
|
|
|
|
pub tera: Tera,
|
|
|
|
pub rng: Mutex<StdRng>,
|
|
|
|
}
|