| #!/usr/bin/env python | |
| """ | |
| Parse phone and email records out of vCard file and store them in an xml file to | |
| be inserted into pidgins blist.xml. | |
| Copyright (C) 2012 Senko Rasic <senko.rasic@dobarkod.hr> | |
| Permission is hereby granted, free of charge, to any person obtaining a copy of | |
| this software and associated documentation files (the "Software"), to deal in | |
| the Software without restriction, including without limitation the rights to | |
| use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | |
| of the Software, and to permit persons to whom the Software is furnished to do | |
| so, subject to the following conditions: | |
| The above copyright notice and this permission notice shall be included in all | |
| copies or substantial portions of the Software. | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| SOFTWARE. | |
| """ | |
| import sys | |
| import logging | |
| import vobject | |
| log = logging.getLogger(__name__) | |
| """ | |
| country and account specific settings | |
| """ | |
| account_num = '61412123123' | |
| valid_phone_prefix = '614' | |
| phone_length = 11 | |
| def sanitize_phone(num, country_prefix): | |
| """ | |
| Convert phone numbers into standard +<ccode><phonenum> format, without | |
| spaces, dashes or slashes. | |
| """ | |
| orig = num | |
| num = num.replace(' ', '').replace('-', '').replace('/', '') | |
| if num.startswith('0'): | |
| if num.startswith('00'): | |
| num = '+' + num[2:] | |
| else: | |
| num = '+' + country_prefix + num[1:] | |
| elif not num.startswith('+') and len(num) > 5: | |
| num = '+' + num | |
| if num != orig: | |
| log.debug('[sanitize_phone] %s -> %s' % (orig, num)) | |
| """ | |
| For whatsapp phone must not contain + | |
| """ | |
| if num.startswith('+'): | |
| num = num[1:] | |
| return num | |
| def parse(fname, country_prefix): | |
| """ | |
| Parse vCard file. Returns a generator producing dicts with 'name' (string), | |
| 'emails' (list of strings) and 'phones' (list of strings) fields. | |
| """ | |
| for vobj in vobject.readComponents(open(fname)): | |
| if not hasattr(vobj, 'fn'): | |
| log.warning('[parse] skipping entry with no name: ' + repr(vobj)) | |
| continue | |
| entry = { | |
| 'name': vobj.fn.value.strip(), | |
| 'emails': [], | |
| 'phones': [], | |
| 'websites': [] | |
| } | |
| if hasattr(vobj, 'email_list'): | |
| entry['emails'] = [e.value.strip() for e in vobj.email_list] | |
| if hasattr(vobj, 'tel_list'): | |
| entry['phones'] = [sanitize_phone(t.value, country_prefix) | |
| for t in vobj.tel_list] | |
| if hasattr(vobj, 'x_socialprofile_list'): | |
| entry['websites'] = [w.value.strip() for w in vobj.x_socialprofile_list] | |
| log.debug('[parse] got entry for ' + entry['name']) | |
| yield entry | |
| def xml_output(fname, entries): | |
| """ | |
| Write the entries generated by parse() to a UTF-8 encoded XML file for use by pidgin blist.xml | |
| """ | |
| pre = "\t\t\t<contact>\n\t\t\t\t<buddy account='%s' proto='prpl-whatsapp'>\n\t\t\t\t\t<name>" % account_num | |
| mid = "</name>\n\t\t\t\t\t<alias>" | |
| post ="</alias>\n\t\t\t\t</buddy>\n\t\t\t</contact>\n" | |
| top = "\t\t<group name='imported'>\n\t\t\t<setting name='collapsed' type='bool'>1</setting>\n" | |
| bottom = "\t\t</group>" | |
| with open(fname, 'wb') as fd: | |
| fd.write(top) | |
| for e in entries: | |
| phone = "" | |
| for p in e['phones']: | |
| if p.startswith(valid_phone_prefix): | |
| phone = p | |
| if phone: | |
| if (len(phone)==phone_length): | |
| fd.write(pre+phone) | |
| fd.write(mid+e['name']) | |
| fd.write(post) | |
| fd.write(bottom) | |
| def vcf2xml(infile, outfile, country_prefix): | |
| """ | |
| Parse entries out of vCard 'infile' and store them to an XML 'outfile'. | |
| """ | |
| xml_output(outfile, parse(infile, country_prefix)) | |
| if __name__ == '__main__': | |
| if len(sys.argv) != 3 and len(sys.argv) != 4: | |
| print "Usage: %s <infile.vcf> <outfile.xml> [<prefix>]" % sys.argv[0] | |
| sys.exit(-1) | |
| logging.basicConfig(level=logging.INFO) | |
| vcf2xml(sys.argv[1], sys.argv[2], | |
| sys.argv[3] if len(sys.argv) == 4 else '61') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment