#[macro_use] extern crate diesel; #[macro_use] extern crate diesel_migrations; use actix::prelude::*; use actix_web::{middleware, App, HttpServer}; use clap::{App as ClapApp, Arg}; use log::{info, warn}; use std::env; use std::fs; use std::net::SocketAddr; use std::path::PathBuf; mod database; mod dataops; mod models; mod routes; mod schema; const VERSION: &str = env!("CARGO_PKG_VERSION"); fn main() -> std::io::Result<()> { let env = env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"); env_logger::init_from_env(env); let app = ClapApp::new("upend") .version(VERSION) .author("Tomáš Mládek ") .arg(Arg::with_name("DIRECTORY").required(true).index(1)) .arg( Arg::with_name("BIND") .long("bind") .default_value("127.0.0.1:8093") .help("address and port to bind the Web interface on") .required(true), ) .arg( Arg::with_name("NO_BROWSER") .long("no-browser") .help("Do not open web browser with the UI."), ); let matches = app.get_matches(); info!("Starting UpEnd {}...", VERSION); let sys = actix::System::new("upend"); let vault_path = PathBuf::from(matches.value_of("DIRECTORY").unwrap()); let _ = fs::remove_file(&vault_path.join("upend.sqlite3")); // TODO REMOVE!!! let open_result = database::open_upend(&vault_path).expect("failed to open database!"); let pool = open_result.pool; let db_addr = SyncArbiter::start(3, move || database::DbExecutor(pool.clone())); let hash_addr = SyncArbiter::start(4, || dataops::HasherWorker); let bind: SocketAddr = matches .value_of("BIND") .unwrap() .parse() .expect("Incorrect bind format."); info!("Starting server at: {}", &bind); let state = routes::State { directory: vault_path.clone(), db: db_addr.clone(), hasher: hash_addr.clone(), }; // Start HTTP server HttpServer::new(move || { App::new() .data(state.clone()) .wrap(middleware::Logger::default()) .service(routes::get_raw) .service(routes::get_lookup) .service(routes::api_refresh) .service( actix_files::Files::new( "/", env::current_exe().unwrap().parent().unwrap().join("webui"), ) .index_file("index.html"), ) }) .bind(&bind)? .run(); if open_result.new { info!("The vault has been just created, running initial update..."); actix::spawn(dataops::update_directory_bg(vault_path, db_addr, hash_addr)); } // TODO REMOVE if !matches.is_present("NO_BROWSER") { let ui_result = webbrowser::open(&format!("http://localhost:{}", bind.port())); if ui_result.is_err() { warn!("Could not open UI in browser!"); } } sys.run() }