#!/usr/bin/env python # -*- coding: UTF8 -*- #*************************************************************************** #* * #* This program is free software; you can redistribute it and/or modify * #* it under the terms of the GNU General Public License (GPL) * #* as published by the Free Software Foundation; either version 2 of * #* the License, or (at your option) any later version. * #* for detail see the LICENCE text file. * #* * #* This program is distributed in the hope that it will be useful, * #* but WITHOUT ANY WARRANTY; without even the implied warranty of * #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * #* GNU Library General Public License for more details. * #* * #* You should have received a copy of the GNU Library General Public * #* License along with this program; if not, write to the Free Software * #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * #* USA * #* * #*************************************************************************** ''' Fluxweather 0.4 - 19.12.2009 author: Yorik van Have url: http://yorik.uncreated.net This program adds an icon in the system tray displaying weather conditions and forecast from yahoo.com. I made this primarily for fluxbox and other window managers that don't have a weather icon embedded in the clock. ''' import os, gtk, gobject, urllib from xml.etree.ElementTree import parse # DEFAULT CONFIGURATION - OVERRIDDEN BY CONFIG FILE .fluxweatherrc IN YOUR HOME DIR # below are the yahoo weather URLs, normaly you don't need to change that WEATHER_URL = 'http://xml.weather.yahoo.com/forecastrss?p=%s&u=c' WEATHER_NS = 'http://xml.weather.yahoo.com/ns/rss/1.0' # below is your zip code, or the code corresponding to your location # from http://weather.yahoo.com ZIPCODE = 'BRXX0232' # below is the url of a weather map image to fetch, get it from same yahoo page. MAPURL='http://weather.yahoo.com/images/sa_satintl_440_mdy_y.jpg' # END CONFIGURATION def fetchweather(zip): url = WEATHER_URL % zip rss = parse(urllib.urlopen(url)).getroot() forecasts = [] for element in rss.findall('channel/item/{%s}forecast' % WEATHER_NS): forecasts.append({ 'date': element.get('date'), 'low': element.get('low'), 'high': element.get('high'), 'condition': element.get('text') }) ycondition = rss.find('channel/item/{%s}condition' % WEATHER_NS) return { 'current_condition': ycondition.get('text'), 'current_temp': ycondition.get('temp'), 'forecasts': forecasts, 'title': rss.findtext('channel/title'), 'code': ycondition.get('code'), 'descr': rss.findtext('channel/item/description') } class TrackerStatusIcon(gtk.StatusIcon): def __init__(self): gtk.StatusIcon.__init__(self) menu = ''' ''' actions = [ ('Menu', None, 'Menu'), ('Update', gtk.STOCK_REFRESH, '_Update now', None, 'Update', self.update), ('Settings', gtk.STOCK_PREFERENCES, '_Settings...', None, 'Settings', self.config), ('About', gtk.STOCK_ABOUT, '_About...', None, 'About Weath', self.about), ('Close', gtk.STOCK_CLOSE, '_Close', None, 'Close', self.close)] ag = gtk.ActionGroup('Actions') ag.add_actions(actions) self.manager = gtk.UIManager() self.manager.insert_action_group(ag, 0) self.manager.add_ui_from_string(menu) self.menu = self.manager.get_widget('/Weath/Menu/About').props.parent self.set_from_stock(gtk.STOCK_CONNECT) self.set_tooltip('Connecting...') self.set_visible(True) self.isMap = False self.connect('popup-menu', self.popup_menu) self.connect('activate', self.map) self.mapdialog = gtk.Window() self.getconfig() self.update() self.mapdialog.add(self.imagemap) self.timeout = gobject.timeout_add(3600000,self.update) def update(self, data=None): report = fetchweather(self.zip) forecasts = report['forecasts'] panel = report['title'] + '\n'+report['current_temp'] + '\260C ' + report['current_condition'] + '\n' panel = panel + 'tomorrow: ' + forecasts[0]['low'] + '/' + forecasts[0]['high'] panel = panel + '\260C ' + forecasts[0]['condition'] + '\n' panel = panel + 'day after: ' + forecasts[1]['low'] + '/' + forecasts[1]['high'] panel = panel + '\260C ' + forecasts[1]['condition'] + '\n' panel = unicode(panel,'latin1') self.set_tooltip(panel) iconurl=report['descr'].split('"')[1] iconfile=urllib.urlopen(iconurl) pbl = gtk.gdk.PixbufLoader() pbl.write(iconfile.read()) pb = pbl.get_pixbuf() pbl.close() self.set_from_pixbuf(pb) imfile=urllib.urlopen(self.map) pbl = gtk.gdk.PixbufLoader() pbl.write(imfile.read()) pb = pbl.get_pixbuf() pbl.close() self.imagemap = gtk.Image() self.imagemap.set_from_pixbuf(pb) return True def getconfig(self): configfile = os.path.expanduser('~') + os.sep + '.fluxweatherrc' self.zip = ZIPCODE self.map = MAPURL if os.path.isfile(configfile): file = open(configfile) for line in file: if not("#" in line): key, value = line.split("=", 1) key = key.strip() value = value.strip() if key == "zipcode": self.zip = value elif key == "mapurl": self.map = value file.close() else: print "Creating config file..." self.writeconfig() def writeconfig(self): configfile = os.path.expanduser('~') + os.sep + '.fluxweatherrc' file = open(configfile,'wb') file.write('# Fluxweather configuration file\n') file.write('# This is the zip or location code from http://weather.yahoo.com\n') file.write('zipcode = ' + self.zip + '\n') file.write('# This is the url of a satellite image you want to display when\n') file.write('# left-clicking the fluxweather icon\n') file.write('mapurl = ' + self.map + '\n') file.close() def close(self, data): gtk.timeout_remove(self.timeout) gtk.main_quit() def popup_menu(self, status, button, time): self.menu.popup(None, None, None, button, time) def about(self, data): dialog = gtk.AboutDialog() dialog.set_name('Fluxweather') dialog.set_version('0.3.0') dialog.set_comments('A system tray icon displaying yahoo weather conditions') dialog.set_website('http://yorik.orgfree.com') dialog.run() dialog.destroy() def config(self,data): dialog = gtk.Dialog() dialog.set_name('Fluxweather settings') table = gtk.Table(2,2) cfzip = gtk.Entry() cfzip.set_text(self.zip) cfzip.set_tooltip_text('Your Location code from http://weather.yahoo.com') cfmap = gtk.Entry() cfmap.set_text(self.map) cfmap.set_tooltip_text('The URL of a satellite image') table.attach(gtk.Label('Zipcode '),0,1,0,1) table.attach(cfzip,1,2,0,1) table.attach(gtk.Label('Map Url '),0,1,1,2) table.attach(cfmap,1,2,1,2) dialog.vbox.pack_start(table) dialog.show_all() cancel_button = dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) ok_button = dialog.add_button(gtk.STOCK_OK,gtk.RESPONSE_OK) ok_button.grab_default() resp = dialog.run() if resp == gtk.RESPONSE_OK: self.zip = cfzip.get_text() self.map = cfmap.get_text() self.writeconfig() dialog.destroy() def map(self,data): if self.isMap: self.mapdialog.hide() self.isMap = False else: self.isMap = True self.mapdialog.show_all() if __name__ == '__main__': TrackerStatusIcon() gtk.main()