Make since command work
This commit is contained in:
parent
3d78b9b108
commit
36b2051d4f
9
config.toml
Normal file
9
config.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
api_key = "<your API key here from https://developers.yepzon.com/>"
|
||||||
|
tags_url = "https://platform.yepzon.com/tags"
|
||||||
|
states_url = "https://platform.yepzon.com/tags/{tag}/states"
|
||||||
|
locations_url = "https://platform.yepzon.com/tags/{tag}/locations/{state}"
|
||||||
|
timestamp_format = "%Y-%m-%dT%H:%M:%S%.fZ"
|
||||||
|
timedate_format = "%d.%m.%Y-%H:%M:%S"
|
||||||
|
date_format = "%d.%m.%Y"
|
||||||
|
time_format = "%H:%M:%S"
|
||||||
|
throttle = 9
|
26
src/cmd.rs
26
src/cmd.rs
@ -11,22 +11,38 @@ pub struct EnvOpt {
|
|||||||
#[derive(FromArgs)]
|
#[derive(FromArgs)]
|
||||||
#[argh(subcommand)]
|
#[argh(subcommand)]
|
||||||
pub enum Subcommand {
|
pub enum Subcommand {
|
||||||
Run(RunOpt),
|
Since(SinceOpt),
|
||||||
Init(InitOpt),
|
Init(InitOpt),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
#[derive(FromArgs)]
|
||||||
#[argh(subcommand, name = "run", description = "Run the tool")]
|
#[argh(
|
||||||
pub struct RunOpt {
|
subcommand,
|
||||||
|
name = "since",
|
||||||
|
description = "fetch locations for a given section in time.\nsince and until in format dd.mm.yyy, OR hh:mm:ss, OR dd.mm.yyy-hh:mm:ss"
|
||||||
|
)]
|
||||||
|
pub struct SinceOpt {
|
||||||
#[argh(
|
#[argh(
|
||||||
option,
|
option,
|
||||||
short = 'c',
|
short = 'c',
|
||||||
description = "otus",
|
description = "config.toml file path.",
|
||||||
default = "PathBuf::from(\"config.toml\")"
|
default = "PathBuf::from(\"config.toml\")"
|
||||||
)]
|
)]
|
||||||
pub config: PathBuf,
|
pub config: PathBuf,
|
||||||
|
#[argh(
|
||||||
|
positional,
|
||||||
|
short = 's',
|
||||||
|
description = "the oldest point in time to get locations from."
|
||||||
|
)]
|
||||||
|
pub since: String,
|
||||||
|
#[argh(
|
||||||
|
option,
|
||||||
|
short = 'u',
|
||||||
|
description = "the most recent point in time to get locations from, default = now."
|
||||||
|
)]
|
||||||
|
pub until: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
#[derive(FromArgs)]
|
||||||
#[argh(subcommand, name = "init", description = "Initialize a config file")]
|
#[argh(subcommand, name = "init", description = "initializes a config file")]
|
||||||
pub struct InitOpt {}
|
pub struct InitOpt {}
|
||||||
|
@ -9,7 +9,9 @@ pub struct Config {
|
|||||||
pub locations_url: String,
|
pub locations_url: String,
|
||||||
|
|
||||||
pub timestamp_format: String,
|
pub timestamp_format: String,
|
||||||
pub between_format: String,
|
pub timedate_format: String,
|
||||||
|
pub date_format: String,
|
||||||
|
pub time_format: String,
|
||||||
|
|
||||||
pub throttle: u32,
|
pub throttle: u32,
|
||||||
}
|
}
|
||||||
@ -24,7 +26,10 @@ impl Default for Config {
|
|||||||
locations_url: "https://platform.yepzon.com/tags/{tag}/locations/{state}".to_owned(),
|
locations_url: "https://platform.yepzon.com/tags/{tag}/locations/{state}".to_owned(),
|
||||||
|
|
||||||
timestamp_format: "%Y-%m-%dT%H:%M:%S%.fZ".to_owned(),
|
timestamp_format: "%Y-%m-%dT%H:%M:%S%.fZ".to_owned(),
|
||||||
between_format: "%d.%m.%Y %H:%M:%S".to_owned(),
|
|
||||||
|
timedate_format: "%d.%m.%Y-%H:%M:%S".to_owned(),
|
||||||
|
date_format: "%d.%m.%Y".to_owned(),
|
||||||
|
time_format: "%H:%M:%S".to_owned(),
|
||||||
|
|
||||||
throttle: 9,
|
throttle: 9,
|
||||||
}
|
}
|
||||||
|
@ -52,12 +52,15 @@ impl From<std::string::FromUtf8Error> for GenericError {
|
|||||||
impl Display for GenericError {
|
impl Display for GenericError {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
let err = match self {
|
let err = match self {
|
||||||
GenericError::ChronoParseError(_) => "Chrono parse error".to_owned(),
|
GenericError::ChronoParseError(e) => format!("Date-Time value parse error: {}", e),
|
||||||
GenericError::FromUTF8Error(_) => "UTF8 error".to_owned(),
|
GenericError::FromUTF8Error(e) => format!("UTF-8 error: {}", e),
|
||||||
GenericError::IOError(e) => format!("IO error: {}", e),
|
GenericError::IOError(e) => format!("IO error: {}", e),
|
||||||
GenericError::MinreqError(_) => "Minreq error".to_owned(),
|
GenericError::MinreqError(e) => format!("Network error: {}", e),
|
||||||
GenericError::TomlError(_) => "Toml error".to_owned(),
|
GenericError::TomlError(e) => format!("Toml error: {}", e),
|
||||||
GenericError::YepzonServerError(_) => "Yepzon server error".to_owned(),
|
GenericError::YepzonServerError(e) => format!(
|
||||||
|
"Yepzon server error: {}",
|
||||||
|
e.message.as_ref().unwrap_or(&String::new())
|
||||||
|
),
|
||||||
GenericError::MessagedError(msg, err) => format!("{}\n {}", msg, err),
|
GenericError::MessagedError(msg, err) => format!("{}\n {}", msg, err),
|
||||||
};
|
};
|
||||||
write!(f, "{}", err)
|
write!(f, "{}", err)
|
||||||
|
46
src/main.rs
46
src/main.rs
@ -4,7 +4,8 @@ mod config;
|
|||||||
mod errors;
|
mod errors;
|
||||||
|
|
||||||
use api::API;
|
use api::API;
|
||||||
use chrono::NaiveDateTime;
|
use chrono::offset::Local;
|
||||||
|
use chrono::{NaiveDate, NaiveDateTime, NaiveTime, ParseError};
|
||||||
use cmd::*;
|
use cmd::*;
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use errors::{GenericError, MessagedError};
|
use errors::{GenericError, MessagedError};
|
||||||
@ -23,7 +24,7 @@ fn main() {
|
|||||||
|
|
||||||
fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
||||||
match env.subcommand {
|
match env.subcommand {
|
||||||
Subcommand::Run(opt) => {
|
Subcommand::Since(opt) => {
|
||||||
let mut file = File::open(&opt.config).with_msg(format!(
|
let mut file = File::open(&opt.config).with_msg(format!(
|
||||||
"Could not find {}",
|
"Could not find {}",
|
||||||
opt.config.to_str().unwrap_or("")
|
opt.config.to_str().unwrap_or("")
|
||||||
@ -35,11 +36,14 @@ fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
|||||||
let config: Config =
|
let config: Config =
|
||||||
toml::from_str(&string).with_msg("given config file is not a valid config file")?;
|
toml::from_str(&string).with_msg("given config file is not a valid config file")?;
|
||||||
|
|
||||||
run(
|
let since = Some(try_get_datetime(opt.since, &config)?);
|
||||||
&config,
|
|
||||||
Some("1.1.2015 00:00:00".to_owned()),
|
let until = match opt.until {
|
||||||
Some("1.5.2021 00:00:00".to_owned()),
|
Some(until) => Some(try_get_datetime(until, &config)?),
|
||||||
)?;
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
run(&config, since, until)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Subcommand::Init(_) => {
|
Subcommand::Init(_) => {
|
||||||
@ -53,12 +57,13 @@ fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(config: &Config, from: Option<String>, to: Option<String>) -> Result<(), GenericError> {
|
fn run(
|
||||||
|
config: &Config,
|
||||||
|
from: Option<NaiveDateTime>,
|
||||||
|
to: Option<NaiveDateTime>,
|
||||||
|
) -> Result<(), GenericError> {
|
||||||
let mut api = API::new(config.clone());
|
let mut api = API::new(config.clone());
|
||||||
|
|
||||||
let from = get_opt(from.map(|f| NaiveDateTime::parse_from_str(&f, &config.between_format)))?;
|
|
||||||
let to = get_opt(to.map(|t| NaiveDateTime::parse_from_str(&t, &config.between_format)))?;
|
|
||||||
|
|
||||||
let tags = api.get_tags()?;
|
let tags = api.get_tags()?;
|
||||||
let first_tag = tags[0].id.clone().unwrap();
|
let first_tag = tags[0].id.clone().unwrap();
|
||||||
let state_list = api.get_states(&first_tag)?;
|
let state_list = api.get_states(&first_tag)?;
|
||||||
@ -103,12 +108,12 @@ fn run(config: &Config, from: Option<String>, to: Option<String>) -> Result<(),
|
|||||||
println!("{:<100}", "Done!");
|
println!("{:<100}", "Done!");
|
||||||
locations.sort_by(|loc1, loc2| loc2.timestamp.cmp(&loc1.timestamp));
|
locations.sort_by(|loc1, loc2| loc2.timestamp.cmp(&loc1.timestamp));
|
||||||
|
|
||||||
let _locs = API::get_between(&locations, from, to, false, &config);
|
let locs = API::get_between(&locations, from, to, false, &config);
|
||||||
/*dbg!(
|
dbg!(
|
||||||
&locs.iter().map(|loc| loc.0).collect::<Vec<NaiveDateTime>>(),
|
&locs.iter().map(|loc| loc.0).collect::<Vec<NaiveDateTime>>(),
|
||||||
locs.len(),
|
locs.len(),
|
||||||
locations.len()
|
locations.len()
|
||||||
);*/
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,3 +132,16 @@ fn exp_time(api: &API, reqs_left: u64) -> Duration {
|
|||||||
let interval = 1_000 / api.config.throttle as u64;
|
let interval = 1_000 / api.config.throttle as u64;
|
||||||
Duration::from_millis(interval * reqs_left)
|
Duration::from_millis(interval * reqs_left)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_get_datetime(parsed: String, config: &Config) -> Result<NaiveDateTime, ParseError> {
|
||||||
|
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),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user