Package yadis :: Module manager
[hide private]
[frames] | no frames]

Source Code for Module yadis.manager

1 -class YadisServiceManager(object):
2 """Holds the state of a list of selected Yadis services, managing 3 storing it in a session and iterating over the services in order.""" 4
5 - def __init__(self, starting_url, yadis_url, services, session_key):
6 # The URL that was used to initiate the Yadis protocol 7 self.starting_url = starting_url 8 9 # The URL after following redirects (the identifier) 10 self.yadis_url = yadis_url 11 12 # List of service elements 13 self.services = list(services) 14 15 self.session_key = session_key 16 17 # Reference to the current service object 18 self._current = None
19
20 - def __len__(self):
21 """How many untried services remain?""" 22 return len(self.services)
23
24 - def __iter__(self):
25 return self
26
27 - def next(self):
28 """Return the next service 29 30 self.current() will continue to return that service until the 31 next call to this method.""" 32 try: 33 self._current = self.services.pop(0) 34 except IndexError: 35 raise StopIteration 36 else: 37 return self._current
38
39 - def current(self):
40 """Return the current service. 41 42 Returns None if there are no services left. 43 """ 44 return self._current
45
46 - def forURL(self, url):
47 return url in [self.starting_url, self.yadis_url]
48
49 - def started(self):
50 """Has the first service been returned?""" 51 return self._current is not None
52
53 - def store(self, session):
54 """Store this object in the session, by its session key.""" 55 session[self.session_key] = self
56
57 -class Discovery(object):
58 """State management for discovery. 59 60 High-level usage pattern is to call .getNextService(discover) in 61 order to find the next available service for this user for this 62 session. Once a request completes, call .finish() to clean up the 63 session state. 64 65 @ivar session: a dict-like object that stores state unique to the 66 requesting user-agent. This object must be able to store 67 serializable objects. 68 69 @ivar url: the URL that is used to make the discovery request 70 71 @ivar session_key_suffix: The suffix that will be used to identify 72 this object in the session object. 73 """ 74 75 DEFAULT_SUFFIX = 'auth' 76 PREFIX = '_yadis_services_' 77
78 - def __init__(self, session, url, session_key_suffix=None):
79 """Initialize a discovery object""" 80 self.session = session 81 self.url = url 82 if session_key_suffix is None: 83 session_key_suffix = self.DEFAULT_SUFFIX 84 85 self.session_key_suffix = session_key_suffix
86
87 - def getNextService(self, discover):
88 """Return the next authentication service for the pair of 89 user_input and session. This function handles fallback. 90 91 92 @param discover: a callable that takes a URL and returns a 93 list of services 94 95 @type discover: str -> [service] 96 97 98 @return: the next available service 99 """ 100 manager = self.getManager() 101 if manager is not None and not manager: 102 self.destroyManager() 103 104 if not manager: 105 yadis_url, services = discover(self.url) 106 manager = self.createManager(services, yadis_url) 107 108 if manager: 109 service = manager.next() 110 manager.store(self.session) 111 else: 112 service = None 113 114 return service
115
116 - def cleanup(self):
117 """Clean up Yadis-related services in the session and return 118 the most-recently-attempted service from the manager, if one 119 exists. 120 121 @return: current service endpoint object or None if there is 122 no current service 123 """ 124 manager = self.getManager() 125 if manager is not None: 126 service = manager.current() 127 self.destroyManager() 128 else: 129 service = None 130 131 return service
132 133 ### Lower-level methods 134
135 - def getSessionKey(self):
136 """Get the session key for this starting URL and suffix 137 138 @return: The session key 139 @rtype: str 140 """ 141 return self.PREFIX + self.session_key_suffix
142
143 - def getManager(self):
144 """Extract the YadisServiceManager for this object's URL and 145 suffix from the session. 146 147 @return: The current YadisServiceManager, if it's for this 148 URL, or else None 149 """ 150 manager = self.session.get(self.getSessionKey()) 151 if (manager is not None and manager.forURL(self.url)): 152 return manager 153 else: 154 return None
155
156 - def createManager(self, services, yadis_url=None):
157 """Create a new YadisService Manager for this starting URL and 158 suffix, and store it in the session. 159 160 @raises KeyError: When I already have a manager. 161 162 @return: A new YadisServiceManager or None 163 """ 164 key = self.getSessionKey() 165 if self.getManager(): 166 raise KeyError('There is already a %r manager for %r' % 167 (key, self.url)) 168 169 if not services: 170 return None 171 172 manager = YadisServiceManager(self.url, yadis_url, services, key) 173 manager.store(self.session) 174 return manager
175
176 - def destroyManager(self):
177 """Delete any YadisServiceManager with this starting URL and 178 suffix from the session. 179 180 If there is no service manager or the service manager is for a 181 different URL, it silently does nothing. 182 """ 183 if self.getManager() is not None: 184 key = self.getSessionKey() 185 del self.session[key]
186