Skip to content

Instantly share code, notes, and snippets.

@vale981
Last active September 7, 2020 16:21
Show Gist options
  • Save vale981/0a5ae8aa6e2899960e955e23ab3eadb1 to your computer and use it in GitHub Desktop.
Save vale981/0a5ae8aa6e2899960e955e23ab3eadb1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import csv
import re
import unicodedata
import sys
from xml.dom.minidom import getDOMImplementation
import copy
contacts = []
def strip_accents(text):
"""
Strip accents from input String.
:param text: The input string.
:type text: String.
:returns: The processed String.
:rtype: String.
"""
try:
text = unicode(text, "utf-8")
except (TypeError, NameError): # unicode is a default on python 3
pass
text = unicodedata.normalize("NFD", text)
text = text.encode("ascii", "ignore")
text = text.decode("utf-8")
return str(text)
# strip unwanted characters from strings
def clean(s):
s = s.replace("+49", "0").replace("+", "00").strip()
return "".join(n for n in s if n.isdigit())
# Import Contacts
with open(sys.argv[1], encoding="utf-8") as csvfile:
records = csv.DictReader(csvfile)
# print(records)
noFax = re.compile(".*fax.*", re.IGNORECASE)
for record in records:
contact = {
"FirstName": (
record["Name Prefix"] + " " if len(record["Name Prefix"]) > 0 else ""
)
+ strip_accents(record["Given Name"]),
"LastName": strip_accents(record["Family Name"]),
"numbers": [],
}
for number in range(1, 4):
typ = "Phone {} - Type".format(number)
val = "Phone {} - Value".format(number)
if record[val] and not noFax.match(record[typ]):
# Grandstream uses three types of phone numbers,
# "Work", "Cell", "Home" WRONG - Home/Work ONLY - but
# is superfluous
record[typ] = 1 if record[typ] == "Home" else record[typ]
record[typ] = 2 if record[typ] == "Main" else record[typ]
record[typ] = 3 if record[typ] == "Other" else record[typ]
record[typ] = 4 if record[typ] == "Work" else record[typ]
record[typ] = 5 if record[typ] == "Mobile" else record[typ]
record[typ] = 6 if record[typ] == "Mobil" else record[typ]
if not record[typ]:
record[typ] = 1 # default to "Home"
# Split field value - multiple numbers of the same
# type are stuffed into a single field, sepatated
# by ':::'
for n in map(clean, record[val].split(":::")):
tmp = copy.deepcopy(contact)
tmp["numbers"].append(
{"type": "Home", "value": n, "idx": str(record[typ])}
)
contacts.append(tmp)
impl = getDOMImplementation()
xml = impl.createDocument(None, "AddressBook", None)
top_element = xml.documentElement
for contact in contacts:
c = xml.createElement("Contact")
# Names
for part in ["FirstName", "LastName"]:
if not contact[part]:
continue
f = xml.createElement(part)
f.appendChild(xml.createTextNode(contact[part]))
c.appendChild(f)
# Numbers
for number in contact["numbers"]:
group = xml.createElement("Phone")
group.setAttribute("type", number["type"])
# phonenumber
num = xml.createElement("phonenumber")
num.appendChild(xml.createTextNode(number["value"]))
group.appendChild(num)
# accountindex
idx = xml.createElement("accountindex")
idx.appendChild(xml.createTextNode(number["idx"]))
group.appendChild(idx)
c.appendChild(group)
top_element.appendChild(c)
print(xml.toprettyxml(encoding="UTF-8").decode())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment