最近单位来了位新领导,他要求把单位全体人员通讯录导入到手机,这样他就可以随时随地摇人派活了。于是,我写了个简易脚本,把单位通讯录打包成 vcf 文件,导入手机即可。
vCard - Wikipedia
vCard
vCard 又称为 Variant Call Format (VCF) ,是一种电子名片标准,用于存储和交换联系人信息。vCard 文件通常以 .vcf 为扩展名。
一个基本的 vCard 文件可能如下所示:
BEGIN:VCARD
VERSION:3.0
N:Gump;Forrest;;Mr.;
FN:Forrest Gump
ORG:Bubba Gump Shrimp Co.
TITLE:Shrimp Man
TEL;TYPE=WORK,VOICE:(111) 555-1212
ADR;TYPE=WORK:;;100 Waters Edge;Baytown;LA;30314;United States of America
EMAIL;TYPE=PREF,INTERNET:forrestgump@example.com
END:VCARD
这里是各个字段的含义:
BEGIN:VCARD
和 END:VCARD
:标记 vCard 数据的开始和结束。
VERSION:3.0
:vCard 的版本号。
N:Gump;Forrest;;Mr.;
:姓名,分别是姓、名、其他名、前缀、后缀。
FN:Forrest Gump
:格式化的全名。
ORG:Bubba Gump Shrimp Co.
:组织名。
TITLE:Shrimp Man
:职位。
TEL;TYPE=WORK,VOICE:(111) 555-1212
:电话号码,类型是工作电话和语音电话。
ADR;TYPE=WORK:;;100 Waters Edge;Baytown;LA;30314;United States of America
:地址,类型是工作地址,分别是邮政箱、扩展地址、街道、城市、州、邮编、国家。
EMAIL;TYPE=PREF,INTERNET:forrestgump@example.com
:电子邮件,类型是首选的 Internet 邮件。
vCard 还支持许多其他字段,如 URL、生日、注释等。具体可以参考 vCard 的官方规范。
简单说, vCard
其实就是一个文本文件,每个字段都是以 key:value
的形式出现;可重复字段为Key;value
,如电话、地址、邮箱等;字段之间用换行符分隔。
RFC 6350 - vCard Format Specification
Python 脚本
了解了 vCard 的格式,只要有联系人数据,就可以通过 Python 脚本生成 vCard 文件,无非就是拼接字符串而已。
这里我们选择将联系人数据存储在 csv 文件中,然后通过 Python 脚本生成 vCard 文件。
Convert .CSV to VCF Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
# -*- coding: utf-8 -*-
#python 3.x
import csv
import sys
#convert a "comma separated values" file to vcf contact cards. I used this to convert a list of student
#names and phone numbers into a vcf and save the trouble of adding one by one through phone
#USAGE:
#CSV_to_Vcards.py CSV_filename
def convert(somefile):
#assuming file format : lastname,firstname,phonenumber,mail
with open( somefile, 'r' ) as source:
reader = csv.reader( source ) #reader now holds the whole data like ['lastname', 'firstname', 'phonenumber', 'mail']
allvcf = open('ALL.vcf', 'w')
i = 0
for row in reader:
#write in the "ALL.vcf" file.
allvcf.write( 'BEGIN:VCARD' + "\n")
allvcf.write( 'VERSION:2.1' + "\n")
allvcf.write( 'N:' + row[0] + ';' + row[1] + "\n")
allvcf.write( 'FN:' + "Bootcamp " + row[1] + ' ' + row[0] + "\n") #remember that lastname first
allvcf.write( 'ORG:' + 'Bootcamp' + "\n")
allvcf.write( 'TEL;CELL:' + row[2] + "\n")
allvcf.write( 'EMAIL:' + row[3] + "\n")
allvcf.write( 'END:VCARD' + "\n")
allvcf.write( "\n")
i += 1#counts
allvcf.close()
print (str(i) + " vcf cards generated")
def main(args):
if len(args) != 2:
print ( "Usage:")
print ( args[0] + " filename")
return
convert(args[1])
if __name__ == '__main__':
main(sys.argv)
|
vobject
上面的脚本只是简单的拼接字符串,如果要生成复杂的 vCard 文件,还是比较麻烦的。这里推荐一个 Python 包,可以方便的生成 vCard 文件。
eventable/vobject: A full-featured Python package for parsing and creating iCalendar and vCard files
Voject 是一个用于解析和创建 iCalendar 和 vCard 文件的全功能 Python 包。
脚本如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
import csv
import vobject
# org,department,name,title,office,phone,email,cell
# 研究院,院领导,xxx,党委书记,主616,xxxxxxx,,186xxxxxxx
def csv2vcf(csv_file, vcf_file):
with open(csv_file, 'r', encoding='utf-8-sig') as f:
reader = csv.DictReader(f)
for row in reader:
v = vobject.vCard()
v.add('n')
v.n.value = vobject.vcard.Name(family=row['name'])
v.add('fn')
v.fn.value = row['name']
v.add('org')
v.org.value = [row['org']]
v.add('title')
v.title.value = row['title'] + ' ' + row['department']
tel1 = v.add('tel')
tel1.value = row['cell']
tel1.type_param = 'cell'
tel2 = v.add('tel')
tel2.value = row['phone']
tel2.type_param = 'work'
v.add('email')
v.email.value = row['email']
v.email.type_param = 'INTERNET'
v.add('adr')
v.adr.value = vobject.vcard.Address(street=row['office'])
v.adr.type_param = 'WORK'
with open(vcf_file, 'a', encoding='utf-8') as f:
f.write(v.serialize())
if __name__ == '__main__':
csv_file = 'input.csv'
vcf_file = 'output.vcf'
csv2vcf(csv_file, vcf_file)
|
以上通过 voject 生成的 vCard 实例,省去了拼接字符串的麻烦,代码更加简洁。
这里需要注意的是,当一个联系人有多个电话号码时,在vCard.add(‘tel’)时,返回值需要赋值给不同的变量,否则会覆盖前面的值。
最后,再强调一下,Voject 不仅可以生成 vCard 文件,还可以操作日历事件。