2 # -*- coding: utf-8 -*-
6 from vobject import readComponents
7 from geohash import encode
8 from urlparse import urlparse
9 from getpass import getpass
10 from lxml import etree
11 from lxml.builder import ElementMaker
13 from address import Address
14 from treecutter import constants as const
16 class Contacts(object):
17 def __init__(self, uri):
20 if uri.scheme == 'file':
21 with open(self.uri.path, 'r') as f:
22 self.card_data = f.read()
24 if uri.scheme == 'http':
26 print "http not yet implemented"
27 if uri.scheme == 'https':
28 print "https not yet implemented"
30 def filter(self,query):
31 (key, name) = query.split(':')
33 for c in readComponents(self.card_data):
34 if key in c.contents.keys():
35 if name.decode('utf-8') == c.contents[key][0].value[0]:
37 if key == 'firstname':
38 if name.decode('utf-8') == c.n.value.given:
41 if name.decode('utf-8') == c.n.value.family:
45 class Contact(object):
46 def __init__(self,card):
49 self.organization = Organization('')
58 if 'n' in self.card.contents.keys():
60 empty = n.prefix == '' and n.given == '' and \
61 n.additional =='' and n.family =='' and n.suffix == ''
63 self.person = Person(n.given,n.family,
64 n.prefix,n.additional,n.suffix)
65 if 'title' in self.card.contents.keys():
66 self.jobtitle = self.card.title.value
68 if 'org' in self.card.contents.keys():
69 self.organization = Organization(self.card.org.value[0])
71 for av in self.card.contents['adr']:
73 addr = Address(a.street,a.code,a.city,a.country)
74 if av.type_param == 'work':
75 self.organization.add_address(addr)
76 if av.type_param == 'home':
77 self.address.append(addr)
80 for i,t in enumerate(self.card.contents['tel']):
81 if av.type_param == 'cell': # Does not exist ?
83 if av.type_param == 'work':
84 self.organization.add_phone(i,t.value)
85 if av.type_param == 'home':
86 self.address[i].add_phone(t.value)
88 if 'url' in self.card.contents.keys():
89 self.url = self.card.url.value
91 # if 'email' in self.card.contents.keys():
92 # self.email = self.card.email.value
96 db = ElementMaker(namespace=const.DB_NS, nsmap=const.NSMAP)
98 pers = db.person(self.person.db_xml(),db.phone(self.phone))
99 for a in self.address:
100 pers.append(a.db_xml())
101 pers.append(db.affiliation(db.jobtitle(self.jobtitle),
102 self.organization.db_xml()))
103 pers.append(db.email(self.email))
105 pers = self.organization.db_xml()
106 pers.append(db.uri(db.link(self.url,**{const.XLINK+"href": self.url}),
110 class Person(object):
111 def __init__(self,firstname,surname,honorific,othername,linage):
112 self.honorific = honorific
113 self.firstname = firstname
114 self.othername = othername
115 self.surname = surname
119 db = ElementMaker(namespace=const.DB_NS, nsmap=const.NSMAP)
121 db.honorific(self.honorific),
122 db.firstname(self.firstname),
123 db.othername(self.othername),
124 db.surname(self.surname),
125 db.linage(self.linage)
129 class Organization(object):
130 def __init__(self,orgname):
131 self.orgname = orgname
134 def add_address(self,addr):
135 addr.set_name(self.orgname)
136 self.address.append(addr)
138 def add_phone(self, i, phone):
139 # Quick fix for when an address has two phone numbers : FIXME
141 self.address[i].add_phone(phone)
142 except IndexError, e:
146 db = ElementMaker(namespace=const.DB_NS, nsmap=const.NSMAP)
147 org = db.org(db.orgname(self.orgname))
148 for a in self.address:
149 org.append(a.db_xml())
152 def recursively_empty(e):
153 if e.text or e.tag == const.DB+'imagedata':
155 return all((recursively_empty(c) for c in e.iterchildren()))
158 context = etree.iterwalk(xml)
159 for action, elem in context:
160 parent = elem.getparent()
161 if recursively_empty(elem):
165 if __name__ == "__main__":
166 for arg in sys.argv[1:]:
167 al = arg.split("=",1)
173 (uristr,query) = argument.split('|')
174 uri = urlparse(uristr)
175 contact = Contacts(uri).filter(query)
176 cxml = contact.db_xml()
179 #print(etree.tostring(cxml, pretty_print=True))
180 #sys.stdout.write(out.encode('utf-8'))
181 sys.stdout.write(etree.tostring(cxml,encoding='UTF-8',pretty_print=False))