Package caldavclientlibrary :: Package client :: Module principal
[hide private]
[frames] | no frames]

Source Code for Module caldavclientlibrary.client.principal

  1  ## 
  2  # Copyright (c) 2007-2016 Apple Inc. All rights reserved. 
  3  # 
  4  # Licensed under the Apache License, Version 2.0 (the "License"); 
  5  # you may not use this file except in compliance with the License. 
  6  # You may obtain a copy of the License at 
  7  # 
  8  # http://www.apache.org/licenses/LICENSE-2.0 
  9  # 
 10  # Unless required by applicable law or agreed to in writing, software 
 11  # distributed under the License is distributed on an "AS IS" BASIS, 
 12  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 13  # See the License for the specific language governing permissions and 
 14  # limitations under the License. 
 15  ## 
 16   
 17  from caldavclientlibrary.protocol.caldav.definitions import caldavxml 
 18  from caldavclientlibrary.client.calendar import Calendar 
 19  from caldavclientlibrary.protocol.url import URL 
 20  from caldavclientlibrary.protocol.webdav.definitions import davxml 
 21  from caldavclientlibrary.protocol.caldav.definitions import headers 
 22   
23 -class PrincipalCache(object):
24
25 - def __init__(self):
26 self.cache = {}
27
28 - def getPrincipal(self, session, path, refresh=False):
29 if path.toString() not in self.cache: 30 principal = CalDAVPrincipal(session, path) 31 principal.loadDetails() 32 self.cache[path.toString()] = principal 33 self.cache[principal.principalURL] = principal 34 if principal.alternateURIs is not None: 35 for uri in principal.alternateURIs: 36 self.cache[uri] = principal 37 elif refresh: 38 self.cache[path.toString()].loadDetails(refresh=True) 39 return self.cache[path.toString()]
40 41 principalCache = PrincipalCache() 42
43 -def make_tuple(item):
44 return item if isinstance(item, tuple) else (item,)
45
46 -class CalDAVPrincipal(object):
47
48 - def __init__(self, session, path):
49 50 self.session = session 51 self.principalPath = path 52 self._initFields()
53
54 - def __str__(self):
55 return """ 56 Principal Path : %s 57 Display Name : %s 58 Principal URL : %s 59 Alternate URLs : %s 60 Group Members : %s 61 Memberships : %s 62 Calendar Homes : %s 63 Outbox URL : %s 64 Inbox URL : %s 65 Calendar Addresses: %s 66 """ % ( 67 self.principalPath, 68 self.displayname, 69 self.principalURL, 70 self.alternateURIs, 71 self.memberset, 72 self.memberships, 73 self.homeset, 74 self.outboxURL, 75 self.inboxURL, 76 self.cuaddrs 77 )
78
79 - def _initFields(self):
80 self.loaded = False 81 self.valid = False 82 self.displayname = "Invalid Principal" 83 self.principalURL = "" 84 self.alternateURIs = () 85 self.memberset = () 86 self.memberships = () 87 self.homeset = () 88 self.outboxURL = "" 89 self.inboxURL = "" 90 self.cuaddrs = () 91 92 self.proxyFor = None 93 self.proxyreadURL = "" 94 self.proxywriteURL = ""
95
96 - def loadDetails(self, refresh=False):
97 if self.loaded and not refresh: 98 return 99 self._initFields() 100 101 results, _ignore_bad = self.session.getProperties( 102 self.principalPath, 103 ( 104 davxml.resourcetype, 105 davxml.displayname, 106 davxml.principal_URL, 107 davxml.alternate_URI_set, 108 davxml.group_member_set, 109 davxml.group_membership, 110 caldavxml.calendar_home_set, 111 caldavxml.schedule_outbox_URL, 112 caldavxml.schedule_inbox_URL, 113 caldavxml.calendar_user_address_set, 114 ), 115 ) 116 if results: 117 # First check that we have a valid principal and see if its a proxy principal too 118 type = results.get(davxml.resourcetype, None) 119 self.valid = type.find(str(davxml.principal)) is not None 120 if (self.session.hasDAVVersion(headers.calendar_proxy) and 121 (type.find(str(caldavxml.calendar_proxy_read)) is not None or 122 type.find(str(caldavxml.calendar_proxy_write)) is not None)): 123 parentPath = self.principalPath.dirname() 124 self.proxyFor = principalCache.getPrincipal(self.session, parentPath, refresh) 125 126 if self.valid: 127 self.displayname = results.get(davxml.displayname, None) 128 self.principalURL = results.get(davxml.principal_URL, None) 129 self.alternateURIs = make_tuple(results.get(davxml.alternate_URI_set, None)) 130 self.memberset = make_tuple(results.get(davxml.group_member_set, None)) 131 self.memberships = make_tuple(results.get(davxml.group_membership, None)) 132 self.homeset = make_tuple(results.get(caldavxml.calendar_home_set, None)) 133 self.outboxURL = results.get(caldavxml.schedule_outbox_URL, None) 134 self.inboxURL = results.get(caldavxml.schedule_inbox_URL, None) 135 self.cuaddrs = make_tuple(results.get(caldavxml.calendar_user_address_set, None)) 136 137 # Get proxy resource details if proxy support is available 138 if self.session.hasDAVVersion(headers.calendar_proxy) and not self.proxyFor: 139 results = self.session.getPropertiesOnHierarchy(self.principalPath, (davxml.resourcetype,)) 140 for path, items in results.iteritems(): 141 if davxml.resourcetype in items: 142 rtype = items[davxml.resourcetype] 143 if rtype.find(str(caldavxml.calendar_proxy_read)) is not None: 144 self.proxyreadURL = URL(url=path) 145 elif rtype.find(str(caldavxml.calendar_proxy_write)) is not None: 146 self.proxywriteURL = URL(url=path) 147 148 self.loaded = True
149
150 - def getSmartDisplayName(self):
151 if self.proxyFor: 152 return "%s#%s" % (self.proxyFor.displayname, self.displayname,) 153 else: 154 return self.displayname
155
156 - def listCalendars(self, root=None):
157 calendars = [] 158 home = self.homeset[0] 159 if not home.path.endswith("/"): 160 home.path += "/" 161 162 results = self.session.getPropertiesOnHierarchy(home, (davxml.resourcetype,)) 163 for path, items in results.iteritems(): 164 if davxml.resourcetype in items: 165 rtype = items[davxml.resourcetype] 166 if rtype.find(str(davxml.collection)) is not None and rtype.find(str(caldavxml.calendar)) is not None: 167 calendars.append(Calendar(path=path, session=self.session)) 168 return calendars
169
170 - def listFreeBusySet(self):
171 return self._getFreeBusySet()
172
173 - def addToFreeBusySet(self, calendars):
174 current = self._getFreeBusySet() 175 for calendar in calendars: 176 current.append(calendar) 177 self._setFreeBusySet(current)
178
179 - def removeFromFreeBusySet(self, calendars):
180 calendar_paths = [calendar.path for calendar in calendars] 181 current = self._getFreeBusySet() 182 current = [cal for cal in current if cal.path not in calendar_paths] 183 self._setFreeBusySet(current)
184
185 - def cleanFreeBusySet(self):
186 fbset = self.listFreeBusySet() 187 badfbset = [] 188 for calendar in fbset: 189 if not calendar.exists(): 190 badfbset.append(calendar) 191 192 if badfbset: 193 self.removeFromFreeBusySet(badfbset)
194
195 - def _getFreeBusySet(self):
198
199 - def _setFreeBusySet(self, calendars):
200 hrefs = [URL(url=calendar.path) for calendar in calendars] 201 self.session.setProperties(self.inboxURL, ((caldavxml.calendar_free_busy_set, hrefs),))
202
203 - def getReadProxies(self, refresh=True):
204 if not self.proxyreadURL: 205 return () 206 207 principal = principalCache.getPrincipal(self.session, self.proxyreadURL, refresh=refresh) 208 return [principalCache.getPrincipal(self.session, member) for member in principal.memberset]
209 210
211 - def setReadProxies(self, principals):
212 if not self.proxyreadURL: 213 return () 214 215 self.session.setProperties(self.proxyreadURL, ((davxml.group_member_set, principals),))
216
217 - def getWriteProxies(self, refresh=True):
218 if not self.proxywriteURL: 219 return () 220 221 principal = principalCache.getPrincipal(self.session, self.proxywriteURL, refresh=refresh) 222 return [principalCache.getPrincipal(self.session, member) for member in principal.memberset]
223
224 - def setWriteProxies(self, principals):
225 if not self.proxywriteURL: 226 return () 227 228 self.session.setProperties(self.proxywriteURL, ((davxml.group_member_set, principals),))
229