--- OutputScreenlet.py 2011-03-27 04:00:23.000000000 +0200 +++ Output/OutputScreenlet.py 2011-03-28 01:19:45.000000000 +0200 @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#! /usr/bin/python # This application is released under the GNU General Public License # v3 (or, at your option, any later version). You can find the full @@ -14,7 +14,7 @@ import screenlets -from screenlets.options import ColorOption, StringOption, IntOption +from screenlets.options import ColorOption, StringOption, IntOption, BoolOption import cairo import pango import gtk @@ -29,9 +29,9 @@ # default meta-info for Screenlets __name__ = 'OutputScreenlet' - __version__ = '0.1' + __version__ = '0.1.p3' __author__ = 'Helder Fraga aka whise' - __desc__ = 'A screenlet displays output from any unix command' + __desc__ = 'A screenlet that displays output from any UNIX command' # a list of the converter class objects __timeout = None @@ -51,6 +51,8 @@ ctxx = None w = 350 h = 100 + reverse = False + # constructor def __init__(self, **keyword_args): #call super @@ -67,17 +69,19 @@ self.add_option(IntOption('Options', 'update_interval', self.update_interval, 'Update interval seconds', - 'The interval for refreshing RSS feed (in seconds)', min=1, max=10000)) + 'The interval for refreshing (in seconds)', min=1, 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(BoolOption('Options', 'reverse', + self.reverse, 'Reverse output', + 'Display the lines in reverse order, especially suitable for logs')) self.add_option(ColorOption('Options','frame_color', self.frame_color, 'Background Frame color', @@ -95,9 +99,10 @@ self.text_color, 'Text color', 'Text color')) - self.__timeout = gobject.timeout_add(1000, self.update) + self.__timeout = gobject.timeout_add(int(self.update_interval * 1000), self.update) self.update() + def __setattr__(self, name, value): # call Screenlet.__setattr__ in baseclass (ESSENTIAL!!!!) screenlets.Screenlet.__setattr__(self, name, value) @@ -110,27 +115,44 @@ else: self.__dict__['update_interval'] = 1 pass - if name == 'w': + elif name == 'w': self.width = value - if name == 'h': + elif name == 'h': self.height = value - if name == 'run': + + # Visualize changes immediately + if name in ('run', 'reverse'): self.update() + elif name in ('w', 'h') or name.endswith('_color'): + self.redraw_canvas() def on_init(self): - self.add_default_menuitems() - - def update(self): - self.output = commands.getoutput(self.run).replace('&','').replace('<','').replace('@','') - if len(self.output) > 300: - self.output = self.output[len(self.output)-300:] - self.redraw_canvas() + output = commands.getoutput(self.run) + + # Need to replace certain characters, because they lead to an empty display for whatever reason + if any(i in output for i in "&<@"): + output = (output.decode("utf-8") + .replace('&','+') + .replace('<', u'\u2039').replace('>', u'\u203a') + .replace('@', u'\u00aa') + ).encode("utf-8") + + maxlines = max(1, (self.height - 18) // 12) + output = output.splitlines()[-maxlines:] + if self.reverse: + output = reversed(output) + output = '\n'.join(output) + + if self.output != output: # do not flicker video overlays without any need + self.output = output + self.redraw_canvas() return True + def on_draw(self, ctx): self.ctxx = ctx