extern crate actix;
extern crate actix_web;
extern crate bcrypt;
extern crate clap;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_migrations;
extern crate failure;
#[macro_use]
extern crate failure_derive;
extern crate futures;
#[macro_use]
extern crate log;
extern crate r2d2;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate askama;
extern crate chrono;
extern crate rand;
#[macro_use]
extern crate diesel_derive_enum;
use clap::{App as Clap, AppSettings, Arg, SubCommand};
use std::process;
mod db;
mod flash;
mod models;
mod report;
mod schema;
mod server;
mod time;
const _EXIT_SUCCESS: i32 = 0;
const EXIT_FAILURE: i32 = 1;
const DEFAULT_DATABASE_URL: &str = "punch.db";
const DEFAULT_BIND: &str = "127.0.0.1:8080";
const DEFAULT_STATIC_PATH: &str = "static/";
fn main() {
let database_arg = Arg::with_name("database")
.short("d")
.long("database-url")
.takes_value(true)
.default_value(DEFAULT_DATABASE_URL)
.help("Specify the path to the database")
.required(false);
let app = Clap::new("Punch time-tracking tool")
.version("0.1.0")
.about("Punch in, punch out, and report on time usage.")
.setting(AppSettings::SubcommandRequiredElseHelp)
.global_setting(AppSettings::GlobalVersion)
.global_setting(AppSettings::VersionlessSubcommands)
.global_setting(AppSettings::UnifiedHelpMessage)
.subcommand(
SubCommand::with_name("init")
.about("Initialize a new Punch instance.")
.arg(Arg::with_name("username").required(true))
.arg(Arg::with_name("password").required(true))
.arg(database_arg.clone()),
)
.subcommand(
SubCommand::with_name("testdb")
.about("Create a new Punch database populated with test data.")
.arg(Arg::with_name("username").required(true))
.arg(Arg::with_name("password").required(true))
.arg(database_arg.clone()),
)
.subcommand(
SubCommand::with_name("report")
.about("Display a summary report.")
.arg(database_arg.clone()),
)
.subcommand(
SubCommand::with_name("server")
.about("Start the web server")
.arg(
Arg::with_name("bind")
.short("b")
.long("bind")
.takes_value(true)
.default_value(DEFAULT_BIND)
.help("Specify the ip:port for binding.")
.required(false),
)
.arg(
Arg::with_name("static_path")
.short("s")
.long("static-path")
.takes_value(true)
.default_value(DEFAULT_STATIC_PATH)
.help("Path to static resources.")
.required(false),
)
.arg(database_arg),
);
let mut app_clone = app.clone();
let matches = app.get_matches();
match matches.subcommand() {
("init", Some(m)) => cmd_init(
m.value_of("database").unwrap(),
m.value_of("username").unwrap(),
m.value_of("password").unwrap(),
),
("testdb", Some(m)) => cmd_testdb(
m.value_of("database").unwrap(),
m.value_of("username").unwrap(),
m.value_of("password").unwrap(),
),
("report", Some(m)) => cmd_report(m.value_of("database").unwrap()),
("server", Some(m)) => cmd_server(
m.value_of("database").unwrap(),
m.value_of("bind").unwrap(),
m.value_of("static_path").unwrap(),
),
_ => {
app_clone.print_help().unwrap();
println!();
process::exit(EXIT_FAILURE);
}
};
std::process::exit(1);
}
fn cmd_init(database: &str, username: &str, password: &str) {
db::database_setup(database, username, password).unwrap();
}
fn cmd_testdb(database: &str, username: &str, password: &str) {
db::database_setup_test(database, username, password).unwrap();
}
fn cmd_report(database: &str) {
print!("{}", db::do_report(database).unwrap());
}
fn cmd_server(database: &str, bind: &str, static_path: &str) {
::std::env::set_var("RUST_LOG", "actix=info,actix_web=info,punch=trace");
server::do_server(database, bind, static_path);
}