meteo_france: add plugin
Also remove the silly Python 3.7 requirement.
This commit is contained in:
parent
6256975f90
commit
3a756a7489
3
Pipfile
3
Pipfile
|
@ -8,6 +8,3 @@ verify_ssl = true
|
|||
[packages]
|
||||
irc = "*"
|
||||
requests = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.7"
|
||||
|
|
116
Pipfile.lock
generated
116
Pipfile.lock
generated
|
@ -1,12 +1,10 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "b9ea2a09600a7aba7d67761e0e8338ba3711a93442f9be86e950621b70be216f"
|
||||
"sha256": "cd3456f770a7bd477ad79cd1ce56fd05fb3e3b08167b430021c3aee8fa4b3fcf"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.7"
|
||||
},
|
||||
"requires": {},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
|
@ -18,32 +16,26 @@
|
|||
"default": {
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3",
|
||||
"sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"
|
||||
"sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee",
|
||||
"sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"
|
||||
],
|
||||
"version": "==2020.6.20"
|
||||
"version": "==2021.5.30"
|
||||
},
|
||||
"chardet": {
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
"sha256:7098e7e862f6370a2a8d1a6398cd359815c45d12626267652c3f13dec58e2367",
|
||||
"sha256:fa471a601dfea0f492e4f4fca035cd82155e65dc45c9b83bf4322dfab63755dd"
|
||||
],
|
||||
"version": "==3.0.4"
|
||||
"markers": "python_version >= '3'",
|
||||
"version": "==2.0.5"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6",
|
||||
"sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"
|
||||
"sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a",
|
||||
"sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"
|
||||
],
|
||||
"version": "==2.10"
|
||||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da",
|
||||
"sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"
|
||||
],
|
||||
"markers": "python_version < '3.8'",
|
||||
"version": "==2.0.0"
|
||||
"markers": "python_version >= '3'",
|
||||
"version": "==3.2"
|
||||
},
|
||||
"irc": {
|
||||
"hashes": [
|
||||
|
@ -55,95 +47,81 @@
|
|||
},
|
||||
"jaraco.classes": {
|
||||
"hashes": [
|
||||
"sha256:116429c2047953f525afdcae165475c4589c7b14870e78b2d068ecb01018827e",
|
||||
"sha256:c38698ff8ef932eb33d91c0e8fc192ad7c44ecee03f7f585afd4f35aeaef7aab"
|
||||
"sha256:22ac35313cf4b145bf7b217cc51be2d98a3d2db1c8558a30ca259d9f0b9c0b7d",
|
||||
"sha256:ed54b728af1937dc16b7236fbaf34ba561ba1ace572b03fffa5486ed363ecf34"
|
||||
],
|
||||
"version": "==3.1.0"
|
||||
"version": "==3.2.1"
|
||||
},
|
||||
"jaraco.collections": {
|
||||
"hashes": [
|
||||
"sha256:a7889f28c80c4875bd6256d9924e8526dacfef22cd7b80ff8469b4d312f9f144",
|
||||
"sha256:be570ef4f2e7290b757449395238fa63d70a9255574624e73c5ff9f1ee554721"
|
||||
"sha256:344d14769d716e7496af879ac71b3c6ebdd46abc64bd9ec21d15248365aa3ac9",
|
||||
"sha256:6fdf48b6268d44b589a9d7359849f5c4ea6447b59845e489da261996fbc41b79"
|
||||
],
|
||||
"version": "==3.0.0"
|
||||
"version": "==3.4.0"
|
||||
},
|
||||
"jaraco.functools": {
|
||||
"hashes": [
|
||||
"sha256:9fedc4be3117512ca3e03e1b2ffa7a6a6ffa589bfb7d02bfb324e55d493b94f4",
|
||||
"sha256:d3dc9f6c1a1d45d7f59682a3bf77aceb685c1a60891606c7e4161e72ecc399ad"
|
||||
"sha256:7c788376d69cf41da675b186c85366fe9ac23c92a70697c455ef9135c25edf31",
|
||||
"sha256:bfcf7da71e2a0e980189b0744b59dba6c1dcf66dcd7a30f8a4413e478046b314"
|
||||
],
|
||||
"version": "==3.0.1"
|
||||
"version": "==3.3.0"
|
||||
},
|
||||
"jaraco.logging": {
|
||||
"hashes": [
|
||||
"sha256:31716fe84d3d5df39d95572942513bd4bf8ae0a478f64031eff4c2ea9e83434e",
|
||||
"sha256:b05ed07101883997a30e05c2472798d86129803d9961a0d1081a3236ad37c52a"
|
||||
"sha256:150dc8701207b28bc65a16f0e91c07250a8d1b9da324ce674c0e375774944f13",
|
||||
"sha256:ec4720a1ed8d7e4667a5f0178c4864df1a2f085aad5ba47355c41fcb2f9d68cd"
|
||||
],
|
||||
"version": "==3.0.0"
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"jaraco.stream": {
|
||||
"hashes": [
|
||||
"sha256:287e1cba9f278e0146fdded6bc40518930813a5584579769aeaa1d0bfd178a73",
|
||||
"sha256:a42357141288bbd55938b9ff464173c078038374ce5ffa1bf31895138acc0f30"
|
||||
"sha256:0ede0988de595d15a72fa95f1eec4dee20fdede30e8d2ddee1b9c2a963eb67ef",
|
||||
"sha256:86c57fedffd4d5a4b18817f99ddf62ac8ed0a1bc31a1c41b9a88df9c6bb56e0b"
|
||||
],
|
||||
"version": "==3.0.0"
|
||||
"version": "==3.0.2"
|
||||
},
|
||||
"jaraco.text": {
|
||||
"hashes": [
|
||||
"sha256:c87569c9afae14f71b2e1c57f316770ab6981ab675d9c602be1c7981161bacdd",
|
||||
"sha256:e5078b1126cc0f166c7859aa75103a56c0d0f39ebcafc21695615472e0f810ec"
|
||||
"sha256:dc900b7916cefdaf943fbd43870abc8b0a6ff68f2c8c33e212fd51139219f68d",
|
||||
"sha256:ede4e9103443b62b3d1d193257dfb85aab7c69a6cef78a0887d64bb307a03bc3"
|
||||
],
|
||||
"version": "==3.2.0"
|
||||
"version": "==3.5.1"
|
||||
},
|
||||
"more-itertools": {
|
||||
"hashes": [
|
||||
"sha256:6f83822ae94818eae2612063a5101a7311e68ae8002005b5e05f03fd74a86a20",
|
||||
"sha256:9b30f12df9393f0d28af9210ff8efe48d10c94f73e5daf886f10c4b0b0b4f03c"
|
||||
"sha256:70401259e46e216056367a0a6034ee3d3f95e0bf59d3aa6a4eb77837171ed996",
|
||||
"sha256:8c746e0d09871661520da4f1241ba6b908dc903839733c8203b552cffaf173bd"
|
||||
],
|
||||
"version": "==8.5.0"
|
||||
"version": "==8.9.0"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed",
|
||||
"sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"
|
||||
"sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da",
|
||||
"sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"
|
||||
],
|
||||
"version": "==2020.1"
|
||||
"version": "==2021.1"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b",
|
||||
"sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898"
|
||||
"sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24",
|
||||
"sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.24.0"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
|
||||
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
|
||||
],
|
||||
"version": "==1.15.0"
|
||||
"version": "==2.26.0"
|
||||
},
|
||||
"tempora": {
|
||||
"hashes": [
|
||||
"sha256:599a3a910b377f2b544c7b221582ecf4cb049b017c994b37f2b1a9ed1099716e",
|
||||
"sha256:9f46de767be7dd21d9602a8a5b0978fd55abc70af3e2a7814c85c00d7a8fffa3"
|
||||
"sha256:c54da0f05405f04eb67abbb1dff4448fd91428b58cb00f0f645ea36f6a927950",
|
||||
"sha256:ef2d8bb35902d5ea7da95df33456685a6d305b97f311725c12e55c13d85c0938"
|
||||
],
|
||||
"version": "==4.0.0"
|
||||
"version": "==4.1.1"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a",
|
||||
"sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461"
|
||||
"sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4",
|
||||
"sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"
|
||||
],
|
||||
"version": "==1.25.10"
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:64ad89efee774d1897a58607895d80789c59778ea02185dd846ac38394a8642b",
|
||||
"sha256:eed8ec0b8d1416b2ca33516a37a08892442f3954dee131e92cfd92d8fe3e7066"
|
||||
],
|
||||
"version": "==3.3.0"
|
||||
"version": "==1.26.6"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
|
|
|
@ -62,6 +62,21 @@
|
|||
"commands": ["journée mondiale"],
|
||||
"url": "https://www.journee-mondiale.com/"
|
||||
},
|
||||
"meteofrance": {
|
||||
"commands": ["météo"],
|
||||
"aliases": {
|
||||
"météo": ["meteo"]
|
||||
},
|
||||
"result_message": "{nearest_s}; {today_s}.",
|
||||
"nearest_message": "({city} @ {hour}) {weather}, {temp}, {wind} and {rain}",
|
||||
"temp_format": "{temp_c}°C (windchill {temp_wc})",
|
||||
"wind_format": "wind {speed} km/h to {direction}",
|
||||
"unknown_direction": "unknown",
|
||||
"rain_chance_format": "{p}% over {h}",
|
||||
"all_rain_format": "rain chances {all_percs}",
|
||||
"today_message": "today {temp_minmax}, {rain}, and sunset at {sunset}",
|
||||
"minmax_temp_format": "max {t_max} min {t_min}"
|
||||
},
|
||||
"miscreactions": {
|
||||
"reactions": [
|
||||
"stop", "king", "mmm", "ooo", "detector", "question_marks",
|
||||
|
|
107
edmond/plugins/meteo_france.py
Normal file
107
edmond/plugins/meteo_france.py
Normal file
|
@ -0,0 +1,107 @@
|
|||
import time
|
||||
|
||||
try:
|
||||
import meteofrance_api as mf
|
||||
DEPENDENCIES_FOUND = True
|
||||
except ImportError:
|
||||
DEPENDENCIES_FOUND = False
|
||||
|
||||
from edmond.plugin import Plugin
|
||||
|
||||
|
||||
class MeteoFrancePlugin(Plugin):
|
||||
|
||||
REQUIRED_CONFIGS = [
|
||||
"commands", "result_message", "nearest_message", "temp_format",
|
||||
"rain_chance_format", "all_rain_format", "today_message",
|
||||
"minmax_temp_format"
|
||||
]
|
||||
|
||||
def __init__(self, bot):
|
||||
super().__init__(bot)
|
||||
self.client = None
|
||||
|
||||
def on_welcome(self, event):
|
||||
self.client = mf.MeteoFranceClient()
|
||||
|
||||
def on_pubmsg(self, event):
|
||||
if not self.should_handle_command(event.arguments[0]):
|
||||
return False
|
||||
if self.command.ident == self.config["commands"][0]:
|
||||
self.tell_weather(event)
|
||||
return True
|
||||
|
||||
def tell_weather(self, event):
|
||||
places = self.client.search_places(self.command.content)
|
||||
if not places:
|
||||
self.signal_failure(event.target)
|
||||
return
|
||||
place = places[0] # Assume first result is the good one.
|
||||
|
||||
try:
|
||||
forecast = self.client.get_forecast_for_place(place)
|
||||
except: # really unsure about that unofficial API
|
||||
self.signal_failure(event.target)
|
||||
return
|
||||
|
||||
nearest_f = forecast.nearest_forecast
|
||||
today_f = forecast.today_forecast
|
||||
try:
|
||||
nearest_s = self.format_nearest_forecast(nearest_f, place)
|
||||
today_s = self.format_today_forecast(today_f)
|
||||
except KeyError:
|
||||
self.signal_failure(event.target)
|
||||
return
|
||||
|
||||
result = self.config["result_message"].format(
|
||||
nearest_s=nearest_s, today_s=today_s)
|
||||
self.bot.say(event.target, result)
|
||||
|
||||
def format_nearest_forecast(self, nearest, place):
|
||||
city = place.name
|
||||
hour = format_ts_hour(nearest["dt"])
|
||||
temp = self.format_temperature(nearest["T"])
|
||||
weather = format_weather(nearest["weather"])
|
||||
wind = self.format_wind(nearest["wind"])
|
||||
rain = self.format_rain_perc(nearest["rain"])
|
||||
return self.config["nearest_message"].format(
|
||||
city=city, hour=hour, weather=weather, temp=temp, wind=wind,
|
||||
rain=rain
|
||||
)
|
||||
|
||||
def format_temperature(self, temperature):
|
||||
temp_c = temperature.get("value", "?")
|
||||
temp_wc = temperature.get("windchill", "?")
|
||||
return self.config["temp_format"].format(
|
||||
temp_c=temp_c, temp_wc=temp_wc)
|
||||
|
||||
def format_rain_perc(self, rain_percs):
|
||||
perc_fmt = self.config["rain_chance_format"]
|
||||
all_percs = ', '.join(
|
||||
perc_fmt.format(p=p, h=h)
|
||||
for h, p in rain_percs.items()
|
||||
)
|
||||
return self.config["all_rain_format"].format(all_percs=all_percs)
|
||||
|
||||
def format_wind(self, wind):
|
||||
speed = wind.get('speed')
|
||||
direction = wind.get('icon')
|
||||
if direction == "Variable":
|
||||
direction = self.config["unknown_direction"]
|
||||
return self.config["wind_format"].format(
|
||||
speed=speed, direction=direction)
|
||||
|
||||
def format_today_forecast(self, today_f):
|
||||
temp = today_f['T']
|
||||
temp_minmax = self.config["minmax_temp_format"].format(
|
||||
t_max=temp["max"], t_min=temp["min"])
|
||||
rain = self.format_rain_perc(today_f['precipitation'])
|
||||
sunset = format_ts_hour(today_f['sun']['set'])
|
||||
return self.config["today_message"].format(
|
||||
temp_minmax=temp_minmax, rain=rain, sunset=sunset)
|
||||
|
||||
def format_ts_hour(timestamp):
|
||||
return time.strftime("%H:%M", time.localtime(timestamp))
|
||||
|
||||
def format_weather(weather):
|
||||
return weather.get("desc", "?").lower()
|
|
@ -15,3 +15,6 @@ scaruffi==0.0.3
|
|||
|
||||
# WolframAlpha
|
||||
wolframalpha
|
||||
|
||||
# Météo France
|
||||
meteofrance-api~=1.0.2
|
||||
|
|
Loading…
Reference in a new issue