[f29f50e] | 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 |
---|
[4f37a98] | 37 | try: |
---|
| 38 | password = acc.getElementsByTagName('password')[0].firstChild.wholeText |
---|
| 39 | except IndexError: |
---|
| 40 | password = '' |
---|
[f29f50e] | 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: |
---|
[4f37a98] | 58 | print 'account add %s %s "%s"' % acc |
---|
[f29f50e] | 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 |
---|
[4f37a98] | 90 | print 'Write the following XML data to a file called %s.xml (rename it if' % user.lower() |
---|
[f29f50e] | 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) |
---|