]>
jfr.im git - erebus.git/blob - modules/avweather.py
1 # Erebus IRC bot - Author: Erebus Team
2 # vim: fileencoding=utf-8
3 # weather module (from aviationweather.gov)
4 # This file is released into the public domain; see http://unlicense.org/
8 'author': 'Erebus Team',
9 'license': 'public domain',
11 'depends': ['userinfo'],
17 lib
= modlib
.modlib(__name__
)
18 modstart
= lib
.modstart
26 if sys
.version_info
.major
< 3:
27 from urllib
import urlopen
, quote_plus
29 from urllib
.request
import urlopen
30 from urllib
.parse
import quote_plus
32 def location(person
, default
=None): return lib
.mod('userinfo').get(person
, 'location', default
=None)
34 def _dayofweek(dayname
):
35 return ['mon','tue','wed','thu','fri','sat','sun'].index(dayname
.lower())
38 t
= d
['current']['observation_time']
40 #mo = re.match(r"(\d\d):(\d\d) (AM|PM)", t)
46 return round(celsius
* 9.0/5 + 32, 2)
49 return round(kmh
/ 1.60934, 2)
52 if not lib
.parent
.cfg
.get('weatherstack_weather', 'key'):
53 return "Weather is not enabled - please set the API key in the config file"
56 url
= 'http://api.weatherstack.com/current?access_key=%s&query=%s' % (lib
.parent
.cfg
.get('weatherstack_weather', 'key'), quote_plus(place
))
57 if sys
.version_info
.major
< 3:
58 url
= url
.encode('utf8')
59 weather
= json
.load(urlopen(url
))
60 if lib
.parent
.cfg
.getboolean('debug', 'weather'):
61 lib
.parent
.log('*', "?", repr(weather
))
62 if 'error' in weather
:
63 return "Error from WeatherStack: (%d) %s" % (weather
['error']['code'], weather
['error']['info'])
65 return u
"Weather in %(location)s, %(region)s, %(country)s: As of %(time)s, %(conditions)s, %(cel)s°C (%(far)s°F) (feels like %(flcel)s°C (%(flfar)s°F)). Wind %(windk)skm/h (%(windm)smph) %(winddir)s." % {
66 'location': weather
['location']['name'],
67 'region': weather
['location']['region'],
68 'country': weather
['location']['country'],
69 'time': _time_adjust(weather
),
70 'conditions': ', '.join(weather
['current']['weather_descriptions']),
71 'cel': weather
['current']['temperature'], 'far': _c2f(weather
['current']['temperature']),
72 'flcel': weather
['current']['feelslike'], 'flfar': _c2f(weather
['current']['feelslike']),
73 'windk': weather
['current']['wind_speed'], 'windm': _kmh2mph(weather
['current']['wind_speed']),
74 'winddir': weather
['current']['wind_dir'],
77 return "I don't know where to look! Try %ssetinfo location <your location>" % (lib
.parent
.trigger
,)
80 def _get_metar(place
):
81 url
= 'https://aviationweather.gov/cgi-bin/data/metar.php?ids=%s&hours=0&order=id%%2C-obs&sep=true&format=raw' % (quote_plus(place
))
82 if sys
.version_info
.major
< 3:
83 url
= url
.encode('utf8')
84 return urlopen(url
).read().decode('utf8').strip()
86 METAR_REGEX
= re
.compile('(?P<location>[A-Z]{4}) (?P<time>\d{6}Z) (?P<auto>AUTO )?(?P<corrected>COR|CCA )?(?P<winddir>(?:VRB|\d\d\d)(?:V\d\d\d)?)(?P<windspeed>\d{2})(?:G(?P<windgust>\d{2}))?KT (?:\d{3}V\d{3} )?(?:(?:(?P<visibilityus>\d+(?: \d+/\d+)?)SM )|(?:(?P<visibilitymetric>\d+) )).*')
87 def _reformat_metar(metar
):
88 # http://www.dixwx.com/wxdecoding.htm
89 # https://aviationweather.gov/cgi-bin/data/metar.php?ids=EFHK&hours=0&order=id%2C-obs&sep=true&format=raw
90 # https://aviationweather.gov/cgi-bin/data/metar.php?ids=KCTB&hours=0&order=id%2C-obs&sep=true&format=raw
91 # Need to implement: everything after visibility lol
92 res
= METAR_REGEX
.fullmatch(metar
)
94 return "Failed to parse METAR: %s" % (metar
)
96 return repr(res
.groupdict())
98 #@lib.hook(('avweather','avw'), needchan=False, wantchan=True)
99 #@lib.help('<ICAO code>', 'show weather at an airport')
101 def avweather(bot
, user
, chan
, realtarget
, *args
):
104 if len(args
[0]) != 4:
105 bot
.msg(chan
, "You must use a 4-character ICAO code.")
106 bot
.msg(chan
, _reformat_metar(_get_metar(args
[0])))
108 @lib.hook(needchan
=False, wantchan
=True)
109 @lib.help('<ICAO code>', 'show raw METAR for an airport')
111 def metar(bot
, user
, chan
, realtarget
, *args
):
114 if len(args
[0]) != 4:
115 bot
.msg(chan
, "You must use a 4-character ICAO code.")
116 bot
.msg(chan
, _get_metar(args
[0]))