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', 'autoSubmitHTML']
9
10 import binascii
11 import sys
12 import urlparse
13
14 from urllib import urlencode
15
16 elementtree_modules = [
17 'lxml.etree',
18 'xml.etree.cElementTree',
19 'xml.etree.ElementTree',
20 'cElementTree',
21 'elementtree.ElementTree',
22 ]
23
25 return """
26 <html>
27 <head>
28 <title>%s</title>
29 </head>
30 <body onload="document.forms[0].submit();">
31 %s
32 <script>
33 var elements = document.forms[0].elements;
34 for (var i = 0; i < elements.length; i++) {
35 elements[i].style.display = "none";
36 }
37 </script>
38 </body>
39 </html>
40 """ % (title, form)
41
43 """Find a working ElementTree implementation, trying the standard
44 places that such a thing might show up.
45
46 >>> ElementTree = importElementTree()
47
48 @param module_names: The names of modules to try to use as
49 ElementTree. Defaults to C{L{elementtree_modules}}
50
51 @returns: An ElementTree module
52 """
53 if module_names is None:
54 module_names = elementtree_modules
55
56 for mod_name in module_names:
57 try:
58 ElementTree = __import__(mod_name, None, None, ['unused'])
59 except ImportError:
60 pass
61 else:
62
63 try:
64 ElementTree.XML('<unused/>')
65 except (SystemExit, MemoryError, AssertionError):
66 raise
67 except:
68 why = sys.exc_info()[1]
69 log('Not using ElementTree library %r because it failed to '
70 'parse a trivial document: %s' % (mod_name, why))
71 else:
72 return ElementTree
73 else:
74 raise ImportError('No ElementTree library found. '
75 'You may need to install one. '
76 'Tried importing %r' % (module_names,)
77 )
78
79 -def log(message, level=0):
80 """Handle a log message from the OpenID library.
81
82 This implementation writes the string it to C{sys.stderr},
83 followed by a newline.
84
85 Currently, the library does not use the second parameter to this
86 function, but that may change in the future.
87
88 To install your own logging hook::
89
90 from openid import oidutil
91
92 def myLoggingFunction(message, level):
93 ...
94
95 oidutil.log = myLoggingFunction
96
97 @param message: A string containing a debugging message from the
98 OpenID library
99 @type message: str
100
101 @param level: The severity of the log message. This parameter is
102 currently unused, but in the future, the library may indicate
103 more important information with a higher level value.
104 @type level: int or None
105
106 @returns: Nothing.
107 """
108
109 sys.stderr.write(message)
110 sys.stderr.write('\n')
111
113 """Append query arguments to a HTTP(s) URL. If the URL already has
114 query arguemtns, these arguments will be added, and the existing
115 arguments will be preserved. Duplicate arguments will not be
116 detected or collapsed (both will appear in the output).
117
118 @param url: The url to which the arguments will be appended
119 @type url: str
120
121 @param args: The query arguments to add to the URL. If a
122 dictionary is passed, the items will be sorted before
123 appending them to the URL. If a sequence of pairs is passed,
124 the order of the sequence will be preserved.
125 @type args: A dictionary from string to string, or a sequence of
126 pairs of strings.
127
128 @returns: The URL with the parameters added
129 @rtype: str
130 """
131 if hasattr(args, 'items'):
132 args = args.items()
133 args.sort()
134 else:
135 args = list(args)
136
137 if len(args) == 0:
138 return url
139
140 if '?' in url:
141 sep = '&'
142 else:
143 sep = '?'
144
145
146
147 i = 0
148 for k, v in args:
149 if type(k) is not str:
150 k = k.encode('UTF-8')
151
152 if type(v) is not str:
153 v = v.encode('UTF-8')
154
155 args[i] = (k, v)
156 i += 1
157
158 return '%s%s%s' % (url, sep, urlencode(args))
159
161 """Represent string s as base64, omitting newlines"""
162 return binascii.b2a_base64(s)[:-1]
163
165 try:
166 return binascii.a2b_base64(s)
167 except binascii.Error, why:
168
169 raise ValueError(why[0])
170
172 """This class implements an object that compares equal to others
173 of the same type that have the same name. These are distict from
174 str or unicode objects.
175 """
176
179
181 return type(self) is type(other) and self.name == other.name
182
184 return not (self == other)
185
187 return hash((self.__class__, self.name))
188
190 return '<Symbol %s>' % (self.name,)
191