Psi Plugins Soc 2006
The aim of this project is to provide both a plugin system and, as a plugin, a Python scripting interface.
Week 1 (24th-31st May)
Initial work such as creating a branch of the Psi mainline repository completed.
Finding and displaying plugins
- I've implemented some (very basic and initial) code to locate installed plugins and to list them, together with their names (the plugins define their own names) in a new options dialog pane.
- Directory watching has been implemented on the plugin directories, such that new plugins will be located as soon as they're installed
- I've written plugin loading and unloading code. On Windows and Linux this means that plugins can be loaded and unloaded on the fly (allowing plugin upgrading while Psi is running). On OSX it's not possible to unload the .dylib once it's loaded and the code works around this, allowing plugins to be disabled but not unloaded, with the objects cached so they can be re-enabled later without a restart.
- I've written a large chunk of a generic (non-Psi dependent) soft-coded options structure. What this means is that you can use options dynamically by just calling something like
options.setOption("path.to.option",true)and the value will be stored in the tree, regardless of whether the options tree was expecting you to have an option named "path.to.option" or not. This is then dumped to xml for storage on disc, and the xml parsed back in to recreate the tree. It's also possible to store comments for each node or value, this is useful both for the xml to be readable and for writing a generic options dialog, which allows you to edit any value stored in the tree, without knowing in advance what these are.
Week 2 (1st-7th June)
A slack week unfortunately (or rather, a very not slack week on my thesis). I saw Julian's post about a link tracker, so I fixed up the interface enough to write my first plugin.
Excerpt from my blog:
- Well, I read Julian's blog entry about a link history for im clients, rather like those IRC users have been enjoying for years and I thought "Hey, that'd make a great Psi plugin. Now, if only Psi had plugin support.". Of course, some moments later I remembered my Summer of Code project to write a plugin interface for Psi. I hastily implemented a few more functions, fixed those I'd recently broken and implemented my first semi-useful Psi plugin. Yes, it's basic. No you can't close the window, you'll never get it back. No, the plugin doesn't know the user's display name and just shows the jid. On the other hand though, no, this is not a mockup, it's working exactly as presented below. So, I give you a screenshot of an early alpha of the URL Watcher plugin for Psi.
Week 3 (8st-14th June)
This week I've been tidying up a lot of the previous code, making it suitable for the Psi mainline and committing it. As such, this week the OptionsTree code has gone into the Psi mainline and new options are now using this system. I've also merged all my plugin work so far into mainline, available from
./configure --enable-plugins although I don't intend anyone but me to enable them for a while.
I also implemented a basic Snarl plugin to give Psi users on Windows a chance to look pretty like their OSX counterparts using Growl: File:Psi-snarl-plugin-1.png
Week 4,5,6,7 (15th June-12th July)
Unfortunately, for this period, I lost my wiki password and so couldn't update the page. I've now (week 8) recovered it so, from memory, in these weeks I: Tidied up a lot of the plugin interface. Set up a system for sending arbitrary stanzas from plugins. Worked some more on the Python plugin, such that it now finds and loads scripts, allowing them to register themselves and then calls the appropriate methods when a message stanza is received.
Week 8 (13th-20th July)
This week I allowed the plugins to access the Psi options tree, did a bit more work on the api and then wrote two games plugins. I took the old (Qt3) Tic Tac Toe example from Trolltech, ported it to Qt4 and added multiplayer support, wrapping it in a plugin interface and also found a Qt3 chess app, wrapped it in a plugin and rewrote the socket code so that when it thinks it writes to a socket, it really passes strings to the plugin to wrap in <message>s and send along the xmpp stream. Neither game's perfect (and it seems like the checkmate checking in the chess game I used might be dodgy) but they provide a nice example of the plugin interface taking stanzas, processing them and (upon user input) replying to them. Of course, there's no hooks for adding to the Psi GUI yet, so you have to start a chess game by saying 'chess start' to a contact but that's pretty much next on my TODO.
Following Weeks (-20th August)
Having already implemented enough to allow plugins to extend protocol (as shown in the chess plugin) and Python to read incoming messages, I've been concentrating on my PhD completion, which is a matter of some increasing urgency. Even if I don't get another chance to look at this before deadline, I think I've covered those parts of a plugin interface I scoped for this project.
This is as much a reference for myself as it is for anyone else; not all of the following tasks are necessary for the success of this project.
|Load plugins and query for name||Yes|
|Save enable/disable settings||Yes|
|Allow plugin disabling||Yes|
|Work around OSX not allowing plugin unloading||Yes|
|Use DirWatch to find new plugins||Yes|
|Display plugin's own options in OptionDlg||Yes|
|Write a soft-coded options structure, such that we don't need to know what options we have in advance (and also allow us to remember options we don't know about, such as when running without plugins)||Yes|
|Allow plugins to store their options in PluginManager (options, with an options.addComment())||80%|
|Allow plugins to define new Caps||0%|
|Define preliminary interface alerting plugins to messages, presence, iq||50%|
|Define an interface allowing plugins to modify or discard completely incoming and outgoing stanzas||40%|
|Allow plugins to register a namespace to listen to (or many namespaces)||0% (I subsequently decided this was not a worthwhile feature)|
|Allow the plugins to modify the GUI in some way (adding options to the right-click menu on the roster, for example).||40%|
|Create a simple plugin which loads the Python interpreter (Hello World)||100%|
|Develop a framework for locating scripts for Psi||80%|
|Choose scripts to load/not||0% (All scripts are loaded all the time)|
|Develop a method for loading and executing scripts||90%|
|Write a glue layer from the plugin interface to Python||30%|
|Write a set of GUI glues, such that scripts can create message boxes and the like||0%|
This is just a list of plugins I might implement to showcase the interface if I have time.
- Null Plugin
- This is just to demo the plugin loading and does nothing (Complete)
- Hello World
- A simple plugin to pop up a "Hello World" dialogue at inopportune moments
- Console Dump
- Dump all incoming messages to console
- Python Scripting Plugin
- This one's pretty crucial to the project
- URL watcher
- As Julian suggested, it would be nice for clients to keep a log of URLs sent to you which you can visit later, much like many IRC users enjoy.
- Noughts and crosses
- I hadn't originally intended doing this, but it's a decent example of plugins extending protocol
- Console Dump
- Just as with the plugin, dump messages to the console
- Google New Mail
- Google Talk sends new mail stanzas, notify the user when they have new mail
The original proposal
Plugin and scripting support for rapid protocol prototyping in Psi
Psi is a featureful, cross-platform XMPP client written in C++ using the Qt toolkit. Psi's traditional development cycle has focused on producing a stable, responsive client, and many users choose it for this reason. This thorough approach, however, coupled with the compiled nature of C++/Qt makes it difficult for users to customise their client. A C++/Qt plugin interface would allow users to share modifications and customisations without a need to either patch their builds, or to submit to the patch review process. Previous investigation has resulted in the beginnings of a plugin loader, but no plugin interface. The first section of this project proposal is to merge the previous plugin work into the current mainline and to write an abstraction interface, such that plugins need not access Psi's internals. It is expected that the first half of the project time would be spent on this, with priority on protocol abstraction in the interface rather than gui modification. If this work were to be completed early, there is the possibility to work on a configuration interface using XMPP data forms.
The second half of the project time would be spent on the development of a Python plugin, and the associated scripting interface. A scripting interface using a popular, high-level, easy to read/write language such as Python provides two very useful features. The first and potentially most obvious of these is that it allows users to add features to the client with use of nothing more than a text editor. The less obvious advantage is that it allows the Psi developers and JEP authors to rapidly prototype new features. The final days of the project would be spent, depending upon the time constraints, developing example scripts.
Plugin and scripting support are very frequently requested features for Psi so this would be a project benefitting many users and coupled with the ability to prototype protocol extensions easily would be a valuable contribution to the XMPP community in general, where multiple protocol implementations are important.
I'm a 24 year old PhD Student studying Multi-objective optimisation techniques using simulated annealing algorithms in the Computer Science department of Exeter University (UK). I hold a BSc(Hons) degree in Computer Science from the University of Exeter, with first class honours. I received 'best results' awards in both my first and second years of my degree, and a first class grade my final-year project, which studied parallel implementations of multi-objective genetic algorithms with the focus on increased autonomy of nodes (allowing each machine to optimise a subset of the search space), written in C++. Degree modules relevant to a Summer of Code placement include a study of HCI, object-oriented programming in Java, GUI design, compiler creation, other languages such as LISP and assembly, system design, formal modelling and logic.
I have previously been a developer for two OSS projects, a psuedo-AI chatbot script (http://bmotion.sf.net) and the Psi XMPP client (https://psi-im.org). I've been contributing to Psi for approximately four years and have more recently been managing the project; as such I have a reasonable understanding of the issues involved in this project (and the Psi codebase) and am confident a solution can be produced in the timeframe. I am currently at the write-up stage of my thesis, aiming to be splitting my time between that and SoC for the start of June and thereafter dedicating it to SoC. This is the only SoC project I have applied for and I've not previously participated in the program.