From d0ce8573653b81e4227ddb6d2db5d03fa05d8026 Mon Sep 17 00:00:00 2001 From: Artemis Tosini Date: Mon, 11 Dec 2023 05:14:03 +0000 Subject: [PATCH] Add new local_time and system_time tiles --- Cargo.lock | 677 +++++++++++++++++++++++++- Cargo.toml | 4 + config.toml.example | 9 +- src/config.rs | 37 +- src/main.rs | 1 + src/tiles/local_time.rs | 114 +++++ src/tiles/mod.rs | 8 +- src/tiles/{time.rs => system_time.rs} | 6 +- src/tiles/utc_time.rs | 24 + 9 files changed, 868 insertions(+), 12 deletions(-) create mode 100644 src/tiles/local_time.rs rename src/tiles/{time.rs => system_time.rs} (81%) create mode 100644 src/tiles/utc_time.rs diff --git a/Cargo.lock b/Cargo.lock index 68951c8..3c19030 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -84,6 +93,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + [[package]] name = "bitflags" version = "1.3.2" @@ -96,6 +111,12 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.5.0" @@ -131,6 +152,28 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "chrono-tz" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e23185c0e21df6ed832a12e2bda87c7d1def6842881fb634a8511ced741b0d76" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + [[package]] name = "clap" version = "2.34.0" @@ -146,6 +189,16 @@ dependencies = [ "vec_map", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -176,12 +229,42 @@ dependencies = [ "tokio", ] +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + [[package]] name = "futures" version = "0.3.29" @@ -310,6 +393,25 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "h2" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -340,6 +442,78 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + [[package]] name = "iana-time-zone" version = "0.1.58" @@ -363,6 +537,16 @@ dependencies = [ "cc", ] +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "2.1.0" @@ -373,6 +557,21 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "ipnetwork" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4088d739b183546b239688ddbc79891831df421773df95e236daf7867866d355" +dependencies = [ + "serde", +] + [[package]] name = "itoa" version = "1.0.10" @@ -409,18 +608,48 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "local-ip-address" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66357e687a569abca487dc399a9c9ac19beb3f13991ed49f00c144e02cbd42ab" +dependencies = [ + "libc", + "neli", + "thiserror", + "windows-sys", +] + [[package]] name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "maxminddb" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe2ba61113f9f7a9f0e87c519682d39c43a6f3f79c2cc42c3ba3dda83b1fa334" +dependencies = [ + "ipnetwork", + "log", + "memchr", + "serde", +] + [[package]] name = "memchr" version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -441,6 +670,31 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "neli" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1100229e06604150b3becd61a4965d5c70f3be1759544ea7274166f4be41ef43" +dependencies = [ + "byteorder", + "libc", + "log", + "neli-proc-macros", +] + +[[package]] +name = "neli-proc-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168194d373b1e134786274020dae7fc5513d565ea2ebb9bc9ff17ffb69106d4" +dependencies = [ + "either", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", +] + [[package]] name = "num-traits" version = "0.2.17" @@ -475,6 +729,59 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "1.1.3" @@ -555,22 +862,156 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustls" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +dependencies = [ + "base64", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustybar" version = "0.1.0" dependencies = [ "async-trait", "chrono", + "chrono-tz", "dbus", "dbus-tokio", "futures", "futures-async-stream", + "local-ip-address", + "maxminddb", + "reqwest", "serde", "serde_json", "smart-default", @@ -587,6 +1028,16 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "serde" version = "1.0.193" @@ -627,6 +1078,24 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -647,6 +1116,16 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "socket2" version = "0.5.5" @@ -657,6 +1136,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "strsim" version = "0.8.0" @@ -709,6 +1194,27 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -718,6 +1224,41 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.35.0" @@ -730,7 +1271,7 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "socket2", + "socket2 0.5.5", "tokio-macros", "windows-sys", ] @@ -746,6 +1287,16 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.14" @@ -757,6 +1308,20 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + [[package]] name = "toml" version = "0.8.8" @@ -791,12 +1356,58 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-bidi" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.10.1" @@ -809,6 +1420,23 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "uuid" version = "1.6.1" @@ -830,6 +1458,15 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -861,6 +1498,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.89" @@ -890,6 +1539,22 @@ version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +[[package]] +name = "web-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + [[package]] name = "winapi" version = "0.3.9" @@ -995,3 +1660,13 @@ checksum = "b67b5f0a4e7a27a64c651977932b9dc5667ca7fc31ac44b03ed37a0cf42fdfff" dependencies = [ "memchr", ] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys", +] diff --git a/Cargo.toml b/Cargo.toml index e6bfb9f..dca0764 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,10 +10,14 @@ check_latency = [] [dependencies] async-trait = "0.1" chrono = "0.4" +chrono-tz = "0.8" dbus = "0.9" dbus-tokio = "0.7" futures = "0.3" futures-async-stream = "0.2" +local-ip-address = "0.5" +maxminddb = "0.23" +reqwest = { version = "0.11", features = ["rustls-tls"], default-features = false } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" smart-default = "0.7" diff --git a/config.toml.example b/config.toml.example index 806e070..d7bfa3c 100644 --- a/config.toml.example +++ b/config.toml.example @@ -15,5 +15,10 @@ type = "hostname" type = "battery" [[tile]] -type = "time" -format = "%Y-%m-%dT%H:%M:%S" +type = "utc_time" +format = "%Y-%m-%dT%H:%M:%SZ" + +[[tile]] +type = "local_time" +format = "%Y-%m-%dT%H:%M:%S%Z" +geoip_path = "/path/to/GeoLite2-City.mmdb" diff --git a/src/config.rs b/src/config.rs index 1b12eef..305de12 100644 --- a/src/config.rs +++ b/src/config.rs @@ -6,12 +6,13 @@ use serde::{Deserialize, Deserializer}; use smart_default::SmartDefault; use std::env::var; use std::io; +use std::path::Path; use std::path::PathBuf; use std::sync::Arc; +use std::time::Duration; use structopt::StructOpt; use tokio::fs::File; use tokio::io::AsyncReadExt; -use tokio::time::Duration; use tokio_stream::StreamExt; #[derive(Deserialize, Clone, Debug, Default)] @@ -58,7 +59,9 @@ pub enum TileConfigType { Memory, Load, Hostname, - Time(TimeConfig), + UtcTime(UtcTimeConfig), + SystemTime(SystemTimeConfig), + LocalTime(LocalTimeConfig), Iwd(IwdConfig), } @@ -78,13 +81,37 @@ pub struct IwdConfig { #[derive(SmartDefault, Deserialize, Clone, Debug)] #[serde(default)] -pub struct TimeConfig { +pub struct UtcTimeConfig { #[default("%Y-%m-%d %H:%M:%S")] pub format: Box, #[default("%H:%M:%S")] pub short_format: Box, } +#[derive(SmartDefault, Deserialize, Clone, Debug)] +#[serde(default)] +pub struct SystemTimeConfig { + #[default("%Y-%m-%d %H:%M:%S %Z")] + pub format: Box, + #[default("%H:%M:%S %Z")] + pub short_format: Box, +} + +#[derive(SmartDefault, Deserialize, Clone, Debug)] +#[serde(default)] +pub struct LocalTimeConfig { + #[default("%Y-%m-%d %H:%M:%S %Z")] + pub format: Box, + #[default("%H:%M:%S %Z")] + pub short_format: Box, + pub geoip_path: Option>, + #[default(_code = "Duration::from_secs(3600)")] + pub update_interval: Duration, + pub fallback_zone: Option>, + #[default("https://myip.wtf/text")] + pub ip_addr_api: Box, +} + #[derive(Debug, StructOpt)] #[structopt( name = "rustybar", @@ -141,11 +168,13 @@ pub fn process_tile( TileConfigType::Hostname => wrap(tiles::hostname_stream(connection.as_ref()), tile.update), TileConfigType::Load => wrap(tiles::load_stream(), tile.update.or(Some(five_secs))), TileConfigType::Memory => wrap(tiles::memory_stream(), tile.update.or(Some(five_secs))), - TileConfigType::Time(c) => wrap(tiles::time_stream(c.clone()), tile.update), + TileConfigType::UtcTime(c) => wrap(tiles::utc_time_stream(c.clone()), tile.update), TileConfigType::Iwd(c) => wrap( tiles::iwd_stream(connection.clone(), c.clone()), tile.update.or(Some(five_secs)), ), + TileConfigType::SystemTime(c) => wrap(tiles::system_time_stream(c.clone()), tile.update), + TileConfigType::LocalTime(c) => wrap(tiles::local_time_stream(c.clone()), tile.update), } } diff --git a/src/main.rs b/src/main.rs index a008b8f..7bf3f63 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ #![feature(never_type)] #![feature(proc_macro_hygiene)] #![feature(stmt_expr_attributes)] +#![feature(ip)] mod async_iter; mod config; diff --git a/src/tiles/local_time.rs b/src/tiles/local_time.rs new file mode 100644 index 0000000..64b8e3f --- /dev/null +++ b/src/tiles/local_time.rs @@ -0,0 +1,114 @@ +use crate::config::LocalTimeConfig; +use crate::tile::Block; +use chrono::prelude::*; +use futures_async_stream::try_stream; +use maxminddb::geoip2; +use std::error::Error; +use std::net::IpAddr; +use std::str::FromStr; +use tokio::sync::watch; +use tokio::time::sleep; + +struct State { + pub tz: Option, +} + +async fn request_ipv4( + client: &reqwest::Client, + api: &str, +) -> Result> { + let response = client.get(api).send().await?; + let text = response.text().await?; + Ok(IpAddr::from_str(text.trim())?) +} + +fn lookup_timezone(db: &maxminddb::Reader>, addr: Option) -> Option { + let city: geoip2::City = db.lookup(addr?).ok()?; + let tz_name = city.location?.time_zone?; + chrono_tz::Tz::from_str(tz_name).ok() +} + +async fn find_time_zone( + config: LocalTimeConfig, + sender: watch::Sender, +) -> Result> { + // TODO: Add error messages; + let Some(geoip_path) = &config.geoip_path else { + return Err(Box::new(std::io::Error::new( + std::io::ErrorKind::NotFound, + "geoip path not specified", + ))); + }; + let db_reader = maxminddb::Reader::open_readfile(geoip_path)?; + + // Force IPv4 since we don't need to make a request for ipv6 + let http_client = reqwest::Client::builder() + .local_address(IpAddr::from([0, 0, 0, 0])) + .build() + .unwrap(); + + let mut interval = tokio::time::interval(config.update_interval); + let mut prev_addr = None; + + loop { + let curr_addr = if let Ok(curr_ipv6) = local_ip_address::local_ipv6() { + Some(curr_ipv6) + } else { + request_ipv4(&http_client, &config.ip_addr_api).await.ok() + }; + + if curr_addr != prev_addr { + if let Some(new_tz) = lookup_timezone(&db_reader, curr_addr) { + sender.send_if_modified(|state: &mut State| { + if state.tz != Some(new_tz) { + state.tz = Some(new_tz); + true + } else { + false + } + }); + prev_addr = curr_addr; + } + } + + interval.tick().await; + } +} + +#[try_stream(ok = Block, error = Box)] +pub async fn local_time_stream(config: LocalTimeConfig) { + let fallback_tz = if let Some(tz_name) = &config.fallback_zone { + Some(chrono_tz::Tz::from_str(tz_name)?) + } else { + None + }; + let (sender, mut receiver) = watch::channel(State { tz: fallback_tz }); + + let config_clone = config.clone(); + let tz_thread = tokio::spawn(async move { find_time_zone(config_clone, sender).await }); + + loop { + let utc_now = Utc::now(); + + if tz_thread.is_finished() { + tz_thread.await??; + } + + if let Some(tz) = { + let state = receiver.borrow_and_update(); + state.tz + } { + let local_now = utc_now.with_timezone(&tz); + yield Block { + full_text: local_now.format(&config.format).to_string().into(), + short_text: Some(local_now.format(&config.short_format).to_string().into()), + name: "local_time".into(), + ..Default::default() + }; + } + let utc_next = utc_now.trunc_subsecs(0) + chrono::Duration::seconds(1); + let difference = utc_next - utc_now; + + sleep(difference.to_std().unwrap()).await; + } +} diff --git a/src/tiles/mod.rs b/src/tiles/mod.rs index cff1977..a94c8ae 100644 --- a/src/tiles/mod.rs +++ b/src/tiles/mod.rs @@ -2,14 +2,18 @@ pub mod battery; pub mod hostname; pub mod iwd; pub mod load; +pub mod local_time; pub mod memory; -pub mod time; +pub mod system_time; +pub mod utc_time; pub use battery::battery_stream; pub use hostname::hostname_stream; pub use iwd::iwd_stream; pub use load::load_stream; +pub use local_time::local_time_stream; pub use memory::memory_stream; -pub use time::time_stream; +pub use system_time::system_time_stream; +pub use utc_time::utc_time_stream; use crate::tile::Block; use std::error::Error; diff --git a/src/tiles/time.rs b/src/tiles/system_time.rs similarity index 81% rename from src/tiles/time.rs rename to src/tiles/system_time.rs index 436d918..d4de7fc 100644 --- a/src/tiles/time.rs +++ b/src/tiles/system_time.rs @@ -1,18 +1,18 @@ use super::TileResult; -use crate::config::TimeConfig; +use crate::config::SystemTimeConfig; use crate::tile::Block; use chrono::prelude::*; use futures_async_stream::stream; use tokio::time::sleep; #[stream(item = TileResult)] -pub async fn time_stream(config: TimeConfig) { +pub async fn system_time_stream(config: SystemTimeConfig) { loop { let now = Local::now(); yield Ok(Block { full_text: now.format(&config.format).to_string().into(), short_text: Some(now.format(&config.short_format).to_string().into()), - name: "time".into(), + name: "system_time".into(), ..Default::default() }); diff --git a/src/tiles/utc_time.rs b/src/tiles/utc_time.rs new file mode 100644 index 0000000..5e1e619 --- /dev/null +++ b/src/tiles/utc_time.rs @@ -0,0 +1,24 @@ +use super::TileResult; +use crate::config::UtcTimeConfig; +use crate::tile::Block; +use chrono::prelude::*; +use futures_async_stream::stream; +use tokio::time::sleep; + +#[stream(item = TileResult)] +pub async fn utc_time_stream(config: UtcTimeConfig) { + loop { + let now = Utc::now(); + yield Ok(Block { + full_text: now.format(&config.format).to_string().into(), + short_text: Some(now.format(&config.short_format).to_string().into()), + name: "utc_time".into(), + ..Default::default() + }); + + let next = now.trunc_subsecs(0) + chrono::Duration::seconds(1); + let difference = next - now; + + sleep(difference.to_std().unwrap()).await; + } +}