1 """This module contains functions and classes used for extracting
2 endpoint information out of a Yadis XRD file using the ElementTree XML
3 parser.
4 """
5
6 __all__ = [
7 'BasicServiceEndpoint',
8 'mkFilter',
9 'IFilter',
10 'TransformFilterMaker',
11 'CompoundFilter',
12 ]
13
14 from openid.yadis.etxrd import expandService
15
17 """Generic endpoint object that contains parsed service
18 information, as well as a reference to the service element from
19 which it was generated. If there is more than one xrd:Type or
20 xrd:URI in the xrd:Service, this object represents just one of
21 those pairs.
22
23 This object can be used as a filter, because it implements
24 fromBasicServiceEndpoint.
25
26 The simplest kind of filter you can write implements
27 fromBasicServiceEndpoint, which takes one of these objects.
28 """
29 - def __init__(self, yadis_url, type_uris, uri, service_element):
30 self.type_uris = type_uris
31 self.yadis_url = yadis_url
32 self.uri = uri
33 self.service_element = service_element
34
36 """Query this endpoint to see if it has any of the given type
37 URIs. This is useful for implementing other endpoint classes
38 that e.g. need to check for the presence of multiple versions
39 of a single protocol.
40
41 @param type_uris: The URIs that you wish to check
42 @type type_uris: iterable of str
43
44 @return: all types that are in both in type_uris and
45 self.type_uris
46 """
47 return [uri for uri in type_uris if uri in self.type_uris]
48
50 """Trivial transform from a basic endpoint to itself. This
51 method exists to allow BasicServiceEndpoint to be used as a
52 filter.
53
54 If you are subclassing this object, re-implement this function.
55
56 @param endpoint: An instance of BasicServiceEndpoint
57 @return: The object that was passed in, with no processing.
58 """
59 return endpoint
60
61 fromBasicServiceEndpoint = staticmethod(fromBasicServiceEndpoint)
62
64 """Interface for Yadis filter objects. Other filter-like things
65 are convertable to this class."""
66
68 """Returns an iterator of endpoint objects"""
69 raise NotImplementedError
70
125
127 """Create a new filter that applies a set of filters to an endpoint
128 and collects their results.
129 """
131 self.subfilters = subfilters
132
134 """Generate all endpoint objects for all of the subfilters of
135 this filter and return their concatenation."""
136 endpoints = []
137 for subfilter in self.subfilters:
138 endpoints.extend(
139 subfilter.getServiceEndpoints(yadis_url, service_element))
140 return endpoints
141
142
143 filter_type_error = TypeError(
144 'Expected a filter, an endpoint, a callable or a list of any of these.')
145
147 """Convert a filter-convertable thing into a filter
148
149 @param parts: a filter, an endpoint, a callable, or a list of any of these.
150 """
151
152 if parts is None:
153 parts = [BasicServiceEndpoint]
154
155 try:
156 parts = list(parts)
157 except TypeError:
158 return mkCompoundFilter([parts])
159 else:
160 return mkCompoundFilter(parts)
161
163 """Create a filter out of a list of filter-like things
164
165 Used by mkFilter
166
167 @param parts: list of filter, endpoint, callable or list of any of these
168 """
169
170 transformers = []
171 filters = []
172 for subfilter in parts:
173 try:
174 subfilter = list(subfilter)
175 except TypeError:
176
177 if hasattr(subfilter, 'getServiceEndpoints'):
178
179 filters.append(subfilter)
180 elif hasattr(subfilter, 'fromBasicServiceEndpoint'):
181
182
183
184 transformers.append(subfilter.fromBasicServiceEndpoint)
185 elif callable(subfilter):
186
187
188 transformers.append(subfilter)
189 else:
190 raise filter_type_error
191 else:
192 filters.append(mkCompoundFilter(subfilter))
193
194 if transformers:
195 filters.append(TransformFilterMaker(transformers))
196
197 if len(filters) == 1:
198 return filters[0]
199 else:
200 return CompoundFilter(filters)
201