#![doc = include_str!("../README.md")]
use actix_web::{middleware::Logger, web::Data, App, HttpServer};
use actix_web_httpauth::extractors::basic;
use anyhow::Context;
use clap::Parser;
use db::conn::{get_conn, get_pool, AnyConnection};
use routes::list::list;
use routes::login::login;
use routes::stats::stats;
use routes::status::status;
use routes::triggers::trigger_post;
use routes::{index::hello, triggers::trigger_get};
use service::manager::PulseManager;
use settings::Settings;
use std::sync::Arc;
use tracing::info;
use tracing_appender::non_blocking::WorkerGuard;
use utils::cli::Args;
use utils::logs::setup_logs;
#[doc(hidden)]
mod tests;
pub mod routes;
pub mod settings;
pub mod db;
pub mod service;
pub mod utils;
#[doc(hidden)]
#[tokio::main]
async fn run(settings: Settings, _guard: Option<WorkerGuard>) -> anyhow::Result<()> {
let hostname = settings.app.hostname.clone();
let port = settings.app.port;
let database_url = settings.app.database_url.clone();
AnyConnection::pre_init(&database_url)?;
let pool = get_pool(database_url)?;
let conn = &mut get_conn(&pool);
conn.migrate()?;
conn.init()?;
let manager = PulseManager::new(settings, pool.clone());
let manager = Arc::new(manager);
let manager_task = manager.start();
let webhook_task = manager.start_webhooks();
let notify_task = manager.start_notify();
info!("🚀 Listening on {}:{}", hostname, port);
HttpServer::new(move || {
App::new()
.wrap(Logger::default())
.service(hello)
.service(trigger_get)
.service(trigger_post)
.service(status)
.service(stats)
.service(login)
.service(list)
.app_data(basic::Config::default().realm("Restricted area"))
.app_data(Data::new(manager.clone()))
})
.bind((hostname, port))?
.run()
.await
.with_context(|| "Failed to start server")?;
info!("Shutting down...");
manager_task.abort();
webhook_task.abort();
notify_task.abort();
Ok(())
}
#[doc(hidden)]
pub fn main() -> anyhow::Result<()> {
let args = Args::parse();
let settings = Settings::get_settings(args.config).with_context(|| "Failed to get settings")?;
let guard = setup_logs(
settings.app.log_level.clone(),
settings.opts.log_file.clone(),
)?;
info!("💫 autopulse starting up...");
run(settings, guard)
}