import appuifw import e32 #------ # Program logic #------ import urllib import re import os def getRawWeatherForCity(city): tempfile = "c:\\weather_tempfile.xml" urllib.urlretrieve('http://www.google.com/ig/api?weather=%s' % city, tempfile) weather_file = open(tempfile) weather = weather_file.read() weather_file.close() urllib.urlcleanup() os.unlink(tempfile) return weather def getCurrentWeather(city): raw = getRawWeatherForCity(city) if raw.find('problem_cause') > 1: return None return Weather(raw) class struct: pass class Weather: _curRE = re.compile(r'.*(.*)<\/current_conditions>.*') _conditionRE = re.compile(r'.*.*') _tempRE = re.compile('.*(.*?)<\/forecast_conditions>') def __init__(self, xml): conditions = self._curRE.match(xml).group(1) forecasts = self._forecastRE.findall(xml) self.setCurrent(conditions) self.setToday(forecasts[0]) self.setTomorrow(forecasts[1]) def setCurrent(self, conditions): self.current = struct() self.current.condition = self.getCondition(conditions) self.current.temperature = self.getTemperature(conditions) self.current.humidity = self.getHumidity(conditions) self.current.wind = self.getWind(conditions) def setToday(self, conditions): self.today = struct() self.today.condition = self.getCondition(conditions) self.today.low = self.getLowTemperature(conditions) self.today.high = self.getHighTemperature(conditions) def setTomorrow(self, conditions): self.tomorrow = struct() self.tomorrow.condition = self.getCondition(conditions) self.tomorrow.low = self.getLowTemperature(conditions) self.tomorrow.high = self.getHighTemperature(conditions) def getCondition(self, conditions): return self._conditionRE.match(conditions).group(1) def getTemperature(self, conditions): tempString = self._tempRE.match(conditions).group(1) return Temperature(int(tempString), 'c') def getLowTemperature(self, conditions): tempString = self._lowTempRE.match(conditions).group(1) return Temperature(int(tempString), 'F') def getHighTemperature(self, conditions): tempString = self._highTempRE.match(conditions).group(1) return Temperature(int(tempString), 'F') def getHumidity(self, conditions): humString = self._humRE.match(conditions).group(1) return int(humString) def getWind(self, conditions): groups = self._windRe.match(conditions).groups() wind = struct() wind.speed = Speed(int(groups[1]), 'mph') wind.direction = Direction(groups[0]) return wind class Temperature: def __init__(self, value, unit): if unit.upper() not in ['C', 'F']: raise AttributeError("Invalid temperature unit") if unit.upper() == 'C': self.value = value else: self.value = int(round((value - 32) / 1.8)) def celsius(self): return self.value def fahrenheit(self): return int(round((self.value * 1.8) + 32)) def __eq__(self, other): if not isinstance(other, self.__class__): return False return self.value == other.value class Speed: def __init__(self, value, unit): if unit.upper() not in ['MPH', 'KPH']: raise AttributeError("Invalid speed unit") if unit.upper() == 'KPH': self.value = value else: self.value = int(round(value * 1.609344)) def kmh(self): return self.value def mph(self): return int(round(self.value / 1.609344)) def __eq__(self, other): if not isinstance(other, self.__class__): return False return self.value == other.value class Direction: def __init__(self, dir): if dir.upper() not in ['N', 'E', 'S', 'W', 'NE', 'SE', 'SW', 'NW']: raise AttributeError("Invalid direction") self.dir = dir def __eq__(self, other): if not isinstance(other, self.__class__): return False return self.dir == other.dir #------ # UI #------ weather = None app_lock = e32.Ao_lock() def exit_handler(): app_lock.signal() appuifw.app.exit_key_handler = exit_handler old_title = appuifw.app.title appuifw.app.title = u"Tomo's Weather" while weather is None: city = appuifw.query(u"Enter city:", "text") appuifw.note(u"Fetching weather forecast...") weather = getCurrentWeather(city) if weather is None: appuifw.note(u'Cannot find city. Try bigger one in the area', 'error') wind = weather.current.wind conditions = [(u'Current Condition', unicode(weather.current.condition)), (u'Temp', u'%d C' % weather.current.temperature.celsius()), (u'Wind', u'%s at %d kph' % (wind.direction.dir, wind.speed.kmh())), (u'Humidity', u'%d%%' % weather.current.humidity) ] lb_current = appuifw.Listbox(conditions) today = [(u"Today's Condition", unicode(weather.today.condition)), (u'High Temp', u'%d C' % weather.today.high.celsius()), (u'Low Temp', u'%d C' % weather.today.low.celsius()), ] lb_today = appuifw.Listbox(today) tomorrow = [(u"Tomorrow's Condition", unicode(weather.tomorrow.condition)), (u'High Temp', u'%d C' % weather.tomorrow.high.celsius()), (u'Low Temp', u'%d C' % weather.tomorrow.low.celsius()), ] lb_tomorrow = appuifw.Listbox(tomorrow) def handle_tabs(index): if index == 0: appuifw.app.body = lb_current elif index == 1: appuifw.app.body = lb_today elif index == 2: appuifw.app.body = lb_tomorrow appuifw.app.body = lb_current appuifw.app.set_tabs([u"Currenly", u"Today", u"Tomorrow"], handle_tabs) app_lock.wait() appuifw.app.title = old_title