panorama/src/main.rs

95 lines
2.6 KiB
Rust
Raw Normal View History

2021-02-14 13:20:35 +00:00
#[macro_use]
extern crate log;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
2021-02-12 08:12:43 +00:00
use anyhow::Result;
2021-02-12 12:32:17 +00:00
use futures::future::TryFutureExt;
2021-02-14 13:20:35 +00:00
use panorama::{
config::{spawn_config_watcher, MailConfig},
mail, ui,
};
use structopt::StructOpt;
use tokio::sync::{mpsc, oneshot};
use xdg::BaseDirectories;
2021-02-12 08:12:43 +00:00
#[derive(Debug, StructOpt)]
2021-02-12 13:52:46 +00:00
#[structopt(author, about)]
struct Opt {
/// Config file
#[structopt(long = "config-file", short = "c")]
config_path: Option<PathBuf>,
/// The path to the log file. By default, does not log.
#[structopt(long = "log-file")]
log_file: Option<PathBuf>,
}
2021-02-12 08:54:19 +00:00
#[tokio::main]
async fn main() -> Result<()> {
// parse command line arguments into options struct
let opt = Opt::from_args();
// print logs to file as directed by command line options
setup_logger(&opt)?;
2021-02-12 08:12:43 +00:00
let xdg = BaseDirectories::new()?;
2021-02-14 13:20:35 +00:00
let (config_thread, config_update) = spawn_config_watcher()?;
// let config: MailConfig = {
// let config_path = opt
// .config_path
// .clone()
// .unwrap_or_else(|| "config.toml".into());
// let mut config_file = File::open(config_path)?;
// let mut contents = Vec::new();
// config_file.read_to_end(&mut contents)?;
// toml::from_slice(&contents)?
// };
// used to notify the runtime that the process should exit
2021-02-14 13:20:35 +00:00
let (exit_tx, mut exit_rx) = mpsc::channel::<()>(1);
// used to send commands to the mail service
let (mail_tx, mail_rx) = mpsc::unbounded_channel();
2021-02-12 08:12:43 +00:00
2021-02-14 13:20:35 +00:00
let mail_thread = tokio::spawn(mail::run_mail(config_update.clone(), mail_rx).unwrap_or_else(report_err));
let stdout = std::io::stdout();
2021-02-14 13:20:35 +00:00
let ui_thread = tokio::spawn(ui::run_ui(stdout, exit_tx).unwrap_or_else(report_err));
2021-02-12 08:12:43 +00:00
2021-02-14 13:20:35 +00:00
exit_rx.recv().await;
// TODO: graceful shutdown
// yada yada create a background process and pass off the connections so they can be safely
// shutdown
std::process::exit(0);
// Ok(())
2021-02-12 08:12:43 +00:00
}
2021-02-12 12:32:17 +00:00
fn setup_logger(opt: &Opt) -> Result<()> {
let mut fern = fern::Dispatch::new()
2021-02-12 12:32:17 +00:00
.format(|out, message, record| {
out.finish(format_args!(
"{}[{}][{}] {}",
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
record.target(),
record.level(),
message
))
})
.level(log::LevelFilter::Debug);
if let Some(path) = &opt.log_file {
fern = fern.chain(fern::log_file(path)?);
}
fern.apply()?;
2021-02-12 12:32:17 +00:00
Ok(())
}
2021-02-14 12:27:13 +00:00
fn report_err(err: anyhow::Error) {
2021-02-14 13:20:35 +00:00
error!("error: {:?}", err);
2021-02-14 12:27:13 +00:00
}