Adding table generation from simple textfile
[treecutter.git] / xinclude / contact.py
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 import sys
5
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
12
13 from address import Address
14 from treecutter import constants as const
15
16 class Contacts(object):
17     def __init__(self, uri):
18         self.uri = uri
19         self.card_data = None
20         if uri.scheme == 'file':
21             with open(self.uri.path, 'r') as f:
22                 self.card_data = f.read()
23             f.closed
24         if uri.scheme == 'http':
25             pw = getpass()
26             print "http not yet implemented"
27         if uri.scheme == 'https':
28             print "https not yet implemented"
29
30     def filter(self,query):
31         (key, name) = query.split(':')
32         card = None
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]:
36                     card = c
37             if key == 'firstname':
38                 if name.decode('utf-8') == c.n.value.given:
39                     card = c
40             if key == 'surname':
41                 if name.decode('utf-8') == c.n.value.family:
42                     card = c
43         return Contact(card)
44
45 class Contact(object):
46     def __init__(self,card):
47         self.card = card
48         self.person = None
49         self.organization = Organization('')
50         self.address = []
51         self.phone = ''
52         self.jobtitle = ''
53         self.url = ''
54         self.email = ''
55         self.parsecard()
56
57     def parsecard(self):
58         if 'n' in self.card.contents.keys():
59             n = self.card.n.value
60             empty = n.prefix == '' and n.given == '' and \
61                 n.additional =='' and n.family ==''  and n.suffix == ''
62         if not empty:
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
67
68         if 'org' in self.card.contents.keys():
69             self.organization = Organization(self.card.org.value[0])
70
71         for av in self.card.contents['adr']:
72             a = av.value
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)
78             addr.geocode()
79
80         for i,t in enumerate(self.card.contents['tel']):
81             if av.type_param == 'cell':  # Does not exist ?
82                 self.phone = t.value
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)
87
88         if 'url' in self.card.contents.keys():
89             self.url = self.card.url.value
90
91 #        if 'email' in self.card.contents.keys():
92 #            self.email = self.card.email.value
93
94
95     def db_xml(self):
96         db = ElementMaker(namespace=const.DB_NS, nsmap=const.NSMAP)
97         if self.person:
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))
104         else:
105             pers = self.organization.db_xml()
106         pers.append(db.uri(db.link(self.url,**{const.XLINK+"href": self.url}),
107                            type='website'))
108         return pers
109
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
116         self.linage = linage
117
118     def db_xml(self):
119         db = ElementMaker(namespace=const.DB_NS, nsmap=const.NSMAP)
120         p = db.personname(
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)
126           )
127         return p
128
129 class Organization(object):
130     def __init__(self,orgname):
131         self.orgname = orgname
132         self.address = []
133
134     def add_address(self,addr):
135         addr.set_name(self.orgname)
136         self.address.append(addr)
137
138     def add_phone(self, i, phone):
139         # Quick fix for when an address has two phone numbers : FIXME
140         try:
141             self.address[i].add_phone(phone)
142         except IndexError, e:
143             pass
144
145     def db_xml(self):
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())
150         return org
151
152 def recursively_empty(e):
153     if e.text or e.tag == const.DB+'imagedata':
154         return False
155     return all((recursively_empty(c) for c in e.iterchildren()))
156
157 def clean_db(xml):
158     context = etree.iterwalk(xml)
159     for action, elem in context:
160         parent = elem.getparent()
161         if recursively_empty(elem):
162             parent.remove(elem)
163
164
165 if __name__ == "__main__":
166     for arg in sys.argv[1:]:
167         al = arg.split("=",1)
168         if al[0] == "lang":
169             lang = al[1]
170         if al[0] == "xptr":
171             argument = al[1]
172
173     (uristr,query) = argument.split('|')
174     uri = urlparse(uristr)
175     contact = Contacts(uri).filter(query)
176     cxml = contact.db_xml()
177     clean_db(cxml)
178
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))