1
2 """XRI resolution.
3 """
4
5 from urllib import urlencode
6 from openid import fetchers
7 from openid.yadis import etxrd
8 from openid.yadis.xri import toURINormal
9 from openid.yadis.services import iterServices
10
11 DEFAULT_PROXY = 'http://proxy.xri.net/'
12
14 """Python interface to a remote XRI proxy resolver.
15 """
17 self.proxy_url = proxy_url
18
19
20 - def queryURL(self, xri, service_type=None):
21 """Build a URL to query the proxy resolver.
22
23 @param xri: An XRI to resolve.
24 @type xri: unicode
25
26 @param service_type: The service type to resolve, if you desire
27 service endpoint selection. A service type is a URI.
28 @type service_type: str
29
30 @returns: a URL
31 @returntype: str
32 """
33
34
35
36 qxri = toURINormal(xri)[6:]
37 hxri = self.proxy_url + qxri
38 args = {
39
40
41
42
43 '_xrd_r': 'application/xrds+xml',
44 }
45 if service_type:
46 args['_xrd_t'] = service_type
47 else:
48
49 args['_xrd_r'] += ';sep=false'
50 query = _appendArgs(hxri, args)
51 return query
52
53
54 - def query(self, xri, service_types):
55 """Resolve some services for an XRI.
56
57 Note: I don't implement any service endpoint selection beyond what
58 the resolver I'm querying does, so the Services I return may well
59 include Services that were not of the types you asked for.
60
61 May raise fetchers.HTTPFetchingError or L{etxrd.XRDSError} if
62 the fetching or parsing don't go so well.
63
64 @param xri: An XRI to resolve.
65 @type xri: unicode
66
67 @param service_types: A list of services types to query for. Service
68 types are URIs.
69 @type service_types: list of str
70
71 @returns: tuple of (CanonicalID, Service elements)
72 @returntype: (unicode, list of C{ElementTree.Element}s)
73 """
74
75 services = []
76
77
78
79
80 canonicalID = None
81
82 for service_type in service_types:
83 url = self.queryURL(xri, service_type)
84 response = fetchers.fetch(url)
85 if response.status not in (200, 206):
86
87
88 continue
89 et = etxrd.parseXRDS(response.body)
90 canonicalID = etxrd.getCanonicalID(xri, et)
91 some_services = list(iterServices(et))
92 services.extend(some_services)
93
94
95
96
97 return canonicalID, services
98
99
101 """Append some arguments to an HTTP query.
102 """
103
104 if hasattr(args, 'items'):
105 args = args.items()
106 args.sort()
107
108 if len(args) == 0:
109 return url
110
111
112
113
114
115
116
117
118 if '?' in url.rstrip('?'):
119 sep = '&'
120 else:
121 sep = '?'
122
123 return '%s%s%s' % (url, sep, urlencode(args))
124