meteo_france: add plugin

Also remove the silly Python 3.7 requirement.
master
dece 3 years ago
parent 6256975f90
commit 3a756a7489

@ -8,6 +8,3 @@ verify_ssl = true
[packages]
irc = "*"
requests = "*"
[requires]
python_version = "3.7"

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"
],
"version": "==2.10"
},
"importlib-metadata": {
"hashes": [
"sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da",
"sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"
"sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a",
"sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"
],
"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",

@ -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…
Cancel
Save