Compare commits
2 Commits
0e027005a1
...
1834ddac1b
Author | SHA1 | Date | |
---|---|---|---|
1834ddac1b
|
|||
a8591da49b
|
@@ -2,6 +2,7 @@
|
|||||||
name = "unibar"
|
name = "unibar"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
@@ -14,3 +15,4 @@ chrono = "0.4.41"
|
|||||||
chrono-tz = "0.10.3"
|
chrono-tz = "0.10.3"
|
||||||
iana-time-zone = "0.1.63"
|
iana-time-zone = "0.1.63"
|
||||||
clap = { version = "4.5.1", features = ["derive"] }
|
clap = { version = "4.5.1", features = ["derive"] }
|
||||||
|
thiserror = "1.0"
|
||||||
|
@@ -1,3 +1,30 @@
|
|||||||
|
// MIT License
|
||||||
|
// Copyright (c) 2025 Mahesh @ HeshApps
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//! CPU usage monitoring module for Unibar
|
||||||
|
//!
|
||||||
|
//! This module tracks CPU utilization by sampling /proc/stat and calculating
|
||||||
|
//! the percentage of time spent in different CPU states. It provides real-time
|
||||||
|
//! CPU usage information for display in the status bar.
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, BufRead, BufReader};
|
use std::io::{self, BufRead, BufReader};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
@@ -6,6 +33,11 @@ use std::time::Duration;
|
|||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::bar_modules;
|
use crate::bar_modules;
|
||||||
|
|
||||||
|
/// Represents CPU time spent in various states
|
||||||
|
///
|
||||||
|
/// This struct holds counters for different CPU states as reported by /proc/stat.
|
||||||
|
/// Each field represents the amount of time the CPU has spent in that particular state
|
||||||
|
/// since system boot, measured in USER_HZ units (typically 100Hz).
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
struct CpuTimes {
|
struct CpuTimes {
|
||||||
user: u64,
|
user: u64,
|
||||||
|
@@ -1,7 +1,40 @@
|
|||||||
|
// MIT License
|
||||||
|
// Copyright (c) 2025 Mahesh @ HeshApps
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//! Date module for Unibar
|
||||||
|
//!
|
||||||
|
//! This module displays the current date in a formatted string.
|
||||||
|
//! It updates automatically to show the current date with month,
|
||||||
|
//! day, and year information.
|
||||||
|
//!
|
||||||
|
//! # Features
|
||||||
|
//! - Formatted date display
|
||||||
|
//! - Automatic daily updates
|
||||||
|
//! - Calendar icon
|
||||||
|
|
||||||
use chrono::{DateTime, Local};
|
use chrono::{DateTime, Local};
|
||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::bar_modules;
|
use crate::bar_modules;
|
||||||
|
|
||||||
|
/// Date display module showing current calendar date
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UnibarModuleDate {
|
pub struct UnibarModuleDate {
|
||||||
opts: common::AppOptions,
|
opts: common::AppOptions,
|
||||||
|
@@ -1,3 +1,35 @@
|
|||||||
|
// MIT License
|
||||||
|
// Copyright (c) 2025 Mahesh @ HeshApps
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//! Memory module for Unibar
|
||||||
|
//!
|
||||||
|
//! This module monitors system memory usage by reading /proc/meminfo.
|
||||||
|
//! It calculates and displays current memory utilization as a percentage
|
||||||
|
//! of total available memory.
|
||||||
|
//!
|
||||||
|
//! # Features
|
||||||
|
//! - Real-time memory usage monitoring
|
||||||
|
//! - Percentage-based display
|
||||||
|
//! - Automatic updates at configured intervals
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
@@ -6,6 +38,7 @@ use regex::Regex;
|
|||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::bar_modules;
|
use crate::bar_modules;
|
||||||
|
|
||||||
|
/// Memory monitor that displays current system memory usage
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UnibarModuleMemory {
|
pub struct UnibarModuleMemory {
|
||||||
opts: common::AppOptions,
|
opts: common::AppOptions,
|
||||||
|
@@ -1,8 +1,42 @@
|
|||||||
|
// MIT License
|
||||||
|
// Copyright (c) 2025 Mahesh @ HeshApps
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//! Music module for Unibar
|
||||||
|
//!
|
||||||
|
//! This module displays current music playback information.
|
||||||
|
//! It shows the currently playing track and playback progress
|
||||||
|
//! using the system's music player.
|
||||||
|
//!
|
||||||
|
//! # Features
|
||||||
|
//! - Current track information
|
||||||
|
//! - Playback progress
|
||||||
|
//! - Playback state (playing/paused)
|
||||||
|
//! - Music note icon
|
||||||
|
|
||||||
use std::process::{Stdio, Command};
|
use std::process::{Stdio, Command};
|
||||||
|
|
||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::bar_modules;
|
use crate::bar_modules;
|
||||||
|
|
||||||
|
/// Music playback monitor showing current track and progress
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UnibarModuleMusic {
|
pub struct UnibarModuleMusic {
|
||||||
opts: common::AppOptions,
|
opts: common::AppOptions,
|
||||||
|
@@ -1,3 +1,36 @@
|
|||||||
|
// MIT License
|
||||||
|
// Copyright (c) 2025 Mahesh @ HeshApps
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//! Network module for Unibar
|
||||||
|
//!
|
||||||
|
//! This module monitors network interfaces and displays current connection status
|
||||||
|
//! and IP addresses. It supports both wireless and ethernet interfaces, with
|
||||||
|
//! different icons for each connection type.
|
||||||
|
//!
|
||||||
|
//! # Features
|
||||||
|
//! - Automatic interface detection
|
||||||
|
//! - Priority-based interface selection (ethernet over wireless)
|
||||||
|
//! - IP address display
|
||||||
|
//! - Connection status monitoring
|
||||||
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::process::{Stdio, Command};
|
use std::process::{Stdio, Command};
|
||||||
@@ -5,6 +38,7 @@ use std::process::{Stdio, Command};
|
|||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::bar_modules;
|
use crate::bar_modules;
|
||||||
|
|
||||||
|
/// Network interface monitor that displays connection status and IP addresses
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UnibarModuleNetwork {
|
pub struct UnibarModuleNetwork {
|
||||||
opts: common::AppOptions,
|
opts: common::AppOptions,
|
||||||
|
@@ -1,10 +1,42 @@
|
|||||||
|
// MIT License
|
||||||
|
// Copyright (c) 2025 Mahesh @ HeshApps
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//! Power module for Unibar
|
||||||
|
//!
|
||||||
|
//! This module monitors system power status using UPower.
|
||||||
|
//! It displays battery level and charging status with appropriate icons.
|
||||||
|
//!
|
||||||
|
//! # Features
|
||||||
|
//! - Battery level monitoring
|
||||||
|
//! - Charging status detection
|
||||||
|
//! - Different icons for charging/discharging states
|
||||||
|
//! - Automatic updates
|
||||||
|
|
||||||
use std::process::{Stdio, Command};
|
use std::process::{Stdio, Command};
|
||||||
//use std::collections::HashMap;
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::bar_modules;
|
use crate::bar_modules;
|
||||||
|
|
||||||
|
/// Power monitor that displays battery status and level
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UnibarModulePower {
|
pub struct UnibarModulePower {
|
||||||
opts: common::AppOptions,
|
opts: common::AppOptions,
|
||||||
|
@@ -1,8 +1,42 @@
|
|||||||
|
// MIT License
|
||||||
|
// Copyright (c) 2025 Mahesh @ HeshApps
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//! Time module for Unibar
|
||||||
|
//!
|
||||||
|
//! This module displays the current time with timezone information.
|
||||||
|
//! It automatically updates to show the current time in 12-hour format
|
||||||
|
//! with AM/PM indicator.
|
||||||
|
//!
|
||||||
|
//! # Features
|
||||||
|
//! - 12-hour time format with AM/PM
|
||||||
|
//! - Timezone display
|
||||||
|
//! - Automatic updates
|
||||||
|
//! - Unicode clock icon
|
||||||
|
|
||||||
use chrono::{DateTime, TimeZone, Local, Utc};
|
use chrono::{DateTime, TimeZone, Local, Utc};
|
||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::bar_modules;
|
use crate::bar_modules;
|
||||||
use chrono_tz::{OffsetName, Tz};
|
use chrono_tz::{OffsetName, Tz};
|
||||||
|
|
||||||
|
/// Time display module showing current time and timezone
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UnibarModuleTime {
|
pub struct UnibarModuleTime {
|
||||||
opts: common::AppOptions,
|
opts: common::AppOptions,
|
||||||
|
@@ -1,13 +1,53 @@
|
|||||||
|
// MIT License
|
||||||
|
// Copyright (c) 2025 Mahesh @ HeshApps
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//! Weather module for Unibar
|
||||||
|
//!
|
||||||
|
//! Fetches weather data from the National Weather Service API and displays
|
||||||
|
//! current temperature and conditions using Unicode weather symbols.
|
||||||
|
//!
|
||||||
|
//! # Features
|
||||||
|
//! - Temperature display in Celsius or Fahrenheit
|
||||||
|
//! - Automatic updates at configurable intervals
|
||||||
|
//! - Weather condition icons using Unicode symbols
|
||||||
|
//! - Robust error handling for API interactions
|
||||||
|
|
||||||
use std::str;
|
use std::str;
|
||||||
use curl::easy::{Easy, List};
|
use curl::easy::{Easy, List};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use thiserror::Error;
|
||||||
|
use std::num::ParseFloatError;
|
||||||
|
|
||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::common::UpdateResult;
|
use crate::common::UpdateResult;
|
||||||
use crate::bar_modules;
|
use crate::bar_modules;
|
||||||
|
|
||||||
|
/// Number of cycles between weather updates
|
||||||
|
const UPDATE_INTERVAL: u32 = 300;
|
||||||
|
|
||||||
|
/// Base URL for the National Weather Service API
|
||||||
|
const WEATHER_API_BASE: &str = "https://api.weather.gov";
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct UnibarModuleWeather {
|
pub struct UnibarModuleWeather {
|
||||||
opts: common::AppOptions,
|
opts: common::AppOptions,
|
||||||
@@ -15,7 +55,27 @@ pub struct UnibarModuleWeather {
|
|||||||
update_cnt: u32,
|
update_cnt: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum WeatherError {
|
||||||
|
#[error("Invalid temperature format: {0}")]
|
||||||
|
ParseError(String),
|
||||||
|
#[error("API response missing temperature field: {0}")]
|
||||||
|
ApiResponseStrErr(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ParseFloatError> for WeatherError {
|
||||||
|
fn from(err: ParseFloatError) -> Self {
|
||||||
|
WeatherError::ParseError(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl UnibarModuleWeather {
|
impl UnibarModuleWeather {
|
||||||
|
const FAHRENHEIT_MULTIPLIER: f64 = 9.0 / 5.0;
|
||||||
|
const FAHRENHEIT_OFFSET: f64 = 32.0;
|
||||||
|
|
||||||
|
fn celsius_to_fahrenheit(celsius: f64) -> f64 {
|
||||||
|
celsius * Self::FAHRENHEIT_MULTIPLIER + Self::FAHRENHEIT_OFFSET
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
pub fn new(o :common::AppOptions) -> Self {
|
pub fn new(o :common::AppOptions) -> Self {
|
||||||
@@ -27,23 +87,27 @@ impl UnibarModuleWeather {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
fn get_current_temperature(&self) -> f32 {
|
fn get_current_temperature(&self) -> Result<f64, WeatherError> {
|
||||||
let deg_c :f32;
|
let deg_c = match &self.weather_info {
|
||||||
|
serde_json::Value::Null => 0.0,
|
||||||
match self.weather_info {
|
|
||||||
serde_json::Value::Null => {
|
|
||||||
deg_c = 0.0;
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
deg_c = self.weather_info["features"][0]["properties"]["temperature"]["value"]
|
// Safely navigate the JSON structure
|
||||||
.to_string().parse().unwrap();
|
self.weather_info
|
||||||
|
.get("features")
|
||||||
|
.and_then(|f| f.get(0))
|
||||||
|
.and_then(|f| f.get("properties"))
|
||||||
|
.and_then(|p| p.get("temperature"))
|
||||||
|
.and_then(|t| t.get("value"))
|
||||||
|
.and_then(|v| v.as_f64())
|
||||||
|
.ok_or(WeatherError::ApiResponseStrErr("as_str likely failed".to_string()))?
|
||||||
|
// .parse()?
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
match self.opts.weather_units {
|
Ok(match self.opts.weather_units {
|
||||||
common::TemperatureUnits::Metric => return deg_c,
|
common::TemperatureUnits::Metric => deg_c,
|
||||||
common::TemperatureUnits::Imperial => return (deg_c * 9.0 / 5.0) + 32.0,
|
common::TemperatureUnits::Imperial => Self::celsius_to_fahrenheit(deg_c),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
@@ -100,7 +164,8 @@ impl UnibarModuleWeather {
|
|||||||
let mut url_string = Vec::new();
|
let mut url_string = Vec::new();
|
||||||
let mut curl_ret = Vec::new();
|
let mut curl_ret = Vec::new();
|
||||||
|
|
||||||
url_string.push("https://api.weather.gov/icons".to_owned());
|
url_string.push(WEATHER_API_BASE.to_owned());
|
||||||
|
url_string.push("/icons".to_owned());
|
||||||
|
|
||||||
curl.url(url_string.concat().as_str()).unwrap();
|
curl.url(url_string.concat().as_str()).unwrap();
|
||||||
{
|
{
|
||||||
@@ -171,7 +236,7 @@ impl bar_modules::BarModuleActions for UnibarModuleWeather {
|
|||||||
// Weather update every 60 cycles
|
// Weather update every 60 cycles
|
||||||
fn should_update(&mut self) -> UpdateResult {
|
fn should_update(&mut self) -> UpdateResult {
|
||||||
if self.update_cnt == 0 {
|
if self.update_cnt == 0 {
|
||||||
self.update_cnt = 300;
|
self.update_cnt = UPDATE_INTERVAL;
|
||||||
return UpdateResult::Update;
|
return UpdateResult::Update;
|
||||||
} else {
|
} else {
|
||||||
self.update_cnt -= 1;
|
self.update_cnt -= 1;
|
||||||
@@ -192,7 +257,8 @@ impl bar_modules::BarModuleActions for UnibarModuleWeather {
|
|||||||
let mut curl_ret = Vec::new();
|
let mut curl_ret = Vec::new();
|
||||||
let mut curl_err = false;
|
let mut curl_err = false;
|
||||||
|
|
||||||
url_string.push("https://api.weather.gov/stations/".to_owned());
|
url_string.push(WEATHER_API_BASE.to_owned());
|
||||||
|
url_string.push("/stations/".to_owned());
|
||||||
url_string.push(self.opts.weather_station.to_owned());
|
url_string.push(self.opts.weather_station.to_owned());
|
||||||
url_string.push("/observations?limit=1".to_owned());
|
url_string.push("/observations?limit=1".to_owned());
|
||||||
|
|
||||||
@@ -233,8 +299,8 @@ impl bar_modules::BarModuleActions for UnibarModuleWeather {
|
|||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
fn get_content(&self) -> String {
|
fn get_content(&self) -> String {
|
||||||
let temperature_value :f32 = self.get_current_temperature();
|
let temperature_value :f64 = self.get_current_temperature().expect("Temperature query");
|
||||||
let temperature_unit :String = self.get_temperature_unit();
|
let temperature_unit :String = self.get_temperature_unit();
|
||||||
// let temperature_icon :String = self.get_icon(v.clone());
|
// let temperature_icon :String = self.get_icon(v.clone());
|
||||||
|
|
||||||
return format!("{:.0}{}", temperature_value, temperature_unit);
|
return format!("{:.0}{}", temperature_value, temperature_unit);
|
||||||
@@ -251,6 +317,9 @@ impl bar_modules::BarModuleActions for UnibarModuleWeather {
|
|||||||
// "icon": "https://api.weather.gov/icons/land/night/ovc?size=medium",
|
// "icon": "https://api.weather.gov/icons/land/night/ovc?size=medium",
|
||||||
let re = Regex::new(r"(\w+)\?size").unwrap();
|
let re = Regex::new(r"(\w+)\?size").unwrap();
|
||||||
let json_val = self.weather_info["features"][0]["properties"]["icon"].to_string();
|
let json_val = self.weather_info["features"][0]["properties"]["icon"].to_string();
|
||||||
|
if self.opts.debug {
|
||||||
|
println!("-----> weather_data - {:#?}", self.weather_info["features"][0]["properties"]);
|
||||||
|
}
|
||||||
match self.weather_info["features"][0]["properties"]["icon"] {
|
match self.weather_info["features"][0]["properties"]["icon"] {
|
||||||
serde_json::Value::Null => {
|
serde_json::Value::Null => {
|
||||||
return "⁈".to_string();
|
return "⁈".to_string();
|
||||||
|
@@ -1,36 +1,67 @@
|
|||||||
|
// MIT License
|
||||||
|
// Copyright (c) 2025 Mahesh @ HeshApps
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//! Bar modules for the Unibar status bar
|
||||||
|
//!
|
||||||
|
//! This module contains implementations of various status bar components that
|
||||||
|
//! display system information like weather, CPU usage, memory, etc.
|
||||||
|
//!
|
||||||
|
//! Each module implements the `BarModuleActions` trait which defines the core
|
||||||
|
//! functionality required for status bar components.
|
||||||
|
|
||||||
use crate::common::UpdateResult;
|
use crate::common::UpdateResult;
|
||||||
|
|
||||||
// --------------------
|
/// Core trait that must be implemented by all bar modules.
|
||||||
/// All Bar modules must implement the actions
|
///
|
||||||
|
/// This trait defines the interface that every status bar component must implement
|
||||||
|
/// to provide its functionality to the Unibar system.
|
||||||
pub trait BarModuleActions {
|
pub trait BarModuleActions {
|
||||||
/// Return String with name of the module
|
/// Returns the name of the module
|
||||||
fn get_name(&self) -> String;
|
fn get_name(&self) -> String;
|
||||||
|
|
||||||
/// Do necessary clean up before starting new fetch
|
/// Cleans up any state before refreshing data
|
||||||
fn clear(&mut self);
|
fn clear(&mut self);
|
||||||
|
|
||||||
/// Do necessary processing to generate data for this bar module
|
/// Fetches and processes new data for the module
|
||||||
fn generate_data(&mut self);
|
fn generate_data(&mut self);
|
||||||
|
|
||||||
/// Return String content to be displayed in the bar
|
/// Returns the formatted content to display in the bar
|
||||||
fn get_content(&self) -> String;
|
fn get_content(&self) -> String;
|
||||||
|
|
||||||
/// Return a Unicode icon to display before content in the bar.
|
/// Returns a Unicode icon representing the module's current state
|
||||||
/// This icon may differ based on content of the data
|
|
||||||
fn get_icon(&self) -> String;
|
fn get_icon(&self) -> String;
|
||||||
|
|
||||||
/// Returns UpdateResult depending on whether the module
|
/// Determines if the module should update its data
|
||||||
/// should be updated during the current update cycle
|
/// Default implementation always returns Update
|
||||||
fn should_update(&mut self) -> UpdateResult {
|
fn should_update(&mut self) -> UpdateResult {
|
||||||
return UpdateResult::Update;
|
return UpdateResult::Update;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait BarModuleDebug {
|
pub trait BarModuleDebug {
|
||||||
/// Print debug information at the end
|
/// Prints debug information about the module
|
||||||
fn post_debug(&self);
|
fn post_debug(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Module declarations
|
||||||
pub mod bar_module_weather;
|
pub mod bar_module_weather;
|
||||||
pub mod bar_module_music;
|
pub mod bar_module_music;
|
||||||
pub mod bar_module_network;
|
pub mod bar_module_network;
|
||||||
|
95
src/main.rs
95
src/main.rs
@@ -1,23 +1,68 @@
|
|||||||
|
// MIT License
|
||||||
|
// Copyright (c) 2025 Mahesh @ HeshApps
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
//! Unibar - A Versatile Status Bar Information Provider
|
||||||
|
//!
|
||||||
|
//! Unibar is a customizable status bar information provider that displays various
|
||||||
|
//! system metrics and information in a format suitable for integration with
|
||||||
|
//! status bars like i3bar, polybar, or similar tools.
|
||||||
|
//!
|
||||||
|
//! # Features
|
||||||
|
//! - System monitoring (CPU, memory, network)
|
||||||
|
//! - Power management (battery status, charging)
|
||||||
|
//! - Weather information
|
||||||
|
//! - Date and time display
|
||||||
|
//! - Music playback information
|
||||||
|
//! - Configurable update intervals
|
||||||
|
//! - Support for both metric and imperial units
|
||||||
|
//!
|
||||||
|
//! # Usage
|
||||||
|
//! ```bash
|
||||||
|
//! unibar --interval 1 --weather-station khio --weather-metric
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! The output is formatted as a string that can be directly used
|
||||||
|
//! by status bar applications.
|
||||||
|
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use crate::common::UpdateResult;
|
use crate::common::UpdateResult;
|
||||||
|
|
||||||
// Common utilities/types
|
/// Common utilities and types used across modules
|
||||||
mod common;
|
mod common;
|
||||||
// Bar Modules
|
/// Status bar component modules
|
||||||
mod bar_modules;
|
mod bar_modules;
|
||||||
|
/// Command-line arguments for configuring Unibar behavior
|
||||||
// Commandline parsing
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(name = "unibar")]
|
#[command(name = "unibar")]
|
||||||
#[command(version = "1.0")]
|
#[command(version = "1.0")]
|
||||||
#[command(about = "Get string of info for a status bar")]
|
#[command(about = "A versatile status bar information provider")]
|
||||||
#[command(about, long_about = "A tool that returns variety of components in a string
|
#[command(long_about = "Unibar provides system information, weather, and other metrics \
|
||||||
suitable to use in a status bar")]
|
in a format suitable for status bars. It supports various modules including \
|
||||||
|
system monitoring, weather information, and music playback status.")]
|
||||||
struct CommandlineArgs {
|
struct CommandlineArgs {
|
||||||
/// Update interval in seconds
|
/// The frequency at which information is updated, in seconds.
|
||||||
|
/// Lower values provide more frequent updates but increase system load.
|
||||||
#[arg(short = 'i', long, default_value = "1")]
|
#[arg(short = 'i', long, default_value = "1")]
|
||||||
interval: u64,
|
interval: u64,
|
||||||
|
|
||||||
@@ -52,14 +97,25 @@ struct CommandlineArgs {
|
|||||||
// Application (Unibar)
|
// Application (Unibar)
|
||||||
//
|
//
|
||||||
//#[derive(Clone)]
|
//#[derive(Clone)]
|
||||||
|
/// Main application structure that manages all status bar modules
|
||||||
|
/// and coordinates their updates.
|
||||||
struct Unibar {
|
struct Unibar {
|
||||||
opts: common::AppOptions,
|
/// Application-wide configuration options
|
||||||
bar_modules_enabled: Vec<Box<dyn bar_modules::BarModuleActions>>,
|
opts: common::AppOptions,
|
||||||
debug_modules_done: bool,
|
/// List of active status bar modules
|
||||||
|
bar_modules_enabled: Vec<Box<dyn bar_modules::BarModuleActions>>,
|
||||||
|
/// Flag to track if module debugging has been performed
|
||||||
|
debug_modules_done: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Unibar {
|
impl Unibar {
|
||||||
// --------------------
|
/// Starts the main application loop, initializing all modules and
|
||||||
|
/// updating them at the configured interval.
|
||||||
|
///
|
||||||
|
/// This function:
|
||||||
|
/// 1. Initializes all enabled modules
|
||||||
|
/// 2. Enters an infinite loop for updates
|
||||||
|
/// 3. Coordinates module updates based on their individual timing requirements
|
||||||
fn run(&mut self) {
|
fn run(&mut self) {
|
||||||
if self.opts.debug {
|
if self.opts.debug {
|
||||||
self.debug_msg("Debugging ...");
|
self.debug_msg("Debugging ...");
|
||||||
@@ -163,9 +219,18 @@ impl Unibar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/// Main entry point for the Unibar application.
|
||||||
// Entry point
|
///
|
||||||
//
|
/// This function:
|
||||||
|
/// 1. Parses command-line arguments
|
||||||
|
/// 2. Creates and configures the main application instance
|
||||||
|
/// 3. Starts the application loop
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```bash
|
||||||
|
/// # Run with metric units and 1-second updates
|
||||||
|
/// unibar --interval 1 --weather-metric
|
||||||
|
/// ```
|
||||||
fn main() {
|
fn main() {
|
||||||
let cmd_args = CommandlineArgs::parse();
|
let cmd_args = CommandlineArgs::parse();
|
||||||
let mut app = Unibar {
|
let mut app = Unibar {
|
||||||
|
Reference in New Issue
Block a user