This repository has been archived by the owner on Sep 28, 2022. It is now read-only.
/
weather.py
111 lines (100 loc) · 3.21 KB
/
weather.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
from grazyna.utils import register
from grazyna import format
from grazyna.format import color
from datetime import timedelta, datetime, timezone
from aiohttp import request
import re
URL_API = 'http://api.openweathermap.org/data/2.5/forecast'
URL_API_LONG = URL_API + '/daily'
re_date = re.compile(r'([+-]?\d+)([dh])')
ICON_TO_UTF = {
'01d': color('☀', color.yellow),
'02d': color('☀', color.yellow),
'03d': color('☁', color.white),
'04d': color('☁', color.white),
'09d': color('☔', color.light_blue),
'10d': color('☔', color.light_blue),
'11d': color('⚡', color.yellow),
'13d': color('❄', color.white),
'01n': color('☾', color.white),
'02n': color('☾', color.white),
'03n': color('☁', color.white),
'04n': color('☁', color.white),
'09n': color('☔', color.light_blue),
'10n': color('☔', color.light_blue),
'11n': color('⚡', color.yellow),
'13n': color('❄', color.white),
}
@register(cmd='weather')
def weather(bot, city, day=None):
dt = check_and_return_datetime(day)
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
delta_days = (dt - datetime.now()).days
is_long_forecast = (delta_days > 5)
if not is_long_forecast:
response = yield from request('GET', URL_API, params={
'q': city,
'units': 'metric',
'lang': 'pl',
'APPID': bot.config.get('app_id'),
})
else:
response = yield from request('GET', URL_API_LONG, params={
'q': city,
'units': 'metric',
'lang': 'pl',
'cnt': min(delta_days, 16),
'APPID': bot.config.get('app_id'),
})
try:
json_data = yield from response.json()
finally:
response.close()
if json_data.get('cod') == 401:
return
data_list = json_data.get("list")
if data_list is None:
bot.reply('404 lol')
return
data = sorted(data_list, key=lambda x: abs(x['dt'] - timestamp))[0]
try:
weather = data['weather'][0]
except IndexError:
weather = {'description': '', 'icon': ''}
if not is_long_forecast:
temperature = data['main']['temp']
else:
if dt.hour < 6:
period = 'night'
elif dt.hour < 10:
period = 'morn'
elif dt.hour < 18:
period = 'day'
elif dt.hour < 22:
period = 'eve'
else:
period = 'night'
temperature = data['temp'][period]
bot.reply('{city}: {temp} °C {icon} {desc}'.format(
city=format.bold(city),
temp=temperature,
desc=weather['description'],
icon=ICON_TO_UTF.get(weather['icon'], '')
))
def check_and_return_datetime(day):
dt = datetime.now()
if day is None:
return dt
dt_hour = datetime.now().replace(hour=12, minute=0, second=0)
if day == "yesterday":
return dt_hour - timedelta(days=1)
if day == "tomorrow":
return dt_hour + timedelta(days=1)
match = re_date.match(day)
if match is None:
return dt
number = int(match.group(1))
if match.group(2) == 'd':
return dt_hour + timedelta(days=number)
else:
return dt + timedelta(hours=number)