init
This commit is contained in:
commit
598bfe812b
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2023 thetek <mail@thetek.de>
|
||||
|
||||
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.
|
|
@ -0,0 +1,58 @@
|
|||
# waybar-weather
|
||||
|
||||
A simple weather module for Waybar based on data from OpenWeatherMap that also
|
||||
comes with a handy CLI.
|
||||
|
||||
## Preview
|
||||
|
||||
<center>
|
||||
![preview](preview.png)
|
||||
</center>
|
||||
|
||||
## Usage
|
||||
|
||||
### Initial Steps
|
||||
|
||||
1. Obtain a valid API key from OpenWeatherMap (the free tier is enough)
|
||||
2. Change the `API_KEY` variable in the script to your API key
|
||||
3. Get the coordinates of the place you want to receive the data for by running
|
||||
`./weather.py geocoding <city[,state][,country]>` with an appropriate search
|
||||
term, e.g. `./weather.py geocoding London,CA` for London, Canada.
|
||||
4. Change the `LATITUDE` and `LONGITUDE` variables in the script to the values
|
||||
received in the previous step
|
||||
|
||||
### CLI
|
||||
|
||||
The available subcommands for CLI usage, besides the already discussed
|
||||
`geocoding` are:
|
||||
|
||||
- `current`: information about current weather conditions
|
||||
- `forecast[-daily]`: forecast data for the next ~5 days, daily
|
||||
- `forecast-detail`: forecast data for the next ~5 days in 3h intervals
|
||||
|
||||
Sample usage: `./weather.py current`
|
||||
|
||||
### Waybar Integration
|
||||
|
||||
To integrate the weather widget with Waybar, create a custom module:
|
||||
|
||||
```json
|
||||
"custom/weather": {
|
||||
"exec": "~/.config/waybar/weather.py waybar",
|
||||
"restart-interval": 900,
|
||||
"return-type": "json",
|
||||
},
|
||||
```
|
||||
|
||||
Remember to change the path to the `weather.py` script specified within the
|
||||
`exec` field.
|
||||
|
||||
Then, include the `custom/weather` module in your desired module list.
|
||||
|
||||
By default, the module will display the current weather category and
|
||||
temperature in the bar. When hovering the mouse over the widget, a tooltip will
|
||||
pop up with detailed information about the current weather and a forecast for
|
||||
the next ~5 days.
|
||||
|
||||
The colors used within the widget and tooltip may be changed in the
|
||||
`weather.py` script in order to match your colorscheme.
|
Binary file not shown.
After Width: | Height: | Size: 124 KiB |
|
@ -0,0 +1,527 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import requests
|
||||
import statistics
|
||||
import sys
|
||||
|
||||
|
||||
|
||||
# TODO
|
||||
# - snowfall data
|
||||
# - weather warnings
|
||||
|
||||
|
||||
|
||||
### CONSTANTS ###
|
||||
|
||||
# api key - get it at https://openweathermap.org/
|
||||
API_KEY = None
|
||||
|
||||
# latitude and longitude of the city you want to query
|
||||
# can be obtained through `./weather.py geocoding <city[,state,country]>`
|
||||
LATITUDE = None
|
||||
LONGITUDE = None
|
||||
|
||||
# waybar colors
|
||||
GRAY = '#859289'
|
||||
DARK = '#5a6772'
|
||||
GREEN = '#a7c080'
|
||||
YELLOW = '#dbbc7f'
|
||||
ORANGE = '#e69875'
|
||||
RED = '#e67e80'
|
||||
PURPLE = '#d699b6'
|
||||
BLUE = '#7fbbb3'
|
||||
|
||||
|
||||
|
||||
### UTILITIES ###
|
||||
|
||||
def print_error(msg: str):
|
||||
'''
|
||||
print an error message with appropriate prefix.
|
||||
|
||||
@param str: the message to print
|
||||
'''
|
||||
print('\x1b[90m[\x1b[31merr\x1b[90m]\x1b[0m', msg)
|
||||
|
||||
|
||||
def print_help():
|
||||
'''
|
||||
print help message, to be used for the `--help` flag and as response to
|
||||
incorrect usage
|
||||
'''
|
||||
print('usage: \x1b[33m./weather.py <subcommand> [options]\x1b[0m')
|
||||
print()
|
||||
print('available subcommands:')
|
||||
print(' - \x1b[32mgeocoding\x1b[0m <city[,state][,country]> : search for city to get its coordinates')
|
||||
print(' - \x1b[32mcurrent\x1b[0m : print current weather information')
|
||||
print(' - \x1b[32mforecast[-daily]\x1b[0m : print forecast for the next ~5 days')
|
||||
print(' - \x1b[32mforecast-detail\x1b[0m : print detailed forecast in 3h intervals')
|
||||
print(' - \x1b[32mwaybar\x1b[0m : get output for usage with waybar')
|
||||
|
||||
|
||||
def make_request(call: str) -> list | dict:
|
||||
'''
|
||||
make a request to an openweathermap api and returns the response as either
|
||||
a list or a dictionary. the api key is added automatically. quits on error.
|
||||
|
||||
@param call: the api path, e.g. `data/2.5/weather?...`
|
||||
|
||||
@return response of the api request as a list or dict
|
||||
'''
|
||||
try:
|
||||
req = requests.get(f'https://api.openweathermap.org/{call}&appid={API_KEY}')
|
||||
return req.json()
|
||||
except:
|
||||
print_error(f'failed to make request to `/{call}`')
|
||||
quit(1)
|
||||
|
||||
|
||||
def get_wind_direction(deg: int) -> str:
|
||||
'''
|
||||
turn a wind direction specified by meteorological degrees into a
|
||||
human-readable form
|
||||
|
||||
@param deg: degrees. expected to be in range [0..360]
|
||||
|
||||
@return human-readable form (e.g. 'NE' for `deg == 45`)
|
||||
'''
|
||||
if deg < 22.5: return 'N'
|
||||
if deg < 67.5: return 'NE'
|
||||
if deg < 112.5: return 'E'
|
||||
if deg < 157.5: return 'SE'
|
||||
if deg < 202.5: return 'S'
|
||||
if deg < 247.5: return 'SW'
|
||||
if deg < 292.5: return 'W'
|
||||
if deg < 337.5: return 'NW'
|
||||
else: return 'N'
|
||||
|
||||
|
||||
def print_entry(label: str, content: str, indent: int = 0, label_width: int = 8):
|
||||
'''
|
||||
print an 'entry' that consists of a label (printed in gray) and some
|
||||
content. the labels are automatically filled with whitespace to align
|
||||
multiple lines properly.
|
||||
|
||||
@param label: the label of the line
|
||||
@param content: content, printed after the label
|
||||
@param indent: number of spaces to indent with
|
||||
@param label_width: width of label
|
||||
'''
|
||||
label_with_whitespace = label.ljust(label_width)
|
||||
print(f'{" " * indent}\x1b[90m{label_with_whitespace}\x1b[0m {content}')
|
||||
|
||||
|
||||
def get_weekday(date: str) -> str:
|
||||
'''
|
||||
get weekday from date
|
||||
|
||||
@param date: date as ISO-8601-formatted string (YYYY-mm-dd)
|
||||
|
||||
@return weekday as lowercase string (e.g. 'monday')
|
||||
'''
|
||||
return datetime.datetime.strptime(date, '%Y-%m-%d').strftime('%A').lower()
|
||||
|
||||
|
||||
def colorize(text: str, color: str) -> str:
|
||||
'''
|
||||
wrap `text` with pango markup to colorize it for usage with waybar.
|
||||
|
||||
@param text: the text to colorize
|
||||
@param color: the color as string ('#rrggbb')
|
||||
'''
|
||||
return f'<span foreground="{color}">{text}</span>'
|
||||
|
||||
|
||||
def waybar_entry(label: str, content: str, indent: int = 2, label_width: int = 9):
|
||||
'''
|
||||
create an 'entry' for a waybar tooltip that consists of a label (printed in
|
||||
gray) and some content. the labels are automatically filled with whitespace
|
||||
to align multiple lines properly.
|
||||
|
||||
@param label: the label of the line
|
||||
@param content: content, printed after the label
|
||||
@param indent: number of spaces to indent with
|
||||
@param label_width: width of label
|
||||
|
||||
@return the entry for use within waybar
|
||||
'''
|
||||
|
||||
label_with_whitespace = label.ljust(label_width)
|
||||
return f'{" " * indent}{colorize(label_with_whitespace, GRAY)} {content}\n'
|
||||
|
||||
|
||||
|
||||
### GEOCODING ###
|
||||
|
||||
def geocoding(search: str):
|
||||
'''
|
||||
call openweathermap's geocoding api to find the coordinates of cities. can
|
||||
be used to find the values required for the `LATITUDE` and `LONGITUDE`
|
||||
constants within this script. the results are printed.
|
||||
|
||||
@param: search term in the format 'city[,state][,country]'
|
||||
'''
|
||||
|
||||
res = make_request(f'geo/1.0/direct?q={search}&limit=5')
|
||||
num_results = len(res)
|
||||
|
||||
if (num_results == 0):
|
||||
print_error('no results found')
|
||||
else:
|
||||
print(f'found {num_results} result{"" if num_results == 1 else "s"}:')
|
||||
for entry in res:
|
||||
# obtain data
|
||||
name = entry['name']
|
||||
state = entry['state'] if 'state' in entry.keys() else None
|
||||
country = entry['country']
|
||||
latitude = entry['lat']
|
||||
longitude = entry['lon']
|
||||
|
||||
# print data
|
||||
print(f' - \x1b[32m{name}\x1b[90m',
|
||||
f'({f"{state}, " if state else ""}{country})\x1b[0m:',
|
||||
f'latitude = \x1b[35m{latitude}\x1b[0m,',
|
||||
f'longitude = \x1b[35m{longitude}\x1b[0m')
|
||||
|
||||
|
||||
### CURRENT WEATHER ###
|
||||
|
||||
def get_current_weather_data() -> dict:
|
||||
'''
|
||||
get current weather data from openweathermap api. when the `rain` is not
|
||||
set (due to there not being any rain), it will be added with a rain amount
|
||||
of 0 mm over the last hour.
|
||||
|
||||
@return api response
|
||||
'''
|
||||
|
||||
res = make_request(f'data/2.5/weather?lat={LATITUDE}&lon={LONGITUDE}&units=metric')
|
||||
|
||||
if 'rain' not in res.keys():
|
||||
res['rain'] = { '1h': 0 }
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def current_weather():
|
||||
'''
|
||||
print current weather information
|
||||
'''
|
||||
|
||||
data = get_current_weather_data()
|
||||
|
||||
# collect relevant data
|
||||
weather = data['weather'][0]['description'].lower()
|
||||
temperature = round(data['main']['temp'], 1)
|
||||
temperature_felt = round(data['main']['feels_like'], 1)
|
||||
humidity = data['main']['humidity']
|
||||
wind_speed = round(data['wind']['speed'], 1)
|
||||
wind_direction = get_wind_direction(data['wind']['deg'])
|
||||
rainfall = data['rain']['1h']
|
||||
|
||||
# print data
|
||||
print_entry('weather', f'\x1b[32m{weather}\x1b[0m')
|
||||
print_entry('temp', f'\x1b[33m{temperature} °C\x1b[90m, feels like \x1b[33m{temperature_felt} °C\x1b[0m')
|
||||
print_entry('humidity', f'\x1b[31m{humidity} % RH\x1b[0m')
|
||||
print_entry('wind', f'\x1b[35m{wind_speed} m/s\x1b[90m ({wind_direction})\x1b[0m')
|
||||
print_entry('rain', f'\x1b[34m{rainfall} mm\x1b[0m')
|
||||
|
||||
|
||||
|
||||
### FORECAST ###
|
||||
|
||||
def get_forecast_data() -> dict:
|
||||
'''
|
||||
get forecast data for the next ~5 days from the openweathermap api, with
|
||||
data points separated by 3 hours. the data is grouped by date (the api does
|
||||
not group the data by default and instead sends it as one sequence).
|
||||
|
||||
@return api response grouped by date
|
||||
'''
|
||||
|
||||
res = make_request(f'data/2.5/forecast?lat={LATITUDE}&lon={LONGITUDE}&units=metric')
|
||||
|
||||
days = dict()
|
||||
for i in res['list']:
|
||||
day = i['dt_txt'].split(' ')[0]
|
||||
if day not in days.keys():
|
||||
days[day] = list()
|
||||
if 'rain' not in i.keys():
|
||||
i['rain'] = { '3h': 0 }
|
||||
days[day].append(i)
|
||||
|
||||
return days
|
||||
|
||||
|
||||
def get_daily_forecast_data() -> dict[dict]:
|
||||
'''
|
||||
obtain forecast data for the next ~5 days, where values are grouped by day.
|
||||
since the api only provides the data in 3h intervals, the properties of
|
||||
different data points are combined in order to provide appropriate data for
|
||||
each day.
|
||||
|
||||
@return the processed data as a dict with key = date and value = data as
|
||||
another dict
|
||||
'''
|
||||
|
||||
res = get_forecast_data()
|
||||
|
||||
output = dict()
|
||||
|
||||
for day in sorted(res):
|
||||
data = res[day]
|
||||
number_of_data_points = len(data)
|
||||
|
||||
# collect relevant from data for each day
|
||||
temperatures = [i['main']['temp'] for i in data]
|
||||
weather_descriptions = [i['weather'][0]['description'].lower() for i in data]
|
||||
humidity = [i['main']['humidity'] for i in data]
|
||||
rainfall = [i['rain']['3h'] for i in data]
|
||||
precipitation_prob = [i['pop'] for i in data]
|
||||
wind_speeds = [i['wind']['speed'] for i in data]
|
||||
weekday = get_weekday(day)
|
||||
|
||||
# min and max temperature for the day
|
||||
min_temperature = round(min(temperatures))
|
||||
max_temperature = round(max(temperatures))
|
||||
|
||||
# obtain the average weather by finding the weather description with the highest number of occurances in `weather_descriptions`
|
||||
weather_count = {i: weather_descriptions.count(i) for i in set(weather_descriptions)}
|
||||
weather_count_max = max(weather_count.values())
|
||||
weather_average = tuple(filter(lambda x: weather_count[x] == weather_count_max, weather_count.keys()))[0]
|
||||
|
||||
# humidiy
|
||||
humidity_average = round(statistics.mean(humidity))
|
||||
|
||||
# total rainfall and probability of precipitation. also, estimate the total rainfall if not all data points for a day are available
|
||||
rainfall_total = round(sum(rainfall), 1)
|
||||
rainfall_total_estimated = round(rainfall_total / number_of_data_points * 8, 1)
|
||||
max_precipitation_prob = round(max(precipitation_prob) * 100)
|
||||
|
||||
# average wind
|
||||
wind_average = round(statistics.mean(wind_speeds), 1)
|
||||
|
||||
output[day] = {
|
||||
'number_of_data_points': number_of_data_points,
|
||||
'min_temperature': min_temperature,
|
||||
'max_temperature': max_temperature,
|
||||
'weather_average': weather_average,
|
||||
'humidity_average': humidity_average,
|
||||
'rainfall_total': rainfall_total,
|
||||
'rainfall_total_estimated': rainfall_total_estimated,
|
||||
'max_precipitation_prob': max_precipitation_prob,
|
||||
'wind_average': wind_average,
|
||||
'weekday': weekday,
|
||||
}
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def daily_forecast():
|
||||
'''
|
||||
print forecast data for the next ~5 days
|
||||
'''
|
||||
|
||||
daily_data = get_daily_forecast_data()
|
||||
|
||||
for day in sorted(daily_data):
|
||||
data = daily_data[day]
|
||||
|
||||
# only display data point if at least half of the data points are available
|
||||
if data['number_of_data_points'] < 4:
|
||||
continue
|
||||
|
||||
# print data
|
||||
print(f'\x1b[1m{day}\x1b[0m ({data["weekday"]}):')
|
||||
print_entry('weather', f'\x1b[32m{data["weather_average"]}\x1b[0m', indent = 2)
|
||||
print_entry('temp', f'\x1b[33m{data["min_temperature"]} °C\x1b[0m / \x1b[33m{data["max_temperature"]} °C\x1b[0m', indent = 2)
|
||||
print_entry('humidity', f'\x1b[31m{data["humidity_average"]} % RH\x1b[0m', indent = 2)
|
||||
print_entry('wind', f'\x1b[35m{data["wind_average"]} m/s\x1b[0m', indent = 2)
|
||||
print_entry('rain', f'\x1b[34m{data["rainfall_total_estimated"]} mm\x1b[0m' +
|
||||
f'\x1b[90m{f""" ({data["max_precipitation_prob"]}%)""" if data["max_precipitation_prob"] > 0 else ""}' +
|
||||
f'{f" (estimated)" if data["rainfall_total"] != data["rainfall_total_estimated"] else ""}\x1b[0m\n', indent = 2)
|
||||
|
||||
|
||||
|
||||
### DETAILED FORECAST ###
|
||||
|
||||
def detailed_forecast():
|
||||
'''
|
||||
print forecast data for the next ~5 days, where values are printed for
|
||||
every 3h interval provided by the api. some data (e.g. humidity or wind
|
||||
speeds) are omitted.
|
||||
'''
|
||||
|
||||
res = get_forecast_data()
|
||||
|
||||
for day in sorted(res):
|
||||
weekday = get_weekday(day)
|
||||
print(f'\x1b[1m{day}\x1b[0m ({weekday})')
|
||||
|
||||
for entry in res[day]:
|
||||
# collect data
|
||||
weather = entry['weather'][0]['description'].lower()
|
||||
temperature = round(entry['main']['temp'], 1)
|
||||
rainfall = entry['rain']['3h']
|
||||
precipitation_prob = round(entry['pop'] * 100)
|
||||
time = f"{int(entry['dt_txt'].split(' ')[1].split(':')[0]):2}h"
|
||||
|
||||
# print data
|
||||
output = ''
|
||||
output += f'\x1b[33m{temperature:4} °C\x1b[90m, '
|
||||
output += f'\x1b[32m{weather}\x1b[0m'
|
||||
if rainfall > 0:
|
||||
output += f'\x1b[90m: \x1b[34m{rainfall} mm \x1b[90m({precipitation_prob}%)\x1b[0m'
|
||||
print_entry(time, output, indent = 2, label_width = 3)
|
||||
|
||||
print()
|
||||
|
||||
|
||||
|
||||
### WAYBAR ###
|
||||
|
||||
def waybar_widget(data: dict) -> str:
|
||||
'''
|
||||
get the widget component of the waybar output. contains the current weather
|
||||
group and temperature.
|
||||
|
||||
@param current weather data
|
||||
|
||||
@return widget component
|
||||
'''
|
||||
|
||||
weather = data['weather'][0]['main'].lower()
|
||||
temperature = round(data['main']['temp'])
|
||||
|
||||
return f'{colorize(weather, DARK)} {temperature}°'
|
||||
|
||||
|
||||
def waybar_current(data: dict) -> str:
|
||||
'''
|
||||
get the current weather overview for the tooltip of the waybar output.
|
||||
|
||||
@param current weather data
|
||||
|
||||
@return formatted current weather overview
|
||||
'''
|
||||
|
||||
# retrieve relevant data
|
||||
weather = data['weather'][0]['description'].lower()
|
||||
temperature = round(data['main']['temp'], 1)
|
||||
temperature_felt = round(data['main']['feels_like'], 1)
|
||||
humidity = data['main']['humidity']
|
||||
wind_speed = round(data['wind']['speed'], 1)
|
||||
wind_direction = get_wind_direction(data['wind']['deg'])
|
||||
rainfall = data['rain']['1h']
|
||||
|
||||
# generate output
|
||||
output = ''
|
||||
output += waybar_entry('weather', colorize(weather, YELLOW))
|
||||
output += waybar_entry('temp', f'{colorize(f"{temperature} °C", ORANGE)}{colorize(", feels like ", GRAY)}{colorize(f"{temperature_felt} °C", ORANGE)}')
|
||||
output += waybar_entry('humditiy', colorize(f'{humidity} % RH', RED))
|
||||
output += waybar_entry('wind', f'{colorize(f"{wind_speed} m/s", PURPLE)} {colorize(f"({wind_direction})", GRAY)}')
|
||||
output += waybar_entry('rain', colorize(f"{rainfall} mm", BLUE))
|
||||
return output
|
||||
|
||||
|
||||
def waybar_forecast(data: dict) -> str:
|
||||
'''
|
||||
get the daily forecast for the tooltip of the waybar output.
|
||||
|
||||
@param forecast weather data
|
||||
|
||||
@return formatted daily forecast
|
||||
'''
|
||||
|
||||
output = ''
|
||||
|
||||
daily_data = get_daily_forecast_data()
|
||||
|
||||
for day in sorted(daily_data):
|
||||
data = daily_data[day]
|
||||
|
||||
line_content = colorize(f'{data["min_temperature"]:2}°', ORANGE) + \
|
||||
colorize(' / ', GRAY) + \
|
||||
colorize(f'{data["max_temperature"]:2}°', ORANGE) + \
|
||||
colorize(', ', GRAY) + \
|
||||
colorize(data['weather_average'], YELLOW)
|
||||
|
||||
if data['rainfall_total_estimated'] > 0:
|
||||
line_content += colorize(': ', GRAY) + \
|
||||
colorize(f'{data["rainfall_total_estimated"]} mm ', BLUE) + \
|
||||
colorize(f'({data["max_precipitation_prob"]}%)', GRAY)
|
||||
|
||||
output += waybar_entry(data['weekday'], line_content)
|
||||
|
||||
return output.rstrip()
|
||||
|
||||
|
||||
def waybar():
|
||||
'''
|
||||
get current and forecast weather data and output it formatted in a way that
|
||||
allows it to be included as a widget in waybar. only shows weather category
|
||||
and temperature in the widget, but reveals detailed weather information and
|
||||
a ~5 day forecast in the tooltip.
|
||||
'''
|
||||
|
||||
current_data = get_current_weather_data()
|
||||
forecast_data = get_forecast_data()
|
||||
|
||||
widget = waybar_widget(current_data)
|
||||
current = waybar_current(current_data)
|
||||
forecast = waybar_forecast(forecast_data)
|
||||
tooltip = colorize('current weather', GREEN) + '\n' + current + '\n' + \
|
||||
colorize('forecast', GREEN) + '\n' + forecast
|
||||
|
||||
print(json.dumps({
|
||||
'text': widget,
|
||||
'tooltip': tooltip,
|
||||
}))
|
||||
|
||||
|
||||
|
||||
### MAIN ###
|
||||
|
||||
def main():
|
||||
'''
|
||||
main function
|
||||
'''
|
||||
|
||||
# no parameters or `--help`
|
||||
if len(sys.argv) == 1 or sys.argv[1] in ('help', '-h', '--help'):
|
||||
print_help()
|
||||
|
||||
# >= 1 parameter provided
|
||||
else:
|
||||
# geocoding
|
||||
if sys.argv[1] == 'geocoding':
|
||||
if len(sys.argv) == 3:
|
||||
geocoding(sys.argv[2])
|
||||
else:
|
||||
print_error('expected argument `<city[,state][,country]>`')
|
||||
print_help()
|
||||
# constants not set
|
||||
elif API_KEY is None or LATITUDE is None or LONGITUDE is None:
|
||||
print_error('please modify the constants within the script before use.')
|
||||
# current weather
|
||||
elif sys.argv[1] == 'current':
|
||||
current_weather()
|
||||
# daily forecast
|
||||
elif sys.argv[1] == 'forecast' or sys.argv[1] == 'forecast-daily':
|
||||
daily_forecast()
|
||||
# detailed forecast
|
||||
elif sys.argv[1] == 'forecast-detail':
|
||||
detailed_forecast()
|
||||
# waybar
|
||||
elif sys.argv[1] == 'waybar':
|
||||
waybar()
|
||||
# unknown command
|
||||
else:
|
||||
print_error(f'unknown command `{sys.argv[1]}`')
|
||||
print_help()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue