summaryrefslogtreecommitdiffstats
path: root/modules/weather.py
diff options
context:
space:
mode:
Diffstat (limited to 'modules/weather.py')
-rwxr-xr-xmodules/weather.py786
1 files changed, 393 insertions, 393 deletions
diff --git a/modules/weather.py b/modules/weather.py
index 29b01e5..5999b79 100755
--- a/modules/weather.py
+++ b/modules/weather.py
@@ -13,400 +13,400 @@ from tools import deprecated
r_from = re.compile(r'(?i)([+-]\d+):00 from')
-def location(name):
- name = urllib.quote(name.encode('utf-8'))
- uri = 'http://ws.geonames.org/searchJSON?q=%s&maxRows=1' % name
- for i in xrange(10):
- u = urllib.urlopen(uri)
- if u is not None: break
- bytes = u.read()
- u.close()
-
- results = web.json(bytes)
- try: name = results['geonames'][0]['name']
- except IndexError:
- return '?', '?', '0', '0'
- countryName = results['geonames'][0]['countryName']
- lat = results['geonames'][0]['lat']
- lng = results['geonames'][0]['lng']
- return name, countryName, lat, lng
-
-class GrumbleError(object):
- pass
-
-def local(icao, hour, minute):
- uri = ('http://www.flightstats.com/' +
- 'go/Airport/airportDetails.do?airportCode=%s')
- try: bytes = web.get(uri % icao)
- except AttributeError:
- raise GrumbleError('A WEBSITE HAS GONE DOWN WTF STUPID WEB')
- m = r_from.search(bytes)
- if m:
- offset = m.group(1)
- lhour = int(hour) + int(offset)
- lhour = lhour % 24
- return (str(lhour) + ':' + str(minute) + ', ' + str(hour) +
- str(minute) + 'Z')
- # return (str(lhour) + ':' + str(minute) + ' (' + str(hour) +
- # ':' + str(minute) + 'Z)')
- return str(hour) + ':' + str(minute) + 'Z'
-
-def code(phenny, search):
- from icao import data
-
- if search.upper() in [loc[0] for loc in data]:
- return search.upper()
- else:
- name, country, latitude, longitude = location(search)
- if name == '?': return False
- sumOfSquares = (99999999999999999999999999999, 'ICAO')
- for icao_code, lat, lon in data:
- latDiff = abs(latitude - lat)
- lonDiff = abs(longitude - lon)
- diff = (latDiff * latDiff) + (lonDiff * lonDiff)
- if diff < sumOfSquares[0]:
- sumOfSquares = (diff, icao_code)
- return sumOfSquares[1]
+def location(name):
+ name = urllib.quote(name.encode('utf-8'))
+ uri = 'http://ws.geonames.org/searchJSON?q=%s&maxRows=1' % name
+ for i in xrange(10):
+ u = urllib.urlopen(uri)
+ if u is not None: break
+ bytes = u.read()
+ u.close()
+
+ results = web.json(bytes)
+ try: name = results['geonames'][0]['name']
+ except IndexError:
+ return '?', '?', '0', '0'
+ countryName = results['geonames'][0]['countryName']
+ lat = results['geonames'][0]['lat']
+ lng = results['geonames'][0]['lng']
+ return name, countryName, lat, lng
+
+class GrumbleError(object):
+ pass
+
+def local(icao, hour, minute):
+ uri = ('http://www.flightstats.com/' +
+ 'go/Airport/airportDetails.do?airportCode=%s')
+ try: bytes = web.get(uri % icao)
+ except AttributeError:
+ raise GrumbleError('A WEBSITE HAS GONE DOWN WTF STUPID WEB')
+ m = r_from.search(bytes)
+ if m:
+ offset = m.group(1)
+ lhour = int(hour) + int(offset)
+ lhour = lhour % 24
+ return (str(lhour) + ':' + str(minute) + ', ' + str(hour) +
+ str(minute) + 'Z')
+ # return (str(lhour) + ':' + str(minute) + ' (' + str(hour) +
+ # ':' + str(minute) + 'Z)')
+ return str(hour) + ':' + str(minute) + 'Z'
+
+def code(phenny, search):
+ from icao import data
+
+ if search.upper() in [loc[0] for loc in data]:
+ return search.upper()
+ else:
+ name, country, latitude, longitude = location(search)
+ if name == '?': return False
+ sumOfSquares = (99999999999999999999999999999, 'ICAO')
+ for icao_code, lat, lon in data:
+ latDiff = abs(latitude - lat)
+ lonDiff = abs(longitude - lon)
+ diff = (latDiff * latDiff) + (lonDiff * lonDiff)
+ if diff < sumOfSquares[0]:
+ sumOfSquares = (diff, icao_code)
+ return sumOfSquares[1]
@deprecated
-def f_weather(self, origin, match, args):
- """.weather <ICAO> - Show the weather at airport with the code <ICAO>."""
- if origin.sender == '#talis':
- if args[0].startswith('.weather '): return
-
- icao_code = match.group(2)
- if not icao_code:
- return self.msg(origin.sender, 'Try .weather London, for example?')
-
- icao_code = code(self, icao_code)
-
- if not icao_code:
- self.msg(origin.sender, 'No ICAO code found, sorry')
- return
-
- uri = 'http://weather.noaa.gov/pub/data/observations/metar/stations/%s.TXT'
- try: bytes = web.get(uri % icao_code)
- except AttributeError:
- raise GrumbleError('OH CRAP NOAA HAS GONE DOWN THE WEB IS BROKEN')
- if 'Not Found' in bytes:
- self.msg(origin.sender, icao_code+': no such ICAO code, or no NOAA data')
- return
-
- metar = bytes.splitlines().pop()
- metar = metar.split(' ')
-
- if len(metar[0]) == 4:
- metar = metar[1:]
-
- if metar[0].endswith('Z'):
- time = metar[0]
- metar = metar[1:]
- else: time = None
-
- if metar[0] == 'AUTO':
- metar = metar[1:]
- if metar[0] == 'VCU':
- self.msg(origin.sender, icao_code + ': no data provided')
- return
-
- if metar[0].endswith('KT'):
- wind = metar[0]
- metar = metar[1:]
- else: wind = None
-
- if ('V' in metar[0]) and (metar[0] != 'CAVOK'):
- vari = metar[0]
- metar = metar[1:]
- else: vari = None
-
- if ((len(metar[0]) == 4) or
- metar[0].endswith('SM')):
- visibility = metar[0]
- metar = metar[1:]
- else: visibility = None
-
- while metar[0].startswith('R') and (metar[0].endswith('L')
- or 'L/' in metar[0]):
- metar = metar[1:]
-
- if len(metar[0]) == 6 and (metar[0].endswith('N') or
- metar[0].endswith('E') or
- metar[0].endswith('S') or
- metar[0].endswith('W')):
- metar = metar[1:] # 7000SE?
-
- cond = []
- while (((len(metar[0]) < 5) or
- metar[0].startswith('+') or
- metar[0].startswith('-')) and (not (metar[0].startswith('VV') or
- metar[0].startswith('SKC') or metar[0].startswith('CLR') or
- metar[0].startswith('FEW') or metar[0].startswith('SCT') or
- metar[0].startswith('BKN') or metar[0].startswith('OVC')))):
- cond.append(metar[0])
- metar = metar[1:]
-
- while '/P' in metar[0]:
- metar = metar[1:]
-
- if not metar:
- self.msg(origin.sender, icao_code + ': no data provided')
- return
-
- cover = []
- while (metar[0].startswith('VV') or metar[0].startswith('SKC') or
- metar[0].startswith('CLR') or metar[0].startswith('FEW') or
- metar[0].startswith('SCT') or metar[0].startswith('BKN') or
- metar[0].startswith('OVC')):
- cover.append(metar[0])
- metar = metar[1:]
- if not metar:
- self.msg(origin.sender, icao_code + ': no data provided')
- return
-
- if metar[0] == 'CAVOK':
- cover.append('CLR')
- metar = metar[1:]
-
- if metar[0] == 'PRFG':
- cover.append('CLR') # @@?
- metar = metar[1:]
-
- if metar[0] == 'NSC':
- cover.append('CLR')
- metar = metar[1:]
-
- if ('/' in metar[0]) or (len(metar[0]) == 5 and metar[0][2] == '.'):
- temp = metar[0]
- metar = metar[1:]
- else: temp = None
-
- if metar[0].startswith('QFE'):
- metar = metar[1:]
-
- if metar[0].startswith('Q') or metar[0].startswith('A'):
- pressure = metar[0]
- metar = metar[1:]
- else: pressure = None
-
- if time:
- hour = time[2:4]
- minute = time[4:6]
- time = local(icao_code, hour, minute)
- else: time = '(time unknown)'
-
- if wind:
- speed = int(wind[3:5])
- if speed < 1:
- description = 'Calm'
- elif speed < 4:
- description = 'Light air'
- elif speed < 7:
- description = 'Light breeze'
- elif speed < 11:
- description = 'Gentle breeze'
- elif speed < 16:
- description = 'Moderate breeze'
- elif speed < 22:
- description = 'Fresh breeze'
- elif speed < 28:
- description = 'Strong breeze'
- elif speed < 34:
- description = 'Near gale'
- elif speed < 41:
- description = 'Gale'
- elif speed < 48:
- description = 'Strong gale'
- elif speed < 56:
- description = 'Storm'
- elif speed < 64:
- description = 'Violent storm'
- else: description = 'Hurricane'
-
- degrees = wind[0:3]
- if degrees == 'VRB':
- degrees = u'\u21BB'.encode('utf-8')
- elif (degrees <= 22.5) or (degrees > 337.5):
- degrees = u'\u2191'.encode('utf-8')
- elif (degrees > 22.5) and (degrees <= 67.5):
- degrees = u'\u2197'.encode('utf-8')
- elif (degrees > 67.5) and (degrees <= 112.5):
- degrees = u'\u2192'.encode('utf-8')
- elif (degrees > 112.5) and (degrees <= 157.5):
- degrees = u'\u2198'.encode('utf-8')
- elif (degrees > 157.5) and (degrees <= 202.5):
- degrees = u'\u2193'.encode('utf-8')
- elif (degrees > 202.5) and (degrees <= 247.5):
- degrees = u'\u2199'.encode('utf-8')
- elif (degrees > 247.5) and (degrees <= 292.5):
- degrees = u'\u2190'.encode('utf-8')
- elif (degrees > 292.5) and (degrees <= 337.5):
- degrees = u'\u2196'.encode('utf-8')
-
- if not icao_code.startswith('EN') and not icao_code.startswith('ED'):
- wind = '%s %skt (%s)' % (description, speed, degrees)
- elif icao_code.startswith('ED'):
- kmh = int(round(speed * 1.852, 0))
- wind = '%s %skm/h (%skt) (%s)' % (description, kmh, speed, degrees)
- elif icao_code.startswith('EN'):
- ms = int(round(speed * 0.514444444, 0))
- wind = '%s %sm/s (%skt) (%s)' % (description, ms, speed, degrees)
- else: wind = '(wind unknown)'
-
- if visibility:
- visibility = visibility + 'm'
- else: visibility = '(visibility unknown)'
-
- if cover:
- level = None
- for c in cover:
- if c.startswith('OVC') or c.startswith('VV'):
- if (level is None) or (level < 8):
- level = 8
- elif c.startswith('BKN'):
- if (level is None) or (level < 5):
- level = 5
- elif c.startswith('SCT'):
- if (level is None) or (level < 3):
- level = 3
- elif c.startswith('FEW'):
- if (level is None) or (level < 1):
- level = 1
- elif c.startswith('SKC') or c.startswith('CLR'):
- if level is None:
- level = 0
-
- if level == 8:
- cover = u'Overcast \u2601'.encode('utf-8')
- elif level == 5:
- cover = 'Cloudy'
- elif level == 3:
- cover = 'Scattered'
- elif (level == 1) or (level == 0):
- cover = u'Clear \u263C'.encode('utf-8')
- else: cover = 'Cover Unknown'
- else: cover = 'Cover Unknown'
-
- if temp:
- if '/' in temp:
- temp = temp.split('/')[0]
- else: temp = temp.split('.')[0]
- if temp.startswith('M'):
- temp = '-' + temp[1:]
- try: temp = int(temp)
- except ValueError: temp = '?'
- else: temp = '?'
-
- if pressure:
- if pressure.startswith('Q'):
- pressure = pressure.lstrip('Q')
- if pressure != 'NIL':
- pressure = str(int(pressure)) + 'mb'
- else: pressure = '?mb'
- elif pressure.startswith('A'):
- pressure = pressure.lstrip('A')
- if pressure != 'NIL':
- inches = pressure[:2] + '.' + pressure[2:]
- mb = int(float(inches) * 33.7685)
- pressure = '%sin (%smb)' % (inches, mb)
- else: pressure = '?mb'
-
- if isinstance(temp, int):
- f = round((temp * 1.8) + 32, 2)
- temp = u'%s\u2109 (%s\u2103)'.encode('utf-8') % (f, temp)
- else: pressure = '?mb'
- if isinstance(temp, int):
- temp = u'%s\u2103'.encode('utf-8') % temp
-
- if cond:
- conds = cond
- cond = ''
-
- intensities = {
- '-': 'Light',
- '+': 'Heavy'
- }
-
- descriptors = {
- 'MI': 'Shallow',
- 'PR': 'Partial',
- 'BC': 'Patches',
- 'DR': 'Drifting',
- 'BL': 'Blowing',
- 'SH': 'Showers of',
- 'TS': 'Thundery',
- 'FZ': 'Freezing',
- 'VC': 'In the vicinity:'
- }
-
- phenomena = {
- 'DZ': 'Drizzle',
- 'RA': 'Rain',
- 'SN': 'Snow',
- 'SG': 'Snow Grains',
- 'IC': 'Ice Crystals',
- 'PL': 'Ice Pellets',
- 'GR': 'Hail',
- 'GS': 'Small Hail',
- 'UP': 'Unknown Precipitation',
- 'BR': 'Mist',
- 'FG': 'Fog',
- 'FU': 'Smoke',
- 'VA': 'Volcanic Ash',
- 'DU': 'Dust',
- 'SA': 'Sand',
- 'HZ': 'Haze',
- 'PY': 'Spray',
- 'PO': 'Whirls',
- 'SQ': 'Squalls',
- 'FC': 'Tornado',
- 'SS': 'Sandstorm',
- 'DS': 'Duststorm',
- # ? Cf. http://swhack.com/logs/2007-10-05#T07-58-56
- 'TS': 'Thunderstorm',
- 'SH': 'Showers'
- }
-
- for c in conds:
- if c.endswith('//'):
- if cond: cond += ', '
- cond += 'Some Precipitation'
- elif len(c) == 5:
- intensity = intensities[c[0]]
- descriptor = descriptors[c[1:3]]
- phenomenon = phenomena.get(c[3:], c[3:])
- if cond: cond += ', '
- cond += intensity + ' ' + descriptor + ' ' + phenomenon
- elif len(c) == 4:
- descriptor = descriptors.get(c[:2], c[:2])
- phenomenon = phenomena.get(c[2:], c[2:])
- if cond: cond += ', '
- cond += descriptor + ' ' + phenomenon
- elif len(c) == 3:
- intensity = intensities.get(c[0], c[0])
- phenomenon = phenomena.get(c[1:], c[1:])
- if cond: cond += ', '
- cond += intensity + ' ' + phenomenon
- elif len(c) == 2:
- phenomenon = phenomena.get(c, c)
- if cond: cond += ', '
- cond += phenomenon
-
- # if not cond:
- # format = u'%s at %s: %s, %s, %s, %s'
- # args = (icao, time, cover, temp, pressure, wind)
- # else:
- # format = u'%s at %s: %s, %s, %s, %s, %s'
- # args = (icao, time, cover, temp, pressure, cond, wind)
-
- if not cond:
- format = u'%s, %s, %s, %s - %s %s'
- args = (cover, temp, pressure, wind, str(icao_code), time)
- else:
- format = u'%s, %s, %s, %s, %s - %s, %s'
- args = (cover, temp, pressure, cond, wind, str(icao_code), time)
-
- self.msg(origin.sender, format.encode('utf-8') % args)
+def f_weather(self, origin, match, args):
+ """.weather <ICAO> - Show the weather at airport with the code <ICAO>."""
+ if origin.sender == '#talis':
+ if args[0].startswith('.weather '): return
+
+ icao_code = match.group(2)
+ if not icao_code:
+ return self.msg(origin.sender, 'Try .weather London, for example?')
+
+ icao_code = code(self, icao_code)
+
+ if not icao_code:
+ self.msg(origin.sender, 'No ICAO code found, sorry')
+ return
+
+ uri = 'http://weather.noaa.gov/pub/data/observations/metar/stations/%s.TXT'
+ try: bytes = web.get(uri % icao_code)
+ except AttributeError:
+ raise GrumbleError('OH CRAP NOAA HAS GONE DOWN THE WEB IS BROKEN')
+ if 'Not Found' in bytes:
+ self.msg(origin.sender, icao_code+': no such ICAO code, or no NOAA data')
+ return
+
+ metar = bytes.splitlines().pop()
+ metar = metar.split(' ')
+
+ if len(metar[0]) == 4:
+ metar = metar[1:]
+
+ if metar[0].endswith('Z'):
+ time = metar[0]
+ metar = metar[1:]
+ else: time = None
+
+ if metar[0] == 'AUTO':
+ metar = metar[1:]
+ if metar[0] == 'VCU':
+ self.msg(origin.sender, icao_code + ': no data provided')
+ return
+
+ if metar[0].endswith('KT'):
+ wind = metar[0]
+ metar = metar[1:]
+ else: wind = None
+
+ if ('V' in metar[0]) and (metar[0] != 'CAVOK'):
+ vari = metar[0]
+ metar = metar[1:]
+ else: vari = None
+
+ if ((len(metar[0]) == 4) or
+ metar[0].endswith('SM')):
+ visibility = metar[0]
+ metar = metar[1:]
+ else: visibility = None
+
+ while metar[0].startswith('R') and (metar[0].endswith('L')
+ or 'L/' in metar[0]):
+ metar = metar[1:]
+
+ if len(metar[0]) == 6 and (metar[0].endswith('N') or
+ metar[0].endswith('E') or
+ metar[0].endswith('S') or
+ metar[0].endswith('W')):
+ metar = metar[1:] # 7000SE?
+
+ cond = []
+ while (((len(metar[0]) < 5) or
+ metar[0].startswith('+') or
+ metar[0].startswith('-')) and (not (metar[0].startswith('VV') or
+ metar[0].startswith('SKC') or metar[0].startswith('CLR') or
+ metar[0].startswith('FEW') or metar[0].startswith('SCT') or
+ metar[0].startswith('BKN') or metar[0].startswith('OVC')))):
+ cond.append(metar[0])
+ metar = metar[1:]
+
+ while '/P' in metar[0]:
+ metar = metar[1:]
+
+ if not metar:
+ self.msg(origin.sender, icao_code + ': no data provided')
+ return
+
+ cover = []
+ while (metar[0].startswith('VV') or metar[0].startswith('SKC') or
+ metar[0].startswith('CLR') or metar[0].startswith('FEW') or
+ metar[0].startswith('SCT') or metar[0].startswith('BKN') or
+ metar[0].startswith('OVC')):
+ cover.append(metar[0])
+ metar = metar[1:]
+ if not metar:
+ self.msg(origin.sender, icao_code + ': no data provided')
+ return
+
+ if metar[0] == 'CAVOK':
+ cover.append('CLR')
+ metar = metar[1:]
+
+ if metar[0] == 'PRFG':
+ cover.append('CLR') # @@?
+ metar = metar[1:]
+
+ if metar[0] == 'NSC':
+ cover.append('CLR')
+ metar = metar[1:]
+
+ if ('/' in metar[0]) or (len(metar[0]) == 5 and metar[0][2] == '.'):
+ temp = metar[0]
+ metar = metar[1:]
+ else: temp = None
+
+ if metar[0].startswith('QFE'):
+ metar = metar[1:]
+
+ if metar[0].startswith('Q') or metar[0].startswith('A'):
+ pressure = metar[0]
+ metar = metar[1:]
+ else: pressure = None
+
+ if time:
+ hour = time[2:4]
+ minute = time[4:6]
+ time = local(icao_code, hour, minute)
+ else: time = '(time unknown)'
+
+ if wind:
+ speed = int(wind[3:5])
+ if speed < 1:
+ description = 'Calm'
+ elif speed < 4:
+ description = 'Light air'
+ elif speed < 7:
+ description = 'Light breeze'
+ elif speed < 11:
+ description = 'Gentle breeze'
+ elif speed < 16:
+ description = 'Moderate breeze'
+ elif speed < 22:
+ description = 'Fresh breeze'
+ elif speed < 28:
+ description = 'Strong breeze'
+ elif speed < 34:
+ description = 'Near gale'
+ elif speed < 41:
+ description = 'Gale'
+ elif speed < 48:
+ description = 'Strong gale'
+ elif speed < 56:
+ description = 'Storm'
+ elif speed < 64:
+ description = 'Violent storm'
+ else: description = 'Hurricane'
+
+ degrees = wind[0:3]
+ if degrees == 'VRB':
+ degrees = u'\u21BB'.encode('utf-8')
+ elif (degrees <= 22.5) or (degrees > 337.5):
+ degrees = u'\u2191'.encode('utf-8')
+ elif (degrees > 22.5) and (degrees <= 67.5):
+ degrees = u'\u2197'.encode('utf-8')
+ elif (degrees > 67.5) and (degrees <= 112.5):
+ degrees = u'\u2192'.encode('utf-8')
+ elif (degrees > 112.5) and (degrees <= 157.5):
+ degrees = u'\u2198'.encode('utf-8')
+ elif (degrees > 157.5) and (degrees <= 202.5):
+ degrees = u'\u2193'.encode('utf-8')
+ elif (degrees > 202.5) and (degrees <= 247.5):
+ degrees = u'\u2199'.encode('utf-8')
+ elif (degrees > 247.5) and (degrees <= 292.5):
+ degrees = u'\u2190'.encode('utf-8')
+ elif (degrees > 292.5) and (degrees <= 337.5):
+ degrees = u'\u2196'.encode('utf-8')
+
+ if not icao_code.startswith('EN') and not icao_code.startswith('ED'):
+ wind = '%s %skt (%s)' % (description, speed, degrees)
+ elif icao_code.startswith('ED'):
+ kmh = int(round(speed * 1.852, 0))
+ wind = '%s %skm/h (%skt) (%s)' % (description, kmh, speed, degrees)
+ elif icao_code.startswith('EN'):
+ ms = int(round(speed * 0.514444444, 0))
+ wind = '%s %sm/s (%skt) (%s)' % (description, ms, speed, degrees)
+ else: wind = '(wind unknown)'
+
+ if visibility:
+ visibility = visibility + 'm'
+ else: visibility = '(visibility unknown)'
+
+ if cover:
+ level = None
+ for c in cover:
+ if c.startswith('OVC') or c.startswith('VV'):
+ if (level is None) or (level < 8):
+ level = 8
+ elif c.startswith('BKN'):
+ if (level is None) or (level < 5):
+ level = 5
+ elif c.startswith('SCT'):
+ if (level is None) or (level < 3):
+ level = 3
+ elif c.startswith('FEW'):
+ if (level is None) or (level < 1):
+ level = 1
+ elif c.startswith('SKC') or c.startswith('CLR'):
+ if level is None:
+ level = 0
+
+ if level == 8:
+ cover = u'Overcast \u2601'.encode('utf-8')
+ elif level == 5:
+ cover = 'Cloudy'
+ elif level == 3:
+ cover = 'Scattered'
+ elif (level == 1) or (level == 0):
+ cover = u'Clear \u263C'.encode('utf-8')
+ else: cover = 'Cover Unknown'
+ else: cover = 'Cover Unknown'
+
+ if temp:
+ if '/' in temp:
+ temp = temp.split('/')[0]
+ else: temp = temp.split('.')[0]
+ if temp.startswith('M'):
+ temp = '-' + temp[1:]
+ try: temp = int(temp)
+ except ValueError: temp = '?'
+ else: temp = '?'
+
+ if pressure:
+ if pressure.startswith('Q'):
+ pressure = pressure.lstrip('Q')
+ if pressure != 'NIL':
+ pressure = str(int(pressure)) + 'mb'
+ else: pressure = '?mb'
+ elif pressure.startswith('A'):
+ pressure = pressure.lstrip('A')
+ if pressure != 'NIL':
+ inches = pressure[:2] + '.' + pressure[2:]
+ mb = int(float(inches) * 33.7685)
+ pressure = '%sin (%smb)' % (inches, mb)
+ else: pressure = '?mb'
+
+ if isinstance(temp, int):
+ f = round((temp * 1.8) + 32, 2)
+ temp = u'%s\u2109 (%s\u2103)'.encode('utf-8') % (f, temp)
+ else: pressure = '?mb'
+ if isinstance(temp, int):
+ temp = u'%s\u2103'.encode('utf-8') % temp
+
+ if cond:
+ conds = cond
+ cond = ''
+
+ intensities = {
+ '-': 'Light',
+ '+': 'Heavy'
+ }
+
+ descriptors = {
+ 'MI': 'Shallow',
+ 'PR': 'Partial',
+ 'BC': 'Patches',
+ 'DR': 'Drifting',
+ 'BL': 'Blowing',
+ 'SH': 'Showers of',
+ 'TS': 'Thundery',
+ 'FZ': 'Freezing',
+ 'VC': 'In the vicinity:'
+ }
+
+ phenomena = {
+ 'DZ': 'Drizzle',
+ 'RA': 'Rain',
+ 'SN': 'Snow',
+ 'SG': 'Snow Grains',
+ 'IC': 'Ice Crystals',
+ 'PL': 'Ice Pellets',
+ 'GR': 'Hail',
+ 'GS': 'Small Hail',
+ 'UP': 'Unknown Precipitation',
+ 'BR': 'Mist',
+ 'FG': 'Fog',
+ 'FU': 'Smoke',
+ 'VA': 'Volcanic Ash',
+ 'DU': 'Dust',
+ 'SA': 'Sand',
+ 'HZ': 'Haze',
+ 'PY': 'Spray',
+ 'PO': 'Whirls',
+ 'SQ': 'Squalls',
+ 'FC': 'Tornado',
+ 'SS': 'Sandstorm',
+ 'DS': 'Duststorm',
+ # ? Cf. http://swhack.com/logs/2007-10-05#T07-58-56
+ 'TS': 'Thunderstorm',
+ 'SH': 'Showers'
+ }
+
+ for c in conds:
+ if c.endswith('//'):
+ if cond: cond += ', '
+ cond += 'Some Precipitation'
+ elif len(c) == 5:
+ intensity = intensities[c[0]]
+ descriptor = descriptors[c[1:3]]
+ phenomenon = phenomena.get(c[3:], c[3:])
+ if cond: cond += ', '
+ cond += intensity + ' ' + descriptor + ' ' + phenomenon
+ elif len(c) == 4:
+ descriptor = descriptors.get(c[:2], c[:2])
+ phenomenon = phenomena.get(c[2:], c[2:])
+ if cond: cond += ', '
+ cond += descriptor + ' ' + phenomenon
+ elif len(c) == 3:
+ intensity = intensities.get(c[0], c[0])
+ phenomenon = phenomena.get(c[1:], c[1:])
+ if cond: cond += ', '
+ cond += intensity + ' ' + phenomenon
+ elif len(c) == 2:
+ phenomenon = phenomena.get(c, c)
+ if cond: cond += ', '
+ cond += phenomenon
+
+ # if not cond:
+ # format = u'%s at %s: %s, %s, %s, %s'
+ # args = (icao, time, cover, temp, pressure, wind)
+ # else:
+ # format = u'%s at %s: %s, %s, %s, %s, %s'
+ # args = (icao, time, cover, temp, pressure, cond, wind)
+
+ if not cond:
+ format = u'%s, %s, %s, %s - %s %s'
+ args = (cover, temp, pressure, wind, str(icao_code), time)
+ else:
+ format = u'%s, %s, %s, %s, %s - %s, %s'
+ args = (cover, temp, pressure, cond, wind, str(icao_code), time)
+
+ self.msg(origin.sender, format.encode('utf-8') % args)
f_weather.rule = (['weather'], r'(.*)')
-if __name__ == '__main__':
- print __doc__.strip()
+if __name__ == '__main__':
+ print __doc__.strip()