"""
cpu.py - ZeroDivide <zerodiv at gmail dot com>, 2005
Themeable cpu monitor:
This is the first of a few system monitors I
plan to make that are themeable and stackable.
"""
import adesklets
import statgrab
from os import getenv, system
from os.path import join, dirname
class Gauge:
def __init__(self,canvas, basedir, image_dir, var_name):
self.canvas=canvas
self.basedir=basedir
self.image_dir=image_dir
self.var_name = var_name
self.x=self.y=self.value=0
adesklets.set( self.var_name, 0)
self.image=adesklets.load_image('%s/%s' % (self.basedir, self.image_dir + 'center.png'))
self.bgimage=adesklets.load_image('%s/%s' % (self.basedir, self.image_dir + 'bg.png'))
# get image size
adesklets.context_set_image(self.bgimage)
self.w=adesklets.image_get_width()
self.h=adesklets.image_get_height()
def draw(self,background=0):
#adesklets.blend_image_onto_image(background,0,self.x+self.canvas.x,self.y+self.canvas.y,self.w,self.h,
# self.x+self.canvas.x,self.y+self.canvas.y,self.w,self.h)
adesklets.blend_image_onto_image(self.image,0,
0,0,'$' + self.var_name,self.h,
self.x+self.canvas.x,self.y+self.canvas.y,'$' + self.var_name,self.h)
def update_background(self,background):
#draw gauge background image on background
adesklets.context_set_blend(True)
self.bgimage=adesklets.load_image('%s/%s' % (self.basedir, self.image_dir + 'bg.png'))
blend_state=adesklets.context_get_blend()
adesklets.blend_image_onto_image(self.bgimage,1,0,0,self.w,self.h,
self.x+self.canvas.x,self.y+self.canvas.y,self.w,self.h)
adesklets.free_image(self.bgimage)
#update gauge foreground image
adesklets.context_set_blend(False)
adesklets.context_set_image(self.image)
temp_image=adesklets.clone_image()
adesklets.blend_image_onto_image(background,0,self.x+self.canvas.x, self.y+self.canvas.y,self.w,self.h,0,0,self.w,self.h)
adesklets.context_set_blend(True)
adesklets.blend_image_onto_image(temp_image,1,0,0,self.w,self.h,0,0,self.w,self.h)
adesklets.free_image(temp_image)
adesklets.context_set_blend(blend_state)
class Icon:
def __init__(self,canvas,basedir,image_file):
self.canvas=canvas
self.basedir=basedir
self.image_file=image_file
self.x=self.y=self.w=self.h=0
# get image size
self.image=adesklets.load_image('%s/%s' % (self.basedir, self.image_file))
adesklets.context_set_image(self.image)
self.w=adesklets.image_get_width()
self.h=adesklets.image_get_height()
def update_background(self, background):
adesklets.blend_image_onto_image(self.image,0,
0,0,self.w,self.h,
self.x+self.canvas.x,self.y+self.canvas.y,self.w,self.h)
class Text:
def __init__(self,canvas, font, text, var_name):
self.canvas=canvas
self.var_name=var_name
adesklets.set( self.var_name, 'Default')
self.font=adesklets.load_font(font)
self.text=text
adesklets.context_set_font(self.font)
size=adesklets.get_text_size(text)
self.w=size[0]
self.h=size[1]
self.x=0
self.y=0
def draw(self,background=0):
adesklets.context_set_color(0,0,0,255)
adesklets.context_set_font(self.font)
#
#adesklets.blend_image_onto_image(background,0,self.x+self.canvas.x,self.y+self.canvas.y,self.w,self.h,
# self.x+self.canvas.x,self.y+self.canvas.y,self.w,self.h)
adesklets.text_draw(self.x+self.canvas.x, self.y+self.canvas.y, '$' + self.var_name)
class Canvas:
def __init__(self, x=0, y=0, w=0, h=0):
self.x = x
self.y = y
self.w = w
self.h = h
class Config(adesklets.ConfigFile):
"""
This is my configuration file description
"""
cfg_default = { 'border' : 'images/borders/white-med/',
'border_mask' : 'images/border-mask/white-ext/',
'border_left' : True,
'border_right' : True,
'border_top' : True,
'border_bottom' : True,
'background_effect': 'tint(alpha=128,red=0,green=0,blue=0);',
'background_blur': '0',
'gauge' : 'images/gauge/rect-rect-white/',
'icon' : 'cpu.png',
'font' : 'VeraBd/8',
'font_color' : '#FFFFFF'}
def __init__(self, id, filename):
adesklets. ConfigFile.__init__(self, id, filename)
class Events(adesklets.Events_handler):
def __init__(self, basedir):
if len(basedir)==0:
self.basedir='.'
else:
self.basedir=basedir
self.top_canvas=Canvas(0,0,200,0)
self.w = None
self.h = None
self.buffer= None
self.id= None
self.delay=None
self.border=None
self.border_mask=None
self.get_config()
stats = statgrab.sg_get_cpu_percents()
self.icon=Icon(self.top_canvas,self.basedir,self.config['icon'])
self.cpu_gauge=Gauge(self.top_canvas,self.basedir,self.config['gauge'],'gauge')
self.text=Text(self.top_canvas,'VeraBd/8','CPU Load 1000%','blah')
margin=3
self.icon.x=margin
#### place gauge
self.cpu_gauge.x=self.icon.x+self.icon.w+margin
self.cpu_gauge.y=margin
#### place text
self.text.x=self.cpu_gauge.x
self.text.y=self.cpu_gauge.y+self.cpu_gauge.h+margin
#### calculate height of canvas
self.top_canvas.h=self.text.y+self.text.h+margin
#### center icon vertically
self.icon.y = (self.top_canvas.h/2) - (self.icon.h/2)
#### setup our border and border mask
self.border=self.create_border_image(self.top_canvas,1,0,self.config['border'])
self.border_mask=self.create_border_image(self.top_canvas,0,1,'images/border-masks/default/')
#### fit our window to the border image
adesklets.context_set_image(self.border)
self.w = adesklets.image_get_width()
self.h = adesklets.image_get_height()
adesklets.Events_handler.__init__(self)
def __del__(self):
adesklets.Events_handler.__del__(self)
def get_config(self):
self.config=Config(adesklets.get_id(),
join(self.basedir,'config.txt'))
def ready(self):
# We use a buffer image to avoid flickering */
self.buffer=adesklets.create_image(self.w,self.h)
self.record_display()
# Set the window property
adesklets.window_resize(self.w,self.h)
adesklets.window_set_transparency(False)
editor=getenv('EDITOR')
if editor:
adesklets.menu_add_separator()
adesklets.menu_add_item('README')
adesklets.menu_add_item('Configure')
adesklets.window_show()
def menu_fire(self, delayed, menu_id, item):
if item=='Configure':
editor=getenv('EDITOR')
system('xterm -e %s %s/config.txt &' % (editor, self.basedir))
elif item=='README':
editor=getenv('EDITOR')
system('xterm -e %s %s/README &' % (editor, self.basedir))
def create_border_image(self, canvas, offset_canvas, mask, directory):
"""
create border image around outside of canvas
"""
#load images
tl=adesklets.load_image('%s/%s' % (self.basedir, directory + 'top-left.png'))
tr=adesklets.load_image('%s/%s' % (self.basedir, directory + 'top-right.png'))
bl=adesklets.load_image('%s/%s' % (self.basedir, directory + 'bottom-left.png'))
br=adesklets.load_image('%s/%s' % (self.basedir, directory + 'bottom-right.png'))
l=adesklets.load_image('%s/%s' % (self.basedir, directory + 'left.png'))
r=adesklets.load_image('%s/%s' % (self.basedir, directory + 'right.png'))
t=adesklets.load_image('%s/%s' % (self.basedir, directory + 'top.png'))
b=adesklets.load_image('%s/%s' % (self.basedir, directory + 'bottom.png'))
#get border sizes
adesklets.context_set_image(l)
l_h=adesklets.image_get_height()
l_w=adesklets.image_get_width()
adesklets.context_set_image(r)
r_h=adesklets.image_get_height()
r_w=adesklets.image_get_width()
adesklets.context_set_image(t)
t_w=adesklets.image_get_width()
t_h=adesklets.image_get_height()
adesklets.context_set_image(b)
b_w=adesklets.image_get_width()
b_h=adesklets.image_get_height()
#calculate destination image size and offset canvas if requested
w=canvas.w
h=canvas.h
if self.config['border_top']==True:
h+=t_h
if offset_canvas:
canvas.y += t_h
if self.config['border_bottom']==True:
h+=b_h
if self.config['border_left']==True:
w+=l_w
if offset_canvas:
canvas.x += l_w
if self.config['border_right']==True:
w+=r_w
#create image
image=adesklets.create_image(w,h)
adesklets.context_set_blend(False)
adesklets.context_set_image(image)
if mask:
adesklets.context_set_color(0,0,0,255)
else:
adesklets.context_set_color(0,0,0,0)
adesklets.image_fill_rectangle(0,0,w,h)
#draw sides
if self.config['border_top']==True:
adesklets.blend_image_onto_image(t,1,0,0,t_w,t_h,
0,0,w,t_h)
if self.config['border_bottom']==True:
adesklets.blend_image_onto_image(b,1,0,0,b_w,b_h,
0,h-b_h,w,b_h)
if self.config['border_left']==True:
adesklets.blend_image_onto_image(l,1,0,0,l_w,l_h,
0,0,l_w,h)
if self.config['border_right']==True:
adesklets.blend_image_onto_image(r,1,0,0,r_w,r_h,
w-r_w,0,r_w,h)
#draw corners
if self.config['border_top']==True & self.config['border_left']==True:
adesklets.context_set_image(tl)
corner_w=adesklets.image_get_width()
corner_h=adesklets.image_get_height()
adesklets.context_set_image(image)
adesklets.blend_image_onto_image(tl,1,0,0,corner_w,corner_h,0,0,corner_w,corner_h)
if self.config['border_top']==True & self.config['border_right']==True:
adesklets.context_set_image(tr)
corner_w=adesklets.image_get_width()
corner_h=adesklets.image_get_height()
adesklets.context_set_image(image)
adesklets.blend_image_onto_image(tr,1,0,0,corner_w,corner_h,w-corner_w,0,corner_w,corner_h)
if self.config['border_bottom']==True & self.config['border_left']==True:
adesklets.context_set_image(bl)
corner_w=adesklets.image_get_width()
corner_h=adesklets.image_get_height()
adesklets.context_set_image(image)
adesklets.blend_image_onto_image(bl,1,0,0,corner_w,corner_h,0,h-corner_h,corner_w,corner_h)
if self.config['border_bottom']==True & self.config['border_right']==True:
adesklets.context_set_image(br)
corner_w=adesklets.image_get_width()
corner_h=adesklets.image_get_height()
adesklets.context_set_image(image)
adesklets.blend_image_onto_image(br,1,0,0,corner_w,corner_h,w-corner_w,h-corner_h,corner_w,corner_h)
#free our temp images
for i in range(8):
adesklets.free_image(tl)
return image-8
def background_grab(self, delayed):
#copy background image to buffer and apply effects
adesklets.context_set_blend(False)
adesklets.context_set_image(self.buffer)
adesklets.blend_image_onto_image(1,1,0,0,self.w,self.h,0,0,self.w,self.h)
adesklets.apply_filter(self.config['background_effect'])
adesklets.image_blur(self.config['background_blur'])
#blend modified background onto our bordermask
adesklets.context_set_blend(True)
adesklets.context_set_image(self.border_mask)
adesklets.blend_image_onto_image(self.buffer,0,0,0,self.w,self.h,0,0,self.w,self.h)
#combine everything
adesklets.context_set_blend(True)
adesklets.context_set_image(1)
adesklets.blend_image_onto_image(self.border_mask,0,0,0,self.w,self.h,0,0,self.w,self.h)
adesklets.blend_image_onto_image(self.border,1,0,0,self.w,self.h,0,0,self.w,self.h)
self.icon.update_background(1)
self.cpu_gauge.update_background(1)
#update our buffer with finished background
adesklets.context_set_blend(False)
adesklets.context_set_image(self.buffer)
adesklets.blend_image_onto_image(1,1,0,0,self.w,self.h,0,0,self.w,self.h)
#copy our new background to the foreground image
adesklets.context_set_image(0)
adesklets.blend_image_onto_image(1,1,0,0,self.w,self.h,0,0,self.w,self.h)
adesklets.play(*self.display)
def record_display(self):
adesklets.start_recording()
adesklets.context_set_image(self.buffer)
adesklets.blend_image_onto_image(1,0,self.top_canvas.x,self.top_canvas.y,self.top_canvas.w,self.top_canvas.h,
self.top_canvas.x,self.top_canvas.y,self.top_canvas.w,self.top_canvas.h)
self.cpu_gauge.draw()
self.text.draw()
adesklets.context_set_image(0)
adesklets.blend_image_onto_image(self.buffer,0,self.top_canvas.x,self.top_canvas.y,self.top_canvas.w,self.top_canvas.h,
self.top_canvas.x,self.top_canvas.y,self.top_canvas.w,self.top_canvas.h)
self.display=adesklets.stop_recording()
adesklets.play_set_abort_on_events(False)
def quit(self):
print 'Quitting...'
def get_cpu_stats(self):
stats = statgrab.sg_get_cpu_percents()
self.cpu_total = 100 - stats['idle']
def alarm(self):
self.block()
self.get_cpu_stats()
adesklets.set( self.cpu_gauge.var_name, int(self.cpu_total * (self.cpu_gauge.w / 100.0)) )
adesklets.set( self.text.var_name, 'CPU Load ' + str(int(self.cpu_total)) + '%')
adesklets.play(*self.display)
self.unblock()
return 1
Events(dirname(__file__)).pause()