1 | #!/usr/bin/python |
---|
2 | # |
---|
3 | # Part of BitlBee. Reads a libpurple accounts.xml file and generates some |
---|
4 | # commands/XML that BitlBee understands. For easy migration from Pidgin/ |
---|
5 | # Finch/whatever to BitlBee, be it a public server or your own. |
---|
6 | # |
---|
7 | # Licensed under the GPL2 like the rest of BitlBee. |
---|
8 | # |
---|
9 | # Copyright 2010 Wilmer van der Gaast <wilmer@gaast.net> |
---|
10 | # |
---|
11 | |
---|
12 | import getopt |
---|
13 | import getpass |
---|
14 | import os |
---|
15 | import subprocess |
---|
16 | import sys |
---|
17 | |
---|
18 | import xml.dom.minidom |
---|
19 | |
---|
20 | BITLBEE = '/usr/sbin/bitlbee' |
---|
21 | |
---|
22 | def parse_purple(f): |
---|
23 | protomap = { |
---|
24 | 'msn-pecan': 'msn', |
---|
25 | 'aim': 'oscar', |
---|
26 | 'icq': 'oscar', |
---|
27 | } |
---|
28 | supported = ('msn', 'jabber', 'oscar', 'yahoo', 'twitter') |
---|
29 | accs = list() |
---|
30 | |
---|
31 | if os.path.isdir(f): |
---|
32 | f = f + '/accounts.xml' |
---|
33 | xt = xml.dom.minidom.parse(f) |
---|
34 | for acc in xt.getElementsByTagName('account')[1:]: |
---|
35 | protocol = acc.getElementsByTagName('protocol')[0].firstChild.wholeText |
---|
36 | name = acc.getElementsByTagName('name')[0].firstChild.wholeText |
---|
37 | try: |
---|
38 | password = acc.getElementsByTagName('password')[0].firstChild.wholeText |
---|
39 | except IndexError: |
---|
40 | password = '' |
---|
41 | if protocol.startswith('prpl-'): |
---|
42 | protocol = protocol[5:] |
---|
43 | if name.endswith('/'): |
---|
44 | name = name[:-1] |
---|
45 | if protocol in protomap: |
---|
46 | protocol = protomap[protocol] |
---|
47 | if protocol not in supported: |
---|
48 | print 'Warning: protocol probably not supported by BitlBee: ' + protocol |
---|
49 | accs.append((protocol, name, password)) |
---|
50 | |
---|
51 | return accs |
---|
52 | |
---|
53 | def print_commands(accs): |
---|
54 | print 'To copy all your Pidgin accounts to BitlBee, just copy-paste the following' |
---|
55 | print 'commands into your &bitlbee channel:' |
---|
56 | print |
---|
57 | for acc in accs: |
---|
58 | print 'account add %s %s "%s"' % acc |
---|
59 | |
---|
60 | def bitlbee_x(*args): |
---|
61 | bb = subprocess.Popen([BITLBEE, '-x'] + list(args), stdout=subprocess.PIPE) |
---|
62 | return bb.stdout.read().strip() |
---|
63 | |
---|
64 | def print_xml(accs): |
---|
65 | try: |
---|
66 | bitlbee_x('hash', 'blaataap') |
---|
67 | except: |
---|
68 | print "Can't find/use BitlBee binary. It has to be a 1.2.5 binary or higher." |
---|
69 | print |
---|
70 | usage() |
---|
71 | |
---|
72 | print 'BitlBee .xml files are encrypted using the identify password. Please type your' |
---|
73 | print 'preferred identify password.' |
---|
74 | user = getpass.getuser() |
---|
75 | pwd = getpass.getpass() |
---|
76 | |
---|
77 | root = xml.dom.minidom.Element('user') |
---|
78 | root.setAttribute('nick', user) |
---|
79 | root.setAttribute('password', bitlbee_x('hash', pwd)) |
---|
80 | root.setAttribute('version', '1') |
---|
81 | for acc in accs: |
---|
82 | accx = xml.dom.minidom.Element('account') |
---|
83 | accx.setAttribute('protocol', acc[0]) |
---|
84 | accx.setAttribute('handle', acc[1]) |
---|
85 | accx.setAttribute('password', bitlbee_x('enc', pwd, acc[2])) |
---|
86 | accx.setAttribute('autoconnect', '1') |
---|
87 | root.appendChild(accx) |
---|
88 | |
---|
89 | print |
---|
90 | print 'Write the following XML data to a file called %s.xml (rename it if' % user.lower() |
---|
91 | print 'you want to use a different nickname). It should be in the directory where' |
---|
92 | print 'your BitlBee account files are stored (most likely /var/lib/bitlbee).' |
---|
93 | print |
---|
94 | print root.toprettyxml() |
---|
95 | |
---|
96 | def usage(): |
---|
97 | print 'Usage: %s [-f <purple accounts file>] [-b <bitlbee executable>] [-x]' % sys.argv[0] |
---|
98 | print |
---|
99 | print 'Generates "account add" commands by default. -x generates a .xml file instead.' |
---|
100 | print 'The accounts file can normally be found in ~/.purple/.' |
---|
101 | sys.exit(os.EX_USAGE) |
---|
102 | |
---|
103 | try: |
---|
104 | flags = dict(getopt.getopt(sys.argv[1:], 'f:b:x')[0]) |
---|
105 | except getopt.GetoptError: |
---|
106 | usage() |
---|
107 | if '-f' not in flags: |
---|
108 | usage() |
---|
109 | if '-b' in flags: |
---|
110 | BITLBEE = flags['-b'] |
---|
111 | |
---|
112 | parsed = parse_purple(flags['-f']) |
---|
113 | if '-x' in flags: |
---|
114 | print_xml(parsed) |
---|
115 | else: |
---|
116 | print_commands(parsed) |
---|