so many sops

This commit is contained in:
mjallen18
2025-03-17 21:34:52 -05:00
parent 7741fc575f
commit 32eadb044d
53 changed files with 801 additions and 591 deletions

View File

@@ -0,0 +1,363 @@
{
# https://github.com/Alexays/Waybar/wiki/Module:-Hyprland
# https://www.nerdfonts.com/cheat-sheet
programs.waybar = {
enable = true;
systemd.enable = true;
settings = {
mainBar = {
layer = "bottom";
position = "top";
mod = "dock";
exclusive = true;
passthrough = false;
gtk-layer-shell = true;
height = 0;
modules-left = [ "hyprland/workspaces" ];
modules-center = [ "hyprland/window" ];
modules-right = [
"tray"
# "custom/updates"
"custom/lights"
"temperature"
"temperature#gpu"
"keyboard-state#capslock"
"keyboard-state#numlock"
"pulseaudio"
"pulseaudio#microphone"
"clock"
"custom/weather"
];
"hyprland/window" = {
separate-outputs = true;
format = { };
};
"hyprland/workspaces" = {
disable-scroll = true;
all-outputs = true;
on-click = "activate";
persistent_workspaces = {
"*" = 1;
};
};
"custom/weather" = {
tooltip = true;
format = { };
interval = 30;
exec = "waybar-weather";
return-type = "json";
};
# "custom/updates" = {
# tooltip = true;
# format = { };
# interval = 30;
# exec = "waybar-updates";
# return-type = "json";
# };
"custom/lights" = {
tooltip = false;
format = "󱉓";
# interval = 30;
on-click = "nix-shell /home/matt/.config/waybar/scripts/hass.nix --run \"python /home/matt/.config/waybar/scripts/hass.py --toggle_light light.bedroom_lights\"";
# return-type = "json";
};
temperature = {
hwmon-path = "/sys/class/hwmon/hwmon4/temp1_input";
critical-threshold = 90;
format-critical = "{temperatureC}°C {icon}";
format = "{temperatureC}°C {icon}";
format-icons = [
"" # fa-temperature-empty
"" # fa-temperature-quarter
"" # fa-temperature-half
"" # fa-temperature-three-quarters
"" # fa-temperature-full
"" # fa-temperature-high
];
tooltip-format = "CPU: {temperatureC}°C";
};
"temperature#gpu" = {
hwmon-path = "/sys/class/hwmon/hwmon0/temp1_input";
critical-threshold = 100;
format-critical = "{temperatureC}°C {icon}";
format = "{temperatureC}°C {icon}";
format-icons = [
"" # fa-temperature-empty
"" # fa-temperature-quarter
"" # fa-temperature-half
"" # fa-temperature-three-quarters
"" # fa-temperature-full
"" # fa-temperature-high
];
on-click = "lact";
tooltip-format = "GPU: {temperatureC}°C";
};
tray = {
icon-size = 16;
spacing = 10;
};
clock = {
format = "{:%I:%M %p}";
tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
};
pulseaudio = {
format = "{icon} {volume}%";
tooltip = false;
format-muted = " Muted";
on-click = "pamixer -t";
on-click-right = "pavucontrol -t 1";
on-scroll-up = "pamixer -i 5";
on-scroll-down = "pamixer -d 5";
scroll-step = 5;
format-icons = {
headphone = "󰋋";
headphone-muted = "󰟎";
hands-free = "󰋋";
headset = "󰋋";
phone = "";
portable = "󰋋";
car = "";
default = [
""
""
""
""
];
};
};
"pulseaudio#microphone" = {
format = "{format_source}";
format-source = "";
format-source-muted = "";
on-click = "pamixer --default-source -t";
on-click-right = "pavucontrol -t 2";
on-scroll-up = "pamixer --default-source -i 5";
on-scroll-down = "pamixer --default-source -d 5";
scroll-step = 5;
};
"keyboard-state#capslock" = {
capslock = true;
icon-size = 20;
format = "{icon}";
format-icons = {
locked = "󰪛";
unlocked = " ";
};
};
"keyboard-state#numlock" = {
numlock = true;
icon-size = 60;
format = "{icon}";
format-icons = {
locked = "󰎣";
unlocked = " ";
};
};
};
};
# https://catppuccin.com/palette
style = ''
@define-color nord0 #2e3440;
@define-color nord1 #3b4252;
@define-color nord2 #434c5e;
@define-color nord3 #4c566a;
@define-color nord4 #d8dee9;
@define-color nord5 #e5e9f0;
@define-color nord6 #eceff4;
@define-color nord7 #8fbcbb;
@define-color nord8 #88c0d0;
@define-color nord9 #81a1c1;
@define-color nord10 #5e81ac;
@define-color nord11 #bf616a;
@define-color nord12 #d08770;
@define-color nord13 #ebcb8b;
@define-color nord14 #a3be8c;
@define-color nord15 #b48ead;
/*@import "nord.css";*/
* {
font-family:
Jetbrains Mono Nerd Font,
monospace;
font-size: 14px;
min-height: 0;
}
#waybar {
background: transparent;
color: @nord6;
margin: 5px 5px;
}
#workspaces {
padding: 0.5rem 1rem;
margin: 5px 0;
border-radius: 1rem;
background-color: @nord0;
opacity: 0.6;
margin-left: 1rem;
}
#workspaces button {
color: @nord10;
border-radius: 1rem;
padding: 0.4rem;
}
#workspaces button.active {
color: @nord8;
border-radius: 1rem;
}
#workspaces button:hover {
color: @nord7;
border-radius: 1rem;
}
#workspaces button.focused {
color: @nord6;
background: @nord13;
border-radius: 1rem;
}
#workspaces button.urgent {
color: @nord0;
background: @nord6;
border-radius: 1rem;
}
#tooltip {
background: @nord0;
border-radius: 1rem;
border-width: 1rem;
border-style: solid;
border-color: @nord0;
}
#window {
color: @nord15;
background-color: @nord0;
opacity: 0.6;
padding: 0.5rem 1rem;
margin: 5px 0;
border-radius: 1rem;
margin-left: 6rem;
margin-right: 6rem;
}
#custom-weather {
color: @nord10;
background-color: @nord0;
padding: 0.5rem 1rem;
margin: 5px 0;
border-radius: 0rem 1rem 1rem 0rem;
margin-right: 1rem;
}
#clock {
color: @nord9;
background-color: @nord0;
padding: 0.5rem 1rem;
margin: 5px 0;
border-radius: 1rem 0rem 0rem 1rem;
margin-left: 1rem;
}
/* ------------- */
#pulseaudio.microphone {
color: @nord8;
background-color: @nord0;
padding: 0.5rem 1rem;
margin: 5px 0;
border-radius: 0rem 1rem 1rem 0rem;
}
#pulseaudio {
color: @nord7;
background-color: @nord0;
padding: 0.5rem 1rem;
margin: 5px 0;
border-radius: 0;
}
#keyboard-state.numlock {
color: @nord8;
background-color: @nord0;
padding: 0.5rem;
margin: 5px 0;
border-radius: 0;
font-size: 10rem;
}
#keyboard-state.capslock {
color: @nord9;
background-color: @nord0;
padding: 0.5rem;
margin: 5px 0;
border-radius: 0;
font-size: 18px;
}
#temperature.gpu {
color: @nord10;
background-color: @nord0;
padding: 0.5rem 1rem;
margin: 5px 0;
border-radius: 0;
}
#temperature {
color: @nord9;
background-color: @nord0;
padding: 0.5rem 1rem;
margin: 5px 0;
border-radius: 0;
}
#custom-updates {
color: @nord8;
background-color: @nord0;
padding: 0.5rem 1rem;
margin: 5px 0;
border-radius: 1rem 0rem 0rem 1rem;
margin-left: 1rem;
}
#custom-lights {
color: @nord8;
background-color: @nord0;
padding: 0.5rem 1rem;
margin: 5px 0;
border-radius: 1rem 0rem 0rem 1rem;
}
/* ------------- */
#tray {
background-color: @nord0;
padding: 0.5rem 1rem;
margin: 5px 0;
margin-right: 1rem;
border-radius: 1rem;
}
'';
};
}

View File

@@ -0,0 +1,26 @@
@define-color rosewater #f4dbd6;
@define-color flamingo #f0c6c6;
@define-color pink #f5bde6;
@define-color mauve #c6a0f6;
@define-color red #ed8796;
@define-color maroon #ee99a0;
@define-color peach #f5a97f;
@define-color yellow #eed49f;
@define-color green #a6da95;
@define-color teal #8bd5ca;
@define-color sky #91d7e3;
@define-color sapphire #7dc4e4;
@define-color blue #8aadf4;
@define-color lavender #b7bdf8;
@define-color text #cad3f5;
@define-color subtext1 #b8c0e0;
@define-color subtext0 #a5adcb;
@define-color overlay2 #939ab7;
@define-color overlay1 #8087a2;
@define-color overlay0 #6e738d;
@define-color surface2 #5b6078;
@define-color surface1 #494d64;
@define-color surface0 #363a4f;
@define-color base #24273a;
@define-color mantle #1e2030;
@define-color crust #181926;

View File

@@ -0,0 +1,16 @@
@define-color nord0 #2e3440;
@define-color nord1 #3b4252;
@define-color nord2 #434c5e;
@define-color nord3 #4c566a;
@define-color nord4 #d8dee9;
@define-color nord5 #e5e9f0;
@define-color nord6 #eceff4;
@define-color nord7 #8fbcbb;
@define-color nord8 #88c0d0;
@define-color nord9 #81a1c1;
@define-color nord10 #5e81ac;
@define-color nord11 #bf616a;
@define-color nord12 #d08770;
@define-color nord13 #ebcb8b;
@define-color nord14 #a3be8c;
@define-color nord15 #b48ead;

View File

@@ -0,0 +1,18 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
# The Nix packages provided in the environment
packages = [
pkgs.python312
pkgs.python3Packages.pip
# Whatever other packages are required
];
shellHook = ''
export TMPDIR=/tmp
export VENV_DIR=/tmp/lights
mkdir $VENV_DIR
python -m venv $VENV_DIR/.venv
source $VENV_DIR/.venv/bin/activate
pip install homeassistant-api
'';
}

View File

@@ -0,0 +1,42 @@
import os
import argparse
import time
from homeassistant_api import Client
hass_url = 'https://hass.mjallen.dev/api'
parser = argparse.ArgumentParser(prog='hass python wrapper')
parser.add_argument('--toggle_light')
args = parser.parse_args()
def loadKey():
token_path = ""
for folder in range(1,100):
if os.path.exists("/run/secrets.d/" + str(folder) + "/desktop/hass_token"):
token_path = "/run/secrets.d/" + str(folder) + "/desktop/hass_token"
break
with open(token_path, "r") as key_file:
key = key_file.readline()
return key
def toggle_light(client, light):
lights = client.get_domain("light")
lights.toggle(entity_id=light)
time.sleep(0.5)
light_entity = client.get_entity(entity_id=light)
state = light_entity.get_state()
if state.state == 'on':
return "󰛨"
else:
return "󰹏"
def main():
token = loadKey()
with Client(hass_url, token) as client:
if args.toggle_light is not None:
status = toggle_light(client=client, light=args.toggle_light)
print("{ text: \"" + status + "\" }")
main()

View File

@@ -0,0 +1,90 @@
#!/usr/bin/env nix-shell
#! nix-shell -i python3 --pure
#! nix-shell -p python3
import os
import json
import subprocess
import re
from datetime import datetime
import time
tmp_path = '/tmp/waybar-scripts/updates'
json_cache = tmp_path + "/data.json"
git_repo = 'git@github.com:mjallen18/nix-config.git'
def cache_json(data):
with open(json_cache, mode="w") as cache:
json.dump(data, cache)
def create_folders():
if not os.path.exists(tmp_path):
os.makedirs(tmp_path)
os.chdir(tmp_path)
def clone_repo():
reset_repo()
if os.path.exists(tmp_path) and len(os.listdir(tmp_path)) == 0:
subprocess.run(["git", "clone", git_repo, tmp_path])
def check_for_flake_updates():
return subprocess.run(["sudo", "nix", "flake", "update", "-I", tmp_path, tmp_path], capture_output=True, text=True)
def reset_repo():
if os.path.exists(tmp_path) and not len(os.listdir(tmp_path)) == 0:
subprocess.run(["git", "reset", "--hard"])
subprocess.run(["git", "pull"])
def parse_output(output):
updates_dict = {}
updates = re.findall(r"(• Updated input '(.+)':((\n|\r|\n)(.+\((\d\d\d\d-\d\d-\d\d\)))){2})", output)
for update in updates:
input = re.findall(r"'(.+)':", update[0])[0].strip()
dates = re.findall(r"(\d{4}-\d{2}-\d{2})", update[0])
updates_dict[input] = dates
return updates_dict
def check():
data = {}
# print("create folders")
create_folders()
# print("clone repo")
clone_repo()
# print("checking for updates")
updates = check_for_flake_updates()
updates_dict = parse_output(updates.stderr)
if len(updates_dict.keys()) > 0:
data["text"] = ("󰏕")
else:
data["text"] = (u"\u00A0")
if len(updates_dict.keys()) <= 0:
data["tooltip"] = ("flake inputs up to date")
else:
data["tooltip"] = ("flake input updates:\n\n")
for input in updates_dict.keys():
data["tooltip"] += "<b>{}</b>\n".format(input)
data["tooltip"] += "Old Ref: {0}{1}\n\n".format(updates_dict[input][0].strip(), updates_dict[input][1].strip())
cache_json(data)
print(json.dumps(data))
def read_cache():
with open(json_cache, mode="r") as cache:
print(json.dumps(json.load(cache)))
def main():
now = int(datetime.now().strftime("%H"))
if os.path.exists(json_cache):
mtime = int(time.localtime(os.stat(json_cache).st_ctime).tm_hour)
else:
mtime = now + 1
if (now % 2 == 0 and mtime < now) or not os.path.exists(json_cache):
check()
else:
read_cache()
main()

View File

@@ -0,0 +1,379 @@
#!/usr/bin/env nix-shell
#! nix-shell -i python3 --pure
#! nix-shell -p python3 python3Packages.requests
import json
from datetime import datetime
import requests
WWO_CODE = {
"113": "Sunny",
"116": "PartlyCloudy",
"119": "Cloudy",
"122": "VeryCloudy",
"143": "Fog",
"176": "LightShowers",
"179": "LightSleetShowers",
"182": "LightSleet",
"185": "LightSleet",
"200": "ThunderyShowers",
"227": "LightSnow",
"230": "HeavySnow",
"248": "Fog",
"260": "Fog",
"263": "LightShowers",
"266": "LightRain",
"281": "LightSleet",
"284": "LightSleet",
"293": "LightRain",
"296": "LightRain",
"299": "HeavyShowers",
"302": "HeavyRain",
"305": "HeavyShowers",
"308": "HeavyRain",
"311": "LightSleet",
"314": "LightSleet",
"317": "LightSleet",
"320": "LightSnow",
"323": "LightSnowShowers",
"326": "LightSnowShowers",
"329": "HeavySnow",
"332": "HeavySnow",
"335": "HeavySnowShowers",
"338": "HeavySnow",
"350": "LightSleet",
"353": "LightShowers",
"356": "HeavyShowers",
"359": "HeavyRain",
"362": "LightSleetShowers",
"365": "LightSleetShowers",
"368": "LightSnowShowers",
"371": "HeavySnowShowers",
"374": "LightSleetShowers",
"377": "LightSleet",
"386": "ThunderyShowers",
"389": "ThunderyHeavyRain",
"392": "ThunderySnowShowers",
"395": "HeavySnowShowers",
}
WEATHER_SYMBOL_EMOJI = {
"Unknown": "",
"Cloudy": "☁️",
"Fog": "🌫",
"HeavyRain": "🌧",
"HeavyShowers": "🌧",
"HeavySnow": "❄️",
"HeavySnowShowers": "❄️",
"LightRain": "🌦",
"LightShowers": "🌦",
"LightSleet": "🌧",
"LightSleetShowers": "🌧",
"LightSnow": "🌨",
"LightSnowShowers": "🌨",
"PartlyCloudy": "⛅️",
"Sunny": "☀️",
"ThunderyHeavyRain": "🌩",
"ThunderyShowers": "",
"ThunderySnowShowers": "",
"VeryCloudy": "☁️",
}
WEATHER_SYMBOL = {
"Unknown": "",
"Cloudy": "☁️",
"Fog": "🌫",
"HeavyRain": "🌧",
"HeavyShowers": "🌧",
"HeavySnow": "❄️",
"HeavySnowShowers": "❄️",
"LightRain": "🌦",
"LightShowers": "🌦",
"LightSleet": "🌧",
"LightSleetShowers": "🌧",
"LightSnow": "🌨",
"LightSnowShowers": "🌨",
"PartlyCloudy": "⛅️",
"Sunny": "☀️",
"ThunderyHeavyRain": "🌩",
"ThunderyShowers": "",
"ThunderySnowShowers": "",
"VeryCloudy": "☁️",
}
WEATHER_CODES = {key: WEATHER_SYMBOL[value] for key, value in WWO_CODE.items()}
WIND_DIRECTION = [
"", "", "", "", "", "", "", "",
]
MOON_PHASES = (
"🌑", "🌒", "🌓", "🌔", "🌕", "🌖", "🌗", "🌘"
)
WEATHER_SYMBOL_WI_DAY = {
"Unknown": "",
"Cloudy": "",
"Fog": "",
"HeavyRain": "",
"HeavyShowers": "",
"HeavySnow": "",
"HeavySnowShowers": "",
"LightRain": "",
"LightShowers": "",
"LightSleet": "",
"LightSleetShowers": "",
"LightSnow": "",
"LightSnowShowers": "",
"PartlyCloudy": "",
"Sunny": "",
"ThunderyHeavyRain": "",
"ThunderyShowers": "",
"ThunderySnowShowers": "",
"VeryCloudy": "",
}
WEATHER_CODES_WI_DAY = {key: WEATHER_SYMBOL_WI_DAY[value] for key, value in WWO_CODE.items()}
WEATHER_SYMBOL_WI_NIGHT = {
"Unknown": "",
"Cloudy": "",
"Fog": "",
"HeavyRain": "",
"HeavyShowers": "",
"HeavySnow": "",
"HeavySnowShowers": "",
"LightRain": "",
"LightShowers": "",
"LightSleet": "",
"LightSleetShowers": "",
"LightSnow": "",
"LightSnowShowers": "",
"PartlyCloudy": "",
"Sunny": "",
"ThunderyHeavyRain": "",
"ThunderyShowers": "",
"ThunderySnowShowers": "",
"VeryCloudy": "",
}
WEATHER_CODES_WI_NIGHT = {key: WEATHER_SYMBOL_WI_NIGHT[value] for key, value in WWO_CODE.items()}
WIND_DIRECTION_WI = [
"", "", "", "", "", "", "", "",
]
WIND_SCALE_WI = [
"", "", "", "", "", "", "", "", "", "", "", "", "",
]
MOON_PHASES_WI = (
"", "", "", "", "", "", "",
"", "", "", "", "", "", "",
"", "", "", "", "", "", "",
"", "", "", "", "", "", "",
)
WEATHER_SYMBOL_WEGO = {
"Unknown": [
" .-. ",
" __) ",
" ( ",
" `- ",
""],
"Sunny": [
"\033[38;5;226m \\ / \033[0m",
"\033[38;5;226m .-. \033[0m",
"\033[38;5;226m ― ( ) ― \033[0m",
"\033[38;5;226m `- \033[0m",
"\033[38;5;226m / \\ \033[0m"],
"PartlyCloudy": [
"\033[38;5;226m \\ /\033[0m ",
"\033[38;5;226m _ /\"\"\033[38;5;250m.-. \033[0m",
"\033[38;5;226m \\_\033[38;5;250m( ). \033[0m",
"\033[38;5;226m /\033[38;5;250m(___(__) \033[0m",
" "],
"Cloudy": [
" ",
"\033[38;5;250m .--. \033[0m",
"\033[38;5;250m .-( ). \033[0m",
"\033[38;5;250m (___.__)__) \033[0m",
" "],
"VeryCloudy": [
" ",
"\033[38;5;240;1m .--. \033[0m",
"\033[38;5;240;1m .-( ). \033[0m",
"\033[38;5;240;1m (___.__)__) \033[0m",
" "],
"LightShowers": [
"\033[38;5;226m _`/\"\"\033[38;5;250m.-. \033[0m",
"\033[38;5;226m ,\\_\033[38;5;250m( ). \033[0m",
"\033[38;5;226m /\033[38;5;250m(___(__) \033[0m",
"\033[38;5;111m \033[0m",
"\033[38;5;111m \033[0m"],
"HeavyShowers": [
"\033[38;5;226m _`/\"\"\033[38;5;240;1m.-. \033[0m",
"\033[38;5;226m ,\\_\033[38;5;240;1m( ). \033[0m",
"\033[38;5;226m /\033[38;5;240;1m(___(__) \033[0m",
"\033[38;5;21;1m \033[0m",
"\033[38;5;21;1m \033[0m"],
"LightSnowShowers": [
"\033[38;5;226m _`/\"\"\033[38;5;250m.-. \033[0m",
"\033[38;5;226m ,\\_\033[38;5;250m( ). \033[0m",
"\033[38;5;226m /\033[38;5;250m(___(__) \033[0m",
"\033[38;5;255m * * * \033[0m",
"\033[38;5;255m * * * \033[0m"],
"HeavySnowShowers": [
"\033[38;5;226m _`/\"\"\033[38;5;240;1m.-. \033[0m",
"\033[38;5;226m ,\\_\033[38;5;240;1m( ). \033[0m",
"\033[38;5;226m /\033[38;5;240;1m(___(__) \033[0m",
"\033[38;5;255;1m * * * * \033[0m",
"\033[38;5;255;1m * * * * \033[0m"],
"LightSleetShowers": [
"\033[38;5;226m _`/\"\"\033[38;5;250m.-. \033[0m",
"\033[38;5;226m ,\\_\033[38;5;250m( ). \033[0m",
"\033[38;5;226m /\033[38;5;250m(___(__) \033[0m",
"\033[38;5;111m \033[38;5;255m*\033[38;5;111m \033[38;5;255m* \033[0m",
"\033[38;5;255m *\033[38;5;111m \033[38;5;255m*\033[38;5;111m \033[0m"],
"ThunderyShowers": [
"\033[38;5;226m _`/\"\"\033[38;5;250m.-. \033[0m",
"\033[38;5;226m ,\\_\033[38;5;250m( ). \033[0m",
"\033[38;5;226m /\033[38;5;250m(___(__) \033[0m",
"\033[38;5;228;5m ⚡\033[38;5;111;25m \033[38;5;228;5m⚡\033[38;5;111;25m \033[0m",
"\033[38;5;111m \033[0m"],
"ThunderyHeavyRain": [
"\033[38;5;240;1m .-. \033[0m",
"\033[38;5;240;1m ( ). \033[0m",
"\033[38;5;240;1m (___(__) \033[0m",
"\033[38;5;21;1m \033[38;5;228;5m⚡\033[38;5;21;25m\033[38;5;228;5m⚡\033[38;5;21;25m \033[0m",
"\033[38;5;21;1m \033[38;5;228;5m⚡\033[38;5;21;25m \033[0m"],
"ThunderySnowShowers": [
"\033[38;5;226m _`/\"\"\033[38;5;250m.-. \033[0m",
"\033[38;5;226m ,\\_\033[38;5;250m( ). \033[0m",
"\033[38;5;226m /\033[38;5;250m(___(__) \033[0m",
"\033[38;5;255m *\033[38;5;228;5m⚡\033[38;5;255;25m*\033[38;5;228;5m⚡\033[38;5;255;25m* \033[0m",
"\033[38;5;255m * * * \033[0m"],
"LightRain": [
"\033[38;5;250m .-. \033[0m",
"\033[38;5;250m ( ). \033[0m",
"\033[38;5;250m (___(__) \033[0m",
"\033[38;5;111m \033[0m",
"\033[38;5;111m \033[0m"],
"HeavyRain": [
"\033[38;5;240;1m .-. \033[0m",
"\033[38;5;240;1m ( ). \033[0m",
"\033[38;5;240;1m (___(__) \033[0m",
"\033[38;5;21;1m \033[0m",
"\033[38;5;21;1m \033[0m"],
"LightSnow": [
"\033[38;5;250m .-. \033[0m",
"\033[38;5;250m ( ). \033[0m",
"\033[38;5;250m (___(__) \033[0m",
"\033[38;5;255m * * * \033[0m",
"\033[38;5;255m * * * \033[0m"],
"HeavySnow": [
"\033[38;5;240;1m .-. \033[0m",
"\033[38;5;240;1m ( ). \033[0m",
"\033[38;5;240;1m (___(__) \033[0m",
"\033[38;5;255;1m * * * * \033[0m",
"\033[38;5;255;1m * * * * \033[0m"],
"LightSleet": [
"\033[38;5;250m .-. \033[0m",
"\033[38;5;250m ( ). \033[0m",
"\033[38;5;250m (___(__) \033[0m",
"\033[38;5;111m \033[38;5;255m*\033[38;5;111m \033[38;5;255m* \033[0m",
"\033[38;5;255m *\033[38;5;111m \033[38;5;255m*\033[38;5;111m \033[0m"],
"Fog": [
" ",
"\033[38;5;251m _ - _ - _ - \033[0m",
"\033[38;5;251m _ - _ - _ \033[0m",
"\033[38;5;251m _ - _ - _ - \033[0m",
" "],
}
data = {}
weather = requests.get("https://wttr.in/?u&format=j1").json()
moon = requests.get("https://wttr.in/?format=%m").text
def format_time(time):
return datetime.strptime(format_24_time(time), "%H").strftime("%I %p")
def format_24_time(time):
return time.replace("00", "").zfill(2)
def format_temp(temp):
return (hour["FeelsLikeF"] + "°").ljust(3)
def format_chances(hour):
chances = {
"chanceoffog": "Fog",
"chanceoffrost": "Frost",
"chanceofovercast": "Overcast",
"chanceofrain": "Rain",
"chanceofsnow": "Snow",
"chanceofsunshine": "Sunshine",
"chanceofthunder": "Thunder",
"chanceofwindy": "Wind",
}
conditions = []
for event in chances.keys():
if int(hour[event]) > 0:
conditions.append(chances[event] + " " + hour[event] + "%")
return ", ".join(conditions)
tempint = int(weather["current_condition"][0]["FeelsLikeF"])
extrachar = ""
if tempint > 0 and tempint < 10:
extrachar = "+"
data["text"] = (
""
+ WEATHER_CODES[weather["current_condition"][0]["weatherCode"]]
+ " "
+ extrachar
+ weather["current_condition"][0]["FeelsLikeF"]
+ "°F"
)
data["tooltip"] = (
f"<b>{weather['current_condition'][0]['weatherDesc'][0]['value']} {weather['current_condition'][0]['temp_F']}°</b>\n"
)
data["tooltip"] += f"Feels like: {weather['current_condition'][0]['FeelsLikeF']}°\n"
data["tooltip"] += f"Wind: {weather['current_condition'][0]['windspeedMiles']}mph\n"
data["tooltip"] += f"Humidity: {weather['current_condition'][0]['humidity']}%\n"
data["tooltip"] += f"Moon phase: {weather["weather"][0]['astronomy'][0]['moon_phase']} " + moon + "\n"
for i, day in enumerate(weather["weather"]):
data["tooltip"] += f"\n<b>"
if i == 0:
data["tooltip"] += "Today, "
if i == 1:
data["tooltip"] += "Tomorrow, "
date = datetime.strptime(day['date'], "%Y-%m-%d").strftime("%a %b %d %Y")
data["tooltip"] += f"{date}</b>\n"
data["tooltip"] += f"{day['maxtempF']}°F  {day['mintempF']}°F"
data[
"tooltip"
] += f"{day['astronomy'][0]['sunrise']}{day['astronomy'][0]['sunset']}\n"
for hour in day["hourly"]:
if i == 0:
if int(format_24_time(hour["time"])) < datetime.now().hour - 2:
continue
if int(format_24_time(hour["time"])) > datetime.strptime(day['astronomy'][0]['sunset'], "%I:%M %p").hour or int(format_24_time(hour["time"])) < datetime.strptime(day['astronomy'][0]['sunrise'], "%I:%M %p").hour:
codes = WEATHER_CODES_WI_NIGHT
else:
codes = WEATHER_CODES_WI_DAY
data[
"tooltip"
] += f"{format_time(hour['time'])} {codes[hour['weatherCode']]} {format_temp(hour['FeelsLikeF'])} {hour['weatherDesc'][0]['value']}, {format_chances(hour)}\n"
print(json.dumps(data))

View File

@@ -0,0 +1,166 @@
@import "macchiato.css";
* {
border: none;
border-radius: 0;
font-family:
Jetbrains Mono Nerd Font,
monospace;
font-weight: bold;
font-size: 14px;
min-height: 0;
}
#window.waybar {
background-color: shade(@base, 0.9);
color: @text;
}
#tooltip {
background: #1e1e2e;
border-radius: 10px;
border-width: 2px;
border-style: solid;
border-color: #11111b;
}
#workspaces button {
padding: 5px;
color: #313244;
margin-right: 5px;
}
#workspaces button.active {
color: #a6adc8;
}
#workspaces button.focused {
color: #a6adc8;
background: #eba0ac;
border-radius: 10px;
}
#workspaces button.urgent {
color: #11111b;
background: #a6e3a1;
border-radius: 10px;
}
#workspaces button:hover {
background: #11111b;
color: #cdd6f4;
border-radius: 10px;
}
/*#window,
#custom-weather,
#clock,
#network,
#pulseaudio,
#keyboard-state,
#temperature,
#custom-updates,
#tray,
#workspaces,*/
#workspaces {
/* background: #1e1e2e; */
background: #1e2030; /* Mantle */
border-radius: 10px;
margin-left: 10px;
padding-right: 0px;
padding-left: 5px;
}
#tray {
border-radius: 10px;
margin-right: 10px;
}
/* ------------- */
#custom-updates {
color: #f5c2e7;
border-radius: 10px 0px 0px 10px;
border-left: 0px;
border-right: 0px;
}
#window {
border-radius: 10px;
margin-left: 60px;
margin-right: 60px;
}
#temperature {
color: #a6da95;/* Green */
border-left: 0px;
border-right: 0px;
}
#temperature.gpu {
color: #eed49f;/* Yellow */
border-left: 0px;
border-right: 0px;
}
#keyboard-state.capslock {
color: #f5a97f;/* Peach */
border-left: 0px;
border-right: 0px;
}
#keyboard-state.numlock {
color: #ee99a0;/* Maroon */
border-left: 0px;
border-right: 0px;
}
#pulseaudio {
color: #ed8796;/* Red */
border-radius: 0px 0px 0px 0px;
border-left: 0px;
border-right: 0px;
margin-left: 0px;
padding-right: 0px;
padding-top: 0px;
}
#pulseaudio.microphone {
color: #c6a0f6; /* Mauve */
border-radius: 0px 10px 10px 0px;
border-left: 0px;
border-right: 0px;
padding-top: 5px;
}
/* ------------- */
#network {
color: #f5bde6; /* Pink */
border-left: 0px;
border-right: 0px;
border-radius: 10px 10px 10px 10px;
margin-left: 5px;
padding-right: 15px;
}
/* ------------- */
#clock {
color: #f0c6c6; /* Flamingo */
border-radius: 10px 0px 0px 10px;
margin-left: 5px;
border-right: 0px;
}
#custom-weather {
color: #f4dbd6; /* Rosewater */
border-radius: 0px 10px 10px 0px;
border-right: 0px;
margin-left: 0px;
}