abook Adressen importieren

abook Addressbuch unter Linux

Was ist das doch manchmal schwierig Informationen zu finden. Zum Glück kann man ja heute mithilfe von so LLMs, auch in den Gebieten fischen, in denen man sich nicht so gut auskennt. Deshalb lasse ich Euch hier mal teilhaben.

Ausgangspunkt

Ich habe mir alle Kontakte aus meinem Google Konto, von Apple Kontakte, in eine vcf-Datei exportieren lassen. Diese Daten würde ich nun gern in abook importieren, damit ich die Adressen z.B. in neomutt weiterverwenden kann.

Hier einmal der Code komplett mit Anmerkungen, welche Funktion, was macht.

Script für die Konvertierung >folded
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env python

import sys # Importiert das sys-Modul für die Arbeit mit Systemparametern
import csv # Importiert das csv-Modul für die Arbeit mit CSV-Dateien
from vobject import readComponents # Importiert die Funktion readComponents aus dem vobject-Modul zur Verarbeitung von vCard-Daten

# Definieren Sie den Pfad zur vcf-Datei und die Ausgabe-Addressbook-Datei
vcf_file = '~/Downloads/vcard-export/alle-kontakte.vcf' # Pfad zur vcf-Datei
addressbook_file = '~/Downloads/vcard-export/addressbook.abook' # Pfad zur Ausgabe-Datei im abook-Format

try:
with open(vcf_file, 'r') as f: # Öffnet die vcf-Datei im Lesemodus
vcards = list(readComponents(f)) # Liest und parst die vCard-Daten aus der Datei
except Exception as e: # Fehlerbehandlung bei Dateizugriffsfehlern
print(f"Error reading {vcf_file}: {e}") # Gibt eine Fehlermeldung aus, falls ein Fehler auftritt
sys.exit(1) # Beendet das Programm mit einem Fehlercode

# Funktion zur Extraktion des ersten Werts eines Attributs aus einem vCard-Objekt
def get_first_value(obj, attribute):
if hasattr(obj, attribute): # Prüft, ob das Attribut existiert
attr = getattr(obj, attribute) # Holt das Attribut
if isinstance(attr, list): # Prüft, ob das Attribut eine Liste ist
return attr[0].value # Gibt den ersten Wert der Liste zurück
return attr.value # Gibt den Wert des Attributs zurück
return 'N/A' # Gibt 'N/A' zurück, falls das Attribut nicht existiert

# Funktion zur Extraktion aller Werte eines Attributs aus einem vCard-Objekt
def get_all_values(obj, attribute):
if hasattr(obj, attribute): # Prüft, ob das Attribut existiert
attr = getattr(obj, attribute) # Holt das Attribut
if isinstance(attr, list): # Prüft, ob das Attribut eine Liste ist
return ', '.join([a.value for a in attr]) # Gibt alle Werte als kommaseparierte Zeichenkette zurück
return attr.value # Gibt den Wert des Attributs zurück
return 'N/A' # Gibt 'N/A' zurück, falls das Attribut nicht existiert

# Funktion zur Extraktion einer spezifischen Adresskomponente aus einem adr-Objekt
def get_address_component(adr, component):
return getattr(adr, component, '') # Gibt die spezifische Adresskomponente zurück oder ein leeres Zeichen, falls sie nicht existiert

# Funktion zur Extraktion der Adressinformationen aus einem vCard-Objekt
def get_address(vcard):
if hasattr(vcard, 'adr'): # Prüft, ob das adr-Attribut existiert
adr = vcard.adr.value # Holt das adr-Attribut
address = get_address_component(adr, 'street') # Extrahiert die Straßenadresse
address2 = '' # Setzt address2 auf leer, da es nicht in vCard enthalten ist
city = get_address_component(adr, 'city') # Extrahiert die Stadt
state = get_address_component(adr, 'region') # Extrahiert den Staat/Region
zip_code = get_address_component(adr, 'code') # Extrahiert die Postleitzahl
country = get_address_component(adr, 'country') # Extrahiert das Land
return address, address2, city, state, zip_code, country # Gibt die Adresskomponenten zurück
return 'N/A', 'N/A', 'N/A', 'N/A', 'N/A', 'N/A' # Gibt 'N/A' zurück, falls die Adresse nicht existiert

# Öffnet die abook-Datei im Schreibmodus
with open(addressbook_file, 'w') as abookfile:
# Schreibt die Kopfzeilen der abook-Datei
abookfile.write('[format]\n')
abookfile.write('program=abook\n')
abookfile.write('version=0.6.1\n\n')

# Iteriert über die vCards und schreibt ihre Daten in die abook-Datei
for i, vcard in enumerate(vcards):
name = get_first_value(vcard, 'fn') # Holt den Namen
email = get_all_values(vcard, 'email') # Holt alle E-Mail-Adressen
address, address2, city, state, zip_code, country = get_address(vcard) # Holt die Adressinformationen
phone = get_all_values(vcard, 'tel') # Holt alle Telefonnummern
workphone = get_first_value(vcard, 'workphone') # Holt die geschäftliche Telefonnummer
fax = get_first_value(vcard, 'fax') # Holt die Faxnummer
mobile = get_first_value(vcard, 'cell') # Holt die Handynummer
nickname = get_first_value(vcard, 'nickname') # Holt den Spitznamen
url = get_first_value(vcard, 'url') # Holt die URL
notes = get_first_value(vcard, 'note') # Holt die Notizen
anniversary = get_first_value(vcard, 'bday') # BDAY wird als anniversary gespeichert
groups = get_all_values(vcard, 'categories') # Holt alle Gruppen

# Schreibt die vCard-Daten in das abook-Format
abookfile.write(f'[{i}]\n')
abookfile.write(f'name={name}\n')
abookfile.write(f'email={email}\n')
if address != 'N/A':
abookfile.write(f'address={address}\n')
if address2 != 'N/A':
abookfile.write(f'address2={address2}\n')
if city != 'N/A':
abookfile.write(f'city={city}\n')
if state != 'N/A':
abookfile.write(f'state={state}\n')
if zip_code != 'N/A':
abookfile.write(f'zip={zip_code}\n')
if country != 'N/A':
abookfile.write(f'country={country}\n')
if phone != 'N/A':
abookfile.write(f'phone={phone}\n')
if workphone != 'N/A':
abookfile.write(f'workphone={workphone}\n')
if fax != 'N/A':
abookfile.write(f'fax={fax}\n')
if mobile != 'N/A':
abookfile.write(f'mobile={mobile}\n')
if nickname != 'N/A':
abookfile.write(f'nick={nickname}\n')
if url != 'N/A':
abookfile.write(f'url={url}\n')
if notes != 'N/A':
abookfile.write(f'notes={notes}\n')
if anniversary != 'N/A':
abookfile.write(f'anniversary={anniversary}\n')
if groups != 'N/A':
abookfile.write(f'groups={groups}\n')
abookfile.write('\n') # Fügt eine Leerzeile nach jedem Eintrag hinzu

print(f"Successfully written data to {addressbook_file}") # Gibt eine Erfolgsnachricht aus

# Ende des Skripts

Das Ergebnis sieht dann wie folgt aus. So kann man mit der Datei weiterarbeiten. Das Format ist gleich korrekt und wird von abook ohne Murren verarbeitet. Ich hatte mehrere Versuche und bei den ersten wurde die Datei direkt gelöscht. Das lag offensichtlich daran, dass ich Probleme mit dem Format hatte.

1
2
3
4
5
6
7
8
9
10
11
12
# abook addressbook file

[format]
program=abook
version=0.6.1


[0]
name=Autohaus Ludwigshaven
email=N/A
address=N/A
phone=+490026950000

In einer der ersten Versionen wurden die Geburtstage nicht korrekt übernommen. Die habe ich in einer der Iterationen dann von BDAY in das Feld Anniversary übergeben. So passte das für mich besser.

Backen, mein neues Hobby in 2024

Backen, mein neues Hobby in 2024

Das war so gar nicht geplant, denn ich hatte vor ein paar Jahren schon einmal überlegt, was ich mit den letzten 20 Sommern noch so anfangen will, da war Backen gar nicht in die Betrachtung gekommen. Nun denn, TickTock ist Dein Freund, wenn es darum geht mit so was angefixt zu werden.

Mehr lesen
Ostern in Italien

Ostern in Italien

Italien ist wie immer einer Reise wert

Auch in diesem Jahr waren wir an Ostern wieder in Ligurien. Da Ostern sehr früh im Jahr war, hatten wir durchwachsenes Wetter. Oft schön, aber auch immer mal 13°C. Ich fand es super, meiner Frau war es oft ein wenig zu kalt. Insgesamt aber eine sehr schöne Zeit.

Es ist touristisch wenig los, man hat den Strand oft für sich alleine und insgesamt ist es nicht überlaufen.

Impressionen

Mehr lesen

Herbstferien in den Niederlanden

Herbstferien in den Niederlanden

Noch habe ich keinen Text zusammengeschrieben, aber die Statistiken von der An- und Abreise sind schon fertig 😆

Auf dem Weg in die Niederlande kann man ganz schön Energie sparen.

Mehr lesen
4 Wochen Homeoffice in Italien

4 Wochen Homeoffice in Italien

Vier Wochen Italien, wie aus einer fixen Idee ganz schnell Abreise wird

Im vergangenen Jahr im Herbst, nachdem ich nach über 20 Jahren das erste Mal wieder in Italien war, hatten wir die fixe Idee, dass ich doch einfach statt zu Hause in Rheinland-Pfalz im Home-Office zu sitzen, die Zeit auch mal in Italien verbringen kann, schnelles Internet, das ganze Equipment mitnehmen, da sollte das eigentlich kein Problem sein.

Mehr lesen