1 """This module contains general utility code that is used throughout
2 the library.
3
4 For users of this library, the C{L{log}} function is probably the most
5 interesting.
6 """
7
8 __all__ = ['log', 'appendArgs', 'toBase64', 'fromBase64']
9
10 import binascii
11 import sys
12 import urlparse
13
14 from urllib import urlencode
15
16 elementtree_modules = [
17 'xml.etree.cElementTree',
18 'xml.etree.ElementTree',
19 'cElementTree',
20 'elementtree.ElementTree',
21 ]
22
24 for mod_name in elementtree_modules:
25 try:
26 return __import__(mod_name, None, None, ['unused'])
27 except ImportError:
28 pass
29 else:
30 raise
31
32 -def log(message, level=0):
33 """Handle a log message from the OpenID library.
34
35 This implementation writes the string it to C{sys.stderr},
36 followed by a newline.
37
38 Currently, the library does not use the second parameter to this
39 function, but that may change in the future.
40
41 To install your own logging hook::
42
43 from openid import oidutil
44
45 def myLoggingFunction(message, level):
46 ...
47
48 oidutil.log = myLoggingFunction
49
50 @param message: A string containing a debugging message from the
51 OpenID library
52 @type message: str
53
54 @param level: The severity of the log message. This parameter is
55 currently unused, but in the future, the library may indicate
56 more important information with a higher level value.
57 @type level: int or None
58
59 @returns: Nothing.
60 """
61
62 sys.stderr.write(message)
63 sys.stderr.write('\n')
64
66 """Append query arguments to a HTTP(s) URL. If the URL already has
67 query arguemtns, these arguments will be added, and the existing
68 arguments will be preserved. Duplicate arguments will not be
69 detected or collapsed (both will appear in the output).
70
71 @param url: The url to which the arguments will be appended
72 @type url: str
73
74 @param args: The query arguments to add to the URL. If a
75 dictionary is passed, the items will be sorted before
76 appending them to the URL. If a sequence of pairs is passed,
77 the order of the sequence will be preserved.
78 @type args: A dictionary from string to string, or a sequence of
79 pairs of strings.
80
81 @returns: The URL with the parameters added
82 @rtype: str
83 """
84 if hasattr(args, 'items'):
85 args = args.items()
86 args.sort()
87 else:
88 args = list(args)
89
90 if len(args) == 0:
91 return url
92
93 if '?' in url:
94 sep = '&'
95 else:
96 sep = '?'
97
98
99
100 i = 0
101 for k, v in args:
102 if type(k) is not str:
103 k = k.encode('UTF-8')
104
105 if type(v) is not str:
106 v = v.encode('UTF-8')
107
108 args[i] = (k, v)
109 i += 1
110
111 return '%s%s%s' % (url, sep, urlencode(args))
112
114 """Represent string s as base64, omitting newlines"""
115 return binascii.b2a_base64(s)[:-1]
116
118 try:
119 return binascii.a2b_base64(s)
120 except binascii.Error, why:
121
122 raise ValueError(why[0])
123
125 """Does this URL look like a http or https URL that has a host?
126
127 @param url: The url to check
128 @type url: str
129
130 @return: Whether the URL looks OK
131 @rtype: bool
132 """
133 parts = urlparse.urlparse(url)
134 return parts[0] in ['http', 'https'] and parts[1]
135
137 """This class implements an object that compares equal to others
138 of the same type that have the same name. These are distict from
139 str or unicode objects.
140 """
141
143 self.name = name
144
146 return type(self) is type(other) and self.name == other.name
147
149 return not (self == other)
150
152 return hash((self.__class__, self.name))
153
155 return '<Symbol %s>' % (self.name,)
156