1 Title: How can you don't love FLOSS?
2 Tags: en, floss, jabber, psi, mcabber, python, script, migration
4 Let me tell you my story.
6 I'm moving to a new jabber_ server, so I had to migrate my contacts. I have
7 several jabber accounts, collected all over the years (I started using jabber_
8 a long time ago, around 2001 [1]_; in that days ICQ_ interoperability was an
9 issue =P), with a bunch of contacts each, so manual migration was out of the
12 First I thought "this is gonna get ugly" so I thought about using some XMPP_
13 Python_ library to do the work talking directly to the servers, but then
14 I remember 2 key facts:
16 1. I use Psi_, which likes XML_ a **lot**, and it has a roster cache in a file.
17 2. I use mcabber_, which has a FIFO_ for injecting commands via the command
20 Having this two facts in mind, the migration was as easy as a less than 25 SLOC_
21 Python_ script, without any external dependencies (just Python_ stdlib)::
24 import xml.etree.ElementTree as et
27 return '{http://psi-im.org/options}' + s
29 tree = et.parse(sys.argv[1])
31 accounts = tree.getroot()[0]
33 for account in accounts.getchildren():
34 roster_cache = account.find(ns('roster-cache'))
35 if roster_cache is None:
37 for contact in roster_cache:
38 name = contact.findtext(ns('name')).strip().encode('utf-8')
39 jid = contact.findtext(ns('jid')).strip().encode('utf-8')
40 print '/add', jid, name
41 print '/roster search', jid
42 g = contact.find(ns('groups')).findtext(ns('item'))
44 group = g.strip().encode('utf-8')
49 Now all you have to do is know where your Psi_ ``accounts.xml`` file is (usually
50 ``~/.psi/profiles/<your_profile_name>/accounts.xml``), and where your mcabber_
51 FIFO_ is (usually ``~/.mcabber/mcabber.fifo``, but maybe you have to configure
52 mcabber_ first) and run::
54 python script.py /path/to/accounts.xml > /path/to/mcabber.fifo
56 You can omit the ``> /path/to/mcabber.fifo`` first if you have to take a peek at
57 what mcabber_ commands will be executed, and if you are happy with the results
58 run the full command to execute them.
60 The nice thing is it's very easy to customize if you have some notions of
61 Python_, for example, I didn't want to migrate one account; adding this line
62 just below the ``for`` did the trick (the account is named ``Bad Account`` in
65 if account.findtext(ns('name')).strip() == 'Bad Account':
68 Adding similar simple lines you can filter unwanted users, or groups, or
71 And all of this is thanks to:
74 * `Open file formats`__
77 __ http://en.wikipedia.org/wiki/Free_and_open_source_software
78 __ http://en.wikipedia.org/wiki/Open_file_format
79 __ http://en.wikipedia.org/wiki/Unix_philosophy
84 .. [1] A few people will be interested in this, but I think the ones that are
85 will appreciate this link :) (in spanish):
87 http://www.lugmen.org.ar/pipermail/lug-org/2001-December/004482.html
90 .. _jabber: http://www.jabber.org/
91 .. _ICQ: http://en.wikipedia.org/wiki/Icq
92 .. _Python: http://www.python.org/
93 .. _XMPP: http://en.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol
94 .. _Psi: http://en.wikipedia.org/wiki/Psi_%28instant_messaging_client%29
95 .. _XML: http://en.wikipedia.org/wiki/Xml
96 .. _mcabber: http://en.wikipedia.org/wiki/MCabber
97 .. _FIFO: http://en.wikipedia.org/wiki/FIFO#Pipes
98 .. _SLOC: http://en.wikipedia.org/wiki/Source_lines_of_code
101 .. vim: set et sw=3 sts=3 :