From 4a93c8809afa289b1d0de210eb2b57fa0aad3f2b Mon Sep 17 00:00:00 2001 From: bitheaven Date: Thu, 28 Aug 2025 19:18:03 +0500 Subject: [PATCH] first commit --- .gitignore | 1 + Cargo.lock | 604 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 8 + src/main.rs | 342 +++++++++++++++++++++++++++++ 4 files changed, 955 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..7145dff --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,604 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "bumpalo" +version = "3.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "dwmbar-rs" +version = "0.1.0" +dependencies = [ + "chrono", + "tokio", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.173" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.59.0", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "syn" +version = "2.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tokio" +version = "1.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..d339dbd --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "dwmbar-rs" +version = "0.1.0" +edition = "2024" + +[dependencies] +chrono = { version = "0.4.41", features = ["serde"] } +tokio = { version = "1.45.1", features = ["full"] } diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..4355f11 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,342 @@ +use std::fs; +use std::process::Command; +use std::sync::Arc; +use std::time::Duration; +use chrono::{DateTime, Local}; +use tokio::sync::RwLock; +use tokio::time::interval; + +#[derive(Clone, Debug)] +struct SystemInfo { + battery: String, + volume: String, + memory: String, + cpu_temp: String, + network: String, + datetime: String, +} + +impl Default for SystemInfo { + fn default() -> Self { + Self { + battery: "🔋 N/A".to_string(), + volume: "🔊 N/A".to_string(), + memory: "💾 N/A".to_string(), + cpu_temp: "🌡️ N/A".to_string(), + network: "🔌 N/A".to_string(), + datetime: "📅 N/A".to_string(), + } + } +} + +type SharedSystemInfo = Arc>; + +// Модуль батареи - обновляется каждые 30 секунд +async fn battery_module(system_info: SharedSystemInfo) { + let mut interval = interval(Duration::from_secs(10)); + + loop { + interval.tick().await; + + let battery_info = tokio::task::spawn_blocking(|| { + if let Ok(capacity) = fs::read_to_string("/sys/class/power_supply/BAT0/capacity") { + let capacity = capacity.trim(); + let status = fs::read_to_string("/sys/class/power_supply/BAT0/status") + .unwrap_or_default() + .trim() + .to_string(); + + let icon = match status.as_str() { + "Charging" => "⚡", + "Full" => "🔋", + "Discharging" => { + let cap: i32 = capacity.parse().unwrap_or(0); + match cap { + 0..=15 => "🪫", + 16..=50 => "🔋", + _ => "🔋", + } + }, + _ => "🔋", + }; + + format!("{} {}%", icon, capacity) + } else { + "🔋 N/A".to_string() + } + }).await.unwrap_or_else(|_| "🔋 Error".to_string()); + + let mut info = system_info.write().await; + info.battery = battery_info; + } +} + +// Модуль громкости - обновляется каждые 5 секунд +async fn volume_module(system_info: SharedSystemInfo) { + let mut interval = interval(Duration::from_secs(5)); + + loop { + interval.tick().await; + + let volume_info = tokio::task::spawn_blocking(|| { + if let Ok(output) = Command::new("amixer") + .args(&["get", "Master"]) + .output() + { + let output_str = String::from_utf8_lossy(&output.stdout); + if let Some(volume_line) = output_str.lines() + .find(|line| line.contains("[") && line.contains("%")) + { + if let Some(start) = volume_line.find('[') { + if let Some(end) = volume_line.find('%') { + let volume = &volume_line[start+1..end]; + let muted = volume_line.contains("[off]"); + return if muted { + format!("🔇 {}%", volume) + } else { + let vol_num: i32 = volume.parse().unwrap_or(0); + let icon = match vol_num { + 0 => "🔇", + 1..=33 => "🔈", + 34..=66 => "🔉", + _ => "🔊", + }; + format!("{} {}%", icon, volume) + }; + } + } + } + } + "🔊 N/A".to_string() + }).await.unwrap_or_else(|_| "🔊 Error".to_string()); + + let mut info = system_info.write().await; + info.volume = volume_info; + } +} + +// Модуль памяти - обновляется каждые 3 секунды +async fn memory_module(system_info: SharedSystemInfo) { + let mut interval = interval(Duration::from_secs(3)); + + loop { + interval.tick().await; + + let memory_info = tokio::task::spawn_blocking(|| { + if let Ok(meminfo) = fs::read_to_string("/proc/meminfo") { + let mut total = 0u64; + let mut available = 0u64; + + for line in meminfo.lines() { + if line.starts_with("MemTotal:") { + total = line.split_whitespace() + .nth(1) + .and_then(|s| s.parse().ok()) + .unwrap_or(0); + } else if line.starts_with("MemAvailable:") { + available = line.split_whitespace() + .nth(1) + .and_then(|s| s.parse().ok()) + .unwrap_or(0); + } + } + + if total > 0 { + let used = total - available; + let used_mb = used / 1024; + let total_mb = total / 1024; + let usage_percent = (used * 100) / total; + + let icon = match usage_percent { + 0..=50 => "💾", + 51..=80 => "📊", + _ => "⚠️", + }; + + format!("{} {}/{}MB ({}%)", icon, used_mb, total_mb, usage_percent) + } else { + "💾 N/A".to_string() + } + } else { + "💾 N/A".to_string() + } + }).await.unwrap_or_else(|_| "💾 Error".to_string()); + + let mut info = system_info.write().await; + info.memory = memory_info; + } +} + +// Модуль температуры CPU - обновляется каждые 2 секунды +async fn cpu_temp_module(system_info: SharedSystemInfo) { + let mut interval = interval(Duration::from_secs(2)); + + loop { + interval.tick().await; + + let temp_info = tokio::task::spawn_blocking(|| { + let temp_paths = [ + "/sys/class/thermal/thermal_zone0/temp", + "/sys/class/hwmon/hwmon0/temp1_input", + "/sys/class/hwmon/hwmon1/temp1_input", + "/sys/class/hwmon/hwmon2/temp1_input", + ]; + + for path in &temp_paths { + if let Ok(temp_str) = fs::read_to_string(path) { + if let Ok(temp) = temp_str.trim().parse::() { + let temp_celsius = if temp > 1000 { temp / 1000 } else { temp }; + + let icon = match temp_celsius { + 0..=40 => "❄️", + 41..=60 => "🌡️", + 61..=80 => "🔥", + _ => "💥", + }; + + return format!("{} {}°C", icon, temp_celsius); + } + } + } + + "🌡️ N/A".to_string() + }).await.unwrap_or_else(|_| "🌡️ Error".to_string()); + + let mut info = system_info.write().await; + info.cpu_temp = temp_info; + } +} + +// Модуль сети - обновляется каждые 10 секунд +async fn network_module(system_info: SharedSystemInfo) { + let mut interval = interval(Duration::from_secs(10)); + + loop { + interval.tick().await; + + let network_info = tokio::task::spawn_blocking(|| { + // Проверяем активное подключение + if let Ok(output) = Command::new("ip") + .args(&["route", "get", "8.8.8.8"]) + .output() + { + if output.status.success() { + let output_str = String::from_utf8_lossy(&output.stdout); + if let Some(dev_line) = output_str.lines().find(|line| line.contains(" dev ")) { + if let Some(dev_start) = dev_line.find(" dev ") { + let remaining = &dev_line[dev_start + 5..]; + if let Some(interface) = remaining.split_whitespace().next() { + return if interface.starts_with("wl") || interface.starts_with("wlan") { + // Попробуем получить силу сигнала Wi-Fi + if let Ok(wifi_output) = Command::new("iwconfig") + .arg(interface) + .output() + { + let wifi_str = String::from_utf8_lossy(&wifi_output.stdout); + if let Some(signal_line) = wifi_str.lines() + .find(|line| line.contains("Signal level")) + { + if let Some(level_start) = signal_line.find("Signal level=") { + let level_part = &signal_line[level_start + 13..]; + if let Some(level_end) = level_part.find(' ') { + let level = &level_part[..level_end]; + return format!("📶 {} ({})", interface, level); + } + } + } + } + format!("📶 {}", interface) + } else { + format!("🌐 {}", interface) + }; + } + } + } + } + } + + "🔌 Offline".to_string() + }).await.unwrap_or_else(|_| "🔌 Error".to_string()); + + let mut info = system_info.write().await; + info.network = network_info; + } +} + +// Модуль времени - обновляется каждую секунду +async fn datetime_module(system_info: SharedSystemInfo) { + let mut interval = interval(Duration::from_secs(1)); + + loop { + interval.tick().await; + + let now: DateTime = Local::now(); + let datetime_str = format!("📅 {} 🕐 {}", + now.format("%Y-%m-%d"), + now.format("%H:%M:%S")); + + let mut info = system_info.write().await; + info.datetime = datetime_str; + } +} + +// Модуль вывода - обновляется каждые 100мс (0.1 секунды) +async fn output_module(system_info: SharedSystemInfo) { + let mut interval = interval(Duration::from_millis(100)); + + loop { + interval.tick().await; + + let info = system_info.read().await; + let status_text = format!("{} | {} | {} | {} | {} | {}", + info.network, + info.cpu_temp, + info.memory, + info.volume, + info.battery, + info.datetime); + + // Обновляем dwm bar + tokio::task::spawn_blocking(move || { + let _ = Command::new("xsetroot") + .args(&["-name", &status_text]) + .output(); + }).await.ok(); + } +} + +#[tokio::main] +async fn main() { + println!("DWM Async Status Bar запущен..."); + println!("Интервалы обновления:"); + println!(" 🔋 Батарея: 30 сек"); + println!(" 🔊 Громкость: 5 сек"); + println!(" 💾 Память: 3 сек"); + println!(" 🌡️ CPU температура: 2 сек"); + println!(" 🌐 Сеть: 10 сек"); + println!(" 📅 Время: 1 сек"); + println!(" 📊 Вывод в bar: 0.1 сек"); + println!("Для остановки нажмите Ctrl+C"); + + let system_info: SharedSystemInfo = Arc::new(RwLock::new(SystemInfo::default())); + + // Запускаем все модули параллельно + let battery_task = tokio::spawn(battery_module(system_info.clone())); + let volume_task = tokio::spawn(volume_module(system_info.clone())); + let memory_task = tokio::spawn(memory_module(system_info.clone())); + let cpu_temp_task = tokio::spawn(cpu_temp_module(system_info.clone())); + let network_task = tokio::spawn(network_module(system_info.clone())); + let datetime_task = tokio::spawn(datetime_module(system_info.clone())); + let output_task = tokio::spawn(output_module(system_info.clone())); + + // Ждем завершения любой из задач (что в принципе не должно произойти) + tokio::select! { + _ = battery_task => println!("Battery module stopped"), + _ = volume_task => println!("Volume module stopped"), + _ = memory_task => println!("Memory module stopped"), + _ = cpu_temp_task => println!("CPU temp module stopped"), + _ = network_task => println!("Network module stopped"), + _ = datetime_task => println!("DateTime module stopped"), + _ = output_task => println!("Output module stopped"), + } +}