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 | password = acc.getElementsByTagName('password')[0].firstChild.wholeText |
---|
38 | if protocol.startswith('prpl-'): |
---|
39 | protocol = protocol[5:] |
---|
40 | if name.endswith('/'): |
---|
41 | name = name[:-1] |
---|
42 | if protocol in protomap: |
---|
43 | protocol = protomap[protocol] |
---|
44 | if protocol not in supported: |
---|
45 | print 'Warning: protocol probably not supported by BitlBee: ' + protocol |
---|
46 | accs.append((protocol, name, password)) |
---|
47 | |
---|
48 | return accs |
---|
49 | |
---|
50 | def print_commands(accs): |
---|
51 | print 'To copy all your Pidgin accounts to BitlBee, just copy-paste the following' |
---|
52 | print 'commands into your &bitlbee channel:' |
---|
53 | print |
---|
54 | for acc in accs: |
---|
55 | print 'account add %s %s %s' % acc |
---|
56 | |
---|
57 | def bitlbee_x(*args): |
---|
58 | bb = subprocess.Popen([BITLBEE, '-x'] + list(args), stdout=subprocess.PIPE) |
---|
59 | return bb.stdout.read().strip() |
---|
60 | |
---|
61 | def print_xml(accs): |
---|
62 | try: |
---|
63 | bitlbee_x('hash', 'blaataap') |
---|
64 | except: |
---|
65 | print "Can't find/use BitlBee binary. It has to be a 1.2.5 binary or higher." |
---|
66 | print |
---|
67 | usage() |
---|
68 | |
---|
69 | print 'BitlBee .xml files are encrypted using the identify password. Please type your' |
---|
70 | print 'preferred identify password.' |
---|
71 | user = getpass.getuser() |
---|
72 | pwd = getpass.getpass() |
---|
73 | |
---|
74 | root = xml.dom.minidom.Element('user') |
---|
75 | root.setAttribute('nick', user) |
---|
76 | root.setAttribute('password', bitlbee_x('hash', pwd)) |
---|
77 | root.setAttribute('version', '1') |
---|
78 | for acc in accs: |
---|
79 | accx = xml.dom.minidom.Element('account') |
---|
80 | accx.setAttribute('protocol', acc[0]) |
---|
81 | accx.setAttribute('handle', acc[1]) |
---|
82 | accx.setAttribute('password', bitlbee_x('enc', pwd, acc[2])) |
---|
83 | accx.setAttribute('autoconnect', '1') |
---|
84 | root.appendChild(accx) |
---|
85 | |
---|
86 | print |
---|
87 | print 'Write the following XML data to a file called %s.xml (rename it if' |
---|
88 | print 'you want to use a different nickname). It should be in the directory where' |
---|
89 | print 'your BitlBee account files are stored (most likely /var/lib/bitlbee).' |
---|
90 | print |
---|
91 | print root.toprettyxml() |
---|
92 | |
---|
93 | def usage(): |
---|
94 | print 'Usage: %s [-f <purple accounts file>] [-b <bitlbee executable>] [-x]' % sys.argv[0] |
---|
95 | print |
---|
96 | print 'Generates "account add" commands by default. -x generates a .xml file instead.' |
---|
97 | print 'The accounts file can normally be found in ~/.purple/.' |
---|
98 | sys.exit(os.EX_USAGE) |
---|
99 | |
---|
100 | try: |
---|
101 | flags = dict(getopt.getopt(sys.argv[1:], 'f:b:x')[0]) |
---|
102 | except getopt.GetoptError: |
---|
103 | usage() |
---|
104 | if '-f' not in flags: |
---|
105 | usage() |
---|
106 | if '-b' in flags: |
---|
107 | BITLBEE = flags['-b'] |
---|
108 | |
---|
109 | parsed = parse_purple(flags['-f']) |
---|
110 | if '-x' in flags: |
---|
111 | print_xml(parsed) |
---|
112 | else: |
---|
113 | print_commands(parsed) |
---|