1
|
import collections
|
2
|
import copy
|
3
|
import os
|
4
|
from shutil import copyfile
|
5
|
import re
|
6
|
import sys
|
7
|
|
8
|
def read_vcard(path):
|
9
|
lines = collections.OrderedDict()
|
10
|
content = ''
|
11
|
for line in open(path).readlines():
|
12
|
if line.startswith(' '):
|
13
|
content = content[:-1] + line[1:]
|
14
|
else:
|
15
|
if content:
|
16
|
lines[key] = content
|
17
|
content = line
|
18
|
key = re.match(r'.*?:', line).group(0)
|
19
|
if content:
|
20
|
lines[key] = content
|
21
|
return lines
|
22
|
|
23
|
def merge(p1, p2, p3):
|
24
|
v1 = read_vcard(p1)
|
25
|
v2 = read_vcard(p2)
|
26
|
v3 = copy.deepcopy(v1)
|
27
|
for k, v in v2.items():
|
28
|
if k not in v1:
|
29
|
# add new fields regardless
|
30
|
sys.stdout.write(f' ADD {v}')
|
31
|
v3[k] = v
|
32
|
continue
|
33
|
# ; and whitespaces are not significant, remove them for comparison purposes
|
34
|
a1 = re.sub('[;\W]+', '', v1[k].strip())
|
35
|
a2 = re.sub('[;\W]+', '', v.strip())
|
36
|
if len(a2) > len(a1) and a2.startswith(a1):
|
37
|
# always prefer the longer field
|
38
|
sys.stdout.write(f' LONGEST {v1[k].strip()} => {v}')
|
39
|
v3[k] = v1[k]
|
40
|
elif v != v1[k] and a1.lower() == a2.lower():
|
41
|
# ignore differences that are not significant
|
42
|
print(f' WHITESPACE/SEMICOLON/CASE {k}')
|
43
|
elif v != v1[k]:
|
44
|
sys.stdout.write(f' DIFFERENCE\n USE {v1[k]} NOT {v}')
|
45
|
open(p3, 'w').write(''.join(v3.values()))
|
46
|
|
47
|
d1 = sys.argv[1]
|
48
|
d2 = sys.argv[2]
|
49
|
d3 = sys.argv[3]
|
50
|
|
51
|
for f in os.listdir(d1):
|
52
|
if not os.path.exists(f'{d2}/{f}'):
|
53
|
copyfile(f'{d1}/{f}', f'{d3}/{f}')
|
54
|
print(f'COPYING {d1}/{f}')
|
55
|
else:
|
56
|
print(f'MERGING {f}')
|
57
|
merge(f'{d1}/{f}', f'{d2}/{f}', f'{d3}/{f}')
|
58
|
|
59
|
for f in os.listdir(d2):
|
60
|
if not os.path.exists(f'{d1}/{f}'):
|
61
|
copyfile(f'{d2}/{f}', f'{d3}/{f}')
|
62
|
print(f'COPYING {d2}/{f}')
|