j ai pas de fichier config.txt mais un newsfeed.py
et le contenu de ce fichier est le suivant :
#! /usr/bin/env python
"""
--------------------------------------------------------------------------------
Copyright (C) 2005 Alessio Carenini <farquaad@users.sourceforge.net>
for the code
Released under the GPL, version 2.
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.
--------------------------------------------------------------------------------
RSS/ATOM news feed desklets
Tested on adesklet-0.4.0 with python-2.3.4
Required feedparser.py from www.feedparser.org
Just run this script from its final location on you disk to start the desklet.
--------------------------------------------------------------------------------
"""
#-------------------------------------------------------------------------------
import adesklets
from os import getenv, system
from os.path import join, dirname
import feedparser
import textwrap
#-------------------------------------------------------------------------------
class Config(adesklets.ConfigFile):
"""
This is newsfeed.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 URL of the feed
and the size of the desklet
Details:
sizeX,sizeY: width and height
head_font, head_font_height: font for news title
item_font, item_font_height: font for news details
url: rss/atom newsfeed url
line_spacing: pixels between two lines
borderX, borderY: area reserved to borders
interactive: if True, enables highlighting of news details and calling
selected browser
browser: browser to call for viewing selected news
"""
cfg_default = {
'sizeX':400,
'sizeY':600,
'delay':600,
'url':'http://slashdot.org/index.rss',
'head_font':'VeraBd',
'head_font_height':8,
'head_font_color':'ffff00',
'item_font':'Vera',
'item_font_height':8,
'item_font_color':'02c601',
'selected_font_color':'ffffff',
'title_font':'VeraBd',
'title_font_height':12,
'title_font_color':'ffe600',
'line_spacing':5,
'interactive':False,
'browser':'firefox',
'managed':True,
'borderX':7,
'borderY':7
}
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
self.item_pos=None
self.selected_item=None
self.feed=None
self.modified=None
self.error_flag=0
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'))
if self.config['delay']<300:
self.config['delay']=300
self.x=self.config['sizeX']
self.y=self.config['sizeY']
self.url=self.config['url']
# Font config
self.h_font=self.config['head_font']
self.h_font_height=self.config['head_font_height']
self.h_font_color=self.config.color(self.config['head_font_color'])
self.i_font=self.config['item_font']
self.i_font_height=self.config['item_font_height']
self.i_font_color=self.config.color(self.config['item_font_color'])
self.sel_font_color=self.config.color(self.config['selected_font_color'])
self.t_font=self.config['title_font']
self.t_font_height=self.config['title_font_height']
self.t_font_color=self.config.color(self.config['title_font_color'])
self.line_spacing=self.config['line_spacing']
self.interactive=self.config['interactive']
self.borderX=self.config['borderX']
self.borderY=self.config['borderY']
self.browser=self.config['browser']
adesklets.add_path_to_font_path(join(self.basedir))
self.buffer=adesklets.create_image(self.x,self.y)
# Set the window property
adesklets.window_resize(self.x,self.y)
adesklets.window_set_transparency(True)
if (self.config['managed']):
adesklets.window_reset(adesklets.WINDOW_MANAGED)
adesklets.menu_add_separator()
adesklets.menu_add_item('Configure')
adesklets.menu_add_item('Update feed')
adesklets.window_show()
def alarm(self):
self.block()
self.feed=self.update_feed()
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))
if item=='Update feed':
self.block()
self.feed=self.update_feed()
self._display()
self.unblock()
def _display(self):
self.set_buffer_image()
if self.feed.bozo==1:
self.error_flag=1
self.draw_error_info()
else:
self.error_flag=0
self.draw_info()
self.copy_to_desklet()
def set_buffer_image(self):
# 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.x,self.y)
adesklets.context_set_blend(True)
self.draw_borders()
#--------------- Item selection and viewing ---------------
def fire_browser(self,item):
system(self.browser+' '+self.feed['items'][self.selected_item].link)
def button_release(self, delayed, x, y, button):
if (button==1)&(self.interactive):
self.select_item(x,y)
self.fire_browser(self.selected_item)
def select_item(self,x,y):
prev_selected=self.selected_item
for i in range(len(self.item_pos)):
if (self.item_pos[i]!=[]):
y_start=self.item_pos[i][0]
y_end=self.item_pos[i][1]
if (y>y_start)&(y<y_end):
self.selected_item=i
if (prev_selected!=self.selected_item):
if (prev_selected>-1):
self.redraw_news_content(prev_selected,0)
self.redraw_news_content(self.selected_item,1)
def motion_notify(self, delayed, x, y):
if (self.error_flag==0):
if (not delayed)&(self.interactive):
self.select_item(x,y)
def leave_notify(self, delayed, x, y):
if (self.error_flag==0):
self.selected_item=-1
self._display()
#------------- Drawing functions -------------
def draw_info(self):
self.item_pos=[]
total_feeds=len(self.feed['items'])-1
if total_feeds>20: total_feeds=20
self.item_pos=[[] for i in range (total_feeds)]
self.y_current=self.draw_title()
for item in range(total_feeds):
if (self.draw_news_header(item)==0):
if (item==self.selected_item):
ret=self.draw_news_content(item,1)
else:
ret=self.draw_news_content(item,0)
if (ret==1):
return
else:
return
def copy_to_desklet(self):
# 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.x,self.y,0,0,self.x,self.y)
adesklets.context_set_blend(True)
# Free all fonts used
adesklets.fonts_reset_all()
def draw_error_info(self):
adesklets.context_set_font(adesklets.load_font(self.t_font+'/'+str(self.t_font_height)))
adesklets.context_set_color(*self.h_font_color)
adesklets.text_draw(45,15,'News: Error fetching news!')
icon=adesklets.load_image(join(self.basedir,'img/news.png'))
adesklets.blend_image_onto_image(icon,1,0,0,68,60,11,10,30,30)
adesklets.free_image(icon)
adesklets.context_set_font(adesklets.load_font('VeraBd/8'))
adesklets.context_set_color(*self.t_font_color)
adesklets.text_draw(12,40,'Error: '+str(self.feed.bozo_exception))
def draw_news_header(self,item):
adesklets.context_set_font(adesklets.load_font(self.h_font+'/'+str(self.h_font_height)))
feed_title=str(self.feed['items'][item]['title'])
text_x=12
text_y=self.line_spacing+self.y_current
adesklets.context_set_color(*self.h_font_color)
if ((text_y+self.line_spacing+self.h_font_height)<self.y):
adesklets.text_draw(text_x,text_y,feed_title)
return 0
else:
return 1
def redraw_news_content(self,item,selected):
if (selected==0):
image=adesklets.load_image(join(self.basedir,'img/dark.png'))
header_space=self.line_spacing+self.h_font_height
xstart=self.borderX
ystart=self.item_pos[item][0]+1.5*header_space
width=self.x-2*self.borderX
height=self.item_pos[item][1]-self.item_pos[item][0]-header_space
adesklets.blend_image_onto_image(image,0,0,0,80,80,xstart,ystart,width,height)
adesklets.free_image(image)
adesklets.context_set_color(*self.i_font_color)
else:
adesklets.context_set_color(*self.sel_font_color)
current=0
header_space=self.line_spacing+self.h_font_height
adesklets.context_set_font(adesklets.load_font(self.i_font+'/'+str(self.i_font_height)))
feed_content=str(self.feed['items'][item]['description'])
feed_lines= self.string_to_paragraph(feed_content)
for i in range(len(feed_lines)):
text_x=15
text_y=header_space+self.item_pos[item][0]+self.line_spacing+(self.line_spacing+self.i_font_height)*current
if ((text_y+self.line_spacing+self.i_font_height)<self.y):
adesklets.text_draw(text_x,text_y,feed_lines[i])
current+=1
else:
return 1
def draw_news_content(self,item,selected):
last=0
if (selected==0):
adesklets.context_set_color(*self.i_font_color)
else:
adesklets.context_set_color(*self.selected_font_color)
current=0
header_space=self.line_spacing+self.h_font_height
adesklets.context_set_font(adesklets.load_font(self.i_font+'/'+str(self.i_font_height)))
feed_content=str(self.feed['items'][item]['description'])
feed_lines= self.string_to_paragraph(feed_content)
for i in range(len(feed_lines)):
text_x=15
text_y=header_space+self.y_current+self.line_spacing+(self.line_spacing+self.i_font_height)*current
if ((text_y+self.line_spacing+self.i_font_height)<self.y):
adesklets.text_draw(text_x,text_y,feed_lines[i])
current+=1
else:
self.item_pos[item].append(self.y_current)
self.item_pos[item].append(self.y-self.borderY)
return 1
y_start,self.y_current=self.calculate_bounds(self.y_current,feed_lines)
self.item_pos[item].append(y_start)
self.item_pos[item].append(self.y_current)
return 0
def draw_title(self):
adesklets.context_set_font(adesklets.load_font(self.t_font+'/'+str(self.t_font_height)))
adesklets.context_set_color(*self.t_font_color)
adesklets.text_draw(45,15,'News: '+str(self.feed['feed']['title']))
icon=adesklets.load_image(join(self.basedir,'img/news.png'))
adesklets.blend_image_onto_image(icon,1,0,0,68,60,11,10,30,30)
adesklets.free_image(icon)
return 45
def draw_borders(self):
image=adesklets.load_image(join(self.basedir,'img/dark.png'))
adesklets.blend_image_onto_image(image,1,0,0,80,80,0,0,self.x,self.y)
adesklets.free_image(image)
image=adesklets.load_image(join(self.basedir,'img/e-light.png'))
adesklets.blend_image_onto_image(image,1,0,0,15,10,
self.x-self.borderX,self.borderY,
self.borderX,self.y-(2*self.borderY))
adesklets.free_image(image)
image=adesklets.load_image(join(self.basedir,'img/w-light.png'))
adesklets.blend_image_onto_image(image,1,0,0,15,10,
0,self.borderY,
self.borderX,self.y-(2*self.borderY))
adesklets.free_image(image)
image=adesklets.load_image(join(self.basedir,'img/n-light.png'))
adesklets.blend_image_onto_image(image,1,0,0,10,9,
self.borderX,0,
self.x-(2*self.borderX),self.borderY)
adesklets.free_image(image)
image=adesklets.load_image(join(self.basedir,'img/ne-light.png'))
adesklets.blend_image_onto_image(image,1,0,0,15,9,
self.x-self.borderX,0,
self.borderX,self.borderY)
adesklets.free_image(image)
image=adesklets.load_image(join(self.basedir,'img/nw-light.png'))
adesklets.blend_image_onto_image(image,1,0,0,15,9,
0,0,
self.borderX,self.borderY)
adesklets.free_image(image)
image=adesklets.load_image(join(self.basedir,'img/sw-light.png'))
adesklets.blend_image_onto_image(image,1,0,0,15,9,
0,self.y-self.borderY,
self.borderX,self.borderY)
adesklets.free_image(image)
image=adesklets.load_image(join(self.basedir,'img/s-light.png'))
adesklets.blend_image_onto_image(image,1,0,0,10,9,
self.borderX,self.y-self.borderY,
self.x-(2*self.borderX),self.borderY)
adesklets.free_image(image)
image=adesklets.load_image(join(self.basedir,'img/se-light.png'))
adesklets.blend_image_onto_image(image,1,0,0,15,9,
self.x-self.borderX,self.y-self.borderY,
self.borderX,self.borderY)
adesklets.free_image(image)
#-------------- Utility methods -----------------
def string_to_paragraph(self,string):
string_size=adesklets.get_text_size(string)
char_per_line=(self.x-2*self.borderX)/adesklets.get_text_size('x')[0]
lines=len(string)/char_per_line
limit=char_per_line
result=[]
result=textwrap.wrap(string,char_per_line)
return result
def calculate_bounds(self,y_start,paragraph):
item_space=len(paragraph)*(self.line_spacing+self.i_font_height)
header_space=self.line_spacing+self.h_font_height
return y_start,y_start+item_space+header_space
def update_feed(self):
# Parse url
if (self.modified==None):
return feedparser.parse(self.url)
else:
temp_feed=feedparser.parse(self.url,modified=self.feed.modified)
if (temp_feed.status=='304'):
return self.feed
else:
return temp_feed
#-------------------------------------------------------------------------------
if hasattr(adesklets,'version_check'):
Events(dirname(__file__)).pause()
else:
raise RuntimeError, 'You need adesklets >= 0.4.0. See README.'
je sais pas si ca t aide...