#! /usr/bin/env python """ -------------------------------------------------------------------------------- Dmitry Goykolov Based on the weather desklet by Sylvain Fourmanoit and iWeather gDesklet by Michael Favia Copyright (C) Superkaramba's Liquid Weather ++ team for ALL the artwork (icons + background) The maintainer (also the main author I believe) is Matthew Released under the GPL, version 2. Except the artwork, which is released pursuant to the restrictions imposed by their authors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies of the Software and its documentation and acknowledgment shall be given in the documentation and software packages that this Software was used. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. See COPYING file for details -------------------------------------------------------------------------------- """ #------------------------------------------------------------------------------- import adesklets import urllib import re import xmltramp from time import time from os import getenv, system from os.path import join, dirname #------------------------------------------------------------------------------- class Config(adesklets.ConfigFile): """ This is weatherforecast.py desklet configuration file; for each desklet, you only have to write down the minimal delay between updates (in seconds: less than 300 will be ignored), the location code from www.weather.com and specify True or False for metric, depending if you want temperature given in Celcius or in Fahrenheits. """ cfg_default = { 'location' : 'USKY1079', 'metric':True, 'delay':1800, 'theme':'weather.com', 'show_current_conditions':True, 'show_forecast':True, 'show_big_icon':True, 'location_font_size':10, 'small_font_size': 10, 'location_color':'AAAAAAFF', 'cc_color':'AAAAAAFF', 'forecast_color':'AAAAAAFF', 'time_format':12, 'bg':False} def __init__(self,id,filename): adesklets.ConfigFile.__init__(self,id,filename) def color(self,string): colors = [eval('0x%s' % string[i*2:i*2+2]) for i in range(len(string)/2)] if (len(colors) != 4): colors += [255] return colors #------------------------------------------------------------------------------- class Events(adesklets.Events_handler): def __init__(self, basedir): if len(basedir)==0: self.basedir='.' else: self.basedir=basedir self.w = None self.buffer= None self.id= None self.delay=None adesklets.Events_handler.__init__(self) def __del__(self): adesklets.Events_handler.__del__(self) def ready(self): # Real initialisation take place here self.config=Config(adesklets.get_id(), join(self.basedir,'config.txt')) self.delay=self.config['delay'] if self.delay<300: self.delay=300 self.units=self.config['metric'] self.show_cc=self.config['show_current_conditions'] self.show_forecast=self.config['show_forecast'] self.show_icon=self.config['show_big_icon'] if self.units: self.unit_sys='m' else: self.unit_sys='s' self.buffer=adesklets.create_image(500,130) self.theme=self.config['theme'] self.location_color=self.config.color(self.config['location_color']) self.cc_color=self.config.color(self.config['cc_color']) self.forecast_color=self.config.color(self.config['forecast_color']) # Set the window property self.window_w=0 if self.show_icon: self.window_w=120 if self.show_cc: self.window_w=140 if self.show_forecast: self.window_w=240 if self.show_icon and self.show_cc: self.window_w=260 if self.show_icon and self.show_forecast: self.window_w=360 if self.show_cc and self.show_forecast: self.window_w=380 if self.show_icon and self.show_cc and self.show_forecast: self.window_w=500 adesklets.window_resize(self.window_w,130) adesklets.window_set_transparency(True) adesklets.menu_add_separator() adesklets.menu_add_item('Configure') adesklets.window_show() def alarm(self): self.block() self._display() self.unblock() # One second adjustment to make sure everything will be fine return self.config['delay']+1 def menu_fire(self, delayed, menu_id, item): if item=='Configure': editor=getenv('EDITOR') if editor: system('xterm -e %s %s/config.txt &' % (editor, self.basedir)) def _display(self): # As you may have guessed, this is the main drawing routine # Reset the whole buffer image in transparent black adesklets.context_set_image(self.buffer) adesklets.context_set_color(0,0,0,0) adesklets.context_set_blend(False) adesklets.image_fill_rectangle(0,0,self.window_w,130) adesklets.context_set_blend(True) # Draw the background if self.config['bg']: self.background="" if self.window_w==260: self.background='%s/icons/bg.png' % self.basedir if self.window_w==360: self.background='%s/icons/bg-360.png' % self.basedir if self.window_w==380: self.background='%s/icons/bg-380.png' % self.basedir if self.window_w==500: self.background='%s/icons/bg-500.png' % self.basedir if self.background != "": image=adesklets.load_image(self.background) adesklets.blend_image_onto_image(image,1,0,0,self.window_w,130,60,0,self.window_w,130) adesklets.free_image(image) # Getting the XML file from weather.com self.connection=True try: self.w = xmltramp.load('http://xoap.weather.com/weather/local/%s?par=1003832479&key=bb12936706a2d601&cc=*&dayf=3&unit=%s' % (str(self.config['location']), self.unit_sys)) except: self.connection=False adesklets.context_set_color(255,0,0,255) adesklets.context_set_font(adesklets.load_font('VeraBd/12')) adesklets.text_draw(0,0,'Weatherforecast: No internet connection') adesklets.free_font(0) # Draw the weather icon if self.show_icon and self.connection: try: icon=str(self.w['cc']['icon']) except (KeyError, ValueError, TypeError): icon='na' image=adesklets.load_image("%s/icons/%s/%s.png" % (self.basedir, self.theme, icon)) adesklets.blend_image_onto_image(image,1,0,0,120,120,0,0,120,120) adesklets.free_image(image) # Getting and printing out current conditions if self.show_cc and self.connection: # Get the location's name try: location=str(self.w.loc.dnam).split(',')[0] except (KeyError, ValueError): location='Unknown' # Get the conditions try: conditions=str(self.w.cc.t) except (KeyError, ValueError): conditions='N/A' # Get the temperature try: tmp=str(self.w.cc.tmp) unit=' ' + str(self.w.head.ut) except (KeyError, ValueError): tmp='N/A' if tmp=='N/A': unit='' # Get the Feals like temp try: flik=str(self.w.cc.flik) unit=' ' + str(self.w.head.ut) except (KeyError, ValueError): flik='N/A' if flik=='N/A': unit='' # Determine vertical text position from text width # if self.show_icon: text_x=120 #width of the icon else: text_x=0 # Draw all text strings: location, conditions and temperatures # adesklets.context_set_color(*self.location_color) adesklets.context_set_font(adesklets.load_font('Vera/%d' % self.config['location_font_size'])) adesklets.text_draw(text_x,20,location) self.loc_size=self._get_str_width(location) adesklets.free_font(0) adesklets.context_set_font(adesklets.load_font('Vera/%d' % self.config['small_font_size'])) adesklets.context_set_color(*self.cc_color) adesklets.text_draw(text_x,45,conditions) self.cond_size=self._get_str_width(conditions) adesklets.text_draw(text_x,65, tmp + unit) adesklets.text_draw(text_x,85, "FL: "+flik + unit) adesklets.free_font(0) self.f_x=max(self.loc_size,self.cond_size) if self.show_forecast and self.connection: # Extracting and printing out forecast forecastTHi=[0,0,0] forecastTLo=[0,0,0] forecastSunrise=[0,0,0] forecastSunset=[0,0,0] forecastDay=[0,0,0] forecastDayIcon=[0,0,0] forecastNightIcon=[0,0,0] counter=0 for forecast in self.w.dayf["day":]: forecastTHi[counter]=str(forecast.hi)+str(self.w.head.ut) forecastTHi[counter]=str(forecast.hi)+str(self.w.head.ut) forecastTLo[counter]=str(forecast.low)+str(self.w.head.ut) if forecastTHi[counter]=="N/AC": forecastTHi[counter]="N/A" if forecastTLo[counter]=="N/AC": forecastTLo[counter]="N/A" if forecastTHi[counter]=="N/AF": forecastTHi[counter]="N/A" if forecastTLo[counter]=="N/AF": forecastTLo[counter]="N/A" forecastSunrise[counter]=str(forecast.sunr)[:-3] forecastSunset[counter]=str(forecast.suns)[:-3] forecastDay[counter]=str(forecast("t")) for dayparts in forecast['part':]: if dayparts("p")=="d": forecastDayIcon[counter]= str(dayparts.icon) else: forecastNightIcon[counter]=str(dayparts.icon) #Output of the forecast icon_width=28 icon_offset=8 if not self.show_cc and not self.show_icon: forecast_x=0 if not self.show_cc and self.show_icon: forecast_x=120 if self.show_cc and not self.show_icon: forecast_x=self.f_x+10 if self.show_cc and self.show_icon: forecast_x=120+self.f_x+10 forecast_x=forecast_x+85*counter adesklets.context_set_font(adesklets.load_font('Vera/10')) adesklets.context_set_color(*self.forecast_color) image=adesklets.load_image("%s/icons/%s/%s.png" % (self.basedir, self.theme, forecastDayIcon[counter])) adesklets.blend_image_onto_image(image,1,0,0,120,120,forecast_x,40,28,28) adesklets.free_image(image) image=adesklets.load_image("%s/icons/%s/%s.png" % (self.basedir, self.theme, forecastNightIcon[counter])) adesklets.blend_image_onto_image(image,1,0,0,120,120,forecast_x+icon_offset+icon_width,40,28,28) adesklets.free_image(image) day_x=forecast_x+(2*icon_width+icon_offset)/2-self._get_str_width(forecastDay[counter])/2 adesklets.text_draw(day_x,20,forecastDay[counter]) t_hi_x=forecast_x+icon_width/2-self._get_str_width(forecastTHi[counter])/2 adesklets.text_draw(t_hi_x,68,forecastTHi[counter]) t_lo_x=forecast_x+icon_width+icon_offset+icon_width/2-self._get_str_width(forecastTLo[counter])/2 adesklets.text_draw(t_lo_x,68,forecastTLo[counter]) sunrise_x=forecast_x+icon_width/2-self._get_str_width(forecastSunrise[counter])/2 adesklets.text_draw(sunrise_x,85,forecastSunrise[counter]) sunset_hour=int(forecastSunset[counter][0]) if self.config['time_format']==24: sunset_hour=sunset_hour+12 ss_h="%s%s" % (str(sunset_hour), forecastSunset[counter][1:]) sunset_x=forecast_x+icon_width+icon_offset+icon_width/2-self._get_str_width(ss_h)/2 adesklets.text_draw(sunset_x,85,ss_h) adesklets.free_font(0) counter=counter+1 # Copy everything from the buffer image to the real foreground image adesklets.context_set_image(0) adesklets.context_set_blend(False) adesklets.blend_image_onto_image(self.buffer,1,0,0,self.window_w,130,0,0,self.window_w,130) adesklets.context_set_blend(True) system('rm -rf *.pyc') def _get_str_width(self,text): width, height = adesklets.get_text_size(text) return width #------------------------------------------------------------------------------- Events(dirname(__file__)).pause()