#!/usr/bin/env python # -*- coding: utf-8 -*- import sys, getopt import cPickle as pickle g_verbose = False class VCardContact: def __init__( self ): self.fn = "" # dict with {type, number} self.tel = {} def reset( self ): self.fn = "" self.tel.clear() def setName( self, name ): self.fn = name.strip('\r\n') self.fn = name.strip('\n') def addPhoneNumber( self, type, number ): self.tel[ type ] = number.strip('\r\n') self.tel[ type ] = number.strip('\n') def to_list( self ): """ return a list of entries for FN and numbers """ phone_list = [] for e,v in self.tel.iteritems(): try: u_nam_typ = unicode(self.fn + ' ' + e, encoding="utf-8", errors='replace' ) phone_list.append( [ u_nam_typ ,unicode(v)] ) except: print "Error appending entry for ", self.fn, " phone: ", v return phone_list def importVCardFile( file, outfile ): global g_verbose # Read a VCARD-entry from file containing one or more entries # Each entry may have following format. # Starts with a 'BEGIN:VCARD', ends with 'END:VCARD' # We're just extracting the fields 'FN' and 'TEL' # - We'll add a name and a number for each TEL-subfield i.e. 'WORK', 'HOME', 'CELL' # name + 'WORK' = number # name + 'CELL' = number # # BEGIN:VCARD # VERSION:2.1 # N;CHARSET=UTF-8:Sjöberg;Elisabet Eir # FN;CHARSET=UTF-8:Elisabet Eir Sjöberg # TEL;WORK;VOICE:0812341234 # TEL;CELL;VOICE:+46707774488 # EMAIL;PREF;INTERNET:elisa...@somewhere.se # END:VCARD contacts = [] cur_contact = VCardContact() for line in file: if line[0:11] == 'BEGIN:VCARD': # Start with a new fresh entry cur_contact.reset() elif line[0:9] == 'END:VCARD': # unpack a list of name+type = number into dictionary entry... cur_list = cur_contact.to_list() for i in cur_list: # Phone dictionary entry only consists of 'tel' and 'name' fields entry = {} entry['tel'] = i[1] entry['name'] = i[0] if g_verbose: print "Adding entry > ", entry contacts.append( entry ) elif line[0:2] == 'FN': # Assign the the value of FN... cur_contact.setName( line[line.index(':')+1:] ) elif line[0:3] == 'TEL': try: # phone_info will contain a list like # ['CELL', 'VOICE:+460812341234'] phone_info = line[4:].split(';') # phone_number (just eat away the 'VOICE:') if len(phone_info) == 1: phone_number = phone_info[0].split(':')[1] else: phone_number = phone_info[1].split(':')[1] cur_contact.addPhoneNumber( phone_info[0], phone_number ) except: # if it's isn't in the format accepted above it probably isn't # anything we want to add # I'm ignoring 'TEL;FAX...' for example... print "Exception parsing line: ", line if g_verbose: print "Contacts: ", contacts ofile = open( outfile, 'w' ) pickle.dump( contacts, ofile, pickle.HIGHEST_PROTOCOL ) print len(contacts), "Contacts were successfully written to file: ", outfile def usage(): print "VCard-file importer for Paroli contacts" print "Usage:" print " vcard_import.py {[-i|--infile] infile.vcf} [[-o|--outfile] phone] [-v|--verbose] [-h|--help]" print "" print " outfile : defaults to 'phone'" print "" print " To install the file on the phone, quit all (kill!) the Paroli applications." print " Then copy the 'outfile' to the phone like:" print "$ scp 'outfile' r...@192.168.0.202:/home/root/.paroli/contacts/phone" print " ('outfile' is the filename you specified for outfile-argument)" def main(): global g_verbose try: opts, args = getopt.getopt( sys.argv[1:], 'i:o:hv', ['infile=','outfile=','help','verbose'] ) except getopt.GetoptError, err: print str(err) usage() sys.exit(2) if len(opts) < 1: usage() sys.exit(2) infile = "-" outfile = "phone" for o, a in opts: if o in ("-v", "--verbose"): g_verbose = True elif o in ("-h", "--help"): usage() sys.exit() elif o in ("-i", "--infile"): infile = a elif o in ("-o", "--outfile"): outfile = a else: assert False, "unhandled option" # ... if infile == "-": print "Error: required argument '[-i | --infile] ' is missing" usage() sys.exit(2) file = None try: file = open(infile, 'r') except: print "Error opening file: ", infile sys.exit(1) importVCardFile( file, outfile ) if __name__ == '__main__': main()