Address book .wab to vCard .vcf

Az van, hogy migrálok Office Outlook, Outlook Express és Thunderbird klienseket intranetes Roundcube webmailbe. A migrálás egyszerű: a meglévő offline levelező programban létrehozom az új IMAP-os fiókot, és áthúzom a mappákat. Pár klikk az egész. Viszont a címjegyzéket is migrálnom kell.

A Roundcube címjegyzéke vCard-ot tud megenni, erre akartam egy szabad szoftveres megoldást találni. Találtam is, de csak fél megoldást, ezért hozzáírtam a másik felét.

Kellékek:
- Thunderbird
- 2vcard (benne van Debian és Ubuntu repoban)
- vcard_reformat.py (az én progim)

Lépsek:
1) Thunderbird telepítése csak címjegyzék importáláshoz (ha nem TB volt a levelező kliens alapból)
2) Címjegyzék exportálása TB-ből LDIF formátumba (egyetlen fájl lesz)
3)

2vcard -f ldif -i cimek.ldif -o cimek.vcf

(szintén egyetlen fájlba teszi az összes vCard-ot)
4)

./progim cimek.vcf

A keletkezett fájl már egyben beadható Roundcube-nak.

2vcard leírása:
"2vcard is a little perl script to convert an addressbook to the popular VCARD file format. Currently, 2vcard can convert address‐books and alias files from the following formats: abook, eudora, juno, ldif, mutt, mh and pine."

Jó hír: 2vcard egyetlen vCard-ba tudja tolni az összes LDIF-es címet. Kevésbé jó hír: a karakter kódolás nem lesz jó, unicode-osak lesznek az ékezetes karakterek, de csak ezek, és ráadásul a Roundcube nem eszi meg azokat a vCard-okat, amelyeknél hiányzik a név bejegyzés (pl. csak e-mail cím van).

Erre írtam a python-os progit. Hamar gyorsan, nincs több időm rá. Nem fogom szépítgetni.
Pastebin link

Licenc: public domain


#!/usr/bin/python
# coding=utf8

# reconvert vCard format by filling FN: tag in vCard blocks
# with mail address names if empty
# also, remove vCard blocks not containing any e-mail addresses

import os
import sys
import re

# vars
PARAM = ""
COUNT_ADD = 0
COUNT_SUB = 0

if len(sys.argv) > 1:
	PARAM = sys.argv[1]
else:
	print "error: imput file missing"
	exit(1)

print "* start"

# read .vcf text file
if not os.path.exists(PARAM):
	print "error: invalid file"
	exit(1)
FILE = open(PARAM)
# get lines of text
TEXT = FILE.readlines()

L3 = ""
OUT = ""

# cycle thorugh every line
for i in TEXT:
	# get line without ending new line char
	L = i[:-1]

	# add next block
	if L: L3 += L + "\n"

	# does the line start with "END:" tag?
	L2 = L[:4]
	if L2 == "END:":
		if L3:
			# is there any e-mail address in the block?
			if re.findall("^EMAIL.*:.*@", L3, re.M):

				# is there an empty "FN:" tag?
				if re.findall("^FN:\n", L3, re.M):
					# if so, then add the mail name to it
					# get the name part of the e-mail address before "@" char
					PRE  = re.findall("^EMAIL.*$", L3, re.M)[0]
					NAME = re.findall("[^:]+$", PRE, re.M)[0]
					# is it not empty?
					L4 = ""
					if NAME:
						L4 = re.sub("FN:\n", "FN:" + NAME + "\n", L3, re.M)
					else:
						L4 = re.sub("FN:\n", "FN:" + "empty" + "\n", L3, re.M)

				else: L4 = L3
				
				# store output
				OUT += L4 + "\n"
				
				# count it
				COUNT_ADD += 1

			else:
				COUNT_SUB += 1

		# clear temporary block holder
		L3 = ""


# convert unicode chars back to utf8 in output
# 123=C3=B6=C3=BC=C3=B3=C5=91=C3=BA=C3=A9=C3=A1=C5=B1=C3=AD123=C3=96=C3=9C=C3==0A=93=C5=90=C3=9A=C3=89=C3=81=C5=B0=C3=8D123=0A
# 123öüóőúéáűí123ÖÜÓŐÚÉÁŰÍ123
if OUT:
	TEMP = re.sub("=C3=B6", "ö", OUT);	OUT = TEMP
	TEMP = re.sub("=C3=BC", "ü", OUT);	OUT = TEMP
	TEMP = re.sub("=C3=B3", "ó", OUT);	OUT = TEMP
	TEMP = re.sub("=C5=91", "ő", OUT);	OUT = TEMP
	TEMP = re.sub("=C3=BA", "ú", OUT);	OUT = TEMP
	TEMP = re.sub("=C3=A9", "é", OUT);	OUT = TEMP
	TEMP = re.sub("=C3=A1", "á", OUT);	OUT = TEMP
	TEMP = re.sub("=C3=A1", "á", OUT);	OUT = TEMP
	TEMP = re.sub("=C5=B1", "ű", OUT);	OUT = TEMP
	TEMP = re.sub("=C3=AD", "í", OUT);	OUT = TEMP

	TEMP = re.sub("=C3=96", "Ö", OUT);	OUT = TEMP
	TEMP = re.sub("=C3=9C", "Ü", OUT);	OUT = TEMP
	TEMP = re.sub("=C3==0A", "Ó", OUT);	OUT = TEMP
	TEMP = re.sub("=93=C5", "Ő", OUT);	OUT = TEMP
	TEMP = re.sub("=90=C3", "Ú", OUT);	OUT = TEMP
	TEMP = re.sub("=9A=C3", "É", OUT);	OUT = TEMP
	TEMP = re.sub("=89=C3", "Á", OUT);	OUT = TEMP
	TEMP = re.sub("=81=C5", "Ű", OUT);	OUT = TEMP
	TEMP = re.sub("=B0=C3=8D", "Í", OUT);	OUT = TEMP

	TEMP = re.sub("==0A", "", OUT);		OUT = TEMP
	TEMP = re.sub("=0A", "", OUT);		OUT = TEMP


# file operations
FILE.close()
FILE = open(PARAM, "w")
FILE.writelines(OUT)
FILE.close()

# print info
print "* " + str(COUNT_ADD) + " vCards added, " + str(COUNT_SUB) + " removed"
print "* exit"

exit(0)

Hozzászólások

Kiegészítés: közben rájöttem, hogy a unicode az "quoted printable" kódolás, és a python progim végén nem kell a dekodolós rész, hanem elég pipe-olni q "qprint -d" parancsba a 2vcard kimenetét. Tehát:

cat cimek.ldif | 2vcard -f ldif | qprint -d > cimek.vcf

és így nem kell a "convert unicode chars" rész a "file operations" részig.

Kieg 2.: mégis az eredeti megoldásom a jó, mert 2vcard kimenetében a new line karakter nem megfelelő a quoted print dekódoláshoz. A többit jól dekódolja.

Így van, csak éppen úgy, ahogy az összes outlook-os kliensnél: egyesével tudsz vCard-ot exportálni.

Ez gondolom direkt van, MS részéről megértem, nem akar könnyű lehetőséget adni a usernek exporthoz, hogy másra váltson. TB-nél viszont nem értem, közel nulla idő alatt leprogramozható feladat.

"az OE wab-jat lehet exportalni igy, Ctrl+A, export."

De megnézted? Olyan formátumokba tud exportálni, amelyek nem megfelelőek. Szerintem nem tud vCard-ot, illetve LDIF-et sem.

A fenti kiterjesztést én is megtaláltam, de nem látok forrás kód elérhetőséget hozzá. Csak open source megoldás érdekel.

De-de, csak trükkös.

Az OE címjegyzékén be kell állni egy olyan nézetbe, ahol az összes kontaktot látod, és ki kell húzni öket egy mappába, vagy az asztalra. Ekkor ugyan nem egy fájlba exportálja bele az összes névjegyet, hanem nevenként külön vcf lesz, viszont azon már könnyü segíteni.

Bocs, nekem is utána kellett néznem, hogy müködött ez, évek óta nem volt szükségem erre a tudásra.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Egy kiegészítő megjegyzés: volt olyan vCard exportom (Windows Mail / Vista), hogy nem akara megenni a roundcube megfelelően, a nevek rossz karakterekkel voltak tele. Megoldás volt, hogy eltávolítottam a vCard-okból az "N:" tag-ot, és csak az "FN:"-t hagytam meg a progimba pipe-olás előtt.