I finally got around to putting my gmail-notifier and generic-notifier up on github. They're tiny scripts that sit in your taskbar and notify you of new emails and whatnot.
Initially, I only needed a userland daemon that would poll gmail at specified intervals and send destop notifications that integrate with Ubuntu derivatives. I had written a shell script to do just that using wget and notify-send, but then I started working on machines that weren't using libnotify, so a better solution was in order.
I needed something to sit in the taskbar, have an easy way to change account settings, and fallaback to an at least decent notification bubble if it couldn't use libnotify. Qt offered a remarkably simple GUI setup, decent fallback for notifications, and python bindings. Pynotify (now python-notify) has python bindings for libnotify, but not everyone had pynotify installed back then. Dbus-python was more likely to be on systems that supported the notification spec (since that relies on dbus). I gave up trying to decide which to use, and just did both. Now I had a gmail scraper that did everything I wanted it to.
Gatlin pointed out that quite a few people could use something like this, so I decided to write a more generic version. I designed it so that, to extend the functionality to a different type of account, you would extend the GenericNotifier and PollingDaemon classes. The idea behind this was to have a different process running for each account. Why use threads and manage your own resources when the OS can do it for you?
That said, I'm starting to think that having a manager process running that just forks the different PollingDaemons would be a better UI design.
What do you think?
Comments
Architecture
User installs notifier. They write a module consisting of their subclasses. Module goes in some folder. Remember that in Python a module is just a directory with __init__.py present.
Notifier looks for modules at this location (at startup or at user's behest via taskbar) and imports the appropriate classes from each module, and starts them running (because the parent already had a run method defined which calls the poll, gather message methods).
In this way, you could add/remove new daemons easily without restarting, and it's very Pythonic.
Re: Architecture
That'd be a fine implementation.
My main question was whether I should duplicate the existing functionality in the OS with regards to automatically starting the polling daemons. Do I want to have the user set notifier to autostart and have notifier fork the polling daemons, which is the way most "aggregate information" programs work, or do I want to, say, use the same system tray icon, but let the user decide which daemons start in their global autostart configuration. The first would be replicating existing UI, which allows the user to draw from experience. The second would put all the autostart settings in one place, which I personally prefer.