Trees | Indices | Help |
|
---|
|
1 ### BITPIM 2 ### 3 ### Copyright (C) 2004 Roger Binns <rogerb@rogerbinns.com> 4 ### 5 ### This program is free software; you can redistribute it and/or modify 6 ### it under the terms of the BitPim license as detailed in the LICENSE file. 7 ### 8 ### $Id: egroupware.py 1770 2004-11-22 06:53:49Z rogerb $ 9 10 """Be at one with eGroupware 11 12 We talk to eGroupware using its xmlrpc interface. Unfortunately the interface 13 has several quality issues, so we try to work around them in this code. 14 """ 15 16 import xmlrpclib 17 import urlparse 18 import time 19 import datetime 2022 23 # fixup whatever the user max have given us 24 scheme, location, path, query, fragment = urlparse.urlsplit(url) 25 26 if scheme is None and location is None and query is None: 27 url="http://"+url 28 29 if url[-1]!="/": url+="/" 30 url+="xmlrpc.php" 31 32 sp=xmlrpclib.ServerProxy(url) 33 34 res=sp.system.login({"username": user, "password": password, "domain": domain}) 35 36 if "sessionid" not in res or "kp3" not in res: 37 raise Exception("Invalid username or password") 38 39 scheme, location, path, query, fragment = urlparse.urlsplit(url) 40 41 if location.find("@")>=0: 42 location=location[location.find("@")+1:] 43 44 newurl=urlparse.urlunsplit( (scheme, "%s:%s@%s" % (res["sessionid"], res["kp3"], location), path, query, fragment) ) 45 return Session(xmlrpclib.ServerProxy(newurl), res)4648 52 57188 189 190 if __name__=='__main__': 191 import sys 192 import common 193 s=getsession(*sys.argv[1:]) 194 for v in s.getcategories(): 195 print common.prettyprintdict(v) 196 #for n,i in enumerate(s.getcontacts()): 197 # print n,common.prettyprintdict(i) 198 199 #print n,i.get('id',""),i.get('n_given', ""),i.get('n_family', "") 20059 return getcalendar((year,), (year,))6062 if len(start)!=6 or len(end)!=6: 63 t=time.localtime() 64 startdefs=(t[0], 1, 1, 0,0,0) 65 enddefs=(t[0],12,31,23,59,60) 66 start=start+startdefs[len(start):] 67 end=end+enddefs[len(end):] 68 start="%04d-%02d-%02dT%02d:%02d:%02d" % start 69 end="%04d-%02d-%02dT%02d:%02d:%02d" % end 70 for item in self.sp.calendar.bocalendar.search({"start": start, "end": end}): 71 for k in item.keys(): 72 if isinstance(item[k], xmlrpclib.DateTime): 73 v=str(item[k]) 74 v=[int(x) for x in v[0:4], v[5:7], v[8:10], v[11:13], v[14:16], v[17:19]] 75 if v==[0,0,0,0,0,0]: 76 del item[k] 77 else: 78 item[k]=datetime.datetime(*v) 79 yield item8082 try: 83 return self.sp.addressbook.boaddressbook.read({'id': id}) 84 except xmlrpclib.Fault, f: 85 # in theory only fault 10 - Entry does not (longer) exist! 86 # should be looked for. Unfortunately egroupware has a 87 # bug and returns fault 9 - Access denied if the id 88 # doesn't exist. So we consider any failure to mean 89 # that the id doesn't exist. Reported as SF bug #1057984 90 print "eg contact doesn't exist, fault", f 91 return False9294 "returns all contacts" 95 # internally we read them a group at a time 96 offset=0 97 limit=5 98 99 # NB an offset of zero causes egroupware to return ALL contacts ignoring limit! 100 # This has been filed as bug 1040738 at SourceForge against eGroupware. It 101 # won't hurt unless you have huge number of contacts as egroupware will try 102 # to return all of them at once. Alternatively make the simple fix as in 103 # the bug report 104 105 while True: 106 contacts=self.sp.addressbook.boaddressbook.search({'start': offset, 'limit': limit}) 107 if len(contacts)==0: 108 raise StopIteration() 109 for i in contacts: 110 yield i 111 if len(contacts)<limit: 112 raise StopIteration() 113 offset+=len(contacts)114116 "Returns the id of the contact" 117 # egroupware returns True if the contact was written successfully using the 118 # existing id, otherwise it returns the new id 119 res=self.sp.addressbook.boaddressbook.write(contact) 120 if res is True: 121 return contact['id'] 122 return res123125 "returns contacts in a format suitable for the BitPim phonebook importer" 126 # eGroupware gives a nice shine in the UI, but the underlying data is 127 # somewhat messy 128 for c in self.getcontacts(): 129 res={} 130 # egroupware format is very similar to vCard 131 res['Name']=c['fn'] 132 res['First Name']=c['n_given'] 133 res['Middle Name']=c['n_middle'] 134 res['Last Name']=c['n_family'] 135 res['UniqueSerial-id']=c['id'] 136 res['UniqueSerial-sourcetype']='egroupware' 137 # addresses 138 for t,prefix in ("business", "adr_one"), ("home", "adr_two"): 139 a={} 140 # egroupware has street 2 and 3 in the ui, but doesn't expose them 141 # via xmlrpc - reported as SF bug # 1043862 142 for p2,k in ("_street", "street"), ("_locality", "city"), ("_region", "state"), \ 143 ("_postalcode", "postalcode"), ("_countryname", "country"): 144 if len(c.get(prefix+p2,"")): a[k]=c[prefix+p2] 145 if t=="business" and len(c.get("org_name", "")): a['company']=c["org_name"] 146 if len(a): 147 a['type']=t 148 aa="Address" 149 if aa in res: 150 aa+="2" 151 assert aa not in res 152 res[aa]=a 153 # categories 154 cats=[] 155 ccats=c.get("cat_id", "") 156 if len(ccats): # could be empty string or a dict 157 for cat in ccats: 158 cats.append(ccats[cat]) 159 if len(cats): 160 res["Categories"]=cats 161 # email - we ignore the silly egroupware email type field 162 suf="" 163 if len(c.get("email","")): 164 res["Email Address"]={'email': c['email'], 'type': 'business'} 165 suf="2" 166 if len(c.get("email_home", "")): 167 res["Email Address"+suf]={'email': c['email_home'], 'type': 'home'} 168 # phone numbers 169 res["Home Phone"]=c['tel_home'] 170 res["Mobile Phone"]=c['tel_cell'] # nb: in eGroupware this is business cell 171 res["Business Fax"]=c['tel_fax'] 172 res["Pager"]=c['tel_pager'] # nb: in eGroupware this is business pager 173 res["Business Phone"]=c['tel_work'] 174 # various other fields 175 res['Notes']=c['note'] 176 res['Business Web Page']=c['url'] 177 178 # filter out empty fields 179 res=dict([(k,v) for k,v in res.items() if len(v)]) 180 yield res181183 "Get the list of categories" 184 # egroupware returns a dict with each key being an asciized integer 185 # id. The same field is present in the dict value, so we just return 186 # the values 187 return [v for k,v in self.sp.addressbook.boaddressbook.categories(True).items()]
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Sun Jan 24 16:24:14 2010 | http://epydoc.sourceforge.net |