Overkill is a publish-subscribe framework for collecting and distributing information on a local machine.

So why should anyone care? It's a great tool for generating status bar text (hence the name, overkill). Basically, I have a bunch of system monitors that watch various data sources (number of files in a directory, commands that print system statistics, etc.).

This is an approximate diagram (with quite a few data sources/sinks omitted for clarity) of my current setup:

(bspc control --subscribe)   (conky)    [clock]     [inotify]
           |                    |          |             |
           v                    v          v             v
      BSPWMSource          ConkySource TimeSource MailCountSource
           |                    |          |             |
           +---------+----------+----------+-------------+
                     |
                     v
                  Manager
                     |
         +-----------+------------+----------------+------------+
         |           |            |                |            |
         v           v            v                v            v
  DesktopWidget   CpuWidget   MailCountWidget  ClockWidget MailCountNotifier
         |           |            |                |            |
         |           +------------+----------------+            v
         |                        |                      (notification daemon)
         |                        v
         |                  LayoutWidget
         |                        |
         +------------+-----------+
                      |
                      v
                LayoutWidget
                      |
                      v
                   BarSink
                      |
                      v
             (bar-aint-recursive)

Installing

You can find the various python packages on my GitHub. I recommend that you install them in your home directory using python setup.py install --user.

Packages

Dependency Graph

I haven't uploaded the packages to PyPI so here is a dependency graph:

Using

To use overkill, add some python scripts to $XDG_CONFIG_HOME/overkill/ to up your various sources and sinks and then run overkill. Overkill will start any registered sinks which will in turn start up any relevant sources.

You can find my configs here.

I have also reproduced them below:

Common sources

To use overkill, you'll first need to initialize and register your data sources. Note: A source won't actually start collecting data unless something subscribes to it.

from overkill.extra.sources import *
from overkill import manager
import os

MAIL_BASE = os.path.expanduser("~/.mail")
MAIL_DIRS = [
    os.path.join(MAIL_BASE, f)
    for f in os.listdir(MAIL_BASE)
    if f[0] != "."
]

MAIL_QUEUE = os.path.expanduser("~/.mail.queue")

manager.add_source(BSPWMSource())
manager.add_source(PulseaudioSource())
manager.add_source(ConkySource())
manager.add_source(TimeSource())
manager.add_source(MaildirSource(MAIL_DIRS))
manager.add_source(MailqueueSource(MAIL_QUEUE))

Notifications

The following will setup mail and battery notification sinks. The battery notification sink will also suspend your computer when your battery gets low.

from overkill import manager
from overkill.extra.mail import MailNotifySink
from overkill.extra.notify import Notify
from overkill.sinks import SimpleSink
from subprocess import Popen

manager.add_sink(MailNotifySink())

class BatteryNotifySink(SimpleSink, Notify):
    summary = "Battery Warning"
    subscription = "battery_percent"
    urgent_percent = 5
    critical_percent = 10
    low_percent = 15
    _current = 100

    def handle_update(self, update):
        # FIXME: It starts at zero
        if update == "0":
            return

        previous = self._current
        self._current = int(update)

        if previous > self.urgent_percent >= self._current:
            Popen(["/usr/bin/systemctl", "suspend"])
        if previous > self.critical_percent >= self._current:
            self.message = "Critical Battery: %d%%" % self._current
            self.urgency = self.notify.URGENCY_CRITICAL
            self.show()
        elif previous > self.low_percent >= self._current:
            self.message = "Low Battery: %d%%" % self._current
            self.urgency = self.notify.URGENCY_NORMAL
            self.show()

manager.add_sink(BatteryNotifySink())

lemonbar

This script will start lemonbar.

from overkill import manager
from overkill.extra.bar import *
from overkill.extra.bar.widgets import *

bar = Bar()

arrows = r'\f7 << \fr'

bar.set_widget(Layout([
    MultiMonitorWidget(),
    Layout([
        CPUWidget(),
        MemWidget(),
        TempWidget(),
        AudioWidget(),
        BatteryWidget(),
        ExtendedMailCountWidget(),
        NetWidget(("eth0", "wlan0")),
        ClockWidget(" ".join(("%Y{faded}.{normal}%m{faded}.{normal}%d{focus}/{faded}%a{normal}",
                              "{highlight}%H{faded}:{highlight}%M{normal}")).format(
                                  faded = r"\f3",
                                  normal = r"\fr",
                                  focus = r"\f7",
                                  highlight = r"\f5"
                              ))
    ], prefix=r"\r"+arrows, postfix=arrows, separator=arrows, debounce_params=(.1, 1))
], postfix="   "*5, ))

manager.add_sink(bar)

As I understand that these instructions are underspecified, please feel free to either email me questions or, preferably, post an issue on the relevant GitHub project.

Overkill Initial Release

I have been working on a project I call overkill for the past few months or so. It's is a publish-subscribe framework (or a functional-reactive programming framework if you want to use the latest buzz word) for collecting and distributing information on a local machine. Personally, I use it to generate my status bar (hence the name, overkill). See the project page for more information.