#[macro_use] extern crate diesel; #[macro_use] extern crate diesel_migrations; use actix::prelude::*; use actix_files::NamedFile; use actix_web::{error, get, middleware, post, web, App, Error, HttpResponse, HttpServer}; use clap::{App as ClapApp, Arg}; use std::env; mod database; mod dataops; mod models; mod schema; use env_logger; use log::info; use std::fs; use std::path::PathBuf; struct State { directory: PathBuf, db: Addr, hasher: Addr, } #[get("/raw/{hash}")] async fn get_raw(state: web::Data, hash: web::Path) -> Result { let response = state .db .send(database::RetrieveByHash { hash: hash.into_inner(), }) .await?; match response { Ok(result) => match result { Some(path) => Ok(NamedFile::open(path)?), None => Err(error::ErrorNotFound("NOT FOUND")), }, Err(e) => Err(error::ErrorInternalServerError(e)), } } #[post("/api/refresh")] async fn api_refresh(state: web::Data) -> Result { dataops::update_directory(&state.directory, &state.db, &state.hasher) .await .map_err(|_| error::ErrorInternalServerError("UPDATE ERROR"))?; Ok(HttpResponse::Ok().finish()) } const VERSION: &'static 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), ); let matches = app.get_matches(); info!("Starting UpEnd {}...", VERSION); let dirname = matches.value_of("DIRECTORY").unwrap(); let path = PathBuf::from(dirname); let _ = fs::remove_file(format!("{}/upend.sqlite3", dirname)); // TODO REMOVE!!! let db_pool = database::open_upend(&dirname).expect("failed to open database!"); let sys = actix::System::new("upend"); // let connection = db_pool.get().expect("Could not get SQL connection."); let db_addr = SyncArbiter::start(3, move || database::DbExecutor(db_pool.clone())); let hash_addr = SyncArbiter::start(4, move || dataops::HasherWorker); let bind = matches.value_of("BIND").unwrap(); info!("Starting server at: {}", &bind); // Start HTTP server HttpServer::new(move || { App::new() .data(State { directory: path.clone(), db: db_addr.clone(), hasher: hash_addr.clone(), }) .wrap(middleware::Logger::default()) .service(get_raw) .service(api_refresh) }) .bind(&bind)? .run(); sys.run() }