Initial commit
This commit is contained in:
commit
4a6922c2c1
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
427
Cargo.lock
generated
Normal file
427
Cargo.lock
generated
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "argh"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca1877e24cecacd700d469066e0160c4f8497cc5635367163f50c8beec820154"
|
||||||
|
dependencies = [
|
||||||
|
"argh_derive",
|
||||||
|
"argh_shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argh_derive"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e742194e0f43fc932bcb801708c2b279d3ec8f527e3acda05a6a9f342c5ef764"
|
||||||
|
dependencies = [
|
||||||
|
"argh_shared",
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argh_shared"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e1ba68f4276a778591e36a0c348a269888f3a177c8d2054969389e3b59611ff5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.59"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "66120af515773fb005778dc07c261bd201ec8ce50bd6e7144c927753fe013381"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
|
||||||
|
dependencies = [
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "0.4.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85a7e2c92a4804dd459b86c339278d0fe87cf93757fae222c3fa3ae75458bc73"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.76"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minreq"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab229c252995e9d56cc66857f3ab2c41e3138b1a6c92089f013698388e64d6bd"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
"rustls",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"webpki",
|
||||||
|
"webpki-roots",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.43"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.16.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"spin",
|
||||||
|
"untrusted",
|
||||||
|
"web-sys",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"log",
|
||||||
|
"ring",
|
||||||
|
"sct",
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sct"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3042af939fca8c3453b7af0f1c66e533a15a86169e39de2657310ade8f98d3c"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.115"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.115"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.57"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.39"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "891d8d6567fe7c7f8835a3a98af4208f3846fba258c1bc3c31d6e506239f11f9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thingy"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"argh",
|
||||||
|
"chrono",
|
||||||
|
"minreq",
|
||||||
|
"serde",
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.1.43"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.67"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.67"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc71e4c5efa60fb9e74160e89b93353bc24059999c0ae0fb03affc39770310b0"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.67"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97c57cefa5fa80e2ba15641578b44d36e7a64279bc5ed43c6dbaf329457a2ed2"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.67"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "841a6d1c35c6f596ccea1f82504a192a60378f64b3bb0261904ad8f2f5657556"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.67"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-sys"
|
||||||
|
version = "0.3.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dda38f4e5ca63eda02c059d243aa25b5f35ab98451e518c51612cd0f1bd19a47"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki"
|
||||||
|
version = "0.21.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91cd5736df7f12a964a5067a12c62fa38e1bd8080aff1f80bc29be7c80d19ab4"
|
||||||
|
dependencies = [
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "thingy"
|
||||||
|
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"
|
||||||
|
argh = "0.1"
|
7
config.toml
Normal file
7
config.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
api_key = "E3GrOiQAnY61BP623XXzt9Fo87A1IQrS1FFzD57P"
|
||||||
|
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"
|
||||||
|
between_format = "%d.%m.%Y %H:%M:%S"
|
||||||
|
throttle = 110
|
163
src/api.rs
Normal file
163
src/api.rs
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
use super::Config;
|
||||||
|
use chrono::format::ParseError;
|
||||||
|
use chrono::NaiveDateTime;
|
||||||
|
use minreq::{Error, Response};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
pub trait Timestamped {
|
||||||
|
fn timestamp(&self) -> Option<String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct TagModel {
|
||||||
|
pub id: Option<String>,
|
||||||
|
pub imei: Option<String>,
|
||||||
|
#[serde(rename(deserialize = "batteryValue"))]
|
||||||
|
pub battery_value: Option<i32>,
|
||||||
|
#[serde(rename(deserialize = "btId"))]
|
||||||
|
pub bt_id: Option<String>,
|
||||||
|
#[serde(rename(deserialize = "nfcId"))]
|
||||||
|
pub nfc_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
pub struct StateModel {
|
||||||
|
pub id: Option<String>,
|
||||||
|
pub timestamp: Option<String>,
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
pub state: Option<String>,
|
||||||
|
#[serde(rename(deserialize = "realState"))]
|
||||||
|
pub real_state: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Timestamped for StateModel {
|
||||||
|
fn timestamp(&self) -> Option<String> {
|
||||||
|
self.timestamp.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct LocationModel {
|
||||||
|
pub timestamp: Option<String>,
|
||||||
|
#[serde(rename(deserialize = "type"))]
|
||||||
|
pub loc_type: Option<String>,
|
||||||
|
#[serde(rename(deserialize = "coordinateLat"))]
|
||||||
|
pub lat: Option<f32>,
|
||||||
|
#[serde(rename(deserialize = "coordinateLng"))]
|
||||||
|
pub lon: Option<f32>,
|
||||||
|
pub accuracy: Option<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Timestamped for LocationModel {
|
||||||
|
fn timestamp(&self) -> Option<String> {
|
||||||
|
self.timestamp.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct API {
|
||||||
|
config: Config,
|
||||||
|
pub last_response_ping: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl API {
|
||||||
|
pub fn new(config: Config) -> API {
|
||||||
|
API {
|
||||||
|
last_response_ping: config.throttle,
|
||||||
|
config: config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_tags(&mut self) -> Result<Vec<TagModel>, Error> {
|
||||||
|
let response = self.request(self.config.tags_url.clone())?;
|
||||||
|
response.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_states(&mut self, tag_id: &String) -> Result<Vec<StateModel>, Error> {
|
||||||
|
let response = self.request(str::replace(&self.config.states_url, "{tag}", &tag_id))?;
|
||||||
|
response.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_locations(
|
||||||
|
&mut self,
|
||||||
|
tag_id: &String,
|
||||||
|
state_id: &String,
|
||||||
|
) -> Result<Vec<LocationModel>, Error> {
|
||||||
|
let url = str::replace(&self.config.locations_url, "{tag}", &tag_id);
|
||||||
|
let url = str::replace(&url, "{state}", &state_id);
|
||||||
|
let response = self.request(url)?;
|
||||||
|
response.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_between<T: Timestamped>(
|
||||||
|
list: Vec<T>,
|
||||||
|
from: Option<NaiveDateTime>,
|
||||||
|
to: Option<NaiveDateTime>,
|
||||||
|
inclusive_from: bool,
|
||||||
|
config: &Config,
|
||||||
|
) -> Vec<(NaiveDateTime, T)> {
|
||||||
|
let mut timestamped = Vec::new();
|
||||||
|
for item in list {
|
||||||
|
if let Some(res) = API::parse_timestamp(&item.timestamp(), config) {
|
||||||
|
match res {
|
||||||
|
Ok(t) => {
|
||||||
|
if let Some(to) = to {
|
||||||
|
if t > to {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut too_old = false;
|
||||||
|
if let Some(from) = from {
|
||||||
|
if t < from {
|
||||||
|
too_old = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if too_old {
|
||||||
|
if inclusive_from {
|
||||||
|
timestamped.push((t.clone(), item));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
timestamped.push((t.clone(), item));
|
||||||
|
}
|
||||||
|
Err(e) => panic!(e),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("Skipped item, did not have timestmap");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timestamped
|
||||||
|
}
|
||||||
|
|
||||||
|
fn request(&mut self, url: String) -> Result<Response, Error> {
|
||||||
|
let before = Instant::now();
|
||||||
|
let response = minreq::get(url)
|
||||||
|
.with_header("content-type", "application/json")
|
||||||
|
.with_header("x-api-key", &self.config.api_key)
|
||||||
|
.send();
|
||||||
|
let after = Instant::now();
|
||||||
|
let min_time = Duration::new(0, self.config.throttle * 1_000_000);
|
||||||
|
let duration = after.duration_since(before);
|
||||||
|
self.last_response_ping = (duration.as_millis() as u32).max(self.config.throttle);
|
||||||
|
if min_time > duration {
|
||||||
|
sleep(min_time - duration);
|
||||||
|
}
|
||||||
|
response
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_timestamp(
|
||||||
|
timestamp: &Option<String>,
|
||||||
|
config: &Config,
|
||||||
|
) -> Option<Result<NaiveDateTime, ParseError>> {
|
||||||
|
if let Some(timestamp) = ×tamp {
|
||||||
|
Some(NaiveDateTime::parse_from_str(
|
||||||
|
×tamp,
|
||||||
|
&config.timestamp_format,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
src/config.rs
Normal file
32
src/config.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
pub api_key: String,
|
||||||
|
|
||||||
|
pub tags_url: String,
|
||||||
|
pub states_url: String,
|
||||||
|
pub locations_url: String,
|
||||||
|
|
||||||
|
pub timestamp_format: String,
|
||||||
|
pub between_format: String,
|
||||||
|
|
||||||
|
pub throttle: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Config {
|
||||||
|
fn default() -> Config {
|
||||||
|
Config {
|
||||||
|
api_key: "E3GrOiQAnY61BP623XXzt9Fo87A1IQrS1FFzD57P".to_owned(),
|
||||||
|
|
||||||
|
tags_url: "https://platform.yepzon.com/tags".to_owned(),
|
||||||
|
states_url: "https://platform.yepzon.com/tags/{tag}/states".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(),
|
||||||
|
between_format: "%d.%m.%Y %H:%M:%S".to_owned(),
|
||||||
|
|
||||||
|
throttle: 110,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
src/main.rs
Normal file
56
src/main.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
mod api;
|
||||||
|
mod config;
|
||||||
|
|
||||||
|
use api::API;
|
||||||
|
use chrono::{NaiveDateTime, ParseError};
|
||||||
|
use config::Config;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let config = Config::default();
|
||||||
|
|
||||||
|
let mut file = File::create("config.toml").unwrap();
|
||||||
|
file.write_all(&toml::to_vec(&config).unwrap()).ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(config: &Config, from: Option<String>, to: Option<String>) -> Result<(), ParseError> {
|
||||||
|
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().unwrap();
|
||||||
|
let first_tag = tags[0].id.clone().unwrap();
|
||||||
|
let state_list = api.get_states(&first_tag).unwrap();
|
||||||
|
|
||||||
|
let states = API::get_between(state_list.clone(), from, to, true, &config);
|
||||||
|
let len = states.len();
|
||||||
|
|
||||||
|
let mut locations = Vec::new();
|
||||||
|
for (idx, (_, state)) in states.iter().enumerate() {
|
||||||
|
println!("Expected {}s left", exp_time(&api, (len - idx) as u32));
|
||||||
|
let mut location_list = api
|
||||||
|
.get_locations(&first_tag, state.id.as_ref().unwrap())
|
||||||
|
.unwrap();
|
||||||
|
locations.append(&mut location_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
dbg!(API::get_between(locations, from, to, false, &config));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_opt<A, B>(option: Option<Result<A, B>>) -> Result<Option<A>, B> {
|
||||||
|
if let Some(res) = option {
|
||||||
|
match res {
|
||||||
|
Ok(a) => Ok(Some(a)),
|
||||||
|
Err(b) => Err(b),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exp_time(api: &API, reqs_left: u32) -> f32 {
|
||||||
|
(reqs_left * api.last_response_ping) as f32 / 1000.
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user