如是, 在本地建立一个版本控制的目录, 全是 vCard 文件, 可以方便地做些简单查找, 合并及批量修改.
整理通讯信息, 自然少不了导入导出. 这个 Online vCard Converter 在转换 Gmail 等的联系人信息时十分方便. 我开始便是用这个转换. 但后来数据多了, 教育网又要找代理, 便自己写了几个脚本. 放此备份, 或有同样需求的.
以下为从 Gmail-CSV 到 vCard 转换的脚本.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import csv以下为从 vCard 到 Gmail CSV 转换的脚本.
import sys
import re
def load_csv(fn):
f = open(fn,'rb')
csvs = csv.reader(f)
head = csvs.next()
rows = [row for row in csvs]
for row in rows:
print to_vcard(head, row)
def get_n_from_fn(fn):
fn=fn.decode('utf8')
if ' ' in fn:
(given, family) = fn.rsplit(' ', 1)
if re.match('[a-zA-Z0-9_]', fn[0]):
(given, family) = (fn, '')
else:
(family, given) = (fn[0], fn[1:])
return ('%s;%s;;;' % (family, given)).encode('utf8')
def tel_types_str(*types):
itypes=[]
for type in types:
type=type.upper()
if type == 'MOBILE':
itypes.append('CELL')
continue
if type in ['OTHER', 'PHONE'] :
continue
itypes.append(type)
ts = ','.join(itypes)
if ts: return ';TYPE=%s' % ts
return ''
def to_vcard(head, row):
ln = '\n'
vc = []
vc.append('BEGIN:VCARD')
vc.append('Version:3.0')
vc.append('FN:%s' % row[0])
vc.append('N:%s' % get_n_from_fn(row[0]))
vc.append('EMAIL:%s' % row[1])
vc.append('NOTES:%s' % row[2].replace('\n', '\\n'))
idx = 2
desc = ''
for field in head[3:]:
idx += 1
type = field.split(' - ')[1]
if idx >= len(row):
break
if type == 'Description':
desc = row[idx].upper()
continue
if not row[idx]:
continue
if type == 'Email':
emails = row[idx].split(';')
for email in emails:
vc.append('EMAIL;TYPE=%s:%s' % (desc, email.strip()))
continue
if type == 'IM':
ims = row[idx].split(';')
for im in ims:
if ':' in im:
(imt, ima) = im.split(':', 1)
else:
if '@gmail.com' in im:
(imt, ima) = ('X-GTALK', im)
elif '@hotmail.com' in im:
(imt, ima) = ('X-MSN', im)
else:
(imt, ima) = ('OTHER', im)
vc.append('EMAIL;TYPE=%s:%s' % (imt.upper(), ima.strip()))
continue
if type in ['Mobile', 'Pager', 'Fax', 'Phone']:
tels = row[idx].split(';')
for tel in tels:
vc.append('TEL%s:%s' % (tel_types_str(desc, type), tel.strip()))
continue
if type == 'Title':
vc.append('TITLE;TYPE=%s:%s' % (desc, row[idx]))
continue
if type == 'Other':
continue
if type == 'Company':
vc.append('ORG;TYPE=%s:%s' % (desc, row[idx]))
continue
if type == 'Address':
vc.append('ADDR;TYPE=%s:%s' % (desc, row[idx].replace(';', '\\;')))
continue
vc.append('END:VCARD')
nvc = []
for line in vc:
if re.match('^[^:]*:[ \t]*$', line):
pass
else:
nvc.append(line)
return ln.join(nvc) + ln
load_csv(sys.argv[1])
#!/usr/bin/env python以下为将 vCard 中的生日信息转换为 iCalendar 文件的脚本.
# -*- coding: utf-8 -*-
import csv
import sys
import re
import vobject
def filter_lines(ls, names, types):
if not isinstance(names, list): names = [names]
if not isinstance(types, list): types = [types]
if names:
ls = [l for l in ls if l.name in names]
for type in types:
if type.istitle():
type = type.upper()
ls = [l for l in ls if not type in l.params.get('TYPE', [])]
else:
ls = [l for l in ls if type in l.params.get('TYPE', [])]
return ls
def lines_value(ls):
return [l.value for l in ls]
def filter_lines_value(ls, names, types):
ls = filter_lines(ls, names, types)
return lines_value(ls)
def vcard_to_csv(fp, cw):
for vcf in vobject.readComponents(fp):
vcf_to_csv(vcf, cw)
def vcf_to_csv(vcf, cw):
email = vcf.getChildValue('email') or ''
fn = vcf.getChildValue('fn') or ''
note = vcf.getChildValue('note') or ''
fields = [fn, email, note]
sections = ['WORK', 'HOME', 'OTHER', 'PERSONAL']
f_sections=[['WORK'], ['HOME'], ['OTHER'], ['Work', 'Home', 'Other']]
lines = [l for l in vcf.lines()]
for idx in range(len(sections)):
section = sections[idx]
f_section = f_sections[idx]
s_email=[v for v in filter_lines_value(lines, 'EMAIL', f_section) if v != email]
s_im = [l.name.replace('X-', '')+': ' + l.value
for l in filter_lines(lines, ['X-GTALK', 'X-MSN', 'X-ICQ', 'X-JABBER', 'X-AIM'], f_section)]
s_mobile = filter_lines_value(lines, 'TEL', f_section + ['CELL'])
s_pager = filter_lines_value(lines, 'TEL', f_section + ['PAGER'])
s_fax = filter_lines_value(lines, 'TEL', f_section + ['FAX'])
s_phone = filter_lines_value(lines, 'TEL', f_section +['Cell', 'Pager', 'Fax'])
s_label = filter_lines_value(lines, 'LABEL', f_section)
if section == 'WORK':
s_org = ' '.join(vcf.getChildValue('org') or [])
s_title = vcf.getChildValue('title') or ''
else:
s_org = ''
s_title = ''
if s_email or s_im or s_phone or s_mobile or s_pager or s_fax or s_org or s_title or s_label:
pass
else:
continue
fields.append(section.title())
fields.append(' ::: '.join(s_email))
fields.append(' ::: '.join(s_im))
fields.append(' ::: '.join(s_phone))
fields.append(' ::: '.join(s_mobile))
fields.append(' ::: '.join(s_pager))
fields.append(' ::: '.join(s_fax))
fields.append(s_org)# company
fields.append(s_title)# title
fields.append('')# other
fields.append('\n'.join(s_label))
cw.writerow([field.encode('utf8') for field in fields])
if __name__== '__main__':
csv_prev_headers = ['Name', 'E-mail', 'Notes']
csv_per_headers = ['Description', 'Email', 'IM', 'Phone', 'Mobile', 'Pager', 'Fax',
'Company','Title', 'Other', 'Address']
csv_headers = csv_prev_headers
for i in [1,2,3,4]:
csv_headers.extend(['Section %s - %s' % (i, h) for h in csv_per_headers])
cw = csv.writer(sys.stdout)
cw.writerow(csv_headers)
if len(sys.argv) < 2:
vcard_to_csv(sys.stdin, cw)
else:
for f in sys.argv[1:]:
vcard_to_csv(open(f, 'rb'), cw)
#!/usr/bin/env python
# coding: utf-8
import csv
import sys
import re
import vobject
import datetime
import dateutil
tzlocal = dateutil.tz.tzlocal()
def vcard_bday_to_ical(fp, ic):
for vcf in vobject.readComponents(fp):
bday = vcf.getChildValue('bday')
if not bday: continue
bday = bday.replace('-', '').replace(' ', '')
if len(bday) == '4':
bday = '1980'+bday
if len(bday) != 8:
continue
print >>sys.stderr, 'parsing ', vcf.fn.value, vcf.bday.value
date = datetime.date(int(bday[0:4]), int(bday[4:6]), int(bday[6:8]))
v = ic.add('vevent')
v.add('dtstart').value=date
v.add('dtend').value=date+datetime.timedelta(1)
rrule = dateutil.rrule.rruleset()
rrule.rrule(dateutil.rrule.rrule(dateutil.rrule.YEARLY, dtstart=datetime.datetime(2009,12,12,tzinfo=tzlocal)))
v.rruleset=rrule
v.add('uid').value=vcf.uid.value + '-jiangzuoyan@gmail.com'
v.add('summary').value=' '.join(
[i for i in
[vcf.fn.value,
vcf.getChildValue('email') or '',
vcf.getChildValue('tel') or '',
vcf.getChildValue('bday') or ''
]
if i])
if __name__ == '__main__':
ic = vobject.iCalendar()
for file in sys.argv[1:]:
if file == '-':
fp = sys.stdin
else:
fp = open(file, 'rb')
vcard_bday_to_ical(fp, ic)
print ic.serialize()
No comments:
Post a Comment