Author: duncan
Date: Sat Sep 22 17:44:52 2007
New Revision: 9886
Log:
Updated icons and caching
Plus much more...
Modified:
branches/rel-1/testing/Duncan/weather/1click/oneclick.py
branches/rel-1/testing/Duncan/weather/1click/weatherdata.py
Modified: branches/rel-1/testing/Duncan/weather/1click/oneclick.py
==============================================================================
--- branches/rel-1/testing/Duncan/weather/1click/oneclick.py (original)
+++ branches/rel-1/testing/Duncan/weather/1click/oneclick.py Sat Sep 22
17:44:52 2007
@@ -15,8 +15,8 @@
#
# activate:
#
-# plugin.activate('weather', level=45)
-# PLUGIN_WEATHER_LOCATIONS = [ ("USNC0559", 0, "en", "Home sweet home") ]
+# plugin.activate('oneclick', level=45)
+# PLUGIN_WEATHER_LOCATIONS = [ ("USNC0559", 0, "Home sweet home") ]
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
@@ -62,140 +62,86 @@
from weatherdata import WeatherData
+GUI = True
+if __name__ == '__main__':
+ GUI = False
+
#get the singletons so we get skin info and access the osd
skin = skin.get_singleton()
osd = osd.get_singleton()
-GUI = False
-
#check every 1 hour
WEATHER_AGE = 3600
WEATHER_DIR = os.path.join(config.SHARE_DIR, 'images', 'weather')
WEATHER_DIR = '/sources/svn/freevo-1.x/testing/Duncan/weather/1click/64x64'
+#FIXME These mappings are incorrect
WEATHER_DATA = {
- 1: ( _('Cloudy'), 'cloudy.png'),
- 3: ( _('Mostly Cloudy'), 'mcloudy.png'),
- 4: ( _('Partly Cloudy'), 'pcloudy.png'),
- 13: ( _('Light Rain'), 'lshowers.png'),
- 14: ( _('Showers'), 'showers.png'),
- 16: ( _('Snow'), 'snowshow.png'),
- 18: ( _('Rain'), 'showers.png'),
- 19: ( _('AM Showers'), 'showers.png'),
- 20: ( _('Fog'), 'fog.png'),
- 21: ( _('Few Showers'), 'lshowers.png'),
- 22: ( _('Mostly Sunny'), 'sunny.png'),
- 24: ( _('Sunny'), 'sunny.png'),
- 25: ( _('Scattered Flurries'), 'flurries.png'),
- 26: ( _('AM Clouds/PM Sun'), 'pcloudy.png'),
- 27: ( _('Isolated T-Storms'), 'thunshowers.png'),
- 28: ( _('Scattered Thunderstorms'), 'thunshowers.png'),
- 29: ( _('PM Showers'), 'showers.png'),
- 30: ( _('PM Showers/Wind'), 'showers.png'),
- 31: ( _('Rain/Snow Showers'), 'rainsnow.png'),
- 32: ( _('Few Snow Showers'), 'flurries.png'),
- 33: ( _('Cloudy/Wind'), 'cloudy.png'),
- 34: ( _('Flurries/Wind'), 'flurries.png'),
- 35: ( _('Mostly Cloudy/Windy'), 'mcloudy.png'),
- 36: ( _('Rain/Thunder'), 'thunshowers.png'),
- 37: ( _('Partly Cloudy/Windy'), 'pcloudy.png'),
- 38: ( _('AM Rain/Snow Showers'), 'rainsnow.png'),
- 40: ( _('Light Rain/Wind'), 'lshowers.png'),
- 41: ( _('Showers/Wind'), 'showers.png'),
- 42: ( _('Heavy Snow'), 'snowshow.png'),
- 43: ( _('Drizzle'), 'showers.png'),
- 44: ( _('Mostly Sunny/Wind'), 'sunny.png'),
- 45: ( _('Flurries'), 'flurries.png'),
- 47: ( _('Rain/Wind'), 'showers.png'),
- 49: ( _('Sct Flurries/Wind'), 'flurries.png'),
- 50: ( _('Sct Strong Storms'), 'thunshowers.png'),
- 51: ( _('PM T-Storms'), 'thunshowers.png'),
- 53: ( _('Thunderstorms'), 'thunshowers.png'),
- 55: ( _('Sunny/Windy'), 'sunny.png'),
- 56: ( _('AM Thunderstorms'), 'thunshowers.png'),
- 62: ( _('AM Rain'), 'showers.png'),
- 64: ( _('Iso T-Storms/Wind'), 'thunshowers.png'),
- 65: ( _('Rain/Snow'), 'rainsnow.png'),
- 66: ( _('Sct T-Storms/Wind'), 'showers.png'),
- 67: ( _('AM Showers/Wind'), 'showers.png'),
- 70: ( _('Sct Snow Showers'), 'snowshow.png'),
- 71: ( _('Snow to Ice/Wind'), 'snowshow.png'),
- 76: ( _('AM Ice'), 'rainsnow.png'),
- 77: ( _('Snow to Rain'), 'rainsnow.png'),
- 80: ( _('AM Light Rain'), 'lshowers.png'),
- 81: ( _('PM Light Rain'), 'lshowers.png'),
- 82: ( _('PM Rain'), 'showers.png'),
- 84: ( _('Snow Showers'), 'snowshow.png'),
- 85: ( _('Rain to Snow'), 'rainsnow.png'),
- 86: ( _('PM Rain/Snow'), 'snowshow.png'),
- 88: ( _('Few Showers/Wind'), 'showers.png'),
- 90: ( _('Snow/Wind'), 'snowshow.png'),
- 91: ( _('PM Rain/Snow Showers'), 'rainsnow.png'),
- 92: ( _('PM Rain/Snow/Wind'), 'rainsnow.png'),
- 93: ( _('Rain/Snow Showers/Wind'), 'rainsnow.png'),
- 94: ( _('Rain/Snow/Wind'), 'rainsnow.png'),
- 98: ( _('Light Snow'), 'flurries.png'),
- 100: ( _('PM Snow'), 'snowshow.png'),
- 101: ( _('Few Snow Showers/Wind'), 'snowshow.png'),
- 103: ( _('Light Snow/Wind'), 'flurries.png'),
- 104: ( _('Wintry Mix'), 'flurries.png'),
- 105: ( _('AM Wintry Mix'), 'rainsnow.png'),
- 106: ( _('Hvy Rain/Freezing Rain'), 'rainsnow.png'),
- 108: ( _('AM Light Snow'), 'flurries.png'),
- 109: ( _('PM Rain/Snow/Wind'), 'rainsnow.png'),
- 114: ( _('Rain/Freezing Rain'), 'showers.png'),
- 118: ( _('T-Storms/Wind'), 'thunshowers.png'),
- 123: ( _('Sprinkles'), 'lshowers.png'),
- 125: ( _('AM Snow Showers'), 'snowshow.png'),
- 126: ( _('AM Clouds/PM Sun/Wind'), 'pcloudy.png'),
- 128: ( _('AM Rain/Snow/Wind'), 'rainsnow.png'),
- 130: ( _('Rain to Snow/Wind'), 'rainsnow.png'),
- 132: ( _('Snow to Wintry Mix'), 'snowshow.png'),
- 133: ( _('PM Snow Showers/Wind'), 'snowshow.png'),
- 135: ( _('Snow and Ice to Rain'), 'rainsnow.png'),
- 137: ( _('Heavy Rain'), 'showers.png'),
- 138: ( _('AM Rain/Ice'), 'showers.png'),
- 145: ( _('AM Snow Showers/Wind'), 'snowshow.png'),
- 146: ( _('AM Light Snow/Wind'), 'flurries.png'),
- 150: ( _('PM Light Rain/Wind'), 'lshowers.png'),
- 152: ( _('AM Light Wintry Mix'), 'rainsnow.png'),
- 153: ( _('PM Light Snow/Wind'), 'flurries.png'),
- 154: ( _('Heavy Rain/Wind'), 'showers.png'),
- 155: ( _('PM Snow Shower'), 'snowshow.png'),
- 158: ( _('Snow to Rain/Wind'), 'rainsnow.png'),
- 164: ( _('PM Light Rain/Ice'), 'showers.png'),
- 167: ( _('AM Snow'), 'snowshow.png'),
- 171: ( _('Snow to Ice'), 'snowshow.png'),
- 172: ( _('Wintry Mix/Wind'), 'rainsnow.png'),
- 175: ( _('PM Light Snow'), 'flurries.png'),
- 178: ( _('AM Drizzle'), 'lshowers.png'),
- 189: ( _('Strong Storms/Wind'), 'thunshowers.png'),
- 193: ( _('PM Drizzle'), 'lshowers.png'),
- 194: ( _('Drizzle'), 'lshowers.png'),
- 201: ( _('AM Light Rain/Wind'), 'lshowers.png'),
- 204: ( _('AM Rain/Wind'), 'showers.png'),
- 223: ( _('Wintry Mix to Snow'), 'rainsnow.png'),
- 231: ( _('Rain'), 'showers.png'),
- 240: ( _('AM Light Rain/Ice'), 'rainsnow.png'),
- 259: ( _('Hvy Rain/Freezing Rain'), 'showers.png'),
- 271: ( _('Snow Showers/Windy'), 'snowshow.png'),
- 988: ( _('Partly Cloudy/Windy'), 'pcloudy.png'),
- 989: ( _('Light Rain Shower'), 'lshowers.png'),
- 990: ( _('Light Rain with Thunder'), 'thunshowers.png'),
- 991: ( _('Light Drizzle'), 'lshowers.png'),
- 992: ( _('Mist'), 'fog.png'),
- 993: ( _('Smoke'), 'fog.png'),
- 994: ( _('Haze'), 'fog.png'),
- 995: ( _('Light Snow Shower'), 'flurries.png'),
- 996: ( _('Light Snow Shower/ Windy'), 'flurries.png'),
- 997: ( _('Clear'), 'fair.png'),
- 998: ( _('A Few Clouds'), 'pcloudy.png'),
- 999: ( _('Fair'), 'fair.png')
+# icon tnc.com image fallback
+ 0: ( '0.png', 'thunderstorm.png', 'thunshowers.png'),
+ 1: ( '1.png', 'thunderstorm.png', 'thunshowers.png'),
+ 2: ( '2.png', 'thunderstorm.png', 'thunshowers.png'),
+ 3: ( '3.png', 'thunderstorm.png', 'thunshowers.png'),
+ 4: ( '4.png', 'thunderstorm.png', 'thunshowers.png'),
+ 5: ( '5.png', '', 'rainsnow.png'),
+ 6: ( '6.png', '', 'rainsnow.png'),
+ 7: ( '7.png', '', 'rainsnow.png'),
+#cloudy.png
+#flurries.png
+#fog.png
+#lshowers.png
+#mcloudy.png
+#pcloudy.png
+#rainsnow.png
+#showers.png
+#snowshow.png
+#sunny.png
+#thunshowers.png
+ 8: ( '8.png', 'freezingfog.png', 'fog.png'),
+ 9: ( '9.png', 'drizzle.png', 'fog.png'),
+ 10: ('10.png', 'freezingrain.png', 'rainsnow.png'),
+ 11: ('11.png', 'lightrain.png', 'lshowers.png'),
+ 12: ('12.png', 'rain.png', 'showers.png'),
+ 13: ('13.png', '', 'flurries.png'),
+ 14: ('14.png', '', 'pcloudy.png'),
+ 15: ('15.png', '', 'thunshowers.png'),
+ 16: ('16.png', '', 'thunshowers.png'),
+ 17: ('17.png', '', 'showers.png'),
+ 18: ('18.png', '', 'showers.png'),
+ 19: ('19.png', '', 'rainsnow.png'),
+ 20: ('20.png', 'mist.png', 'fog.png'),
+ 21: ('21.png', '', 'cloudy.png'),
+ 22: ('22.png', '', 'flurries.png'),
+ 23: ('23.png', '', 'mcloudy.png'),
+ 24: ('24.png', '', 'thunshowers.png'),
+ 25: ('25.png', '', 'pcloudy.png'),
+ 26: ('26.png', 'cloudy.png', 'rainsnow.png'),
+ 27: ('27.png', 'mostlycloudy-n.png', 'lshowers.png'),
+ 28: ('28.png', 'mostlycloudy.png', 'showers.png'),
+ 29: ('29.png', 'partlycloudy-n.png', 'pcloudy.png'),
+ 30: ('30.png', 'partlycloudy.png', 'pcloudy.png'),
+ 31: ('31.png', 'clear-n.png', 'sunny.png'),
+ 32: ('32.png', 'sunny.png', 'sunny.png'),
+ 33: ('33.png', 'mostlyclear.png', 'sunny.png'),
+ 34: ('34.png', 'mostlysunny.png', 'sunny.png'),
+ 35: ('35.png', '', 'thunshowers.png'),
+ 36: ('36.png', '', 'thunshowers.png'),
+ 37: ('37.png', '', 'thunshowers.png'),
+ 38: ('38.png', '', 'sunny.png'),
+ 39: ('39.png', '', 'thunshowers.png'),
+ 30: ('40.png', 'heavyrain.png', 'showers.png'),
+ 41: ('41.png', 'snowshowers.png', 'snowshow.png'),
+ 42: ('42.png', '', 'rainsnow.png'),
+ 43: ('43.png', '', 'showers.png'),
+ 44: ('44.png', '', 'showers.png'),
+ 45: ('45.png', '', 'snowshow.png'),
+ 46: ('46.png', '', 'snowshow.png'),
+ 47: ('47.png', '', 'rainsnow.png'),
+ 48: ('48.png', '', 'rainsnow.png'),
}
def wget(url):
- """
- """
+ ''' get a file from the url '''
print 'wget(%s)' % (url)
txdata = None
txheaders = {
@@ -203,38 +149,28 @@
}
req = urllib2.Request(url, txdata, txheaders)
try:
+ t1 = time.time()
response = urllib2.urlopen(req)
try:
data = response.read()
finally:
response.close()
+ t2 = time.time()
if response.msg == 'OK':
return data
+ _debug_('Downloaded "%s" in %.1f seconds' % (url, t2 - t1))
except urllib2.HTTPError, error:
print 'getting %r failed: %s' % (url, error)
except ValueError, error:
- print 'invalid url %r failed: %s' % (url, error)
- fd = open(url)
- data = fd.read()
- fd.close()
- return data
- return None
-
-
-def wget2(iUrl):
- print 'wget(iUrl)'
- for i in range(3):
try:
- t1 = time.time()
- fd = urllib.urlopen(iUrl)
+ fd = open(url)
data = fd.read()
fd.close()
- t2 = time.time()
- print "Weather download: ", iUrl, "-", "%.1f" % (t2-t1), "sec"
return data
- except IOError:
- print "retrying wget '%s'" % (iUrl,)
- pass
+ except:
+ print 'invalid url %r failed: %s' % (url, error)
+ return None
+
def toCelcius(fTemp):
print 'toCelcius(fTemp)'
@@ -265,7 +201,7 @@
class PluginInterface(plugin.MainMenuPlugin):
- """
+ '''
A plugin to obtain more detailed weather forecast information
To activate, put the following lines in local_conf.py:
@@ -280,17 +216,20 @@
where <val#> is a zipcode or an airport code
and <metric> (1 == convert to SI Units; 0 == do not convert)
and <location name#> is a custom name you wish to use for this location
- """
- # make an init func that creates the cache dir if it don't exist
+ '''
def __init__(self):
- print '__init__(self)'
+ '''
+ '''
+ print '__init__()'
if not hasattr(config, 'PLUGIN_WEATHER_LOCATIONS'):
self.reason = 'PLUGIN_WEATHER_LOCATIONS not defined'
return
plugin.MainMenuPlugin.__init__(self)
def config(self):
- print 'config(self)'
+ '''
+ '''
+ print 'config()'
return [
('ONECLICK_LOCATIONS', [('USNC0559', 0)], 'Location codes for
current conditions and forecasts'),
('ONECLICK_URL_CURC',
'http://ff.1click.weather.com/weather/local/%s?cc=*%s', 'Current Conditions
URL'),
@@ -300,14 +239,16 @@
]
def items(self, parent):
+ '''
+ '''
print 'items(self, parent)'
return [ WeatherMainMenu(parent) ]
class WeatherItem(Item):
- """
- Item for the menu for one rss feed
- """
+ '''
+ Item for the menu for one feed
+ '''
def __init__(self, parent, location):
print '__init__(parent=%r, location=%r)' % (parent, location)
Item.__init__(self, parent)
@@ -322,23 +263,37 @@
self.name = None
self.city = None
self.state = None
+ self.tm = None
+ self.latitude = None
+ self.longitude = None
+ self.sunrise = None
+ self.sunset = None
+
self.unit_t = None
self.unit_d = None
self.unit_s = None
self.unit_p = None
self.unit_r = None
self.country = None
- self.curTemp = None
- self.updated = None
- self.curIcon = None
- self.curWind = None
- self.windDir = None
- self.barometer = None
- self.curHumid = None
- self.curFeel = None
- self.uvIndex = None
+
+ self.updated = 0.0
+ self.observation_station = None
+ self.temperature = None
+ self.feeling = None
+ self.current_conditions = None
+ self.icon = None
+ self.pressure = None
+ self.pressure_change = None
+ self.wind_speed = None
+ self.wind_direction = None
+ self.humidity = None
self.visibility = None
- self.shortdesc = None
+ self.uv_index = None
+ self.uv_type = None
+ self.dew_point = None
+ self.moon_icon = None
+ self.moon_phase = None
+
self.description = None
self.forecastData = None
self.pastTime = 0
@@ -384,7 +339,9 @@
self.weatherMapData = None
self.cacheDir = '%s/weather_%s' % (config.FREEVO_CACHEDIR,
self.location)
- self.cacheFile = '%s/data' % (self.cacheDir,)
+ self.cacheElocation = '%s/location' % (self.cacheDir,)
+ self.cacheCurrent = '%s/current' % (self.cacheDir,)
+ self.cacheForecast = '%s/forecast' % (self.cacheDir,)
self.mapFile = '%s/map' % (self.cacheDir,)
if not os.path.isdir(self.cacheDir):
os.mkdir(self.cacheDir,
stat.S_IMODE(os.stat(config.FREEVO_CACHEDIR)[stat.ST_MODE]))
@@ -394,104 +351,157 @@
self.getForecast()
def start_detailed_interface(self, arg=None, menuw=None):
- print 'start_detailed_interface(self, arg=None, menuw=None)'
+ ''' detail handler '''
+ print 'start_detailed_interface(arg=%r, menuw=%r)' % (arg, menuw)
WeatherDetailHandler(arg, menuw, self)
def actions(self):
- print 'actions(self)'
- """
+ '''
return a list of actions for this item
- """
+ '''
+ print 'actions()'
return [ (self.start_detailed_interface, _('Show Weather Details')) ]
def isValid(self):
- print 'isValid(self)'
+ ''' reports is an error was detected '''
+ print 'isValid()'
return not self.error
def getLastUpdated(self):
- print 'getLastUpdated(self)'
- if self.ismetric:
- # day / month / year 24hour:min:sec
- return _("Last updated: %s") % (time.strftime("%d/%m/%Y %H:%M:%S",
time.localtime(self.last_update)),)
- else:
- # month / day / year 12hour:min:sec [AM|PM]
- return _("Last updated: %s") % (time.strftime("%m/%d/%Y %I:%M:%S
%p", time.localtime(self.last_update)),)
+ '''
+ '''
+ print 'getLastUpdated() "%s"' % self.updated
+ value = self.updated.replace(' Local Time', '')
+ print 'getLastUpdated() "%r"' % value
+ # looks to be a bit locale specific
+ try:
+ print 'getLastUpdated() "%r"' % time.strptime(value, "%m/%d/%y
%H:%M %p")
+ updated = time.mktime(time.strptime(value, "%m/%d/%y %H:%M %p"))
+ print time.strftime("%c %Z", time.localtime(updated))
+ print time.strftime("%c %Z", time.gmtime(updated))
+ return time.strftime("%c %Z", time.localtime(updated))
+ except ValueError, e:
+ return '%s' % value
+ #if self.ismetric:
+ # return time.strftime("%d/%m/%Y %H:%M:%S",
time.localtime(self.updated))
+ #else:
+ # return time.strftime("%m/%d/%Y %I:%M:%S %p",
time.localtime(self.updated))
+
+ def getObservationStation(self):
+ ''' get the observation station '''
+ print 'getObservationStation()'
+ return "%s" % (self.observation_station)
+
+ def getTemperature(self):
+ print 'getTemperature()'
+ return u"%s\xb0%s" % (self.temperature, self.unit_t)
+
+ def getFeeling(self):
+ print 'getFeeling(self)'
+ return u"%s\xb0%s" % (self.feeling, self.unit_t)
+
+ def getCurrentCondition(self):
+ ''' gets the current conditions '''
+ print 'getCurrentCondition()'
+ return "%s" % (self.current_conditions)
+
+ def getIcon(self):
+ ''' gets the current conditions icon '''
+ print 'getIcon()'
+ return "%s" % (self.icon)
+
+ def getPressure(self):
+ print 'getPressure(self)'
+ return "%s %s" % (self.pressure, self.unit_p)
+
+ def getPressureChange(self):
+ print 'getPressureChange(self)'
+ return "%s" % (self.pressure_change)
+
+ def getWindDir(self):
+ print 'getWindDir(self)'
+ return "%s" % (self.wind_direction)
+
+ def getWindSpeed(self):
+ print 'getWindSpeed(self)'
+ return "%s %s" % (self.wind_speed, self.unit_s)
def getHumidity(self):
print 'getHumidity(self)'
- return "%s %%" % (self.curHumid,)
-
- def getBarometer(self):
- print 'getBarometer(self)'
- return "%s %s" % (self.barometer, self.unit_p)
-
- def getWind(self):
- print 'getWind(self)'
- return "%s %s" % (self.curWind, self.unit_s)
-
- def getTemp(self):
- print 'getTemp(self)'
- return u"%s\xb0%s" % (self.curTemp, self.unit_t)
-
- def getFeel(self):
- print 'getFeel(self)'
- return u"%s\xb0%s" % (self.curFeel, self.unit_t)
+ return "%s %%" % (self.humidity,)
def getVisibility(self):
print 'getVisibility(self)'
- if float(self.visibility) == 999.00:
- return _("Unlimited")
return "%s %s" % (self.visibility, self.unit_d)
+ def getUvIndex(self):
+ print 'getUvIndex(self)'
+ return "%s" % (self.uv_index)
+
+ def getUvType(self):
+ print 'getUvType(self)'
+ return "%s" % (self.uv_type)
+
+ def getDewPoint(self):
+ print 'getDewPoint()'
+ return u"%s\xb0%s" % (self.dew_point, self.unit_t)
+
+ def getMoonIcon(self):
+ print 'getMoonIcon()'
+ return "%s" % (self.moon_icon)
+
+ def getMoonPhase(self):
+ print 'getMoonPhase(self)'
+ return "%s" % (self.moon_phase)
+
+ def getSunrise(self):
+ print 'getSunrise(self)'
+ return "%s" % (self.sunrise)
+
+ def getSunset(self):
+ print 'getSunset(self)'
+ return "%s" % (self.sunset)
+
+
def getForecast(self, force=0):
print 'getForecast(self, force=0)'
'''grab the forecast, updating for the website if needed'''
# check cache
try:
- if force or self.needRefresh():
+ if force or self.needsRefresh():
self.updateData()
else:
self.loadFromCache()
- except Exception,e:
+ except IOError, e:
self.error = 1
- print "ERROR obtaining forecast data for '%s':%s" %
(self.location, e)
+ print "failed to update data for '%s': %s" % (self.location, e)
else:
# set the last update timestamp
- self.last_update = os.path.getmtime(self.cacheFile)
+ self.last_update = os.path.getmtime(self.cacheCurrent)
# now convert the self.weatherData structure to parsable
information
- self.convertWeatherData1()
- #try:
- # self.convertWeatherData1()
- #except:
- # self.error = 1
- # import traceback, sys
- # print "ERROR parsing forecast data for '%s'" %
(self.location,)
- # print "\tThis could indicate a failed download of weather
data from msnbc. "\
- # "You can confirm this by examining the contents of the
file '%s'. "\
- # "Below is also the traceback indicating where we
discovered the problem "\
- # "with the weather file. If the weather file appears
intact, please report " \
- # "this to the '[EMAIL PROTECTED]'\n" % (self.cacheFile,)
- # output = apply(traceback.format_exception, sys.exc_info())
- # output = ''.join(output)
- # output = urllib.unquote(output)
- # print output
+ self.convertWeatherData()
+ try:
+ self.convertWeatherData()
+ except Exception, error:
+ print 'Failed to convert data for %s: %s' % (self.location,
error)
- def needRefresh(self):
+ def needsRefresh(self):
'''is the cache too old?'''
- print 'needRefresh(self)'
- return 1
- if (os.path.isfile(self.cacheFile) == 0 or \
- (abs(time.time() - os.path.getmtime(self.cacheFile)) >
WEATHER_AGE)):
+ print 'needsRefresh(self)'
+ if (os.path.isfile(self.cacheCurrent) == 0 or \
+ (abs(time.time() - os.path.getmtime(self.cacheCurrent)) >
WEATHER_AGE)):
return 1
else:
return 0
def saveToCache(self):
print 'saveToCache(self)'
- util.save_pickle(self.weatherData, self.cacheFile)
+ util.save_pickle(self.elocationData, self.cacheElocation)
+ util.save_pickle(self.currentData, self.cacheCurrent)
+ util.save_pickle(self.forecastData, self.cacheForecast)
# attempt to save weathermap
try:
if self.weatherMapData is not None:
@@ -503,12 +513,14 @@
def loadFromCache(self):
print 'loadFromCache(self)'
- self.weatherData = util.read_pickle(self.cacheFile)
+ self.elocationData = util.read_pickle(self.cacheElocation)
+ self.currentData = util.read_pickle(self.cacheCurrent)
+ self.forecastData = util.read_pickle(self.cacheForecast)
try:
size = int(os.stat(self.mapFile)[6])
except:
- _debug_("failed attempting to load %s radar map from cache" %
(self.location,), config.DERROR)
+ _debug_("failed attempting to load %s radar map from cache" %
(self.location,), config.DWARNING)
pass
else:
imgfd = os.open(self.mapFile, os.R_OK)
@@ -516,24 +528,53 @@
os.close(imgfd)
def updateData(self):
+ '''update the cache data from the 1click service
+ @notes the elocation is not updated as it is static
+ '''
print 'updateData(self)'
if GUI:
popup = PopupBox(text=_('Fetching Weather for %s...') %
self.popupParam)
popup.show()
- # parse the document
- self.currentData = wget(self.url_curc)
+ if not os.path.exists(self.cacheElocation):
+ try:
+ elocationData = wget(self.url_eloc)
+ self.elocationData = elocationData
+ except Exception, error:
+ print 'Failed to get extended location data for %s: %s' %
(self.location, error)
+ else:
+ self.elocationData = util.read_pickle(self.cacheElocation)
+
+ try:
+ self.currentData = wget(self.url_curc)
+ print 'currentData:', self.currentData
+ except Exception, error:
+ print 'Failed to get the current conditions data for %s: %s' %
(self.location, error)
+ if os.path.exists(self.cacheCurrent):
+ self.currentData = util.read_pickle(self.cacheCurrent)
+ else:
+ self.currentData = None
try:
- self.currentData = wget(self.url_curc)
self.forecastData = wget(self.url_dayf)
- self.locationData = wget(self.url_eloc)
- except:
- if GUI:
- popup.destroy()
- raise 'Weather: failed attempting to grab forecast for %s' %
self.location
+ print 'forecastData:', self.forecastData
+ except Exception, error:
+ print 'Failed to get the forecast data for %s: %s' %
(self.location, error)
+ if os.path.exists(self.cacheForecast):
+ self.forecastData = util.read_pickle(self.cacheForecast)
+ else:
+ self.forecastData = None
- #TODO: Get description from
http://weather.noaa.gov/pub/data/forecasts/zone/nc/ncz041.txt
+ if GUI:
+ popup.destroy()
+ if not self.currentData or not self.forecastData:
+ # raise an error
+ return
+
+ self.saveToCache()
+ return
+
+ #FIXME this needs looking at
# obtain radar map
if GUI:
popup.destroy()
@@ -544,30 +585,27 @@
self.maplink = (self.radarUrl)
if self.maplink is None:
# get the first web page
- for attempt in range(3):
- weatherPage = '' #wget (self.mapurl)
- try:
- # find link to map page
- regexp = re.compile ('if \(isMinNS4\) var mapNURL =
"[^"]*";', re.IGNORECASE )
- results = regexp.search(weatherPage)
- (start, end) = results.span()
- # TODO: I don't like having fixed length offsets from
start, end
- weatherPage2 = "http://www.weather.com/%s" %
(weatherPage[start+30:end-2],)
-
- mapPage = '' #wget (weatherPage2)
- # find a link to the real doplay map
- regexp = re.compile('<img NAME="mapImg"
SRC="http://image.weather.com[^"]*jpg"', re.IGNORECASE)
- results = regexp.search(mapPage)
- (start, end) = results.span()
- # TODO: I don't like having fixed length offsets from
start, end
- self.maplink = mapPage[start+24:end-1]
- break;
- except:
- print "Retrying [%d] %s" % (attempt,self.mapurl)
- pass
+ weatherPage = wget(self.mapurl)
+ try:
+ # find link to map page
+ regexp = re.compile ('if \(isMinNS4\) var mapNURL =
"[^"]*";', re.IGNORECASE )
+ results = regexp.search(weatherPage)
+ (start, end) = results.span()
+ # TODO: I don't like having fixed length offsets from
start, end
+ weatherPage2 = "http://www.weather.com/%s" %
(weatherPage[start+30:end-2],)
+
+ mapPage = '' #wget (weatherPage2)
+ # find a link to the real doplay map
+ regexp = re.compile('<img NAME="mapImg"
SRC="http://image.weather.com[^"]*jpg"', re.IGNORECASE)
+ results = regexp.search(mapPage)
+ (start, end) = results.span()
+ # TODO: I don't like having fixed length offsets from
start, end
+ self.maplink = mapPage[start+24:end-1]
+ except Exception, error:
+ print "Failed getting map %s: %s" % (self.mapurl, error)
# pull down the map locally
try:
- self.weatherMapData = '' #wget(self.maplink)
+ self.weatherMapData = wget(self.maplink)
except:
print 'Weather ERROR: failed attempting to download radar map
from %s' % self.maplink
except:
@@ -581,30 +619,29 @@
output = urllib.unquote(output)
print output
- #write the file
- self.saveToCache()
-
if GUI:
popup.destroy()
+ self.saveToCache()
+
- def convertWeatherData1(self):
- """
- """
- print 'convertWeatherData1(self)'
- #print self.locationData
- locationTree = ET.XML(self.locationData)
- location = WeatherData(locationTree)
- currentTree = ET.XML(self.currentData)
- current = WeatherData(currentTree)
- forecastTree = ET.XML(self.forecastData)
- forecast = WeatherData(forecastTree)
+ def convertWeatherData(self):
+ '''
+ convert the xml weather information for the skin
+ '''
+ print 'convertWeatherData(self)'
+ print self.elocationData
+ print self.currentData
+ print self.forecastData
+ elocation = WeatherData(ET.XML(self.elocationData))
+ current = WeatherData(ET.XML(self.currentData))
+ forecast = WeatherData(ET.XML(self.forecastData))
if not self.name:
- self.name = location.loc.dnam
+ self.name = elocation.loc.dnam
- dnam = location.loc.dnam.split(', ')
- ctry = location.eloc.ctry
+ dnam = elocation.loc.dnam.split(', ')
+ ctry = elocation.eloc.ctry
print dnam
if ctry in ('US'):
self.city = dnam[0]
@@ -616,15 +653,6 @@
self.country = dnam[1]
print 'city=%s, state=%s, country=%s' % (self.city, self.state,
self.country)
- self.unit_t = current.head.ut
- self.unit_d = current.head.ud
- self.unit_s = current.head.us
- self.unit_p = current.head.up
- self.unit_r = current.head.ur
-
- self.curTemp = current.cc.tmp
- self.updated = current.cc.lsup
-
# reset variables
self.date = []
self.weatherIcon = []
@@ -632,17 +660,40 @@
self.lowTemp = []
self.weatherType = []
- self.curIcon = current.cc.icon
- self.curWind = current.cc.wind.s
- self.windDir = current.cc.wind.t
- self.barometer = current.cc.bar.r
- self.curHumid = current.cc.hmid
- self.curFeel = current.cc.flik
- self.uvIndex = current.cc.uv.i
+ self.unit_t = current.head.ut
+ self.unit_d = current.head.ud
+ self.unit_s = current.head.us
+ self.unit_p = current.head.up
+ self.unit_r = current.head.ur
+
+ self.tm = current.loc.tm
+ self.latitude = current.loc.lat
+ self.longitude = current.loc.lon
+ self.sunrise = current.loc.sunr
+ self.sunset = current.loc.suns
+ self.zone = current.loc.zone
+
+ self.updated = current.cc.lsup
+ self.observation_station = current.cc.obst
+ self.temperature = current.cc.tmp
+ self.feeling = current.cc.flik
+ self.current_conditions = current.cc.t
+ self.icon = current.cc.icon
+ self.pressure = current.cc.bar.r
+ self.pressure_change = current.cc.bar.d
+ self.wind_speed = current.cc.wind.s
+ self.wind_direction = current.cc.wind.t
+ self.humidity = current.cc.hmid
self.visibility = current.cc.vis
- self.shortdesc = current.cc.t
- self.description = '%s %s %s' % (self.shortdesc, _("at"),
self.getTemp())
- self.image = self.setWeatherIcon(self.curIcon)
+ self.uv_index = current.cc.uv.i
+ self.uv_type = current.cc.uv.t
+ self.dew_point = current.cc.dewp
+ self.moon_icon = current.cc.moon.icon
+ self.moon_phase = current.cc.moon.t
+
+ self.description = '%s %s %s' % (self.current_conditions, _("at"),
self.getTemperature())
+ print self.icon
+ self.image = self.getWeatherIcon(self.icon)
for day in forecast.dayf.days:
self.date.append(day.t)
@@ -650,14 +701,14 @@
self.lowTemp.append(day.low)
for part in day.parts:
if part.p == 'd':
- self.weatherIcon.append(self.setWeatherIcon(part.icon))
+ self.weatherIcon.append(self.getWeatherIcon(part.icon))
self.weatherType.append(part.t)
#for i in dir(self):
# print i, self[i]
- def setWeatherIcon(self, num):
+ def getWeatherIcon(self, num):
'''obtain the weather icons for multiple day forecast'''
print 'setWeatherTypeIcon(self)'
@@ -668,102 +719,11 @@
return icon
-class WeatherType:
- def __init__(self, iNum=0, iName="", iIcon=""):
- #print '__init__(self, iNum=0, iName="", iIcon="")'
- self.number = iNum
- self.name = iName
- self.icon = iIcon
-
- def setNumber(self, n):
- #print 'setNumber(self, n)'
- self.number = n
-
- def setName(self, n):
- #print 'setName(self, n)'
- self.name = n
-
- def setIcon(self, n):
- #print 'setIcon(self, n)'
- self.icon = n
-
- def getNumber(self):
- #print 'getNumber(self)'
- return self.number
-
- def getName(self):
- #print 'getName(self)'
- return _(self.name)
-
- def getIcon(self):
- #print 'getIcon(self)'
- return self.icon
-
-class WeatherTypesClass:
- def __init__(self):
- print '__init__(self)'
- self.wtypes = []
- self.num_lookup = {} # reverse hash to quickly get a Weathertype w/ a
number
- self.name_lookup = {} # reverse hash to quickly get a Weathertype w/ a
name
- self.icon_lookup = {} # reverse hash to quickly get a Weathertype w/ a
icon
- self.loadWeatherTypes()
- def loadWeatherTypes(self):
- print 'loadWeatherTypes(self)'
-
- for icdata in WEATHER_DATA:
- try:
- wtype = WeatherType()
- wtype.setNumber (icdata[0])
- wtype.setName (icdata[1])
- wtype.setIcon (icdata[2])
-
- # populate reverse dictionaries
- self.num_lookup[ wtype.getNumber() ] = len(self.wtypes)
- self.name_lookup[ wtype.getName() ] = len(self.wtypes)
- self.icon_lookup[ wtype.getIcon() ] = len(self.wtypes)
-
- self.wtypes.append (wtype)
- except:
- pass
-
- def findType(self, number=None, name=None, icon=None):
- print 'findType(self, number=None, name=None, icon=None)'
- ''' return a type given a type number '''
- if number:
- try:
- idx = self.num_lookup[number]
- return self.wtypes[ idx ]
- except:
- return None
- elif name:
- try:
- idx = self.name_lookup[name]
- return self.wtypes[ idx ]
- except:
- return None
- elif icon:
- try:
- idx = self.icon_lookup[icon]
- return self.wtypes[ idx ]
- except:
- return None
- else:
- print 'Unknown type requested number=%s name=%s icon=%s' %
(number, name, icon)
- return None
-
- def __len__(self):
- print '__len__(self)'
- return len(self.wtypes)
-
- def __getitem__(self, i):
- print '__getitem__(self, i)'
- return self.wtypes[i]
-
class WeatherMainMenu(Item):
- """
+ '''
this is the item for the main menu and creates the list
of Weather Locations in a submenu.
- """
+ '''
def __init__(self, parent):
print '__init__(self, parent)'
Item.__init__(self, parent, skin_type='weather')
@@ -772,17 +732,17 @@
def actions(self):
print 'actions(self)'
- """
+ '''
return a list of actions for this item
- """
+ '''
items = [ (self.create_locations_menu , _('Locations')) ]
return items
def __call__(self, arg=None, menuw=None):
print '__call__(self, arg=None, menuw=None)'
- """
+ '''
call first action in the actions() list
- """
+ '''
if self.actions():
return self.actions()[0][0](arg=arg, menuw=menuw)
@@ -817,9 +777,9 @@
menuw.refresh()
class WeatherDetailHandler:
- """
+ '''
A handler class to display several detailed forecast screens and catch
events
- """
+ '''
def __init__(self, iArg=None, iMenuw=None, iWeather=None):
print '__init__(self, iArg=None, iMenuw=None, iWeather=None)'
self.arg = iArg
@@ -842,8 +802,8 @@
skin.draw('weather', self)
def prevSkin(self):
- print 'prevSkin(self)'
- '''decriment self.curSkin'''
+ print 'prevSkin()'
+ '''decrements the skin number round to the last skin'''
self.curSkin -= 1
# out of bounds check, reset to size of skins array
@@ -852,38 +812,36 @@
self.subtitle = self.subtitles[self.curSkin]
def nextSkin(self):
- print 'nextSkin(self)'
- '''increment self.curSkin'''
+ '''increment the skin number round to the first skin'''
+ print 'nextSkin()'
self.curSkin += 1
+ print 'len(self.skins)=%s' % len(self.skins)
# out of bounds check, reset to 0
if self.curSkin >= len(self.skins):
self.curSkin = 0
self.subtitle = self.subtitles[self.curSkin]
def eventhandler(self, event, menuw=None):
- print 'eventhandler(self, event, menuw=None)'
'''eventhandler'''
+ print 'eventhandler(event=%s, menuw=%r)' % (event, menuw)
if event == 'MENU_BACK_ONE_MENU':
rc.app(None)
self.menuw.show()
return True
elif event == 'MENU_SELECT':
- # TODO: update the current forecast data, and refresh
self.weather.getForecast(force=1)
skin.clear()
skin.draw('weather', self)
return True
elif event in ('MENU_DOWN', 'MENU_RIGHT'):
- # Fire up the next skin
self.nextSkin()
skin.draw('weather', self)
return True
elif event in ('MENU_UP', 'MENU_LEFT'):
- # Fire up the previous skin
self.prevSkin()
skin.draw('weather', self)
return True
@@ -891,7 +849,6 @@
return False
if __name__ == '__main__':
- weatherTypes = WeatherTypesClass()
for location in config.PLUGIN_WEATHER_LOCATIONS:
print location
weather_item = WeatherItem(None, location)
@@ -900,11 +857,9 @@
sys.exit(1)
class WeatherBaseScreen(skin.Area):
- """
- A base class for weather screens to inherit from, provides common
members+methods
- """
+ ''' A base class for weather screens to inherit from, provides common
members+methods '''
def __init__(self):
- print 'WeatherBaseScreen.__init__(self)'
+ print 'WeatherBaseScreen.__init__()'
skin.Area.__init__(self, 'content')
# Weather display fonts
@@ -921,7 +876,9 @@
self.update_week, self.update_doplar)
def update_day(self):
- print 'update_day(self)'
+ '''
+ '''
+ print 'update_day()'
# display data
text = _('Humidity')
value = self.parent.weather.getHumidity()
@@ -937,14 +894,14 @@
x=x_col2, y=y_start, height=-1, align_h='left')
text = _('Pressure')
- value = self.parent.weather.getBarometer()
+ value = self.parent.weather.getPressure()
self.write_text(text, self.key_font, self.content,
x=x_col1, y=y_start+y_inc, height=-1, align_h='left')
self.write_text(value, self.val_font, self.content,
x=x_col2, y=y_start+y_inc, height=-1, align_h='left')
text = _('Wind')
- value = '%s %s %s' % (self.parent.weather.windDir, _('at'),
self.parent.weather.getWind())
+ value = '%s %s %s' % (self.parent.weather.getWindDir(), _('at'),
self.parent.weather.getWindSpeed())
y_start += y_inc
self.write_text(text, self.key_font, self.content,
x=x_col1, y=y_start+y_inc, height=-1, align_h='left')
@@ -952,7 +909,7 @@
x=x_col2, y=y_start+y_inc, height=-1, align_h='left')
text = _('Wind Chill')
- value = self.parent.weather.getFeel()
+ value = self.parent.weather.getFeeling()
y_start += y_inc
self.write_text(text, self.key_font, self.content,
x=x_col1, y=y_start+y_inc, height=-1, align_h='left')
@@ -968,7 +925,7 @@
x=x_col2, y=y_start+y_inc, height=-1, align_h='left')
text = _('UV Index')
- value = self.parent.weather.uvIndex
+ value = self.parent.weather.getUvType()
y_start += y_inc
self.write_text(text, self.key_font, self.content,
x=x_col1, y=y_start+y_inc, height=-1, align_h='left')
@@ -983,12 +940,12 @@
int(200*self.xmult), int(150*self.ymult)))
y_start = self.content.y + (200*self.ymult)
- self.write_text(self.parent.weather.shortdesc,
+ self.write_text(self.parent.weather.getCurrentCondition(),
self.key_font, self.content,
x=x_start, y=y_start,
width=200*self.xmult, height=-1, align_h='center')
y_start = self.content.y + (250*self.ymult)
- self.write_text(self.parent.weather.getTemp(),
+ self.write_text(self.parent.weather.getTemperature(),
self.big_font, self.content,
x=x_start, y=y_start,
width=200*self.xmult, height=-1, align_h='center')
@@ -1002,36 +959,40 @@
def update_forecast(self):
- print 'update_forecast(self)'
'''
- this screen is extremely useless, all it\'s doing is putting text
+ this screen is extremely useless, all it's doing is putting text
around the day view. It would be nice if I could use the same source
that the gnome-applet weather applet uses for detailed forecast data
'''
+ print 'update_forecast()'
x_start = self.content.x + (20 * self.xmult)
y_start = self.content.y + (30 * self.xmult)
+ weather = self.parent.weather
lines = []
- lines.append('%s %s %s %s.' % (\
- _('Today, a high of'), self.parent.weather.highTemp[0], \
- _('and a low of'), self.parent.weather.lowTemp[0]))
- lines.append('%s %s %s' % (_("Currently, there is a humidity of"),
- self.parent.weather.getHumidity(), _("and"),))
-
- text = _("the winds are ")
- if self.parent.weather.windDir == "CALM":
- text += "%s. " % (_("calm"),)
- else:
- text += "%s %s %s %s." % (\
- _("coming in at"), self.parent.weather.getWind(), \
- _("from the"), self.parent.weather.windDir)
- lines.append(text)
-
- if float(self.parent.weather.visibility) == 999.00:
- lines.append(_("Visibility will be unlimited today"))
- else:
- lines.append("%s %s." % (\
- _("There will be a visibility of"),
self.parent.weather.getVisibility(),))
+ try:
+ lines.append('%s %s' % (_('As of:'), weather.getLastUpdated()))
+ lines.append('%s %s' % (_('in'), weather.getObservationStation()))
+ lines.append(' %s' % (weather.getCurrentCondition()))
+ lines.append(' %s %s' % (_('Temperature:'),
weather.getTemperature()))
+ lines.append(' %s %s' % (_('Dew Point:'), weather.getDewPoint()))
+ lines.append(' %s %s' % (_('Humidity:'), weather.getHumidity()))
+ lines.append(' %s %s' % (_('Visibility:'),
weather.getVisibility()))
+ lines.append(' %s %s %s %s' %
+ (_('Pressure:'), weather.getPressure(), _('and'),
weather.getPressureChange()))
+ lines.append(' %s %s %s %s' %
+ (_('Winds:'), weather.getWindDir(), _('at'),
weather.getWindSpeed()))
+ lines.append('%s' % (_('Tonight:')))
+ lines.append(' %s %s' % (_('Sunset:'), weather.getSunset()))
+ lines.append(' %s %s' % (_('Moon Phase:'),
weather.getMoonPhase()))
+ except Exception, e:
+ print e
+ import traceback, sys
+ output = apply(traceback.format_exception, sys.exc_info())
+ output = ''.join(output)
+ output = urllib.unquote(output)
+ print output
+ print lines
y = y_start
for line in lines:
@@ -1041,7 +1002,9 @@
def update_week(self):
- print 'update_week(self)'
+ '''
+ '''
+ print 'update_week()'
x_start = self.content.x + (10 * self.xmult)
y_start = self.content.y + (10 * self.xmult)
@@ -1084,7 +1047,9 @@
day += 1
def update_doplar(self):
- print 'update_doplar(self)'
+ '''
+ '''
+ print 'update_doplar()'
if self.parent.weather.weatherMapData is None:
x_start = self.content.x + (10 * self.xmult)
y_start = self.content.y + (10 * self.xmult)
@@ -1096,12 +1061,12 @@
self.content.height))
def update_content(self):
- print 'update_content(self)'
+ ''' update the contents of the skin '''
+ print 'update_content()'
self.parent = self.menu
self.content = self.calc_geometry(self.layout.content,
copy_object=True)
self.update_functions[self.menu.curSkin]()
# create one instance of the WeatherType class
-weatherTypes = WeatherTypesClass()
skin.register ('weather', ('screen', 'subtitle', 'title', 'plugin',
WeatherBaseScreen()))
Modified: branches/rel-1/testing/Duncan/weather/1click/weatherdata.py
==============================================================================
--- branches/rel-1/testing/Duncan/weather/1click/weatherdata.py (original)
+++ branches/rel-1/testing/Duncan/weather/1click/weatherdata.py Sat Sep 22
17:44:52 2007
@@ -425,20 +425,21 @@
if __name__ == '__main__':
- tree=ET.parse('SZXX0033-eloc.xml')
- location = WeatherData(tree)
- tree=ET.parse('SZXX0033-cc.xml')
- conditions = WeatherData(tree)
- tree=ET.parse('SZXX0033-dayf5.xml')
- forecast = WeatherData(tree)
+ location_tree=ET.parse('SZXX0033-eloc.xml')
+ location = WeatherData(location_tree)
+ conditions_tree=ET.parse('SZXX0033-cc.xml')
+ conditions = WeatherData(conditions_tree)
+ forecast_tree=ET.parse('SZXX0033-dayf5.xml')
+ forecast = WeatherData(forecast_tree)
print dir(forecast)
for i in dir(forecast):
item = eval('forecast.%s' % (i))
#print i, type(item), item
#pprint(forecast)
- #f = open('forecast.pickle', 'w')
+ f = open('forecast.pickle', 'w')
#pickle.dump(forecast, f, pickle.HIGHEST_PROTOCOL)
- #f.close()
+ #pickle.dump(forecast_tree, f, pickle.HIGHEST_PROTOCOL)
+ f.close()
print dir(forecast.loc)
print forecast.loc.id
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog