#![windows_subsystem = "windows"] mod args; mod errors; mod gpx; use args::*; use errors::GenericError; use thingy_lib::api::{LocationModel, TagModel, API}; use thingy_lib::chrono::offset::Local; use thingy_lib::chrono::{NaiveDate, NaiveDateTime, NaiveTime, ParseError}; use thingy_lib::{Config, MessagedError}; fn main() { let env: EnvOpt = argh::from_env(); if let Err(e) = from_env(env) { eprintln!("Critical Error: {}", e); std::process::exit(1); } } fn from_env(env: EnvOpt) -> Result<(), GenericError> { match env.subcommand { Subcommand::Between(opt) => { let config = Config::from_path(&env.config)?; let mut api = API::new(config.clone()); let since = Some(try_get_datetime(opt.since, &config).with_msg("Failed to parse since")?); let until = match opt.until { Some(until) => { Some(try_get_datetime(until, &config).with_msg("Failed to parse until")?) } None => None, }; let (tag, locs) = thingy_lib::between(&mut api, opt.device, since, until)?; let gpx = gpx::generate_gpx(&tag, &locs, &api.config)?; gpx::write_gpx(&gpx)?; dbg!( &locs.iter().map(|loc| loc.0).collect::>(), locs.len(), ); Ok(()) } Subcommand::Init(opt) => { thingy_lib::init(&env.config, opt.api_key)?; Ok(()) } Subcommand::Api(_) => { let config = Config::from_path(&env.config)?; let api = API::new(config.clone()); match thingy_lib::check_api(&api) { Ok(_) => { println!("API verified, no issues"); Ok(()) } Err(e) => Err(GenericError::MessagedError( "API integrity failed, or API-key is not valid. ".to_owned(), Some(Box::new(e.into())), )), } } Subcommand::ShareToken(opt) => { let config = Config::from_path(&env.config)?; let api = API::new(config.clone()); println!("{}", thingy_lib::sharetoken(&api, opt.device)?); Ok(()) } Subcommand::Nick(opt) => { let config = Config::from_path(&env.config)?; let mut api = API::new(config.clone()); match opt.subcommand { NickSub::List(_) => { for ((idx, nick), tag) in thingy_lib::nick_list(&api)? { println!("{}. {}\n{}", idx, nick, tag); } } NickSub::Set(opt) => { thingy_lib::nick_set(&mut api, opt.device, opt.nickname)?; api.config.write_to(&env.config)?; } } Ok(()) } #[cfg(debug_assertions)] Subcommand::Get(opt) => { let config = Config::from_path(&env.config)?; let api = API::new(config.clone()); match opt.subcommand { GetSub::Tag(opt) => { let tags = api.get_tag(&opt.device); dbg!(&tags); } GetSub::Tags(_) => { let tags = api.get_tags()?; dbg!(&tags); } GetSub::States(opt) => { API::print_list(thingy_lib::get_states(&api, opt.device)); } GetSub::Locations(opt) => { API::print_list(thingy_lib::get_locations(&api, opt.device, opt.state)) } } Ok(()) } } } fn try_get_datetime(parsed: String, config: &Config) -> Result { match NaiveDateTime::parse_from_str(&parsed, &config.timedate_format) { Ok(timedate) => Ok(timedate), Err(_) => match NaiveDate::parse_from_str(&parsed, &config.date_format) { Ok(date) => Ok(date.and_hms(0, 0, 0)), Err(_) => match NaiveTime::parse_from_str(&parsed, &config.time_format) { Ok(time) => Ok(Local::today().naive_local().and_time(time)), Err(e) => Err(e), }, }, } }