#!/usr/bin/python
# -*- coding: utf-8 -*-
-from vobject import readComponents
import sys
-from address import Address
+
+from vobject import readComponents
from geohash import encode
+from urlparse import urlparse
+from getpass import getpass
+from lxml import etree
+from lxml.builder import ElementMaker
-for arg in sys.argv[1:]:
- al = arg.split("=")
- if al[0] == "lang":
- lang = al[1]
- if al[0] == "xptr":
- argument = al[1]
-
-(cards,query) = argument.split('?')
-(key, name) = query.split(':')
-with open(cards, 'r') as f:
- card_data = f.read()
-f.closed
-
-# Scan for the correct card
-found = None
-out = u''
-for card in readComponents(card_data):
-# card.prettyPrint()
- if key in card.contents.keys():
- if name.decode('utf-8') == card.contents[key][0].value[0]:
- found = card
- if key == 'firstname':
- if name.decode('utf-8') == card.n.value.given:
- found = card
- if key == 'surname':
- if name.decode('utf-8') == card.n.value.family:
- found = card
-
-if not found:
- print query+' failed in '+cards
- exit(2)
-# when card is found parse it to docbook.
-pn = ''
-
-if 'n' in found.contents.keys():
- n = found.n.value
- empty = n.prefix == '' and n.given == '' and \
- n.additional =='' and n.family =='' and n.suffix == ''
- if not empty:
- pn += '<personname>'
- if n.prefix != '':
- pn += '<honorific>'+n.prefix+'</honorific> '
- if n.given != '':
- pn += '<firstname>'+n.given+'</firstname> '
- if n.additional != '':
- pn += '<othername>'+n.additional+'</othername> '
- if n.family != '':
- pn += '<surname>'+n.family+'</surname> '
- if n.suffix != '':
- pn += '<lineage>'+n.suffix+'</lineage> '
- pn += '</personname>'
-
-ad = ''
-if 'adr' in found.contents.keys():
- for a, t in zip(found.contents['adr'],found.contents['tel']):
- ad += '\n<address type="'+a.type_param+'"> '
- if a.value.street != '':
- ad += '<street>'+a.value.street+'</street>'
- if a.value.code != '':
- ad += '<postcode>'+a.value.code+'</postcode> '
- if a.value.city != '':
- ad += '<city>'+a.value.city+'</city>'
- if a.value.country != '':
- ad += '<country>'+a.value.country+'</country>'
- if t.value != '':
- ad += '<phone>'+t.value+'</phone>'
- ad += '</address>'
- geostr = u''+a.value.street+', '+a.value.city+', '+a.value.country
- (lat,lon) = geocode(geostr.encode('utf-8'))
- mapimage([(float(lat),float(lon))])
- ad += maplink(lat,lon)
-
-o = ''
-if 'org' in found.contents.keys():
- o = '''
- <org>
- <orgname>'''+found.org.value[0]+'''</orgname>
- '''+ad+'''
- </org>'''
-
-
-url = ''
-if 'url' in found.contents.keys():
- url += '<uri type="website"><link xlink:href="'+found.url.value+'"/></uri> '
-
-geo = ''
-#if 'geo' in found.contents.keys():
-# (lat,lon) = found.geo.value.split(';')
-# mapimage([(float(lat),float(lon))])
-# # create picture
-# geo += maplink(lat,lon)
-
-
-# Turn off email for now
-email = ''
-#if 'email' in found.contents.keys():
-# email += '<email>'+found.email.value+'</email>'
-
-if empty:
- content = pn+o+url+geo+email
-else:
- if o == '':
- content = '<person>'+pn+ad+url+geo+email+'</person>'
- else:
- content = '<person>'+pn+'<affiliation>'+o+'</affiliation>'+url+geo+email+ \
- '</person>'
-out = '''
-<para xmlns="http://docbook.org/ns/docbook"
- xmlns:xlink="http://www.w3.org/1999/xlink">
- '''+content+'''
-</para>
-'''
-
-ex ='''
- <address>
- <street>Street</street>
- <postcode>Postcode</postcode> <city>City</city>
- <country>Country</country>
- <phone>+1 123 456 789</phone>
- </address>
- <affiliation>
- <jobtitle>Occupation</jobtitle>
- <org>
- <orgname>Organization</orgname>
- <address>
- <street>Street</street>
- <postcode>Postcode</postcode> <city>City</city>
- <country>Country</country>
- <phone>+1 123 456 789</phone>
- </address>
- </org>
- </affiliation>
- </person>
-</para>
-'''
-
-sys.stdout.write(out.encode('utf-8'))
+from address import Address
+from treecutter import constants as const
+
+class Contacts(object):
+ def __init__(self, uri):
+ self.uri = uri
+ self.card_data = None
+ if uri.scheme == 'file':
+ with open(self.uri.path, 'r') as f:
+ self.card_data = f.read()
+ f.closed
+ if uri.scheme == 'http':
+ pw = getpass()
+ print "http not yet implemented"
+ if uri.scheme == 'https':
+ print "https not yet implemented"
+
+ def filter(self,query):
+ (key, name) = query.split(':')
+ card = None
+ for c in readComponents(self.card_data):
+ if key in c.contents.keys():
+ if name.decode('utf-8') == c.contents[key][0].value[0]:
+ card = c
+ if key == 'firstname':
+ if name.decode('utf-8') == c.n.value.given:
+ card = c
+ if key == 'surname':
+ if name.decode('utf-8') == c.n.value.family:
+ card = c
+ return Contact(card)
+
+class Contact(object):
+ def __init__(self,card):
+ self.card = card
+ self.person = None
+ self.organization = Organization('')
+ self.address = []
+ self.phone = ''
+ self.jobtitle = ''
+ self.url = ''
+ self.email = ''
+ self.parsecard()
+
+ def parsecard(self):
+ if 'n' in self.card.contents.keys():
+ n = self.card.n.value
+ empty = n.prefix == '' and n.given == '' and \
+ n.additional =='' and n.family =='' and n.suffix == ''
+ if not empty:
+ self.person = Person(n.given,n.family,
+ n.prefix,n.additional,n.suffix)
+ if 'title' in self.card.contents.keys():
+ self.jobtitle = self.card.title.value
+
+ if 'org' in self.card.contents.keys():
+ self.organization = Organization(self.card.org.value[0])
+
+ for av in self.card.contents['adr']:
+ a = av.value
+ addr = Address(a.street,a.code,a.city,a.country)
+ if av.type_param == 'work':
+ self.organization.add_address(addr)
+ if av.type_param == 'home':
+ self.address.append(addr)
+ addr.geocode()
+
+ for i,t in enumerate(self.card.contents['tel']):
+ if av.type_param == 'cell': # Does not exist ?
+ self.phone = t.value
+ if av.type_param == 'work':
+ self.organization.add_phone(i,t.value)
+ if av.type_param == 'home':
+ self.address[i].add_phone(t.value)
+
+ if 'url' in self.card.contents.keys():
+ self.url = self.card.url.value
+
+# if 'email' in self.card.contents.keys():
+# self.email = self.card.email.value
+
+
+ def db_xml(self):
+ db = ElementMaker(namespace=const.DB_NS, nsmap=const.NSMAP)
+ if self.person:
+ pers = db.person(self.person.db_xml(),db.phone(self.phone))
+ for a in self.address:
+ pers.append(a.db_xml())
+ pers.append(db.affiliation(db.jobtitle(self.jobtitle),
+ self.organization.db_xml()))
+ pers.append(db.email(self.email))
+ else:
+ pers = self.organization.db_xml()
+ pers.append(db.uri(db.link(self.url,**{const.XLINK+"href": self.url}),
+ type='website'))
+ return pers
+
+class Person(object):
+ def __init__(self,firstname,surname,honorific,othername,linage):
+ self.honorific = honorific
+ self.firstname = firstname
+ self.othername = othername
+ self.surname = surname
+ self.linage = linage
+
+ def db_xml(self):
+ db = ElementMaker(namespace=const.DB_NS, nsmap=const.NSMAP)
+ p = db.personname(
+ db.honorific(self.honorific),
+ db.firstname(self.firstname),
+ db.othername(self.othername),
+ db.surname(self.surname),
+ db.linage(self.linage)
+ )
+ return p
+
+class Organization(object):
+ def __init__(self,orgname):
+ self.orgname = orgname
+ self.address = []
+
+ def add_address(self,addr):
+ addr.set_name(self.orgname)
+ self.address.append(addr)
+
+ def add_phone(self, i, phone):
+ # Quick fix for when an address has two phone numbers : FIXME
+ try:
+ self.address[i].add_phone(phone)
+ except IndexError, e:
+ pass
+
+ def db_xml(self):
+ db = ElementMaker(namespace=const.DB_NS, nsmap=const.NSMAP)
+ org = db.org(db.orgname(self.orgname))
+ for a in self.address:
+ org.append(a.db_xml())
+ return org
+
+def recursively_empty(e):
+ if e.text or e.tag == const.DB+'imagedata':
+ return False
+ return all((recursively_empty(c) for c in e.iterchildren()))
+
+def clean_db(xml):
+ context = etree.iterwalk(xml)
+ for action, elem in context:
+ parent = elem.getparent()
+ if recursively_empty(elem):
+ parent.remove(elem)
+
+
+if __name__ == "__main__":
+ for arg in sys.argv[1:]:
+ al = arg.split("=",1)
+ if al[0] == "lang":
+ lang = al[1]
+ if al[0] == "xptr":
+ argument = al[1]
+
+ (uristr,query) = argument.split('|')
+ uri = urlparse(uristr)
+ contact = Contacts(uri).filter(query)
+ cxml = contact.db_xml()
+ clean_db(cxml)
+
+ #print(etree.tostring(cxml, pretty_print=True))
+ #sys.stdout.write(out.encode('utf-8'))
+ sys.stdout.write(etree.tostring(cxml,encoding='UTF-8',pretty_print=False))