-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(package/weather): Version 1.0 of weather package #108
base: develop
Are you sure you want to change the base?
Changes from all commits
024b234
9b35f20
37e8416
ec8f4d6
24bd798
fa35df9
833144a
f5197ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
config/configuration25.sample.py |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
#!/usr/bin/env python | ||
# -*- coding:utf-8 -*- | ||
|
||
import functools | ||
|
||
import utils | ||
|
||
from tzlocal import get_localzone | ||
from pyowm import OWM | ||
|
||
|
||
# Decorators | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should avoid "useless" comments. |
||
|
||
def load_config(func): | ||
@functools.wraps(func) | ||
def wrapper_load_config(string, entities): | ||
payload = dict() | ||
payload["string"] = string | ||
payload["entities"] = entities | ||
|
||
api_key = utils.config("api_key") | ||
pro = utils.config("pro") | ||
payload["temperature_units"] = utils.config("temperature_units") | ||
payload["wind_speed_units"] = utils.config("wind_speed_units") | ||
|
||
if ( | ||
(payload["temperature_units"] != "celsius") | ||
and (payload["temperature_units"] != "fahrenheit") | ||
): | ||
return utils.output( | ||
"end", | ||
"invalid_temperature_units", | ||
utils.translate("invalid_temperature_units") | ||
) | ||
|
||
if payload["wind_speed_units"] == "meters per seconds": | ||
payload["wind_speed_units_response"] = payload["wind_speed_units"] | ||
payload["wind_speed_units"] = "meters_sec" | ||
elif payload["wind_speed_units"] == "miles per hour": | ||
payload["wind_speed_units_response"] = payload["wind_speed_units"] | ||
payload["wind_speed_units"] = "miles_hour" | ||
else: | ||
return utils.output( | ||
"end", | ||
"invalid_wind_speed_units", | ||
utils.translate("invalid_wind_speed_units") | ||
) | ||
|
||
if pro: | ||
payload["owm"] = OWM(api_key, subscription_type="pro") | ||
else: | ||
payload["owm"] = OWM(api_key) | ||
|
||
return func(payload) | ||
return wrapper_load_config | ||
|
||
|
||
def acquire_weather(func): | ||
@functools.wraps(func) | ||
def wrapper_acquire_weather(payload): | ||
for item in payload["entities"]: | ||
if item["entity"] == "city": | ||
utils.output( | ||
"inter", | ||
"acquiring", | ||
utils.translate("acquiring") | ||
) | ||
|
||
payload["city"] = item["sourceText"].title() | ||
payload["observation"] = payload["owm"].weather_at_place(payload["city"]) | ||
payload["wtr"] = payload["observation"].get_weather() | ||
|
||
return func(payload) | ||
return utils.output( | ||
"end", | ||
"request_error", | ||
utils.translate("request_error") | ||
) | ||
|
||
return wrapper_acquire_weather | ||
|
||
|
||
# Methods | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, we should avoid that sort of comment. |
||
|
||
@load_config | ||
@acquire_weather | ||
def current_weather(payload): | ||
""" | ||
Get the current weather. | ||
""" | ||
|
||
detailed_status = payload["wtr"].get_detailed_status() | ||
temperatures = payload["wtr"].get_temperature(payload["temperature_units"]) | ||
humidity = payload["wtr"].get_humidity() | ||
|
||
return utils.output( | ||
"end", | ||
"current_weather", | ||
utils.translate( | ||
"current_weather", | ||
{ | ||
"detailed_status": detailed_status.capitalize(), | ||
"city": payload["city"], | ||
"temperature": temperatures["temp"], | ||
"temperature_units": payload["temperature_units"].capitalize(), | ||
"humidity": humidity | ||
} | ||
) | ||
) | ||
|
||
|
||
@load_config | ||
@acquire_weather | ||
def temperature(payload): | ||
""" | ||
Get the current temperature. | ||
""" | ||
|
||
temperatures = payload["wtr"].get_temperature(payload["temperature_units"]) | ||
|
||
return utils.output( | ||
"end", | ||
"temperature", | ||
utils.translate( | ||
"temperature", | ||
{ | ||
"city": payload["city"], | ||
"temperature": temperatures["temp"], | ||
"temperature_units": payload["temperature_units"].capitalize() | ||
} | ||
) | ||
) | ||
|
||
|
||
@load_config | ||
@acquire_weather | ||
def humidity(payload): | ||
""" | ||
Get the current humidity. | ||
""" | ||
|
||
humidity = payload["wtr"].get_humidity() | ||
|
||
return utils.output( | ||
"end", | ||
"humidity", | ||
utils.translate( | ||
"humidity", | ||
{ | ||
"city": payload["city"], | ||
"humidity": humidity | ||
} | ||
) | ||
) | ||
|
||
|
||
@load_config | ||
@acquire_weather | ||
def wind(payload): | ||
""" | ||
Get the current wind speed and direction. | ||
""" | ||
|
||
wind = payload["wtr"].get_wind(payload["wind_speed_units"]) | ||
|
||
return utils.output( | ||
"end", | ||
"wind", | ||
utils.translate( | ||
"wind", | ||
{ | ||
"city": payload["city"], | ||
"wind_speed": wind["speed"], | ||
"wind_speed_units_response": payload["wind_speed_units_response"], | ||
"wind_direction": wind["deg"] | ||
} | ||
) | ||
) | ||
|
||
|
||
@load_config | ||
@acquire_weather | ||
def sunrise(payload): | ||
""" | ||
Get when the sun rises. | ||
""" | ||
|
||
dt = payload["wtr"].get_sunrise_time("date") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should avoid abbreviations in variable names. |
||
dt = dt.astimezone(get_localzone()) | ||
|
||
return utils.output( | ||
"end", | ||
"sunrise", | ||
utils.translate( | ||
"sunrise", | ||
{"time": dt.strftime("%H:%M:%S"), "city": payload["city"]} | ||
) | ||
) | ||
|
||
|
||
@load_config | ||
@acquire_weather | ||
def sunset(payload): | ||
""" | ||
Get when the sun sets. | ||
""" | ||
|
||
dt = payload["wtr"].get_sunset_time("date") | ||
dt = dt.astimezone(get_localzone()) | ||
|
||
return utils.output( | ||
"end", | ||
"sunset", | ||
utils.translate( | ||
"sunset", | ||
{"time": dt.strftime("%H:%M:%S"), "city": payload["city"]} | ||
) | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Weather Package | ||
|
||
The weather package contains modules which include getting the latest weather forecast. | ||
|
||
## Modules | ||
|
||
### OpenWeatherMap | ||
|
||
#### Requirements | ||
- tzlocal | ||
- PyOWM | ||
|
||
#### Usage | ||
|
||
1. Register a new account on [OpenWeatherMap Sign Up](https://openweathermap.org/sign_up) unless you already have one. | ||
2. Generate a new API key on [OpenWeatherMap API keys](https://home.openweathermap.org/api_keys). | ||
3. Duplicate the file `packages/weather/config/config.sample.json` and rename it `config.json`. | ||
4. Copy the API key in `packages/weather/config/config.json` and set the other options to your liking. | ||
5. This package uses PyOWM. To install it: from inside leon directory `cd bridges/python` | ||
6. `pipenv install tzlocal pyowm` | ||
7. Done! | ||
|
||
``` | ||
(en-US) | ||
- "What's the weather like in Milan?" | ||
- "When is the sun going to set in Rome?" | ||
- "Is it windy in Chicago?" | ||
|
||
(it-IT) | ||
- "Che tempo fa a Milano?" | ||
- "Quando tramonta il sole a Roma?" | ||
... | ||
``` | ||
|
||
#### Options | ||
- `pro`: Set this to `true` if you have a premium subscription. | ||
- `temperature_units`: Choose which temperature scale to use. ["celsius", "fahrenheit"] | ||
- `wind_speed_units`: Choose which units to use for the wind speed. ["meters per second", "miles per hour"] More units coming soon. | ||
|
||
#### Links | ||
|
||
- [OpenWeatherMap API](https://developers.google.com/youtube/v3/getting-started) | ||
- [PyOWM GitHub](https://github.com/csparpa/pyowm) | ||
- [PyOWM Docs](https://pyowm.readthedocs.io/en/latest/) | ||
|
||
#### TODO | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should not use "Todo" inside markdown files, instead it would be GitHub issues or Trello Card. What do you think? |
||
- Implement some sort of caching mechanism. PyOWM does support caching, but it's a bit messy. It might be easier to implement it from scratch, perhaps with some sort of db like TinyDb which is already supported by leon. | ||
- Implement `pro` functionality for OWM. | ||
- Add more weather services and related (UV, pollution, sky events, etc.). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"OpenWeatherMap": { | ||
"api_key": "YOUR_OPEN_WEATHER_MAP_TOKEN", | ||
"pro": false, | ||
"temperature_units": "celsius", | ||
"wind_speed_units": "meters per seconds", | ||
"options": {} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is quite old, before we merge, we should use the latest versions of the dependencies used in this package.
Currently the latest version of
pyowm
is3.2.0
andtzlocal
is2.1.0
.