Tutorial: Write an Evolution Plugin

Evolution Plugin

This tutorial will show you how to write a mumbles plugin for Evolution that sends a notification when new mail is received.

Plugin Files

If you want to save yourself some typing (or indenting!) time, or just want to grab the plugin, the files for the tutorial are available here.

[edit: If you're using a newer version of Evolution (I have 2.12.1 in Gutsy), a new parameter has been added to the NewMail signal. I have updated the tutorial below to include handling of this parameter, however the files linked above do not yet include this update. Updates will appear shortly in svn

Requirements for this tutorial

  • mumbles version 0.4
  • dbus-monitor
  • Evoultion

The DBus

As mumbles makes use of DBus, the first step in writing a plugin for mumbles is to look for the DBus signals, to which, we are able to connect. I like a simple command line application called dbus-monitor for this.

So, let's watch what happens on the DBus while running Evolution. First in a terminal type:


              
dbus-monitor

              

Next start Evolution.

In the output of dbus-monitor you should see (among other things) a few lines that look similar to:


              
signal sender=:1.62 -> dest=(null destination) path=/org/gnome/evolution/mail/newmail; interface=org.gnome.evolution.mail.dbus.Signal; member=MessageReading string "Inbox"

              

Here, we see a DBus signal named 'MessageReading'. In our example, we're interested in what happens when new mail is received. So send your self a test message and click Send/Receive. You should then see, when your message arrives, in dbus-monitor something like:


              
signal sender=:1.62 -> dest=(null destination) path=/org/gnome/evolution/mail/newmail; interface=org.gnome.evolution.mail.dbus.Signal; member=Newmail string "mbox:/home/dot_j/.evolution/mail/local#Inbox" string "Inbox" uint32 1

              

[edit: depending on your version of Evolution you may not see the last uint32]

We see that when, new mail arrives, a signal is sent to the DBus called 'NewMail'. A few other things we'll need to note are:

  • The signal name (member): NewMail
  • The path: /org/gnome/evolution/mail/newmail
  • The interface: org.gnome.evolution.mail.dbus.Signal
  • And the two paramaters that are sent to the signal:
    • "mbox:/home/dot_j/.evolution/mail/local#Inbox"
    • "Inbox"
    • [edit: "uint23 1" for newer versions]

Writing the plugin

We'll make use of those shortly in the code for the plugin. We got what we needed from dbus-monitor, so go ahead and close it and create a new directory in your home directory for our plugin:


              
mkdir ~/evolution_plugin

              

If you have mumbles installed locally and have dug around in the directories, you may have seen the structure of a mumbles plugin. Each plugin has a file named


              
setup.py

              

and a directory named


              
src

              

The src directory contains another python file called


              
__init__.py

              

setup.py is just that - a setup file for our plugin and __init__.py in the src directory is the source file for our plugin.

Now let’s get down to business. Let’s setup that structure in a new directory for our plugin:


              
mkdir ~/evolution_plugin/src

              

Next, create setup.py in your favorite editor:


              
gedit ~/evolution_plugin/setup.py

              

And enter:


              
#------------------------------------------------------------------------ # A Mumbles Plugin for Evolution #   Copyright (c) 2007 dot_j <dot_j[at]mumbles-project[dot]org> #   Lisenced under the GPL #------------------------------------------------------------------------ from setuptools import setup import sys, os from shutil import copy __author__ = 'dot_j[AT]mumbles-project[DOT]org' __doc__ = 'An Evolution plugin for mumbles' __version__ = '0.1' setup(     name='EvolutionMumbles',     version=__version__,     description=__doc__,     author=__author__,     packages=['evolution'],     package_dir={'evolution':'src'},     entry_points='''     [mumbles.plugins]     Evolution = evolution:EvolutionMumbles     ''' )

And save setup.py

Pretty straight forward setup here. We define our author, documentation and plugin version tags and add what we need in order to build our python egg (plugin). For more information about eggs and setuptools see here.

Now create our plugin source file


              
gedit ~/evolution_plugin/src/__init__.py

              

And enter:


              
#------------------------------------------------------------------------ # A Mumbles Plugin for Evolution #   Copyright (c) 2007 dot_j <dot_j[at]mumbles-project[dot]org> #   Lisenced under the GPL #------------------------------------------------------------------------ # We'll extend the MumblesPlugin class to create our Evolution plugin from MumblesPlugin import * class EvolutionMumbles(MumblesPlugin):     # Give our plugin a name (using the same name we used in setup.py).     plugin_name = "EvolutionMumbles"     # Use the dbus interface we saw in dbus-notify     dbus_interface = "org.gnome.evolution.mail.dbus.Signal"     # Use the dbus path we saw in dbus-notify     dbus_path = "/org/gnome/evolution/mail/newmail"     # Configure our plugin icon     icons = {'evolution' : 'evolution.png'}     # setup the __init__ function where we define     # the dbus signal(s), to which, we are connecting.     # Note this function takes 2 parameters (mumbles_notify and     # session_bus) that we will hand off to our     # MumblesPlugin parent class     def __init__(self, mumbles_notify, session_bus):         # Here, we tell our plugin to connect the dbus signal         # 'Newmail' to our plugin class's 'NewMail' function         self.signal_config = {             "Newmail": self.NewMail         }         # and hand off our mumbles_notify and session_bus objects to our parent         MumblesPlugin.__init__(self, mumbles_notify, session_bus)     # NewMail function     # This will get called when a NewMail signal is received on the DBus from Evolution     # Note the function takes 2 parameters (the two we saw in the dbus-monitor activity)     # [edit: newer versions of Evolution may have a 3rd parameter,     # the follwoing should work with or without this parameter]     def NewMail(self, mbox_path, folder_name, some_int=None):         # Get our icon using the key we used above when configuring our icons dictionary         icon = self.get_icon('evolution')         # Define what we want to send in our notification:         # Send a simple title         title = 'Evolution: New Mail!'         # Let's send our folder name as our notification message         message = folder_name         # If you want to try an advanced version of the plugin,         # see if you can use the supplied mbox_path to get more information         # about the message that just arrived! And be sure to let us know         # about your efforts.         # Finally, using our mumbles_notification object, send the notification         self.mumbles_notify.alert(self.plugin_name, title, message, icon)

And just 60 lines of code (with comments!) - not too bad, right? And we’re almost there. But first, we need to create that icon we used and put it where our plugin can find it.

So, create a plugins directory in your hidden .mumbles directory in your home folder. If you have run mumbles already, you will already have a directory called ~/.mumbles. If not, create that first, then create the plugin and plugin/icons directories there.


              
mkdir ~/.mumbles (if you need to, but you shouldn't) mkdir ~/.mumbles/plugins mkdir ~/.mumbles/plugins/icons

              

The default themes that come with mumbles will support an image around 20×20 pixels. So for this example, I used the Evolution icon I had in in /usr/share/icons/hicolor/22×22/apps/evolution.png


              
cp /usr/share/icons/hicolor/22x22/apps/evolution.png ~/.mumbles/plugins/icons

              

Build and install the plugin


              
cd ~/evolution_plugin (if you're not already there) python setup.py bdist_egg

              

This will use our setup.py file to create our plugin. After it runs, you should see a file named


              
EvolutionMumbles-0.1-py2.5.egg

              

in the dist directory that was created by the build process. Here the -py2.5 part of the filename refers to what version of python you are using (it may vary, but if you are able to start mumbles, should not matter).

The .egg file is our plugin, so the only thing left to do is copy that to the mumbles plugin directory.


              
cp dist/EvolutionMumbles-0.1-py2.5.egg ~/.mumbles/plugins

              

Try it

That’s it! Now run mumbles and send yourself another email. You should see your new mail notification!

Thanks for following along. I hope you found this tutorial both helpful and interesting. And I hope it inspired you to write a plugin of your own. If you expand on this example, or write a new plugin for your favorite application be sure to let us know!

Files

Download tutorial files here.