#!/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"{weather['current_condition'][0]['weatherDesc'][0]['value']} {weather['current_condition'][0]['temp_F']}°\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" 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}\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))