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,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))