So, after reading Mark Shuttlework’s blog on ideas for notifications in Ubuntu (basically mimicking Growl notifications for the Mac), I decided I wanted that kind of functionality, but… you know, NOW!
There are a multitude of options available but currently I’m liking Mumbles. Unlike, say, Specto, which does the monitoring itself, Mumbles provides a DBus interface, a command-line app named Woutc, from the Specto project, commented below explaining that Specto is not intended to be a Mumbles competitor, but a package to easily monitor system internals (I quote “…the purposes from mumbles and specto are different…specto is monitoring what happens outside your desktop, mumbles monitors what happens on your desktop (or in your network)…”) Apparently he has plans to build a Mumbles plugin so that one can optionally have Specto send its messages to Mumbles for display.mumbles-send, and (I’m not sure if it’s implemented in the current stable download) libnotify support.
I decided the best easiest route is to access the internal DBus API, however the forums and other resources on the Mumbles site… well… just plain suck. And by suck I mean tell you that something exists and… thaaats about it.
Well in my Google quest I discovered the existence of D-Feet, a DBus debugging tool (on Ars of all places). Thanks to a quick sudo apt-get install d-feet I found the existence of a public interface in info.growl.Growl that allows for a Notify(title, message) signal to be passed.
Well, with a place to access all I needed was DBus integration with PHP (because I want to start sending debug notification via Growl/Mumbles like this idea on the Zend Framework incubator).
Luckily, GREE Labs provides a DBus C extension for PHP that was easily downloaded and installed. Once installed I read the documentation to get an idea on how to use the API (which is a 1:1 mapping to the DBus API).
After a bit of hacking I finally came up with an alpha product:
<?php
function null_callback()
{
var_dump(func_get_args());
}
$dbus = dbus_bus_get(DBUS_BUS_SESSION);
$m = new DBusMessage(DBUS_MESSAGE_TYPE_SIGNAL);
$m->setPath('/info/growl/Growl');
$m->setInterface('info.growl.Growl');
$m->setMember('Notify');
$m->appendArgs('Hello World!');
$m->appendArgs('Lorem Ipsum Dolor Sit Amet. (' . time() . ')');
$r= $dbus->send($m);
After running the script in the console, did I see success?
Damn right I did!
Though with a caveat:
Warning: dbusconnection::sendwithreplyandblock(): dbus_connection_send_with_reply_and_block() failed (Traceback (most recent call last):
File "/var/lib/python-support/python2.5/dbus/service.py", line 643, in _message_cb
(candidate_method, parent_method) = _method_lookup(self, method_name, interface_name)
File "/var/lib/python-support/python2.5/dbus/service.py", line 244, in _method_lookup
raise UnknownMethodException('%s is not a valid method of interface %s' % (method_name, dbus_interface))
UnknownMethodException: org.freedesktop.DBus.Error.UnknownMethod: Unknown method: Notify is not a valid method of interface info.growl.Growl
) in /home/daniel/test.php on line 21
Call Stack:
0.0002 64496 1. {main}() /home/daniel/test.php:0
0.0024 66372 2. dbusconnection->sendwithreplyandblock() /home/daniel/test.php:21
Apparently Mumbles seems to be throwing an Exception that it’s failing to to find the Notify signal (though everything works correctly). I guess I could ignore this, use the error suppressor (@), or even yell at GREE Labs to have the objects throw exceptions so I can catch them… I guess I’ll hack on it some more and report back. I should probably spend more time learning the DBus specs since this is my first project playing with DBus…
Update: Though it’s not listed on the API page for PHP DBus’s API, there is a method send() that takes only a single argument (the message object).
Edit:
I saw a question on Reddit asking what is the use of this technique if it’s limited to the desktop it was called on and PHP is primarily a server side language. Why not do this in Python or Perl?
Well, Mumbles was written in Python so there’s no point in me doing this in Python: it’s already been done.
However, the primary use case of a technique like this is having a web app post notifications and errors for the developer. When I work on a site I have a local copy running on my desktop and/or laptop, so when it posts Growl/Mumbles notifications, I get them on my desktop. It’s great for situations where, say, I have a page in my PHP app that never displays its contents because it processes data then redirects to another page. If a warning or other non-fatal error that I should really fix occurs, then I would normally have to dig through the system wide PHP error log (if you even have error logging enabled). However, if I wrote a custom error handler that posts errors to Growl/Mumbles as they happen, when I visit a transitory page like I described I get little Growl/Mumbles notifications showing that I screwed up!


Comments 6
Very nice, good work. I wonder if this could be engineered on the C side to work with Window’s task bar notifications
Posted 13 Feb 2009 at 9:36 am ¶Well, Windows doesn’t use DBus natively and their tooltip notifications are a bit different. But if you were to write a system tray application that pops up Growl notifications and listens to DBus, this code would work transparently on Linux or Windows :P
Posted 14 Feb 2009 at 12:52 pm ¶Hello,
I am the specto developer and I just want to say that the purposes from mumbles and specto are different…specto is monitoring what happens outside your desktop, mumbles monitors what happens on your desktop (or in your network).
For the moment I am converting specto so it sends dbus signals and a specto plugin for mumbles is already finished.
This means that mumbles will also be able to notify you from specto updates so we will have the ultimate notification system! (all mumbles plugins but also gmail, imap, pop3, rss, websites, processes, ports, greader, facebook,….).
About your error:
Posted 17 Feb 2009 at 1:11 am ¶you use $dbus->sendWithReplyAndBlock($m, 10);
but you should use a method that does not expect a reply because mumbles does not send a reply.
Thanks Woutc! I’ll look more at the PHP DBus API but I didn’t remember seeing anything that didn’t expect a reply. I may just be blind.
And thanks for the correction, I’ll update the post.
Posted 17 Feb 2009 at 1:13 am ¶Hi,
Posted 23 Sep 2009 at 12:37 am ¶Thanks for the tutorial.I tried the same thing but in my error log i am getting “Failed to auto launch D-Bus session :x11 initialisation failed.What could be the reason.
I was wondering, since I found some tutorials online where you could hook up into a different session by finding the session id via SSH and then send commands into that session, would this work in a pure PHP version too?
Posted 30 Jun 2010 at 7:19 am ¶The thing is that I try to remote control Rhythmbox and similar programs via a Web interface and obviously the Webserver runs as www-data and rhythmbox runs as my user.
Trackbacks & Pingbacks 1
[...] Read the original: Tower Of Power – PHP, Mumbles (Growl), and DBus: Sweeet [...]
Post a Comment