Author: duncan
Date: Mon Sep 24 15:44:44 2007
New Revision: 9893
Log:
Fixed weather maps
Fixed pressure
Modified:
branches/rel-1/testing/Duncan/weather/1click/oneclick.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 Mon Sep 24
15:44:44 2007
@@ -8,7 +8,7 @@
#
# Todo:
# X pull down weather on demand MENU_SELECT (need to fix popup behavior)
-# X Ability to specify custom location name in PLUGIN_WEATHER_LOCATIONS
+# X Ability to specify custom location name in ONECLICK_LOCATIONS
# - get location name back onto details screen
# - i18n support
# - a freevo helper to grab weather data behind the scenes
@@ -16,7 +16,7 @@
# activate:
#
# plugin.activate('oneclick', level=45)
-# PLUGIN_WEATHER_LOCATIONS = [ ("USNC0559", 0, "Home sweet home") ]
+# ONECLICK_LOCATIONS = [ ("USNC0559", "", "Home sweet home", 0) ]
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
@@ -76,7 +76,7 @@
WEATHER_DIR = os.path.join(config.SHARE_DIR, 'images', 'weather')
WEATHER_DIR = '/sources/svn/freevo-1.x/testing/Duncan/weather/1click/images'
-#FIXME These mappings are incorrect
+#FIXME Not sure that all of these are correctly named
WEATHER_ICONS = {
# icon twc.com image fallback
'0': ( 'twc/0.png', 'thunderstorm.png', 'thunshowers.png'),
@@ -84,66 +84,56 @@
'2': ( 'twc/2.png', 'thunderstorm.png', 'thunshowers.png'),
'3': ( 'twc/3.png', 'thunderstorm.png', 'thunshowers.png'),
'4': ( 'twc/4.png', 'thunderstorm.png', 'thunshowers.png'),
- '5': ( 'twc/5.png', '', 'rainsnow.png'),
- '6': ( 'twc/6.png', '', 'rainsnow.png'),
- '7': ( 'twc/7.png', '', 'rainsnow.png'),
+ '5': ( 'twc/5.png', 'sleet.png', 'rainsnow.png'),
+ '6': ( 'twc/6.png', 'hail.png', 'rainsnow.png'),
+ '7': ( 'twc/7.png', 'mixed.png', 'rainsnow.png'),
'8': ( 'twc/8.png', 'freezingfog.png', 'fog.png'),
'9': ( 'twc/9.png', 'drizzle.png', 'fog.png'),
'10': ('twc/10.png', 'freezingrain.png', 'rainsnow.png'),
'11': ('twc/11.png', 'lightrain.png', 'lshowers.png'),
'12': ('twc/12.png', 'rain.png', 'showers.png'),
- '13': ('twc/13.png', '', 'flurries.png'),
- '14': ('twc/14.png', '', 'pcloudy.png'),
- '15': ('twc/15.png', '', 'thunshowers.png'),
- '16': ('twc/16.png', '', 'thunshowers.png'),
- '17': ('twc/17.png', '', 'showers.png'),
- '18': ('twc/18.png', '', 'showers.png'),
- '19': ('twc/19.png', '', 'rainsnow.png'),
+ '13': ('twc/13.png', 'lightsnowshowers.png', 'flurries.png'),
+ '14': ('twc/14.png', 'mediumsnowshowers.png', 'flurries.png'),
+ '15': ('twc/15.png', 'freshsnow.png', 'flurries.png'),
+ '16': ('twc/16.png', 'snow.png', 'flurries.png'),
+ '17': ('twc/17.png', 'thunderstorm.png', 'thunshowers.png'),
+ '18': ('twc/18.png', 'drizzle.png', 'showers.png'),
+ '19': ('twc/19.png', 'dust.png', 'fog.png'),
'20': ('twc/20.png', 'mist.png', 'fog.png'),
- '21': ('twc/21.png', '', 'cloudy.png'),
- '22': ('twc/22.png', '', 'flurries.png'),
- '23': ('twc/23.png', '', 'mcloudy.png'),
- '24': ('twc/24.png', '', 'thunshowers.png'),
- '25': ('twc/25.png', '', 'pcloudy.png'),
- '26': ('twc/26.png', 'cloudy.png', 'rainsnow.png'),
- '27': ('twc/27.png', 'mostlycloudy-n.png', 'lshowers.png'),
- '28': ('twc/28.png', 'mostlycloudy.png', 'showers.png'),
+ '21': ('twc/21.png', 'haze.png', 'fog.png'),
+ '22': ('twc/22.png', 'smoke.png', 'fog.png'),
+ '23': ('twc/23.png', 'windy.png', 'pcloudy.png'),
+ '24': ('twc/24.png', 'windy.png', 'pcloudy.png'),
+ '25': ('twc/25.png', 'freezing.png', 'pcloudy.png'),
+ '26': ('twc/26.png', 'cloudy-n.png', 'pcloudy.png'),
+ '27': ('twc/27.png', 'mostlycloudy-n.png', 'mcloudy.png'),
+ '28': ('twc/28.png', 'mostlycloudy.png', 'mcloudy.png'),
'29': ('twc/29.png', 'partlycloudy-n.png', 'pcloudy.png'),
'30': ('twc/30.png', 'partlycloudy.png', 'pcloudy.png'),
'31': ('twc/31.png', 'clear-n.png', 'sunny.png'),
'32': ('twc/32.png', 'sunny.png', 'sunny.png'),
'33': ('twc/33.png', 'mostlyclear.png', 'sunny.png'),
'34': ('twc/34.png', 'mostlysunny.png', 'sunny.png'),
- '35': ('twc/35.png', '', 'thunshowers.png'),
- '36': ('twc/36.png', '', 'thunshowers.png'),
- '37': ('twc/37.png', '', 'thunshowers.png'),
+ '35': ('twc/35.png', 'thunderstorm.png', 'thunshowers.png'),
+ '36': ('twc/36.png', 'hotandsunny.png', 'sunny.png'),
+ '37': ('twc/37.png', 'isolatedthunderstorms.png', 'thunshowers.png'),
'38': ('twc/38.png', 'scatteredthunderstorms.png', 'thunshowers.png'),
- '39': ('twc/39.png', '', 'thunshowers.png'),
+ '39': ('twc/39.png', 'sunnyintervals.png', 'showers.png'),
'40': ('twc/40.png', 'heavyrain.png', 'showers.png'),
'41': ('twc/41.png', 'snowshowers.png', 'snowshow.png'),
- '42': ('twc/42.png', '', 'rainsnow.png'),
- '43': ('twc/43.png', '', 'showers.png'),
- '44': ('twc/44.png', '', 'unknown.png'),
- '45': ('twc/45.png', '', 'snowshow.png'),
- '46': ('twc/46.png', '', 'snowshow.png'),
- '47': ('twc/47.png', 'scatteredthunderstorms.png', 'thunshowers.png'),
- 'na': ('twc/na.png', '', 'unknown.png'),
+ '42': ('twc/42.png', 'snow.png', 'rainsnow.png'),
+ '43': ('twc/43.png', 'snow.png', 'rainsnow.png'),
+ '44': ('twc/44.png', 'na.png', 'unknown.png'),
+ '45': ('twc/45.png', 'rainshowers-n.png', 'rainsnow.png'),
+ '46': ('twc/46.png', 'snowshowers-n.png', 'snowshow.png'),
+ '47': ('twc/47.png', 'scatteredthunderstorms-n.png', 'thunshowers.png'),
+ 'na': ('twc/na.png', 'na.png', 'unknown.png'),
}
-#cloudy.png
-#flurries.png
-#fog.png
-#lshowers.png
-#mcloudy.png
-#pcloudy.png
-#rainsnow.png
-#showers.png
-#snowshow.png
-#sunny.png
-#thunshowers.png
+
def wget(url):
''' get a file from the url '''
- print 'wget(%s)' % (url)
+ _debug_('wget(%s)' % (url), 2)
txdata = None
txheaders = {
'User-Agent' : 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;
rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7'
@@ -174,7 +164,7 @@
def toCelcius(fTemp):
- print 'toCelcius(fTemp)'
+ _debug_('toCelcius(fTemp)', 2)
try:
tTemp = float (fTemp )
except ValueError:
@@ -183,7 +173,7 @@
return "%d" % (nTemp,)
def toKilometers(miles):
- print 'toKilometers(miles)'
+ _debug_('toKilometers(miles)', 2)
try:
tTemp = float(miles)
except ValueError:
@@ -192,7 +182,7 @@
return "%d" % (int(nTemp),)
def toBarometer(baro):
- print 'toBarometer(baro)'
+ _debug_('toBarometer(baro)', 2)
try:
tTemp = float(baro)
except ValueError:
@@ -208,29 +198,31 @@
To activate, put the following lines in local_conf.py:
plugin.activate('oneclick', level=45)
- PLUGIN_WEATHER_LOCATIONS = [
- ("<loc1>", <metric>, "<location name1>"),
- ("<loc2>", <metric>, "<location name2>"),
+ ONECLICK_LOCATIONS = [
+ ("<loc>", [metric], [mapuri], [location name]),
+ ("<loc>", [metric], [mapuri], [location name]),
...
]
- 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
+ where:
+ <loc> is a zipcode or an airport code
+ [metric] (1 == convert to SI Units; 0 == do not convert)
+ [mapuri] is the map's url, doesn't parse the page for a map url
+ [location name] is a custom name you wish to use for this location
'''
def __init__(self):
'''
'''
- print 'PluginInterface.__init__()'
- if not hasattr(config, 'PLUGIN_WEATHER_LOCATIONS'):
- self.reason = 'PLUGIN_WEATHER_LOCATIONS not defined'
+ _debug_('PluginInterface.__init__()', 2)
+ if not hasattr(config, 'ONECLICK_LOCATIONS'):
+ self.reason = 'ONECLICK_LOCATIONS not defined'
return
plugin.MainMenuPlugin.__init__(self)
def config(self):
'''
'''
- print 'config()'
+ _debug_('config()', 2)
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'),
@@ -242,7 +234,7 @@
def items(self, parent):
'''
'''
- print 'items(self, parent)'
+ _debug_('items(self, parent)', 2)
return [ WeatherMainMenu(parent) ]
@@ -251,7 +243,7 @@
Item for the menu for one feed
'''
def __init__(self, parent, location):
- print 'WeatherItem.__init__(parent=%r, location=%r)' % (parent,
location)
+ _debug_('WeatherItem.__init__(parent=%r, location=%r)' % (parent,
location), 2)
Item.__init__(self, parent)
self.parent = parent
@@ -305,16 +297,16 @@
self.weatherType = []
self.wdata = []
self.popupParam = None
- self.radarUrl = None
+ self.mapuri = None
if isinstance(location, tuple):
self.location = location[0]
if len(location) > 1:
- self.ismetric = int(location[1])
+ self.ismetric = bool(location[1])
if len(location) > 2:
- self.name = str(location[3])
+ self.mapuri = str(location[2])
if len(location) > 3:
- self.radarUrl = str(location[4])
+ self.name = str(location[3])
else:
self.location = location
self.ismetric = False
@@ -323,27 +315,21 @@
if self.name:
self.popupParam = Unicode(self.name)
- if self.ismetric:
- self.units = '&unit=m'
- else:
- self.units = ''
+ self.units = self.ismetric and '&unit=m' or ''
self.url_curc = config.ONECLICK_URL_CURC %
(urllib.quote(self.location), self.units)
self.url_dayf = config.ONECLICK_URL_DAYF %
(urllib.quote(self.location), self.units)
self.url_eloc = config.ONECLICK_URL_ELOC %
(urllib.quote(self.location))
- #self.url_curc = 'SZXX0033-cc.xml'
- #self.url_dayf = 'SZXX0033-dayf5.xml'
- #self.url_eloc = 'SZXX0033-eloc.xml'
self.mapurl = config.ONECLICK_URL_MAP % (self.location,)
- self.mapurl2 = None
- self.maplink = None
self.weatherData = None
self.weatherMapData = None
self.cacheDir = '%s/weather_%s' % (config.FREEVO_CACHEDIR,
self.location)
- self.cacheElocation = '%s/location' % (self.cacheDir,)
- self.cacheCurrent = '%s/current' % (self.cacheDir,)
- self.cacheForecast = '%s/forecast' % (self.cacheDir,)
- self.mapFile = '%s/map' % (self.cacheDir,)
+ self.cacheElocation = '%s/location.pickle' % (self.cacheDir)
+ self.cacheCurrent = '%s/current.pickle' % (self.cacheDir)
+ self.cacheForecast = '%s/forecast.pickle' % (self.cacheDir)
+ self.mapFile = '%s/map.jpeg' % (self.cacheDir)
+ self.mapPage1 = '%s/mappage1.html' % (self.cacheDir)
+ self.mapPage2 = '%s/mappage2.html' % (self.cacheDir)
if not os.path.isdir(self.cacheDir):
os.mkdir(self.cacheDir,
stat.S_IMODE(os.stat(config.FREEVO_CACHEDIR)[stat.ST_MODE]))
self.last_update = 0
@@ -351,28 +337,198 @@
#get forecast data
self.getForecast()
- def 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 getForecast(self, force=0):
+ '''grab the forecast, updating for the website if needed'''
+ _debug_('getForecast(force=%s)' % (force), 2)
- def actions(self):
- '''
- return a list of actions for this item
+ # check cache
+ try:
+ if force or self.needsRefresh():
+ self.updateData()
+ self.updateMap()
+ else:
+ self.loadFromCache()
+ except IOError, e:
+ self.error = 1
+ print "failed to update data for '%s': %s" % (self.location, e)
+ else:
+ # set the last update timestamp
+ self.last_update = os.path.getmtime(self.cacheCurrent)
+
+ # now convert the self.weatherData structure to parsable
information
+ self.convertWeatherData()
+ try:
+ self.convertWeatherData()
+ except Exception, error:
+ print 'Failed to convert data for %s: %s' % (self.location,
error)
+
+
+ def needsRefresh(self):
+ '''is the cache too old?'''
+ _debug_('needsRefresh()', 2)
+ if (os.path.isfile(self.cacheCurrent) == 0 or \
+ (abs(time.time() - os.path.getmtime(self.cacheCurrent)) >
WEATHER_AGE)):
+ return 1
+ else:
+ return 0
+
+ def updateData(self):
+ '''update the cache data from the 1click service
+ @notes the elocation is not updated as it is static
'''
- print 'actions()'
+ _debug_('updateData()', 2)
+ if GUI:
+ popup = PopupBox(text=_('Fetching Weather for %s...') %
self.popupParam)
+ popup.show()
+
+ if not os.path.isfile(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.isfile(self.cacheCurrent):
+ self.currentData = util.read_pickle(self.cacheCurrent)
+ else:
+ self.currentData = None
+ try:
+ self.forecastData = wget(self.url_dayf)
+ #print 'forecastData:', self.forecastData
+ except Exception, error:
+ print 'Failed to get the forecast data for %s: %s' %
(self.location, error)
+ if os.path.isfile(self.cacheForecast):
+ self.forecastData = util.read_pickle(self.cacheForecast)
+ else:
+ self.forecastData = None
+
+ if GUI:
+ popup.destroy()
+
+ if not self.currentData or not self.forecastData:
+ # raise an error
+ return
+
+ self.saveToCache()
+ return
+
+
+ def updateMap(self):
+ ''' Update the weather map '''
+ _debug_('updateMap()', 2)
+ # obtain radar map
+ if self.mapuri:
+ try:
+ if GUI:
+ popup = PopupBox(text=_('Fetching Radar Map for %s...') %
self.popupParam)
+ popup.show()
+ try:
+ self.weatherMapData = wget(self.mapuri)
+ self.saveMapToCache()
+ except Exception, error:
+ print 'Cannot download the map for "%s" from %s: %s' %
(self.location, self.mapuri, error)
+ return
+ finally:
+ if GUI:
+ popup.destroy()
+
+ try:
+ if GUI:
+ popup = PopupBox(text=_('Fetching Radar Map for %s...') %
self.popupParam)
+ popup.show()
+ # get the first web page
+ weatherPage = wget(self.mapurl)
+ if config.DEBUG:
+ f = open(self.mapPage1, 'w')
+ f.write(weatherPage)
+ f.close()
+ try:
+ # find link to map page
+ regexp = re.compile ('if \(isMinNS4\) var mapNURL =
"([^"]*)";', re.IGNORECASE)
+ results = regexp.search(weatherPage)
+ print 'weatherPage=%r' % (results.groups())
+ weatherPage2 = "http://www.weather.com/%s" %
(results.groups()[0])
+
+ mapPage = wget(weatherPage2)
+ if config.DEBUG:
+ f = open(self.mapPage2, 'w')
+ f.write(weatherPage)
+ f.close()
+ # find a link to the real weather map
+ regexp = re.compile('<img NAME="mapImg"
SRC="(http://image.weather.com[^"]*jpg)"', re.IGNORECASE)
+ results = regexp.search(mapPage)
+ print 'mapPage=%r' % (results.groups())
+ self.mapuri = results.groups()[0]
+ self.weatherMapData = wget(self.mapuri)
+ self.saveMapToCache()
+ return
+ except Exception, error:
+ print 'Cannot download the map for "%s" from %s: %s' %
(self.location, self.mapurl, error)
+
+ finally:
+ if GUI:
+ popup.destroy()
+
+ def saveToCache(self):
+ _debug_('saveToCache()', 2)
+ util.save_pickle(self.elocationData, self.cacheElocation)
+ util.save_pickle(self.currentData, self.cacheCurrent)
+ util.save_pickle(self.forecastData, self.cacheForecast)
+
+ def saveMapToCache(self):
+ ''' save weather map to the cache '''
+ try:
+ if self.weatherMapData is not None:
+ imgfd = os.open(self.mapFile, os.O_CREAT|os.W_OK)
+ os.write(imgfd, self.weatherMapData)
+ os.close(imgfd)
+ except Exception, error:
+ print 'failed saving weather map to cache "%s": %s' %
(self.mapFile, error)
+
+ def loadFromCache(self):
+ ''' load the data and the map from the cache '''
+ _debug_('loadFromCache()', 2)
+ 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 Exception, error:
+ _debug_('failed loading weather map for "%s" from cache: %s' %
(self.location, error), config.DWARNING)
+ pass
+ else:
+ imgfd = os.open(self.mapFile, os.R_OK)
+ self.weatherMapData = os.read(imgfd, size)
+ os.close(imgfd)
+
+ def actions(self):
+ ''' return a list of actions for this item '''
+ _debug_('actions()', 2)
return [ (self.start_detailed_interface, _('Show Weather Details')) ]
+ def start_detailed_interface(self, arg=None, menuw=None):
+ ''' detail handler '''
+ _debug_('start_detailed_interface(arg=%r, menuw=%r)' % (arg, menuw), 2)
+ WeatherDetailHandler(arg, menuw, self)
+
def isValid(self):
''' reports is an error was detected '''
- print 'isValid()'
+ _debug_('isValid()', 2)
return not self.error
def getLastUpdated(self):
''' parse the lsup time
@notes there seems to be a problem with AM/PM not parsing correctly
'''
- print 'getLastUpdated() "%s"' % self.updated
+ _debug_('getLastUpdated() "%s"' % self.updated, 2)
try:
value = time.strptime(self.updated.replace(' AM Local Time', ''),
'%m/%d/%y %H:%M')
return time.strftime("%c", time.localtime(time.mktime(value)))
@@ -382,8 +538,8 @@
(year, mon, day, hour, min, sec, weekday, yearday, saving) =
value
value = (year, mon, day, hour+12, min, sec, weekday, yearday,
saving)
return time.strftime("%c", time.localtime(time.mktime(value)))
- except ValueError, e:
- print e
+ except ValueError, error:
+ print error
return self.updated.replace(' Local Time', '')
#if self.ismetric:
# return time.strftime("%d/%m/%Y %H:%M:%S",
time.localtime(self.updated))
@@ -392,37 +548,43 @@
def getObservationStation(self):
''' get the observation station '''
- print 'getObservationStation()'
+ _debug_('getObservationStation()', 2)
return "%s" % (self.observation_station)
def getTemperature(self):
- print 'getTemperature()'
+ _debug_('getTemperature()', 2)
return u"%s\xb0%s" % (self.temperature, self.unit_t)
def getFeeling(self):
- print 'getFeeling(self)'
+ _debug_('getFeeling()', 2)
return u"%s\xb0%s" % (self.feeling, self.unit_t)
def getCurrentCondition(self):
''' gets the current conditions '''
- print 'getCurrentCondition()'
+ _debug_('getCurrentCondition()', 2)
return "%s" % (self.current_conditions)
def getIcon(self):
''' gets the current conditions icon '''
- print 'getIcon()'
+ _debug_('getIcon()', 2)
return "%s" % (self.icon)
def getPressure(self):
- print 'getPressure(self)'
+ _debug_('getPressure()', 2)
+ if self.pressure_change == 'N/A':
+ return "%s %s" % (self.pressure, self.unit_p)
+ return "%s %s %s %s" % (self.pressure, self.unit_p, _('and'),
self.pressure_change)
+
+ def getPressureValue(self):
+ _debug_('getPressureValue()', 2)
return "%s %s" % (self.pressure, self.unit_p)
def getPressureChange(self):
- print 'getPressureChange(self)'
+ _debug_('getPressureChange()', 2)
return "%s" % (self.pressure_change)
def getWind(self):
- print 'getWind(self)'
+ _debug_('getWind()', 2)
if self.wind_direction == 'CALM':
return "%s" % (self.wind_speed)
elif self.wind_direction == 'VAR':
@@ -430,220 +592,58 @@
return "%s %s %s %s" % (self.wind_direction, _('at'), self.wind_speed,
self.unit_s)
def getWindDir(self):
- print 'getWindDir(self)'
+ _debug_('getWindDir()', 2)
return "%s" % (self.wind_direction)
def getWindSpeed(self):
- print 'getWindSpeed(self)'
+ _debug_('getWindSpeed()', 2)
return "%s %s" % (self.wind_speed, self.unit_s)
def getHumidity(self):
- print 'getHumidity(self)'
- return "%s %%" % (self.humidity,)
+ _debug_('getHumidity()', 2)
+ return "%s%%" % (self.humidity)
def getVisibility(self):
- print 'getVisibility(self)'
+ _debug_('getVisibility()', 2)
return "%s %s" % (self.visibility, self.unit_d)
def getUvIndex(self):
- print 'getUvIndex(self)'
+ _debug_('getUvIndex()', 2)
return "%s" % (self.uv_index)
def getUvType(self):
- print 'getUvType(self)'
+ _debug_('getUvType()', 2)
return "%s" % (self.uv_type)
def getDewPoint(self):
- print 'getDewPoint()'
+ _debug_('getDewPoint()', 2)
return u"%s\xb0%s" % (self.dew_point, self.unit_t)
def getMoonIcon(self):
- print 'getMoonIcon()'
+ _debug_('getMoonIcon()', 2)
return "%s" % (self.moon_icon)
def getMoonPhase(self):
- print 'getMoonPhase(self)'
+ _debug_('getMoonPhase()', 2)
return "%s" % (self.moon_phase)
def getSunrise(self):
- print 'getSunrise(self)'
+ _debug_('getSunrise()', 2)
return "%s" % (self.sunrise)
def getSunset(self):
- print 'getSunset(self)'
+ _debug_('getSunset()', 2)
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.needsRefresh():
- self.updateData()
- else:
- self.loadFromCache()
- except IOError, e:
- self.error = 1
- print "failed to update data for '%s': %s" % (self.location, e)
- else:
- # set the last update timestamp
- self.last_update = os.path.getmtime(self.cacheCurrent)
-
- # now convert the self.weatherData structure to parsable
information
- self.convertWeatherData()
- try:
- self.convertWeatherData()
- except Exception, error:
- print 'Failed to convert data for %s: %s' % (self.location,
error)
-
-
- def needsRefresh(self):
- '''is the cache too old?'''
- 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.elocationData, self.cacheElocation)
- util.save_pickle(self.currentData, self.cacheCurrent)
- util.save_pickle(self.forecastData, self.cacheForecast)
- # attempt to save weather map
- try:
- if self.weatherMapData is not None:
- imgfd = os.open(self.mapFile, os.O_CREAT|os.W_OK)
- os.write(imgfd, self.weatherMapData)
- os.close(imgfd)
- except:
- print "failed while saving weather map to cache '%s'" %
(self.mapFile,)
-
- def loadFromCache(self):
- print 'loadFromCache(self)'
- 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.DWARNING)
- pass
- else:
- imgfd = os.open(self.mapFile, os.R_OK)
- self.weatherMapData = os.read(imgfd, size)
- 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()
-
- if not os.path.isfile(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.isfile(self.cacheCurrent):
- self.currentData = util.read_pickle(self.cacheCurrent)
- else:
- self.currentData = None
- try:
- self.forecastData = wget(self.url_dayf)
- print 'forecastData:', self.forecastData
- except Exception, error:
- print 'Failed to get the forecast data for %s: %s' %
(self.location, error)
- if os.path.isfile(self.cacheForecast):
- self.forecastData = util.read_pickle(self.cacheForecast)
- else:
- self.forecastData = None
-
- 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()
- popup = PopupBox(text=_('Fetching Radar Map for %s...') %
self.popupParam)
- popup.show()
- try:
- if self.radarUrl is not None:
- self.maplink = (self.radarUrl)
- if self.maplink is None:
- # get the first web page
- 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)
- except:
- print 'Weather ERROR: failed attempting to download radar map
from %s' % self.maplink
- except:
- print 'Weather ERROR: failed attempting to locate radar map URL
for %s' % self.location
- self.weatherMapData = None
- pass
-
- import traceback, sys
- output = apply(traceback.format_exception, sys.exc_info())
- output = ''.join(output)
- output = urllib.unquote(output)
- print output
-
- if GUI:
- popup.destroy()
-
- self.saveToCache()
-
-
def convertWeatherData(self):
'''
convert the xml weather information for the skin
'''
- print 'convertWeatherData(self)'
- print self.elocationData
- print self.currentData
- print self.forecastData
+ _debug_('convertWeatherData()', 2)
+ #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))
@@ -653,7 +653,6 @@
dnam = elocation.loc.dnam.split(', ')
ctry = elocation.eloc.ctry
- print dnam
if ctry in ('US'):
self.city = dnam[0]
self.state = dnam[1]
@@ -703,8 +702,7 @@
self.moon_phase = current.cc.moon.t
self.description = '%s %s %s' % (self.current_conditions, _("at"),
self.getTemperature())
- print self.icon
- self.image = self.getIconDay(self.icon)
+ self.image = self.getDayImage(self.icon)
# skip today in the days
for day in forecast.dayf.days[1:]:
@@ -713,34 +711,28 @@
self.lowTemp.append(day.low)
for part in day.parts:
if part.p == 'd':
- self.weatherIcon.append(self.getIconDay(part.icon))
+ self.weatherIcon.append(self.getDayImage(part.icon))
self.weatherType.append(part.t)
- #for i in dir(self):
- # print i, self[i]
-
- def getIconDay(self, num):
+ def getDayImage(self, num):
'''obtain the weather icons for multiple day forecast'''
- print 'getIconDay()'
+ _debug_('getDayImage()', 2)
icon = os.path.join(WEATHER_DIR, WEATHER_ICONS[num][1])
- print '1: %s: %s' % (num, icon)
if not os.path.isfile(icon):
icon = os.path.join(WEATHER_DIR, WEATHER_ICONS[num][2])
- print '2: %s: %s' % (num, icon)
if not os.path.isfile(icon):
icon = os.path.join(WEATHER_DIR, WEATHER_ICONS[num][0])
- print '0: %s: %s' % (num, icon)
if not os.path.isfile(icon):
icon = os.path.join(WEATHER_DIR, 'na.png')
- print '%s: %s' % (num, icon)
+ print '%s: %s %s' % (num, icon,
os.path.split(WEATHER_ICONS[num][1])[1])
return icon
- def getIconMoon(self, num):
+ def getMoonImage(self, num):
'''obtain the weather icons for multiple day forecast'''
- print 'getIconMoon()'
+ _debug_('getMoonImage()', 2)
icon = os.path.join(WEATHER_DIR, 'moons', '%s.png' % (num))
print '%s: %s' % (num, icon)
@@ -753,30 +745,30 @@
of Weather Locations in a submenu.
'''
def __init__(self, parent):
- print 'WeatherMainMenu.__init__(self, parent)'
+ _debug_('WeatherMainMenu.__init__(parent=%r)' % (parent), 2)
Item.__init__(self, parent, skin_type='oneclick')
self.parent = parent
self.name = _('Weather')
def actions(self):
''' return a list of actions for this item '''
- print 'actions()'
+ _debug_('actions()', 2)
items = [ (self.create_locations_menu , _('Locations')) ]
return items
def __call__(self, arg=None, menuw=None):
''' call first action in the actions list '''
- print '__call__(arg=%r, menuw=%r)' % (arg, menuw)
+ _debug_('__call__(arg=%r, menuw=%r)' % (arg, menuw), 2)
if self.actions():
return self.actions()[0][0](arg=arg, menuw=menuw)
def create_locations_menu(self, arg=None, menuw=None):
''' '''
- print 'create_locations_menu(arg=%r, menuw=%r)' % (arg, menuw)
+ _debug_('create_locations_menu(arg=%r, menuw=%r)' % (arg, menuw), 2)
locations = []
autoselect = 0
# create menu items
- for location in config.PLUGIN_WEATHER_LOCATIONS:
+ for location in config.ONECLICK_LOCATIONS:
weather_item = WeatherItem(self, location)
# Only display this entry if no errors were found
if weather_item.isValid():
@@ -807,14 +799,14 @@
'''
def __init__(self, arg=None, menu=None, weather=None):
''' '''
- print 'WeatherDetailHandler.__init__(arg=%r, menu=%r, weather=%r)' %
(arg, menu, weather)
+ _debug_('WeatherDetailHandler.__init__(arg=%r, menu=%r, weather=%r)' %
(arg, menu, weather), 2)
self.arg = arg
self.menuw = menu
self.weather = weather
self.menuw.hide(clear=False)
rc.app(self)
- self.skins = ('day', 'forecast', 'week', 'doplar')
+ self.skins = ('day', 'forecast', 'week', 'map')
self.skin_num = 0
self.subtitles = (_('Current Conditions'), _('Today\'s Forecast'),
@@ -828,7 +820,7 @@
def prevSkin(self):
'''decrements the skin number round to the last skin'''
- print 'prevSkin()'
+ _debug_('prevSkin()', 2)
self.skin_num -= 1
# out of bounds check, reset to size of skins array
@@ -838,10 +830,9 @@
def nextSkin(self):
'''increment the skin number round to the first skin'''
- print 'nextSkin()'
+ _debug_('nextSkin()', 2)
self.skin_num += 1
- print 'len(self.skins)=%s' % len(self.skins)
# out of bounds check, reset to 0
if self.skin_num >= len(self.skins):
self.skin_num = 0
@@ -849,12 +840,12 @@
def getSubtitle(self, num):
''' returns the subtitle for a skin number '''
- print 'getSubtitle(num=%s)' % (num)
+ _debug_('getSubtitle(num=%s)' % (num), 2)
return '%s %s %s' % (self.subtitles[num], _('for'), self.weather.name)
def eventhandler(self, event, menuw=None):
'''eventhandler'''
- print 'eventhandler(event=%s, menuw=%r)' % (event, menuw)
+ _debug_('eventhandler(event=%s, menuw=%r)' % (event, menuw), 2)
if event == 'MENU_BACK_ONE_MENU':
rc.app(None)
self.menuw.show()
@@ -879,7 +870,7 @@
return False
if __name__ == '__main__':
- for location in config.PLUGIN_WEATHER_LOCATIONS:
+ for location in config.ONECLICK_LOCATIONS:
print location
weather_item = WeatherItem(None, location)
print weather_item
@@ -889,7 +880,7 @@
class WeatherBaseScreen(skin.Area):
''' A base class for weather screens to inherit from, provides common
members+methods '''
def __init__(self):
- print 'WeatherBaseScreen.__init__()'
+ _debug_('WeatherBaseScreen.__init__()', 2)
skin.Area.__init__(self, 'content')
# Weather display fonts
@@ -903,12 +894,12 @@
self.ymult = float(osd.height -
(config.OSD_OVERSCAN_TOP+config.OSD_OVERSCAN_BOTTOM)) / 600
self.update_functions = (self.update_day, self.update_forecast,
- self.update_week, self.update_doplar)
+ self.update_week, self.update_map)
def update_day(self):
'''
'''
- print 'update_day()'
+ _debug_('update_day()', 2)
# display data
text = _('Humidity')
value = self.parent.weather.getHumidity()
@@ -990,7 +981,7 @@
def update_forecast(self):
''' this screen is taken from the 1click weather forecast of the
firefox plug-in. '''
- print 'update_forecast()'
+ _debug_('update_forecast()', 2)
x_start = self.content.x + (20 * self.xmult)
y_start = self.content.y + (30 * self.xmult)
weather = self.parent.weather
@@ -1004,14 +995,13 @@
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' % (_('Pressure:'), weather.getPressure()))
lines.append(' %s %s' % (_('Winds:'), weather.getWind()))
lines.append('%s' % (_('Tonight:')))
lines.append(' %s %s' % (_('Sunset:'), weather.getSunset()))
lines.append(' %s %s' % (_('Moon Phase:'),
weather.getMoonPhase()))
- except Exception, e:
- print e
+ except Exception, error:
+ print error
import traceback, sys
output = apply(traceback.format_exception, sys.exc_info())
output = ''.join(output)
@@ -1027,20 +1017,20 @@
try:
x_start = self.content.x + (500 * self.xmult)
y_start = self.content.y + (300 * self.ymult)
- iconFile = weather.getIconMoon(weather.getMoonIcon())
- self.draw_image(iconFile,
- (x_start, y_start, 90, 90))
+ iconFile = weather.getMoonImage(weather.getMoonIcon())
+ #self.draw_image(iconFile,
+ # (x_start, y_start, 90, 90))
#(x_start, y_start, int(60 * self.xmult), int(60 *
self.ymult)))
print 'x_start=%s, y_start=%s, xmult=%s, ymult=%s' % (x_start,
y_start, self.xmult, self.ymult)
- except Exception, e:
- print e
+ except Exception, error:
+ print error
def update_week(self):
''' update the weeks forecast
@remarks this can be improved
'''
- print 'update_week()'
+ _debug_('update_week()', 2)
x_start = self.content.x + (10 * self.xmult)
y_start = self.content.y + (10 * self.xmult)
@@ -1081,22 +1071,22 @@
width=90*self.xmult, height=-1, align_h='center')
day += 1
- def update_doplar(self):
- ''' update the contents of the skin's radar map '''
- 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)
- self.write_text(_("Error encountered while trying to download
Radar map"),
+ def update_map(self):
+ ''' update the contents of the skin's doppler weather map '''
+ _debug_('update_map()', 2)
+ if not self.parent.weather.weatherMapData:
+ x_start = self.content.x + (10 * self.xmult)
+ y_start = self.content.y + (10 * self.xmult)
+ self.write_text(_("Error encountered while trying to download
weather map"),
self.key_font, self.content, x=x_start, y=y_start,
width=self.content.width, height=-1, align_h='left')
else:
- self.draw_image(self.parent.weather.mapFile, (self.content.x,
self.content.y, self.content.width,
-
self.content.height))
+ self.draw_image(self.parent.weather.mapFile,
+ (self.content.x-3, self.content.y+14, self.content.width,
self.content.height))
def update_content(self):
''' update the contents of the skin '''
- print 'update_content()'
+ _debug_('update_content()', 2)
self.parent = self.menu
self.content = self.calc_geometry(self.layout.content,
copy_object=True)
self.update_functions[self.menu.skin_num]()
-------------------------------------------------------------------------
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