Separate lib and ux
This commit is contained in:
parent
2b835a72b0
commit
b1b8ac417b
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,6 @@
|
||||
/target
|
||||
secret.toml
|
||||
*.gpx
|
||||
*.gpx
|
||||
*.code-workspace
|
||||
/thingy_lib/Cargo.lock
|
||||
/thingy_lib/target/
|
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -371,9 +371,16 @@ name = "thingy"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"argh",
|
||||
"chrono",
|
||||
"geo-types",
|
||||
"gpx",
|
||||
"thingy-lib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thingy-lib"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"minreq",
|
||||
"serde",
|
||||
"toml",
|
||||
|
12
Cargo.toml
12
Cargo.toml
@ -5,10 +5,12 @@ authors = ["Teascade <teascade@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
toml = "0.5"
|
||||
minreq = { version = "2.2.0", features = ["https", "json-using-serde"] }
|
||||
chrono = "0.4"
|
||||
argh = "0.1"
|
||||
gpx = "0.8"
|
||||
geo-types = "*"
|
||||
geo-types = "*"
|
||||
thingy-lib = { path = "./thingy_lib/" }
|
||||
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
rustflags = ["-Ctarget-feature=+crt-static"]
|
||||
[target.i686-pc-windows-msvc]
|
||||
rustflags = ["-Ctarget-feature=+crt-static"]
|
@ -1,52 +1,15 @@
|
||||
use super::api::ErrorModel;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum GenericError {
|
||||
TomlError(toml::de::Error),
|
||||
YepzonServerError(ErrorModel),
|
||||
MinreqError(minreq::Error),
|
||||
ChronoParseError(chrono::ParseError),
|
||||
IOError(io::Error),
|
||||
FromUTF8Error(std::string::FromUtf8Error),
|
||||
ThingyLibError(thingy_lib::Error),
|
||||
GPXError(gpx::errors::Error),
|
||||
MessagedError(String, Option<Box<GenericError>>),
|
||||
}
|
||||
|
||||
impl From<toml::de::Error> for GenericError {
|
||||
fn from(error: toml::de::Error) -> Self {
|
||||
GenericError::TomlError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<minreq::Error> for GenericError {
|
||||
fn from(error: minreq::Error) -> Self {
|
||||
GenericError::MinreqError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<chrono::ParseError> for GenericError {
|
||||
fn from(error: chrono::ParseError) -> Self {
|
||||
GenericError::ChronoParseError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ErrorModel> for GenericError {
|
||||
fn from(error: ErrorModel) -> Self {
|
||||
GenericError::YepzonServerError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for GenericError {
|
||||
fn from(error: io::Error) -> Self {
|
||||
GenericError::IOError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::string::FromUtf8Error> for GenericError {
|
||||
fn from(error: std::string::FromUtf8Error) -> Self {
|
||||
GenericError::FromUTF8Error(error)
|
||||
impl From<thingy_lib::Error> for GenericError {
|
||||
fn from(error: thingy_lib::Error) -> Self {
|
||||
GenericError::ThingyLibError(error)
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,21 +22,13 @@ impl From<gpx::errors::Error> for GenericError {
|
||||
impl Display for GenericError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
let err = match self {
|
||||
GenericError::ChronoParseError(e) => format!("Date-Time value parse error: {}", e),
|
||||
GenericError::FromUTF8Error(e) => format!("UTF-8 error: {}", e),
|
||||
GenericError::IOError(e) => format!("IO error: {}", e),
|
||||
GenericError::MinreqError(e) => format!("Network error: {}", e),
|
||||
GenericError::TomlError(e) => format!("Toml error: {}", e),
|
||||
GenericError::YepzonServerError(e) => format!(
|
||||
"Yepzon server error: {}",
|
||||
e.message.as_ref().unwrap_or(&String::new())
|
||||
),
|
||||
GenericError::ThingyLibError(e) => e.to_string(),
|
||||
GenericError::GPXError(e) => format!("GPX error: {}", e),
|
||||
GenericError::MessagedError(msg, err) => format!(
|
||||
"{}\n {}",
|
||||
msg,
|
||||
err.as_ref().map(|e| e.to_string()).unwrap_or(String::new())
|
||||
),
|
||||
GenericError::GPXError(e) => format!("GPX error: {}", e),
|
||||
};
|
||||
write!(f, "{}", err)
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use super::{Config, GenericError, LocationModel, TagModel};
|
||||
use chrono::offset::Utc as UTC_ZONE;
|
||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
||||
use geo_types::Point;
|
||||
use gpx::{Gpx, GpxVersion, Metadata, Person, Route, Track, TrackSegment, Waypoint};
|
||||
use std::fs::File;
|
||||
use thingy_lib::chrono::offset::Utc as UTC_ZONE;
|
||||
use thingy_lib::chrono::{DateTime, NaiveDateTime, Utc};
|
||||
|
||||
pub fn generate_gpx(
|
||||
tag: &TagModel,
|
||||
|
38
src/main.rs
38
src/main.rs
@ -1,16 +1,15 @@
|
||||
mod api;
|
||||
#![windows_subsystem = "windows"]
|
||||
|
||||
mod args;
|
||||
mod commands;
|
||||
mod config;
|
||||
mod errors;
|
||||
mod gpx;
|
||||
|
||||
use api::{LocationModel, TagModel, API};
|
||||
use args::*;
|
||||
use chrono::offset::Local;
|
||||
use chrono::{NaiveDate, NaiveDateTime, NaiveTime, ParseError};
|
||||
use config::Config;
|
||||
use errors::{GenericError, MessagedError};
|
||||
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();
|
||||
@ -36,7 +35,11 @@ fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
||||
None => None,
|
||||
};
|
||||
|
||||
let (_, locs) = commands::between(&mut api, opt.device, since, until)?;
|
||||
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::<Vec<NaiveDateTime>>(),
|
||||
locs.len(),
|
||||
@ -44,27 +47,27 @@ fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
||||
Ok(())
|
||||
}
|
||||
Subcommand::Init(opt) => {
|
||||
commands::init(&env.config, opt.api_key)?;
|
||||
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 commands::check_api(&api) {
|
||||
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)),
|
||||
Some(Box::new(e.into())),
|
||||
)),
|
||||
}
|
||||
}
|
||||
Subcommand::ShareToken(opt) => {
|
||||
let config = Config::from_path(&env.config)?;
|
||||
let api = API::new(config.clone());
|
||||
println!("{}", commands::sharetoken(&api, opt.device)?);
|
||||
println!("{}", thingy_lib::sharetoken(&api, opt.device)?);
|
||||
Ok(())
|
||||
}
|
||||
Subcommand::Nick(opt) => {
|
||||
@ -73,12 +76,13 @@ fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
||||
|
||||
match opt.subcommand {
|
||||
NickSub::List(_) => {
|
||||
for ((idx, nick), tag) in commands::nick_list(&api)? {
|
||||
for ((idx, nick), tag) in thingy_lib::nick_list(&api)? {
|
||||
println!("{}. {}\n{}", idx, nick, tag);
|
||||
}
|
||||
}
|
||||
NickSub::Set(opt) => {
|
||||
commands::nick_set(&mut api, &env.config, opt.device, opt.nickname)?;
|
||||
thingy_lib::nick_set(&mut api, opt.device, opt.nickname)?;
|
||||
api.config.write_to(&env.config)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -98,10 +102,10 @@ fn from_env(env: EnvOpt) -> Result<(), GenericError> {
|
||||
dbg!(&tags);
|
||||
}
|
||||
GetSub::States(opt) => {
|
||||
API::print_list(commands::get_states(&api, opt.device));
|
||||
API::print_list(thingy_lib::get_states(&api, opt.device));
|
||||
}
|
||||
GetSub::Locations(opt) => {
|
||||
API::print_list(commands::get_locations(&api, opt.device, opt.state))
|
||||
API::print_list(thingy_lib::get_locations(&api, opt.device, opt.state))
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
11
thingy_lib/Cargo.toml
Normal file
11
thingy_lib/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "thingy-lib"
|
||||
version = "0.1.0"
|
||||
authors = ["Teascade <teascade@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
toml = "0.5"
|
||||
minreq = { version = "2.2.0", features = ["https", "json-using-serde"] }
|
||||
chrono = "0.4"
|
@ -1,7 +1,7 @@
|
||||
pub mod structs;
|
||||
|
||||
use super::Config;
|
||||
use super::GenericError;
|
||||
use super::LibError;
|
||||
use chrono::format::ParseError;
|
||||
use chrono::NaiveDateTime;
|
||||
use minreq::Response;
|
||||
@ -25,15 +25,14 @@ impl API {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_raw_string(&self, url: APIUrl) -> Result<String, GenericError> {
|
||||
pub fn get_raw_string(&self, url: APIUrl) -> Result<String, LibError> {
|
||||
Ok(self
|
||||
.request(API::api_url(url, &self.config))?
|
||||
.as_str()?
|
||||
.to_owned())
|
||||
}
|
||||
|
||||
pub fn get_sharetoken(&self, tag_id: &String) -> Result<SharetokenModel, GenericError> {
|
||||
pub fn get_sharetoken(&self, tag_id: &String) -> Result<SharetokenModel, LibError> {
|
||||
let response = self.request(API::api_url(
|
||||
APIUrl::Sharetoken(tag_id.clone()),
|
||||
&self.config,
|
||||
@ -41,33 +40,28 @@ impl API {
|
||||
Ok(response.json()?)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_tags(&self) -> Result<Vec<TagModel>, GenericError> {
|
||||
pub fn get_tags(&self) -> Result<Vec<TagModel>, LibError> {
|
||||
let response = self.request(API::api_url(APIUrl::Tags, &self.config))?;
|
||||
let tags = response.json();
|
||||
if let Err(_) = tags {
|
||||
let err: ErrorModel = response.json()?;
|
||||
Err(GenericError::from(err))
|
||||
Err(LibError::from(err))
|
||||
} else {
|
||||
tags.map_err(GenericError::from)
|
||||
tags.map_err(LibError::from)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_tag(&self, tag_id: &String) -> Result<TagModel, GenericError> {
|
||||
pub fn get_tag(&self, tag_id: &String) -> Result<TagModel, LibError> {
|
||||
let response = self.request(API::api_url(APIUrl::Tag(tag_id.clone()), &self.config))?;
|
||||
Ok(response.json()?)
|
||||
}
|
||||
|
||||
pub fn get_states(&self, tag_id: &String) -> Result<Vec<StateModel>, GenericError> {
|
||||
pub fn get_states(&self, tag_id: &String) -> Result<Vec<StateModel>, LibError> {
|
||||
let response = self.request(API::api_url(APIUrl::States(tag_id.clone()), &self.config))?;
|
||||
Ok(response.json()?)
|
||||
}
|
||||
|
||||
pub fn get_current_locations(
|
||||
&self,
|
||||
tag_id: &String,
|
||||
) -> Result<Vec<LocationModel>, GenericError> {
|
||||
pub fn get_current_locations(&self, tag_id: &String) -> Result<Vec<LocationModel>, LibError> {
|
||||
let response = self.request(API::api_url(
|
||||
APIUrl::CurrLocations(tag_id.clone()),
|
||||
&self.config,
|
||||
@ -79,7 +73,7 @@ impl API {
|
||||
&self,
|
||||
tag_id: &String,
|
||||
state_id: &String,
|
||||
) -> Result<Vec<LocationModel>, GenericError> {
|
||||
) -> Result<Vec<LocationModel>, LibError> {
|
||||
let response = self.request(API::api_url(
|
||||
APIUrl::Locations(tag_id.clone(), state_id.clone()),
|
||||
&self.config,
|
||||
@ -96,7 +90,7 @@ impl API {
|
||||
|
||||
pub fn begin_location_fetch(
|
||||
&mut self,
|
||||
) -> Receiver<Result<Result<Vec<LocationModel>, ErrorModel>, GenericError>> {
|
||||
) -> Receiver<Result<Result<Vec<LocationModel>, ErrorModel>, LibError>> {
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
let mut locations = self.location_req_que.clone();
|
||||
let config = self.config.clone();
|
||||
@ -139,7 +133,7 @@ impl API {
|
||||
Ok(loc) => Ok(Ok(loc)),
|
||||
Err(_) => Ok(Err(r.json()?)),
|
||||
})
|
||||
.map_err(GenericError::from);
|
||||
.map_err(LibError::from);
|
||||
i_sender.send((location, response)).ok();
|
||||
});
|
||||
timer += interval;
|
||||
@ -169,7 +163,7 @@ impl API {
|
||||
receiver
|
||||
}
|
||||
|
||||
pub fn get_between<T: Timestamped + Clone>(
|
||||
pub(crate) fn get_between<T: Timestamped + Clone>(
|
||||
list: &Vec<T>,
|
||||
from: Option<NaiveDateTime>,
|
||||
to: Option<NaiveDateTime>,
|
||||
@ -210,7 +204,7 @@ impl API {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn print_list<T: Display + Timestamped>(list: Result<Vec<T>, GenericError>) {
|
||||
pub fn print_list<T: Display + Timestamped>(list: Result<Vec<T>, LibError>) {
|
||||
match list {
|
||||
Ok(items) => {
|
||||
for item in items {
|
||||
@ -243,7 +237,7 @@ impl API {
|
||||
|
||||
fn add_error_back(
|
||||
location: String,
|
||||
rec: &Result<Result<Vec<LocationModel>, ErrorModel>, GenericError>,
|
||||
rec: &Result<Result<Vec<LocationModel>, ErrorModel>, LibError>,
|
||||
locations: &mut Vec<String>,
|
||||
) -> bool {
|
||||
if let Ok(inner) = rec {
|
||||
@ -258,12 +252,12 @@ impl API {
|
||||
}
|
||||
}
|
||||
|
||||
fn request(&self, url: String) -> Result<Response, GenericError> {
|
||||
fn request(&self, url: String) -> Result<Response, LibError> {
|
||||
let response = minreq::get(url)
|
||||
.with_header("content-type", "application/json")
|
||||
.with_header("x-api-key", &self.config.api_key)
|
||||
.send();
|
||||
response.map_err(GenericError::from)
|
||||
response.map_err(LibError::from)
|
||||
}
|
||||
|
||||
fn parse_timestamp(
|
@ -1,4 +1,4 @@
|
||||
use super::{Config, GenericError};
|
||||
use super::{Config, LibError};
|
||||
use serde::Deserialize;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
@ -77,10 +77,10 @@ impl TagModel {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_id(&self) -> Result<String, GenericError> {
|
||||
pub fn get_id(&self) -> Result<String, LibError> {
|
||||
match &self.id {
|
||||
Some(id) => Ok(id.to_string()),
|
||||
None => Err(GenericError::MessagedError(
|
||||
None => Err(LibError::MessagedError(
|
||||
"Could not find device id. Error probably on Yetzon server side.".to_owned(),
|
||||
None,
|
||||
)),
|
||||
@ -153,10 +153,10 @@ pub struct StateModel {
|
||||
}
|
||||
|
||||
impl StateModel {
|
||||
pub fn get_id(&self) -> Result<String, GenericError> {
|
||||
pub fn get_id(&self) -> Result<String, LibError> {
|
||||
match &self.id {
|
||||
Some(id) => Ok(id.to_string()),
|
||||
None => Err(GenericError::MessagedError(
|
||||
None => Err(LibError::MessagedError(
|
||||
"Could not find state id. Error probably on Yetzon server side.".to_owned(),
|
||||
None,
|
||||
)),
|
@ -1,4 +1,4 @@
|
||||
use super::{GenericError, MessagedError};
|
||||
use super::errors::{LibError, MessagedError};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
@ -27,7 +27,7 @@ pub struct Config {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn from_path(path: &PathBuf) -> Result<Config, GenericError> {
|
||||
pub fn from_path(path: &PathBuf) -> Result<Config, LibError> {
|
||||
let mut file = File::open(&path)
|
||||
.with_msg(format!("Could not find {}", path.to_str().unwrap_or("")))?;
|
||||
let mut string = String::new();
|
||||
@ -37,7 +37,7 @@ impl Config {
|
||||
Ok(toml::from_str(&string).with_msg("given config file is not a valid config file")?)
|
||||
}
|
||||
|
||||
pub fn write_to(&self, path: &PathBuf) -> Result<(), GenericError> {
|
||||
pub fn write_to(&self, path: &PathBuf) -> Result<(), LibError> {
|
||||
let mut file = File::create(&path).unwrap();
|
||||
file.write_all(&toml::to_vec(self).unwrap())
|
||||
.with_msg("Could not write config.toml, make sure you have correct permissions.")?;
|
88
thingy_lib/src/errors.rs
Normal file
88
thingy_lib/src/errors.rs
Normal file
@ -0,0 +1,88 @@
|
||||
use super::api::ErrorModel;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum LibError {
|
||||
TomlError(toml::de::Error),
|
||||
YepzonServerError(ErrorModel),
|
||||
MinreqError(minreq::Error),
|
||||
ChronoParseError(chrono::ParseError),
|
||||
IOError(io::Error),
|
||||
FromUTF8Error(std::string::FromUtf8Error),
|
||||
MessagedError(String, Option<Box<LibError>>),
|
||||
}
|
||||
|
||||
impl From<toml::de::Error> for LibError {
|
||||
fn from(error: toml::de::Error) -> Self {
|
||||
LibError::TomlError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<minreq::Error> for LibError {
|
||||
fn from(error: minreq::Error) -> Self {
|
||||
LibError::MinreqError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<chrono::ParseError> for LibError {
|
||||
fn from(error: chrono::ParseError) -> Self {
|
||||
LibError::ChronoParseError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ErrorModel> for LibError {
|
||||
fn from(error: ErrorModel) -> Self {
|
||||
LibError::YepzonServerError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for LibError {
|
||||
fn from(error: io::Error) -> Self {
|
||||
LibError::IOError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::string::FromUtf8Error> for LibError {
|
||||
fn from(error: std::string::FromUtf8Error) -> Self {
|
||||
LibError::FromUTF8Error(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for LibError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
let err = match self {
|
||||
LibError::ChronoParseError(e) => format!("Date-Time value parse error: {}", e),
|
||||
LibError::FromUTF8Error(e) => format!("UTF-8 error: {}", e),
|
||||
LibError::IOError(e) => format!("IO error: {}", e),
|
||||
LibError::MinreqError(e) => format!("Network error: {}", e),
|
||||
LibError::TomlError(e) => format!("Toml error: {}", e),
|
||||
LibError::YepzonServerError(e) => format!(
|
||||
"Yepzon server error: {}",
|
||||
e.message.as_ref().unwrap_or(&String::new())
|
||||
),
|
||||
LibError::MessagedError(msg, err) => format!(
|
||||
"{}\n {}",
|
||||
msg,
|
||||
err.as_ref().map(|e| e.to_string()).unwrap_or(String::new())
|
||||
),
|
||||
};
|
||||
write!(f, "{}", err)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MessagedError<A> {
|
||||
fn with_msg<T: Into<String>>(self, text: T) -> Result<A, LibError>;
|
||||
}
|
||||
|
||||
impl<A, B: Into<LibError>> MessagedError<A> for Result<A, B> {
|
||||
fn with_msg<T: Into<String>>(self, text: T) -> Result<A, LibError> {
|
||||
match self {
|
||||
Ok(ok) => Ok(ok),
|
||||
Err(e) => Err(LibError::MessagedError(
|
||||
text.into(),
|
||||
Some(Box::new(e.into())),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,21 @@
|
||||
use super::api::{LocationModel, SharetokenModel, StateModel, TagModel, API};
|
||||
use super::config::Config;
|
||||
use super::errors::GenericError;
|
||||
use super::gpx;
|
||||
pub mod api;
|
||||
mod config;
|
||||
mod errors;
|
||||
|
||||
use api::{LocationModel, SharetokenModel, StateModel, TagModel, API};
|
||||
use chrono::NaiveDateTime;
|
||||
use errors::LibError;
|
||||
use std::io::prelude::*;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::mpsc::TryRecvError;
|
||||
use std::time::Duration;
|
||||
|
||||
pub fn init(path: &PathBuf, api_key: Option<String>) -> Result<(), GenericError> {
|
||||
pub use chrono;
|
||||
pub use config::Config;
|
||||
pub use errors::LibError as Error;
|
||||
pub use errors::MessagedError;
|
||||
|
||||
pub fn init(path: &PathBuf, api_key: Option<String>) -> Result<(), LibError> {
|
||||
let mut config = Config::default();
|
||||
if let Some(api_key) = api_key {
|
||||
config.api_key = api_key;
|
||||
@ -21,7 +28,7 @@ pub fn between(
|
||||
tag_str: String,
|
||||
from: Option<NaiveDateTime>,
|
||||
to: Option<NaiveDateTime>,
|
||||
) -> Result<(TagModel, Vec<(NaiveDateTime, LocationModel)>), GenericError> {
|
||||
) -> Result<(TagModel, Vec<(NaiveDateTime, LocationModel)>), LibError> {
|
||||
let tags = api.get_tags()?;
|
||||
let tag = find_tag(tag_str, &tags, &api.config)?;
|
||||
let tag_id = tag.get_id()?;
|
||||
@ -73,12 +80,10 @@ pub fn between(
|
||||
|
||||
let locs = API::get_between(&locations, from, to, false, &api.config);
|
||||
|
||||
let gpx = gpx::generate_gpx(&tag, &locs, &api.config)?;
|
||||
gpx::write_gpx(&gpx)?;
|
||||
Ok((tag, locs))
|
||||
}
|
||||
|
||||
pub fn check_api(api: &API) -> Result<(), GenericError> {
|
||||
pub fn check_api(api: &API) -> Result<(), LibError> {
|
||||
let tags = api.get_tags()?;
|
||||
if let Some(tag) = tags.get(0) {
|
||||
let tag_id = tag.get_id()?;
|
||||
@ -91,23 +96,23 @@ pub fn check_api(api: &API) -> Result<(), GenericError> {
|
||||
api.get_locations(&tag_id, &state_id)?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(GenericError::MessagedError(
|
||||
Err(LibError::MessagedError(
|
||||
"Could not find any states for the first device found.".to_owned(),
|
||||
None,
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(GenericError::MessagedError("Could not find any devices. Please make sure this API-key is paired with a device first.".to_owned(), None))
|
||||
Err(LibError::MessagedError("Could not find any devices. Please make sure this API-key is paired with a device first.".to_owned(), None))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sharetoken(api: &API, tag: String) -> Result<SharetokenModel, GenericError> {
|
||||
pub fn sharetoken(api: &API, tag: String) -> Result<SharetokenModel, LibError> {
|
||||
let tags = api.get_tags()?;
|
||||
let tag = find_tag(tag, &tags, &api.config)?;
|
||||
Ok(api.get_sharetoken(&tag.get_id()?)?)
|
||||
}
|
||||
|
||||
pub fn nick_list(api: &API) -> Result<Vec<((usize, String), TagModel)>, GenericError> {
|
||||
pub fn nick_list(api: &API) -> Result<Vec<((usize, String), TagModel)>, LibError> {
|
||||
let mut tags = api.get_tags()?;
|
||||
tags.sort_by(|tag1, tag2| tag1.id.cmp(&tag2.id));
|
||||
let list = tags
|
||||
@ -127,33 +132,26 @@ pub fn nick_list(api: &API) -> Result<Vec<((usize, String), TagModel)>, GenericE
|
||||
Ok(list)
|
||||
}
|
||||
|
||||
pub fn nick_set(
|
||||
api: &mut API,
|
||||
config_path: &PathBuf,
|
||||
tag_str: String,
|
||||
nickname: String,
|
||||
) -> Result<(), GenericError> {
|
||||
pub fn nick_set(api: &mut API, tag_str: String, nickname: String) -> Result<(), LibError> {
|
||||
let mut tags = api.get_tags()?;
|
||||
tags.sort_by(|tag1, tag2| tag1.id.cmp(&tag2.id));
|
||||
let tag = find_tag(tag_str.clone(), &tags, &api.config)?;
|
||||
if let Some(id) = &tag.id {
|
||||
api.config.nicknames.insert(id.clone(), nickname);
|
||||
api.config.write_to(config_path)?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(GenericError::MessagedError(
|
||||
Err(LibError::MessagedError(
|
||||
format!("Device {} does not have an id", tag_str),
|
||||
None,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_locations(
|
||||
api: &API,
|
||||
tag: String,
|
||||
state: Option<String>,
|
||||
) -> Result<Vec<LocationModel>, GenericError> {
|
||||
) -> Result<Vec<LocationModel>, LibError> {
|
||||
let tags = api.get_tags()?;
|
||||
let tag = find_tag(tag, &tags, &api.config)?;
|
||||
if let Some(state) = state {
|
||||
@ -163,8 +161,7 @@ pub fn get_locations(
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn get_states(api: &API, tag: String) -> Result<Vec<StateModel>, GenericError> {
|
||||
pub fn get_states(api: &API, tag: String) -> Result<Vec<StateModel>, LibError> {
|
||||
let tags = api.get_tags()?;
|
||||
let tag = find_tag(tag, &tags, &api.config)?;
|
||||
Ok(api.get_states(&tag.get_id()?)?)
|
||||
@ -175,11 +172,7 @@ fn exp_time(api: &API, reqs_left: u64) -> Duration {
|
||||
Duration::from_millis(interval * reqs_left)
|
||||
}
|
||||
|
||||
fn find_tag(
|
||||
tag_str: String,
|
||||
tags: &Vec<TagModel>,
|
||||
config: &Config,
|
||||
) -> Result<TagModel, GenericError> {
|
||||
fn find_tag(tag_str: String, tags: &Vec<TagModel>, config: &Config) -> Result<TagModel, LibError> {
|
||||
let mut tag = None;
|
||||
if let Ok(num) = tag_str.parse::<i32>() {
|
||||
if let Some(found) = tags.get((num - 1).max(0) as usize) {
|
||||
@ -195,7 +188,7 @@ fn find_tag(
|
||||
}
|
||||
match tag {
|
||||
Some(tag) => Ok(tag),
|
||||
None => Err(GenericError::MessagedError(
|
||||
None => Err(LibError::MessagedError(
|
||||
format!("Could not find device {}", tag_str),
|
||||
None,
|
||||
)),
|
Loading…
Reference in New Issue
Block a user