This commit is contained in:
mjallen18
2025-11-25 10:16:26 -06:00
parent b62f49b362
commit 34181aa0c9
4 changed files with 231 additions and 21 deletions

View File

@@ -188,19 +188,82 @@ in
vibrancy_darkness = "0.0";
}
];
label = [
# Date display
{
monitor = cfg.primaryDisplay;
text = "cmd[update:1000] echo -e \"$(LC_TIME=en_US.UTF-8 date +\"%A, %B %d\")\"";
color = "#eceff4";
font_size = "25";
font_family = "JetBrainsMono NFM";
position = "0, 350";
halign = "center";
valign = "center";
}
# Time display
{
monitor = cfg.primaryDisplay;
text = "cmd[update:1000] echo \"<span>$(date +\"%I:%M\")</span>\"";
color = "#eceff4";
font_size = "120";
font_family = "JetBrainsMono NFM Bold";
position = "0, 230";
halign = "center";
valign = "center";
}
{
monitor = cfg.primaryDisplay;
text = "$USER";
color = "#eceff4";
outline_thickness = 2;
dots_size = 0.2;
dots_spacing = 0.2;
dots_center = true;
font_size = 18;
font_family = "JetBrainsMono NFM Bold";
position = "0, 0";
halign = "center";
valign = "center";
}
#weather
{
monitor = cfg.primaryDisplay;
text = "cmd[update:30000] waybar-weather --hyprlock";
color = "#eceff4";
font_size = "25";
font_family = "JetBrainsMono NFM";
position = "-100, 100";
halign = "right";
valign = "bottom";
}
];
# user box
shape = [
{
monitor = "";
size = "200, 50";
color = "rgba(46, 52, 64, .25)";
rounding = -1;
border_size = "0";
position = "0, 0";
halign = "center";
valign = "center";
}
];
input-field = [
{
size = "200, 50";
position = "0, -80";
font_family = "JetBrainsMono NFM";
monitor = cfg.primaryDisplay;
dots_center = true;
fade_on_empty = true;
font_color = "rgb(202, 211, 245)";
inner_color = "rgb(91, 96, 120)";
outer_color = "rgb(24, 25, 38)";
font_color = "#eceff4";
inner_color = "#4c566a";
outer_color = "#2e3440";
bothlock_color = -1;
outline_thickness = 5;
placeholder_text = ''<span foreground="##cad3f5">Password...</span>'';
placeholder_text = ''<span foreground="##2e3440">Password...</span>'';
shadow_passes = 2;
}
];

View File

@@ -364,6 +364,11 @@ in
<property name="label">Reboot</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="lock">
<property name="label">Lock</property>
</object>
</child>
</object>
</interface>
'';
@@ -476,6 +481,7 @@ in
reboot = "reboot";
suspend = "systemctl suspend";
hibernate = "systemctl hibernate";
lock = "pidof hyprlock || hyprlock";
};
};
}
@@ -662,7 +668,7 @@ in
tooltip = true;
format = { };
interval = 30;
exec = "waybar-weather";
exec = "waybar-weather --waybar";
return-type = "json";
markup = "pango";
};

View File

@@ -0,0 +1,67 @@
{
config,
lib,
namespace,
pkgs,
...
}:
let
cfg = config.${namespace}.programs.waybar;
waybar-media = pkgs.writeScriptBin "waybar-media" ''
#!/usr/bin/env bash
# Get current playing song from playerctl
if command -v playerctl &> /dev/null; then
# Check if any player is running
if playerctl status &> /dev/null; then
artist=$(playerctl metadata xesam:artist 2>/dev/null)
title=$(playerctl metadata xesam:title 2>/dev/null)
if [[ -n "$artist" && -n "$title" ]]; then
echo " $artist - $title"
elif [[ -n "$title" ]]; then
echo " $title"
else
echo " Music Playing"
fi
else
echo ""
fi
else
echo ""
fi
'';
waybar-media-art = pkgs.writeScriptBin "waybar-media-art" ''
#!/usr/bin/env bash
# Get current playing song from playerctl
if command -v playerctl &> /dev/null; then
# Check if any player is running
if playerctl status &> /dev/null; then
art=$(playerctl metadata mpris:artUrl 2>/dev/null)
if [[ -n "$art" ]]; then
echo " $artist - $title"
else
echo " Music Playing"
fi
else
echo ""
fi
else
echo ""
fi
'';
in
{
imports = [ ../options.nix ];
config = lib.mkIf cfg.enable {
home.packages = [
waybar-media
waybar-media-art
];
};
}

View File

@@ -16,9 +16,15 @@ let
import json
import shutil
from datetime import datetime, timedelta
import argparse
import requests
parser = argparse.ArgumentParser(prog='waybar-weather')
parser.add_argument('--waybar', action='store_true')
parser.add_argument('--hyprlock', action='store_true')
args = parser.parse_args()
WWO_CODE = {
"113": "Sunny",
"116": "PartlyCloudy",
@@ -281,6 +287,12 @@ let
WEATHER_CODES_WEGO = {key: WEATHER_SYMBOL_WEGO[value] for key, value in WWO_CODE.items()}
CACHE_DIR = os.path.join(os.environ.get("XDG_CACHE_HOME", os.path.expanduser("~/.cache")), "waybar-weather")
CACHE_FILE = os.path.join(CACHE_DIR, "wttr.json")
CACHE_MOON_FILE = os.path.join(CACHE_DIR, "moon.json")
CACHE_MOON_ICON_FILE = os.path.join(CACHE_DIR, "moon-icon")
CACHE_TTL = timedelta(minutes=10)
data = {}
data["text"] = ""
@@ -415,31 +427,93 @@ let
after_sunset = time_24_hr > sunset_hour
return after_sunset or before_sunrise
def get_wttr_json():
def load_cache(path, ttl):
"""Load cached file if it is not too old."""
try:
if not os.path.exists(path):
return None
mtime = datetime.fromtimestamp(os.path.getmtime(path))
if datetime.now() - mtime > ttl:
return None
with open(path, "r") as f:
if path.endswith(".json"):
return json.load(f)
return f.read().strip()
except Exception:
return None
def save_cache(path, data):
"""Write cache file safely."""
os.makedirs(os.path.dirname(path), exist_ok=True)
tmp = path + ".tmp"
try:
with open(tmp, "w") as f:
if isinstance(data, dict):
json.dump(data, f)
else:
f.write(str(data))
shutil.move(tmp, path)
except Exception:
pass
def get_wttr_json(hyprlock=False):
"""get the weather json"""
weather = requests.get("https://wttr.in/?u&format=j1", timeout=30).json()
moon = requests.get("https://wttr.in/?format=%m", timeout=30)
moon_icon = moon.text
current_condition = weather["current_condition"][0]
astronomy = weather["weather"][0]['astronomy'][0]
# Try loading cached JSON
cached = load_cache(CACHE_FILE, CACHE_TTL)
cached_moon = load_cache(CACHE_MOON_FILE, CACHE_TTL)
cached_moon_icon = load_cache(CACHE_MOON_ICON_FILE, CACHE_TTL)
text = build_text(current_condition)
if cached and cached_moon and cached_moon_icon:
current_condition = cached
astronomy = cached_moon
moon_icon = cached_moon_icon
else:
weather = requests.get("https://wttr.in/?u&format=j1", timeout=30).json()
moon = requests.get("https://wttr.in/?format=%m", timeout=30)
moon_icon = moon.text
tooltip = build_tooltip(current_condition, astronomy, moon_icon) + build_forecast(weather["weather"])
current_condition = weather["current_condition"][0]
astronomy = weather["weather"][0]['astronomy'][0]
data["text"] = text
data["tooltip"] = tooltip
# Save cache
save_cache(CACHE_FILE, current_condition)
save_cache(CACHE_MOON_FILE, astronomy)
save_cache(CACHE_MOON_ICON_FILE, moon_icon)
return json.dumps(data)
if hyprlock:
return build_tooltip(current_condition, astronomy, moon_icon)
else:
text = build_text(current_condition)
tooltip = build_tooltip(current_condition, astronomy, moon_icon) + build_forecast(weather["weather"])
data["text"] = text
data["tooltip"] = tooltip
return json.dumps(data)
def main():
"""main"""
try:
print(get_wttr_json())
except Exception as e:
print("error")
print(e)
if args.hyprlock:
try:
print(get_wttr_json(hyprlock=True))
except Exception as e:
print("error")
print(e)
else:
try:
print(get_wttr_json())
except Exception as e:
print("error")
print(e)
main()
'';