Jeszcze raz licznik transferu - Python screenlet

sobota, 10 kwietnia 2010 by Michał Jezierski
Ponownie wracam do tematu licznika transferu pod Ubuntu. Ciekawym i przyjemnym wizualnie rozwiązaniem tego tematu może być screenlet. Napisanie tego wymaga dosłownie kilku chwil i podstawowej znajomości Pythona.


Po pierwsze musimy mieć zainstalowaną paczkę screenlets
sudo aptitude install screenlets
Tworzymy plik TrafficCounterScreenlet.py i wklejamy do niego
#!/usr/bin/env python

import screenlets
from screenlets.options import ColorOption, StringOption, IntOption
import cairo
import pango
import gtk
import gobject
from screenlets import DefaultMenuItem 
import commands

class TrafficCounterScreenlet(screenlets.Screenlet):
 """A screenlet displays network traffic for current month"""
 __name__ = 'TrafficCounterScreenlet'
 __version__ = '0.1'
 __author__ = 'Michal Jezierski'
 __desc__ = 'A screenlet displays network traffic for current month.'
 __timeout = None
 update_interval = 60
 __has_focus = False
 __query = ''
 frame_color = (0, 0, 0, 0.7)
 iner_frame_color = (0,0,0,0.3)
 shadow_color = (0,0,0,0.5)
 text_color = (1,1,1, 0.7)
 p_fdesc = None
 p_layout = None
 from time import strftime
 run = 'cat /var/log/traffic/'+strftime("%Y%m")+'.log'
 output = ''
 ctxx = None
 w = 90
 h = 35
 def __init__(self, **keyword_args):
  screenlets.Screenlet.__init__(self, width=90, height=34,ask_on_option_override = False, 
    **keyword_args)
  self.theme_name = "default"

  self.add_options_group('Options', 'Options')
  self.add_option(StringOption('Options', 'run', 
   self.run, 'Command to run', 
   'Command to run'), realtime=False)

  self.add_option(IntOption('Options', 'update_interval', 
   self.update_interval, 'Update interval seconds', 
   'The interval for refreshing RSS feed (in seconds)', min=60, max=10000))

  self.add_option(IntOption('Options', 'w', 
   self.w, 'Width', 
   'width', min=10, max=10000))


  self.add_option(IntOption('Options', 'h', 
   self.h, 'Height', 
   'height', min=10, max=10000))


  self.add_option(ColorOption('Options','frame_color', 
   self.frame_color, 'Background Frame color', 
   'Frame color'))

  self.add_option(ColorOption('Options','iner_frame_color', 
   self.iner_frame_color, 'Iner Frame color', 
   'Iner Frame color'))

  self.add_option(ColorOption('Options','shadow_color', 
   self.shadow_color, 'Shadow color', 
   'Shadow color'))

  self.add_option(ColorOption('Options','text_color', 
   self.text_color, 'Text color', 
   'Text color'))

  self.__timeout = gobject.timeout_add(1000, self.update)
  self.update()

 def __setattr__(self, name, value):
  screenlets.Screenlet.__setattr__(self, name, value)
  if name == "update_interval":
   if value > 0:
    self.__dict__['update_interval'] = value
    if self.__timeout:
     gobject.source_remove(self.__timeout)
    self.__timeout = gobject.timeout_add(int(value * 1000), self.update)
   else:
    self.__dict__['update_interval'] = 1
    pass
  if name == 'w':
   self.width = value
  if name == 'h':
   self.height = value
  if name == 'run':
   self.update()


 def on_init(self):
  self.add_default_menuitems()

 def update(self):
  self.output = commands.getoutput(self.run) + ' MB'
  self.redraw_canvas()
  return True
   
 def on_draw(self, ctx):
  self.ctxx = ctx
  # if a converter or theme is not yet loaded, there's no way to continue
  # set scale relative to scale-attribute
  ctx.scale(self.scale, self.scale)
  # render background
  ctx.set_source_rgba(*self.frame_color)
  self.draw_rectangle_advanced (ctx, 0, 0, self.width-12, self.height-12, rounded_angles=(5,5,5,5), fill=True, border_size=2, border_color=(self.iner_frame_color[0], self.iner_frame_color[1], self.iner_frame_color[2], self.iner_frame_color[3]), shadow_size=6, shadow_color=(self.shadow_color[0], self.shadow_color[1], self.shadow_color[2], self.shadow_color[3]))
  #self.theme['background.svg'].render_cairo(ctx)
  # compute space between fields
  ctx.set_source_rgba(*self.text_color)
  self.draw_text(ctx, str(self.output), 10,10,  'FreeSans',8, self.width-20,allignment=pango.ALIGN_LEFT,justify = True,weight = 0)
 
 def on_draw_shape(self, ctx):
  self.on_draw(ctx)

# If the program is run directly or passed as an argument to the python
# interpreter then create a Screenlet instance and show it
if __name__ == "__main__":
 import screenlets.session
 screenlets.session.create_session(TrafficCounterScreenlet)
Jeżeli nasz screenlet znajduje się w katalogu, np. /home/michal/tmp/TrafficCounter, to z poziomu katalogu /home/michal/tmp/ tworzymy paczkę wydając polecenie
screenlets-packager TrafficCounter
screenlets-packager stworzy archiwum TrafficCounterScreenlet-0.1.tar.gz.
Uwaga: aby interpreter Pythona poprawnie zinterpretował nasz kod, wymagana jest odpowiednia struktura katalogów w jakiej znajduje się nasz screenlet. U mnie wygląda to tak:
TrafficCounter/
   themes/
      default/
         theme.conf
      negative/
         theme.conf
   icon.png
   TrafficCounterScreenlet.py
Pliki theme.conf zawierają informacje o motywie. I tak na przykład default/theme.conf, to motyw standardowy screenletu
[Theme]
name = default
author = Michal Jezierski
version = 0.1
info = default theme

[Options]
frame_color = (0, 0, 0, 0.6)
iner_frame_color = (0,0,0,0.2)
shadow_color = (0,0,0,0.4)
text_color = (1,1,1, 0.7)
Jeżeli wszystko przebiegło poprawnie, to polecenie screenlets-packager TrafficCounter powinno wyświetlić taki wynik
Found path "TrafficCounter".
Screenlet name is TrafficCounter.
Found TrafficCounterScreenlet.py in path.
Successfully imported module: module 'TrafficCounterScreenlet' from 'TrafficCounter/TrafficCounterScreenlet.pyc'>
Successfully got class from module: <class 'TrafficCounterScreenlet.TrafficCounterScreenlet'>
Created package info file.
Cleaned up and finished.
OK.
Aby nasz licznik transferu działał poprawnie, potrzebne jest jeszcze kilka kroków. Podstawą działania licznika transferu są dwa skrypty w bashu, z czego jeden jest uruchamiany cyklicznie co jedną minutę przez cron. Już kiedyś pisałem na ten temat (http://jezier.blogspot.com/2010/02/licznik-transferu-ubuntu-910.html). Nie należy się tym zbytnio tutaj przejmować, gdyż całą sprawę załatwia skrypt instalacyjny, który razem ze screenletem dodałem do archiwum do ściągnięcia. Sposób instalacji opisany jest w pliku README.

Teraz wystarczy uruchomić program screenlets-manager i zainstalować screenlet.

A sam screenlet można ściągnąć stąd: http://jezier.net/files/TrafficCounterScreenlet.zip
Posted in | 1 Comment »

1 komentarz:

Unknown pisze...

OSTATNI LINK NIE DZIAŁA, DAJ GO JESZCZE RAZ.

Prześlij komentarz