]> git.llucax.com Git - personal/website.git/blob - source/blog/posts/2010/06/11-how-can-you-don't-love-floss?.rst
blog: Publish post about LANGUAGE
[personal/website.git] / source / blog / posts / 2010 / 06 / 11-how-can-you-don't-love-floss?.rst
1 Title: How can you don't love FLOSS?
2 Tags: en, floss, jabber, psi, mcabber, python, script, migration
3
4 Let me tell you my story.
5
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
10 question.
11
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:
15
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
18    line.
19
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)::
22
23    import sys
24    import xml.etree.ElementTree as et
25
26    def ns(s):
27            return '{http://psi-im.org/options}' + s
28
29    tree = et.parse(sys.argv[1])
30
31    accounts = tree.getroot()[0]
32
33    for account in accounts.getchildren():
34            roster_cache = account.find(ns('roster-cache'))
35            if roster_cache is None:
36                    continue
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'))
43                    if g is not None:
44                            group = g.strip().encode('utf-8')
45                            print '/move', group
46
47 VoilĂ !
48
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::
53
54    python script.py /path/to/accounts.xml > /path/to/mcabber.fifo
55
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.
59
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
63 the example)::
64
65            if account.findtext(ns('name')).strip() == 'Bad Account':
66                    continue
67
68 Adding similar simple lines you can filter unwanted users, or groups, or
69 whatever.
70
71 And all of this is thanks to:
72
73 * FLOSS__
74 * `Open file formats`__
75 * `Unix philosophy`__
76
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
80
81 Thank god for that!
82
83
84 .. [1] A few people will be interested in this, but I think the ones that are
85    will appreciate this link :) (in spanish):
86
87    http://www.lugmen.org.ar/pipermail/lug-org/2001-December/004482.html
88
89
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
99
100
101 .. vim: set et sw=3 sts=3 :