Author: duncan
Date: Wed Dec 19 15:18:39 2007
New Revision: 10219
Log:
[ 1821809 ] idlebar.weather plugin fix
Update, but not the supplied patch, has been applied
The update uses a thread to update the weather data
Added:
branches/rel-1-7/freevo/share/icons/weather/na.png (contents, props
changed)
branches/rel-1/freevo/share/icons/weather/na.png (contents, props changed)
Modified:
branches/rel-1-7/freevo/ChangeLog
branches/rel-1-7/freevo/src/plugins/idlebar/weather.py
branches/rel-1/freevo/ChangeLog
branches/rel-1/freevo/src/plugins/idlebar/weather.py
Modified: branches/rel-1-7/freevo/ChangeLog
==============================================================================
--- branches/rel-1-7/freevo/ChangeLog (original)
+++ branches/rel-1-7/freevo/ChangeLog Wed Dec 19 15:18:39 2007
@@ -25,6 +25,7 @@
* New somafm web radio fxd file and images added (F#1845786)
* New six channel mixer and idlebar plug-in (F#1833749)
* Updated French translation (F#1832751)
+ * Updated idlebar weather plug-in not to block the main loop (F#1821809)
* Updated mediainfo to stop caching of hidden directories (F#1849569)
* Updated mplayer to allow the volume events to passed over and shown
(F#1834486)
* Updated webserver media library (F#1835346)
Added: branches/rel-1-7/freevo/share/icons/weather/na.png
==============================================================================
Binary file. No diff available.
Modified: branches/rel-1-7/freevo/src/plugins/idlebar/weather.py
==============================================================================
--- branches/rel-1-7/freevo/src/plugins/idlebar/weather.py (original)
+++ branches/rel-1-7/freevo/src/plugins/idlebar/weather.py Wed Dec 19
15:18:39 2007
@@ -30,6 +30,7 @@
import os
import time
import string
+from threading import Thread, Condition
# freevo modules
from plugins.idlebar import IdleBarPlugin
@@ -37,6 +38,68 @@
import util.pymetar as pymetar
+class WeatherFetcher(Thread):
+ """
+ Class to fetch the weather in a thread
+ """
+ def __init__(self, condition, metarcode, tempunits, cachefile):
+ """ Initialise the thread """
+ Thread.__init__(self)
+ _debug_('WeatherFetcher.__init__(condition=%r, metarcode=%r,
tempunits=%r, cachefile=%r)' % (condition, metarcode, tempunits, cachefile), 2)
+ self.condition = condition
+ self.metarcode = metarcode
+ self.tempunits = tempunits
+ self.cachefile = cachefile
+ self.stopping = False
+
+ def run(self):
+ _debug_('WeatherFetcher.run()', 2)
+ self.condition.acquire()
+ _debug_('WeatherFetcher condition.acquired', 2)
+ try:
+ while not self.stopping:
+ _debug_('WeatherFetcher condition.waiting', 2)
+ self.condition.wait()
+ _debug_('WeatherFetcher condition.waited', 2)
+ if self.stopping:
+ break
+ #_debug_('ReportFetcher(%r)' % (self.metarcode,), 2)
+ try:
+ rf = pymetar.ReportFetcher(self.metarcode)
+ rep = rf.FetchReport()
+ rp=pymetar.ReportParser()
+ pr=rp.ParseReport(rep)
+ if (pr.getTemperatureCelsius()):
+ if self.tempunits == 'F':
+ temperature = '%2d' % pr.getTemperatureFahrenheit()
+ elif self.tempunits == 'K':
+ ktemp = pr.getTemperatureCelsius() + 273
+ temperature = '%3d' % ktemp
+ else:
+ temperature = '%2d' % pr.getTemperatureCelsius()
+ else:
+ temperature = '?' # Make it a string to match above.
+ if pr.getPixmap():
+ icon = pr.getPixmap() + '.png'
+ else:
+ icon = 'na.png'
+ try:
+ cachefile = open(self.cachefile, 'w+')
+ cachefile.write(temperature + '\n')
+ cachefile.write(icon + '\n')
+ cachefile.close()
+ _debug_('WeatherFetcher cache written', 2)
+ except IOError, why:
+ _debug_('Failed to create %r: %s' % (self.cachefile,
why), 2)
+
+ except Exception, why:
+ _debug_(why, 2)
+ finally:
+ self.condition.release()
+ _debug_('WeatherFetcher condition.released', 2)
+
+
+
class PluginInterface(IdleBarPlugin):
"""
Shows the current weather.
@@ -49,6 +112,9 @@
"""
def __init__(self, zone='CYYZ', units='C'):
+ """
+ """
+ _debug_('PluginInterface.__init__(zone=%r, units=%r)' % (zone, units),
2)
if not config.USE_NETWORK:
self.reason = 'USE_NETWORK not enabled'
return
@@ -57,78 +123,75 @@
self.TEMPUNITS = units
self.METARCODE = zone
self.WEATHERCACHE = config.FREEVO_CACHEDIR + '/weather'
- print
- print 'WARNING: the idlebar.weather plugin downloads new weather'
- print 'information inside the main loop. This bug makes all menu'
- print 'actions _very_ slow. Consider not using this plugin for higher'
- print 'speed.'
- print
+ self.cachetime = 0
+ self.condition = Condition()
+ self.fetcher = WeatherFetcher(self.condition, self.METARCODE,
self.TEMPUNITS, self.WEATHERCACHE)
+ self.fetcher.start()
+
+
+ def config(self):
+ return [
+ ('IDLEBAR_WEATHER_REFRESH', 3600, 'The time to refresh the weather
cache'),
+ ]
+
+
+ def shutdown(self):
+ _debug_('shutdown()', 2)
+ self.condition.acquire()
+ _debug_('checkweather condition.acquired', 2)
+ try:
+ self.condition.notifyAll()
+ finally:
+ self.condition.release()
+ self.fetcher.stopping = True
+ self.fetcher.join()
def checkweather(self):
- # We don't want to do this every 30 seconds, so we need
- # to cache the date somewhere.
- #
- # First check the age of the cache.
- #
- if (os.path.isfile(self.WEATHERCACHE) == 0 or \
- (abs(time.time() - os.path.getmtime(self.WEATHERCACHE)) > 3600)):
+ """
+ We don't want to do this every 30 seconds, so we need
+ to cache the date somewhere.
+ """
+ _debug_('checkweather()', 2)
+ self.condition.acquire()
+ _debug_('checkweather condition.acquired', 2)
+ try:
try:
- rf=pymetar.ReportFetcher(self.METARCODE)
- rep=rf.FetchReport()
- rp=pymetar.ReportParser()
- pr=rp.ParseReport(rep)
- if (pr.getTemperatureCelsius()):
- if self.TEMPUNITS == 'F':
- temperature = '%2d' % pr.getTemperatureFahrenheit()
- elif self.TEMPUNITS == 'K':
- ktemp = pr.getTemperatureCelsius() + 273
- temperature = '%3d' % ktemp
- else:
- temperature = '%2d' % pr.getTemperatureCelsius()
+ if os.path.isfile(self.WEATHERCACHE):
+ cachetime = os.path.getmtime(self.WEATHERCACHE)
else:
- temperature = '?' # Make it a string to match above.
- if pr.getPixmap():
- icon = pr.getPixmap() + '.png'
- else:
- icon = 'sun.png'
- cachefile = open(self.WEATHERCACHE,'w+')
- cachefile.write(temperature + '\n')
- cachefile.write(icon + '\n')
- cachefile.close()
- except:
- try:
- # HTTP Problems, use cache. Wait till next try.
+ cachetime = 0
+ # Tell the thread to run once
+ if time.time() - cachetime > config.IDLEBAR_WEATHER_REFRESH:
+ self.condition.notify()
+ _debug_('checkweather condition.notified', 2)
+
+ # First time around or when there is no network there may be
no weather cache file
+ _debug_('cachetime=%r diff=%s' % (cachetime, cachetime -
self.cachetime), 2)
+ if cachetime:
cachefile = open(self.WEATHERCACHE,'r')
newlist = map(string.rstrip, cachefile.readlines())
temperature,icon = newlist
cachefile.close()
- except IOError:
- _debug_('error reading cache. Using fake weather.',
DWARNING)
- try:
- cachefile = open(self.WEATHERCACHE,'w+')
- cachefile.write('?' + '\n')
- cachefile.write('sun.png' + '\n')
- cachefile.close()
- except IOError:
- _debug_('You have no permission to write %s' %
self.WEATHERCACHE, DERROR)
- return '0', 'sun.png'
-
+ self.cachetime = cachetime
+ _debug_('checkweather returning %r' % ((temperature,
icon),), 2)
+ return temperature, icon
+ else:
+ _debug_('checkweather returning %r' % (('?', 'na.png'),),
2)
+ return '?', 'na.png'
+ except Exception, why:
+ _debug_(why, 2)
+ finally:
+ self.condition.release()
+ _debug_('checkweather condition.released', 2)
- else:
- cachefile = open(self.WEATHERCACHE,'r')
- newlist = map(string.rstrip, cachefile.readlines())
- temperature,icon = newlist
- cachefile.close()
- return temperature, icon
def draw(self, (type, object), x, osd):
+ _debug_('draw((type=%r, object=%r), x=%r, osd=%r)' % (type, object, x,
osd), 2)
temp,icon = self.checkweather()
font = osd.get_font('small0')
- osd.draw_image(os.path.join(config.ICON_DIR, 'weather/' + icon),
- (x, osd.y + 15, -1, -1))
+ osd.draw_image(os.path.join(config.ICON_DIR, 'weather/' + icon), (x,
osd.y + 15, -1, -1))
temp = u'%s\xb0' % temp
width = font.stringsize(temp)
- osd.write_text(temp, font, None, x + 15, osd.y + 55 - font.h, width,
font.h,
- 'left', 'top')
+ osd.write_text(temp, font, None, x + 15, osd.y + 55 - font.h, width,
font.h, 'left', 'top')
return width + 15
Modified: branches/rel-1/freevo/ChangeLog
==============================================================================
--- branches/rel-1/freevo/ChangeLog (original)
+++ branches/rel-1/freevo/ChangeLog Wed Dec 19 15:18:39 2007
@@ -32,6 +32,7 @@
* New somafm web radio fxd file and images added (F#1845786)
* New six channel mixer and idlebar plug-in (F#1833749)
* Updated French translation (F#1832751)
+ * Updated idlebar weather plug-in not to block the main loop (F#1821809)
* Updated mediainfo to stop caching of hidden directories (F#1849569)
* Updated mplayer to allow the volume events to passed over and shown
(F#1834486)
* Updated webserver media library (F#1835346)
Added: branches/rel-1/freevo/share/icons/weather/na.png
==============================================================================
Binary file. No diff available.
Modified: branches/rel-1/freevo/src/plugins/idlebar/weather.py
==============================================================================
--- branches/rel-1/freevo/src/plugins/idlebar/weather.py (original)
+++ branches/rel-1/freevo/src/plugins/idlebar/weather.py Wed Dec 19
15:18:39 2007
@@ -30,6 +30,7 @@
import os
import time
import string
+from threading import Thread, Condition
# freevo modules
from plugins.idlebar import IdleBarPlugin
@@ -37,6 +38,68 @@
import util.pymetar as pymetar
+class WeatherFetcher(Thread):
+ """
+ Class to fetch the weather in a thread
+ """
+ def __init__(self, condition, metarcode, tempunits, cachefile):
+ """ Initialise the thread """
+ Thread.__init__(self)
+ _debug_('WeatherFetcher.__init__(condition=%r, metarcode=%r,
tempunits=%r, cachefile=%r)' % (condition, metarcode, tempunits, cachefile), 2)
+ self.condition = condition
+ self.metarcode = metarcode
+ self.tempunits = tempunits
+ self.cachefile = cachefile
+ self.stopping = False
+
+ def run(self):
+ _debug_('WeatherFetcher.run()', 2)
+ self.condition.acquire()
+ _debug_('WeatherFetcher condition.acquired', 2)
+ try:
+ while not self.stopping:
+ _debug_('WeatherFetcher condition.waiting', 2)
+ self.condition.wait()
+ _debug_('WeatherFetcher condition.waited', 2)
+ if self.stopping:
+ break
+ #_debug_('ReportFetcher(%r)' % (self.metarcode,), 2)
+ try:
+ rf = pymetar.ReportFetcher(self.metarcode)
+ rep = rf.FetchReport()
+ rp=pymetar.ReportParser()
+ pr=rp.ParseReport(rep)
+ if (pr.getTemperatureCelsius()):
+ if self.tempunits == 'F':
+ temperature = '%2d' % pr.getTemperatureFahrenheit()
+ elif self.tempunits == 'K':
+ ktemp = pr.getTemperatureCelsius() + 273
+ temperature = '%3d' % ktemp
+ else:
+ temperature = '%2d' % pr.getTemperatureCelsius()
+ else:
+ temperature = '?' # Make it a string to match above.
+ if pr.getPixmap():
+ icon = pr.getPixmap() + '.png'
+ else:
+ icon = 'na.png'
+ try:
+ cachefile = open(self.cachefile, 'w+')
+ cachefile.write(temperature + '\n')
+ cachefile.write(icon + '\n')
+ cachefile.close()
+ _debug_('WeatherFetcher cache written', 2)
+ except IOError, why:
+ _debug_('Failed to create %r: %s' % (self.cachefile,
why), 2)
+
+ except Exception, why:
+ _debug_(why, 2)
+ finally:
+ self.condition.release()
+ _debug_('WeatherFetcher condition.released', 2)
+
+
+
class PluginInterface(IdleBarPlugin):
"""
Shows the current weather.
@@ -49,6 +112,9 @@
"""
def __init__(self, zone='CYYZ', units='C'):
+ """
+ """
+ _debug_('PluginInterface.__init__(zone=%r, units=%r)' % (zone, units),
2)
if not config.USE_NETWORK:
self.reason = 'USE_NETWORK not enabled'
return
@@ -57,78 +123,75 @@
self.TEMPUNITS = units
self.METARCODE = zone
self.WEATHERCACHE = config.FREEVO_CACHEDIR + '/weather'
- print
- print 'WARNING: the idlebar.weather plugin downloads new weather'
- print 'information inside the main loop. This bug makes all menu'
- print 'actions _very_ slow. Consider not using this plugin for higher'
- print 'speed.'
- print
+ self.cachetime = 0
+ self.condition = Condition()
+ self.fetcher = WeatherFetcher(self.condition, self.METARCODE,
self.TEMPUNITS, self.WEATHERCACHE)
+ self.fetcher.start()
+
+
+ def config(self):
+ return [
+ ('IDLEBAR_WEATHER_REFRESH', 3600, 'The time to refresh the weather
cache'),
+ ]
+
+
+ def shutdown(self):
+ _debug_('shutdown()', 2)
+ self.condition.acquire()
+ _debug_('checkweather condition.acquired', 2)
+ try:
+ self.condition.notifyAll()
+ finally:
+ self.condition.release()
+ self.fetcher.stopping = True
+ self.fetcher.join()
def checkweather(self):
- # We don't want to do this every 30 seconds, so we need
- # to cache the date somewhere.
- #
- # First check the age of the cache.
- #
- if (os.path.isfile(self.WEATHERCACHE) == 0 or \
- (abs(time.time() - os.path.getmtime(self.WEATHERCACHE)) > 3600)):
+ """
+ We don't want to do this every 30 seconds, so we need
+ to cache the date somewhere.
+ """
+ _debug_('checkweather()', 2)
+ self.condition.acquire()
+ _debug_('checkweather condition.acquired', 2)
+ try:
try:
- rf=pymetar.ReportFetcher(self.METARCODE)
- rep=rf.FetchReport()
- rp=pymetar.ReportParser()
- pr=rp.ParseReport(rep)
- if (pr.getTemperatureCelsius()):
- if self.TEMPUNITS == 'F':
- temperature = '%2d' % pr.getTemperatureFahrenheit()
- elif self.TEMPUNITS == 'K':
- ktemp = pr.getTemperatureCelsius() + 273
- temperature = '%3d' % ktemp
- else:
- temperature = '%2d' % pr.getTemperatureCelsius()
+ if os.path.isfile(self.WEATHERCACHE):
+ cachetime = os.path.getmtime(self.WEATHERCACHE)
else:
- temperature = '?' # Make it a string to match above.
- if pr.getPixmap():
- icon = pr.getPixmap() + '.png'
- else:
- icon = 'sun.png'
- cachefile = open(self.WEATHERCACHE,'w+')
- cachefile.write(temperature + '\n')
- cachefile.write(icon + '\n')
- cachefile.close()
- except:
- try:
- # HTTP Problems, use cache. Wait till next try.
+ cachetime = 0
+ # Tell the thread to run once
+ if time.time() - cachetime > config.IDLEBAR_WEATHER_REFRESH:
+ self.condition.notify()
+ _debug_('checkweather condition.notified', 2)
+
+ # First time around or when there is no network there may be
no weather cache file
+ _debug_('cachetime=%r diff=%s' % (cachetime, cachetime -
self.cachetime), 2)
+ if cachetime:
cachefile = open(self.WEATHERCACHE,'r')
newlist = map(string.rstrip, cachefile.readlines())
temperature,icon = newlist
cachefile.close()
- except IOError:
- _debug_('error reading cache. Using fake weather.',
DWARNING)
- try:
- cachefile = open(self.WEATHERCACHE,'w+')
- cachefile.write('?' + '\n')
- cachefile.write('sun.png' + '\n')
- cachefile.close()
- except IOError:
- _debug_('You have no permission to write %s' %
self.WEATHERCACHE, DERROR)
- return '0', 'sun.png'
-
+ self.cachetime = cachetime
+ _debug_('checkweather returning %r' % ((temperature,
icon),), 2)
+ return temperature, icon
+ else:
+ _debug_('checkweather returning %r' % (('?', 'na.png'),),
2)
+ return '?', 'na.png'
+ except Exception, why:
+ _debug_(why, 2)
+ finally:
+ self.condition.release()
+ _debug_('checkweather condition.released', 2)
- else:
- cachefile = open(self.WEATHERCACHE,'r')
- newlist = map(string.rstrip, cachefile.readlines())
- temperature,icon = newlist
- cachefile.close()
- return temperature, icon
def draw(self, (type, object), x, osd):
+ _debug_('draw((type=%r, object=%r), x=%r, osd=%r)' % (type, object, x,
osd), 2)
temp,icon = self.checkweather()
font = osd.get_font('small0')
- osd.draw_image(os.path.join(config.ICON_DIR, 'weather/' + icon),
- (x, osd.y + 15, -1, -1))
+ osd.draw_image(os.path.join(config.ICON_DIR, 'weather/' + icon), (x,
osd.y + 15, -1, -1))
temp = u'%s\xb0' % temp
width = font.stringsize(temp)
- osd.write_text(temp, font, None, x + 15, osd.y + 55 - font.h, width,
font.h,
- 'left', 'top')
+ osd.write_text(temp, font, None, x + 15, osd.y + 55 - font.h, width,
font.h, 'left', 'top')
return width + 15
-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services
for just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog