summaryrefslogtreecommitdiff
path: root/alternative_wmiircs/python/pygmi/monitor.py
diff options
context:
space:
mode:
Diffstat (limited to 'alternative_wmiircs/python/pygmi/monitor.py')
-rw-r--r--alternative_wmiircs/python/pygmi/monitor.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/alternative_wmiircs/python/pygmi/monitor.py b/alternative_wmiircs/python/pygmi/monitor.py
new file mode 100644
index 0000000..528e9cd
--- /dev/null
+++ b/alternative_wmiircs/python/pygmi/monitor.py
@@ -0,0 +1,118 @@
+from threading import Timer
+
+from pygmi import client
+from pygmi.fs import *
+
+__all__ = 'monitors', 'defmonitor', 'Monitor'
+
+monitors = {}
+
+def defmonitor(*args, **kwargs):
+ """
+ Defines a new monitor to appear in wmii's bar based on
+ the wrapped function. Creates a new Monitor object,
+ initialized with *args and **kwargs. The wrapped function
+ is assigned to the 'action' keyword argument for the
+ Monitor, its name is assigned to the 'name' argument.
+
+ The new monitor is added to the 'monitors' dict in this
+ module.
+ """
+ def monitor(fn):
+ kwargs['action'] = fn
+ if not args and 'name' not in kwargs:
+ kwargs['name'] = fn.__name__
+ monitor = Monitor(*args, **kwargs)
+ monitors[monitor.name] = monitor
+ return monitor
+ if args and callable(args[0]):
+ fn = args[0]
+ args = args[1:]
+ return monitor(fn)
+ return monitor
+
+class Monitor(object):
+ """
+ A class to manage status monitors for wmii's bar. The bar item
+ is updated on a fixed interval based on the values returned
+ by the 'action' method.
+
+ Property active: When true, the monitor is updated at regular
+ intervals. When false, monitor is hidden.
+ Property name: The name of the monitor, which acts as the name
+ of the bar in wmii's filesystem.
+ Property interval: The update interval, in seconds.
+ Property side: The side of the bar on which to place the monitor.
+ Property action: A function of no arguments which returns the
+ value of the monitor. Called at each update interval.
+ May return a string, a tuple of (Color, string), or None
+ to hide the monitor for one iteration.
+ """
+ side = 'right'
+ interval = 1.0
+
+ def __init__(self, name=None, interval=None, side=None,
+ action=None, colors=None, label=None):
+ """
+ Initializes the new monitor. For parameter values, see the
+ corresponding property values in the class's docstring.
+
+ Param colors: The initial colors for the monitor.
+ Param label: The initial label for the monitor.
+ """
+ if side:
+ self.side = side
+ if name:
+ self.name = name
+ if interval:
+ self.interval = interval
+ if action:
+ self.action = action
+
+ self.timer = None
+ self.button = Button(self.side, self.name, colors, label)
+ self.tick()
+
+ def tick(self):
+ """
+ Called internally at the interval defined by #interval.
+ Calls #action and updates the monitor based on the result.
+ """
+ mon = monitors.get(self.name, None)
+ if self.timer and mon is not self:
+ return
+ if self.active:
+ label = self.getlabel()
+ if isinstance(label, basestring):
+ label = None, label
+ if label is None:
+ self.button.remove()
+ else:
+ self.button.create(*label)
+
+ self.timer = Timer(self.interval, self.tick)
+ self.timer.daemon = True
+ self.timer.start()
+
+ def getlabel(self):
+ """
+ Calls #action and returns the result, ignoring any
+ exceptions.
+ """
+ try:
+ return self.action(self)
+ except Exception:
+ return None
+
+ _active = True
+ def _set_active(self, val):
+ self._active = bool(val)
+ self.tick()
+ if not val:
+ self.button.remove()
+
+ active = property(
+ lambda self: self._active,
+ _set_active)
+
+# vim:se sts=4 sw=4 et: