Вышеупомянутый PHP начал меня. Но у меня были проблемы с барахлом в карточках.
Я парень Python, поэтому я написал новую программу на Python. Я использовал Python 2.x для запуска этого.
Использует словарь Python для отслеживания адресов электронной почты, которые уже видны из адресных карточек, и он хранит только один адрес. Это решило еще одну проблему с дублирующимися карточными записями.
Я думаю, что двоичный мусор между картами использовался Evolution, чтобы выяснить, какие карты были действительными. Эта программа просто использует несколько эмпирических правил: если на карте есть мусорные двоичные символы, или она не была надлежащим образом завершена или не имеет в ней адреса электронной почты, это плохая карта и попадает в "плохую" выходной файл.
После того, как вы закончите преобразование, вы можете проверить «плохой» выходной файл и посмотреть, есть ли там что-то, что отсутствует в выходном файле .vcf. В моем случае не было; эта программа получила все хорошие карты для меня.
#!/usr/bin/python
import re
import sys
def bad_chars():
for n in range(0, 32):
if n not in (9, 10, 13):
yield chr(n)
for n in range(128, 256):
yield chr(n)
def has_bad(s):
return any(ch in s for ch in bad_chars())
def get_email(card):
lst = card.split('\n')
for line in lst:
if "EMAIL" in line:
_, _, email = line.partition(':')
return email.strip()
else:
return ''
if len(sys.argv) != 4:
print("Usage: cvt.py <input_old_address_book> <output.vcf> <bad.txt>")
sys.exit(1)
with open(sys.argv[1], "rb") as in_f:
s = in_f.read()
s_start = "BEGIN:VCARD"
s_end = "END:VCARD"
cards = {}
lst_bad = []
while s:
i_start = s.find(s_start)
if i_start == -1:
break
i_next = s.find(s_start, i_start + len(s_start))
if i_next == -1:
i_next = len(s) - 1
i_end = s.find(s_end, i_start + len(s_start))
if i_end == -1:
i_end = len(s) - 1
else:
i_end += len(s_end)
if i_next < i_end:
i_end = i_next
card = s[i_start:i_end+1].strip()
s = s[i_end:]
card = card.replace('\r', '')
card = card.replace('\0', '')
if not card:
continue
key = get_email(card)
if has_bad(card) or s_end not in card or not key:
lst_bad.append(card)
continue
if key not in cards or len(card) > len(cards[key]):
cards[key] = card
with open(sys.argv[2], "w") as out_f:
for key in sorted(cards.keys()):
out_f.write(cards[key] + "\n\n")
with open(sys.argv[3], "w") as bad_f:
for s in lst_bad:
bad_f.write(s + "\n\n")