2 # -*- coding: latin-1 -*-
5 Copyright © 2003 Bogdan Sumanariu <zarrok@yahoo.com>
7 This file is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 script name : evolutionvcard2claws.py
23 script purpose : convert an evolution addressbook VCARD file
24 into a Claws Mail addressbook
26 tested with evolution 1.2.x, and 1.4.x
35 keywds = ('x-evolution-file-as','fn', 'n','email;internet','nickname', 'url', 'org')
38 ################################################################################
39 ## reads a vcard and stores as hash pairs key/value where value is a list ##
40 ################################################################################
42 def readVCARD (file) :
46 skips fom <file> until a 'begin' tag from VCARD is encountered.
47 from this point starts constructing a map (key, [values] )
48 VCARD entry format -> tag:value
51 [values] <- list with the values of <tag> if there are more tags with the same name
59 if len (r) == 0 : return dict()
60 if string.find('begin',string.lower(string.strip(r))) :
64 s = string.split(string.lower(string.strip(r)),':')
72 if s[0] == 'end' : end = 1
75 ##################################################################################
78 ###############################################################################################
79 ## writes on a given file an xml representation for claws-mail addressbook received as a hash ##
80 ###############################################################################################
82 def writeXMLREPR (vcard,file,uid) :
85 based on <vcard> and <uid> writes only recognized tags (the ones defined in <keywds> list)
86 NOTE: <url> and <org> tag will be written as attributes (there are such tags in claws-mail's
89 if len (vcard.keys()) == 0 : return
90 name = string.split(vcard.get(keywds[2])[0],';')
92 fn, ln, nick, cn, a = '', '', '', '', ''
100 if vcard.has_key(keywds[4]) :
101 nick = vcard.get(keywds[4])[0]
102 if len(vcard.get(keywds[1])[0]) :
103 cn = vcard.get(keywds[1])[0]
105 cn = vcard.get(keywds[0])[0];
107 a += str('\n<person uid=\"' + str(uid[0]) + '\" first-name=\"' + fn + '\" last-name=\"' + ln
108 + '\" nick-name=\"' + nick + '\" cn=\"' + cn + '\" >\n')
109 a += '\t<address-list>\n'
110 if vcard.get(keywds[3]) :
111 for c in vcard.get(keywds[3]) :
113 a += '\t\t<address uid=\"' + str(uid[0]) + '\" alias=\"' + nick + '\" email=\"' + c + '\" remarks=\"\" />\n'
116 a += '\t\t<address uid=\"' + str(uid[0]) + '\" alias=\"' + nick + '\" email=\"\" remarks=\"\" />\n'
117 a += '\t</address-list>\n'
118 a += '\t<attribute-list>\n'
119 for key in keywds[5:] :
121 for c in vcard.get(key) :
123 a += '\t\t<attribute uid=\"' + str(uid[0]) + '\" name=\"' + key +'\">'+c+'</attribute>\n'
124 a += '\t</attribute-list>\n'
129 ###################################################################################################
131 def convert (in_f, o_f, name='INBOX') :
133 uid = [int(time.time())]
135 print 'proccessing...\n'
136 o_f.write('<?xml version="1.0" encoding="ISO-8859-1" ?>\n<address-book name="'+name+'" >\n');
138 while len(d.keys()) > 0 :
140 writeXMLREPR (d, o_f, uid)
143 o_f.write('\n</address-book>')
144 print 'finished processing...\n'
145 except IOError, err :
146 print 'Caught an IOError : ',err,'\t ABORTING!!!'
149 #################################################################################################
152 if len(sys.argv) <> 3 and len(sys.argv) <> 2 :
153 print str("\nUsage: vcard2xml.py source_file [destination_file]\n\n" +
154 '\tWhen only <source_file> is specified will overwrite the existing addressbook.\n'+
155 '\tWhen both arguments are suplied will create a new additional addressbook named \n\tas the destination file.'+'\n\tNOTE: in both cases the Claws Mail must be closed and ran at least once.\n\n')
160 path_to_out = os.environ['HOME']+'/.claws-mail/'
161 adr_idx = 'addrbook--index.xml'
163 tmp_adr_idx_file= None
167 in_file = open(sys.argv[1])
169 print 'Could not open input file <',sys.argv[1],'> ABORTING'
172 if len(sys.argv) == 2 :
174 dlist = os.listdir(path_to_out);
177 if l.find('addrbook') == 0 and l.find("addrbook--index.xml") < 0 and l.find('bak') < 0 :
180 out_file = flist.pop()
181 os.rename(path_to_out+out_file, path_to_out+out_file+'.tmp')
182 out_file = open(path_to_out+out_file,'w')
183 convert(in_file, out_file)
186 print 'got exception: ', e
189 os.rename(path_to_out+adr_idx, path_to_out+adr_idx+'.tmp')
190 tmp_adr_idx_file = open(path_to_out+adr_idx+'.tmp')
191 adr_idx_file = open(path_to_out+adr_idx,'w')
192 except Exception, e :
193 print 'Could not open <', path_to_out+adr_idx,'> file. Make sure you started Claws Mail at least once.'
196 out_file = open(path_to_out+sys.argv[2],'w')
197 convert(in_file, out_file, sys.argv[2].split('.xml')[0])
198 l = tmp_adr_idx_file.readline()
200 if l.strip() == '</book_list>' :
201 adr_idx_file.write('\t<book name="'+sys.argv[2].split('.xml')[0] +'" file="'+sys.argv[2]+'" />\n')
202 adr_idx_file.write(l)
204 adr_idx_file.write(l)
205 l = tmp_adr_idx_file.readline()
208 print 'got exception: ', e
213 print 'got exception, cleaning up the mess... changed files will be restored...\n'
218 if len(sys.argv) == 2 :
219 os.rename(out_file.name+'.tmp', out_file.name)
221 os.remove(out_file.name)
222 os.rename(path_to_out+adr_idx+'.tmp', path_to_out+adr_idx)
223 if tmp_adr_idx_file :
224 tmp_adr_idx_file.close()
227 #closing all and moving temporary data into place
228 print 'closing open files...\n'
231 if len(sys.argv) == 3 :
232 os.rename(path_to_out+adr_idx+'.tmp',path_to_out+adr_idx+'.bak' )
233 if len(sys.argv) == 2 :
234 os.rename(out_file.name+'.tmp', out_file.name+'.bak')
237 if tmp_adr_idx_file :
238 tmp_adr_idx_file.close()
242 if __name__ == '__main__':