File: pylons.controllers.xmlrpc.html

package info (click to toggle)
pylons 0.10-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 1,668 kB
  • ctags: 789
  • sloc: python: 4,677; makefile: 36
file content (325 lines) | stat: -rw-r--r-- 34,107 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
<html>
<head>
<title>pylons.controllers.xmlrpc</title>
</head>
<body>
pylons.controllers.xmlrpc
<style>
.coverage pre {float: left; margin: 0px 1em; border: none;
               padding: 0px; }
.num pre { margin: 0px }
.nocov, .nocov pre {background-color: #faa}
.cov, .cov pre {background-color: #cfc}
div.coverage div { clear: both; height: 1.1em}
</style>
<div class="stats">
Covered: 235 lines<br/>
Missed: 0 lines<br/>
Skipped 65 lines<br/>
Percent: 100 %<br/>

</div>
<div class="coverage">
<div class="cov"><span class="num"><pre>  1</pre></span><pre>&quot;&quot;&quot;The base WSGI XMLRPCController&quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre>  2</pre></span><pre>import inspect</pre></div>
<div class="cov"><span class="num"><pre>  3</pre></span><pre>import logging</pre></div>
<div class="cov"><span class="num"><pre>  4</pre></span><pre>import types</pre></div>
<div class="cov"><span class="num"><pre>  5</pre></span><pre>import xmlrpclib</pre></div>
<div class="skip"><span class="num"><pre>  6</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>  7</pre></span><pre>from paste.response import replace_header</pre></div>
<div class="skip"><span class="num"><pre>  8</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>  9</pre></span><pre>from pylons.controllers import WSGIController</pre></div>
<div class="cov"><span class="num"><pre> 10</pre></span><pre>from pylons.controllers.util import abort, Response</pre></div>
<div class="skip"><span class="num"><pre> 11</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre> 12</pre></span><pre>__all__ = ['XMLRPCController']</pre></div>
<div class="skip"><span class="num"><pre> 13</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre> 14</pre></span><pre>log = logging.getLogger(__name__)</pre></div>
<div class="skip"><span class="num"><pre> 15</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre> 16</pre></span><pre>XMLRPC_MAPPING = ((basestring, 'string'), (list, 'array'), (bool, 'boolean'),</pre></div>
<div class="cov"><span class="num"><pre> 17</pre></span><pre>                  (int, 'int'), (float, 'double'), (dict, 'struct'), </pre></div>
<div class="cov"><span class="num"><pre> 18</pre></span><pre>                  (xmlrpclib.DateTime, 'dateTime.iso8601'),</pre></div>
<div class="cov"><span class="num"><pre> 19</pre></span><pre>                  (xmlrpclib.Binary, 'base64'))</pre></div>
<div class="skip"><span class="num"><pre> 20</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre> 21</pre></span><pre>def xmlrpc_sig(args):</pre></div>
<div class="cov"><span class="num"><pre> 22</pre></span><pre>    &quot;&quot;&quot;Returns a list of the function signature in string format based on a </pre></div>
<div class="cov"><span class="num"><pre> 23</pre></span><pre>    tuple provided by xmlrpclib.&quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre> 24</pre></span><pre>    signature = []</pre></div>
<div class="cov"><span class="num"><pre> 25</pre></span><pre>    for param in args:</pre></div>
<div class="cov"><span class="num"><pre> 26</pre></span><pre>        for type, xml_name in XMLRPC_MAPPING:</pre></div>
<div class="cov"><span class="num"><pre> 27</pre></span><pre>            if isinstance(param, type):</pre></div>
<div class="cov"><span class="num"><pre> 28</pre></span><pre>                signature.append(xml_name)</pre></div>
<div class="cov"><span class="num"><pre> 29</pre></span><pre>                break</pre></div>
<div class="cov"><span class="num"><pre> 30</pre></span><pre>    return signature</pre></div>
<div class="skip"><span class="num"><pre> 31</pre></span><pre></pre></div>
<div class="skip"><span class="num"><pre> 32</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre> 33</pre></span><pre>def xmlrpc_fault(code, message):</pre></div>
<div class="cov"><span class="num"><pre> 34</pre></span><pre>    &quot;&quot;&quot;Convienence method to return a Pylons response XMLRPC Fault&quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre> 35</pre></span><pre>    fault = xmlrpclib.Fault(code, message)</pre></div>
<div class="cov"><span class="num"><pre> 36</pre></span><pre>    return Response(body=xmlrpclib.dumps(fault, methodresponse=True))</pre></div>
<div class="skip"><span class="num"><pre> 37</pre></span><pre></pre></div>
<div class="skip"><span class="num"><pre> 38</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre> 39</pre></span><pre>class XMLRPCController(WSGIController):</pre></div>
<div class="cov"><span class="num"><pre> 40</pre></span><pre>    &quot;&quot;&quot;XML-RPC Controller that speaks WSGI</pre></div>
<div class="skip"><span class="num"><pre> 41</pre></span><pre>    </pre></div>
<div class="cov"><span class="num"><pre> 42</pre></span><pre>    This controller handles XML-RPC responses and complies with the </pre></div>
<div class="cov"><span class="num"><pre> 43</pre></span><pre>    `XML-RPC Specification &lt;http://www.xmlrpc.com/spec&gt;`_ as well as</pre></div>
<div class="cov"><span class="num"><pre> 44</pre></span><pre>    the `XML-RPC Introspection</pre></div>
<div class="cov"><span class="num"><pre> 45</pre></span><pre>    &lt;http://scripts.incutio.com/xmlrpc/introspection.html&gt;`_ </pre></div>
<div class="cov"><span class="num"><pre> 46</pre></span><pre>    specification.</pre></div>
<div class="skip"><span class="num"><pre> 47</pre></span><pre>    </pre></div>
<div class="cov"><span class="num"><pre> 48</pre></span><pre>    By default, methods with names containing a dot are translated to</pre></div>
<div class="cov"><span class="num"><pre> 49</pre></span><pre>    use an underscore. For example, the `system.methodHelp` is handled</pre></div>
<div class="cov"><span class="num"><pre> 50</pre></span><pre>    by the method :meth:`system_methodHelp`.</pre></div>
<div class="skip"><span class="num"><pre> 51</pre></span><pre>    </pre></div>
<div class="cov"><span class="num"><pre> 52</pre></span><pre>    Methods in the XML-RPC controller will be called with the method</pre></div>
<div class="cov"><span class="num"><pre> 53</pre></span><pre>    given in the XMLRPC body. Methods may be annotated with a signature</pre></div>
<div class="cov"><span class="num"><pre> 54</pre></span><pre>    attribute to declare the valid arguments and return types.</pre></div>
<div class="skip"><span class="num"><pre> 55</pre></span><pre>    </pre></div>
<div class="cov"><span class="num"><pre> 56</pre></span><pre>    For example::</pre></div>
<div class="skip"><span class="num"><pre> 57</pre></span><pre>        </pre></div>
<div class="cov"><span class="num"><pre> 58</pre></span><pre>        class MyXML(XMLRPCController):</pre></div>
<div class="cov"><span class="num"><pre> 59</pre></span><pre>            def userstatus(self):</pre></div>
<div class="cov"><span class="num"><pre> 60</pre></span><pre>                return 'basic string'</pre></div>
<div class="cov"><span class="num"><pre> 61</pre></span><pre>            userstatus.signature = [ ['string'] ]</pre></div>
<div class="skip"><span class="num"><pre> 62</pre></span><pre>            </pre></div>
<div class="cov"><span class="num"><pre> 63</pre></span><pre>            def userinfo(self, username, age=None):</pre></div>
<div class="cov"><span class="num"><pre> 64</pre></span><pre>                user = LookUpUser(username)</pre></div>
<div class="cov"><span class="num"><pre> 65</pre></span><pre>                response = {'username':user.name}</pre></div>
<div class="cov"><span class="num"><pre> 66</pre></span><pre>                if age and age &gt; 10:</pre></div>
<div class="cov"><span class="num"><pre> 67</pre></span><pre>                    response['age'] = age</pre></div>
<div class="cov"><span class="num"><pre> 68</pre></span><pre>                return response</pre></div>
<div class="cov"><span class="num"><pre> 69</pre></span><pre>            userinfo.signature = [['struct', 'string'],</pre></div>
<div class="cov"><span class="num"><pre> 70</pre></span><pre>                                  ['struct', 'string', 'int']]</pre></div>
<div class="skip"><span class="num"><pre> 71</pre></span><pre>    </pre></div>
<div class="cov"><span class="num"><pre> 72</pre></span><pre>    Since XML-RPC methods can take different sets of data, each set of</pre></div>
<div class="cov"><span class="num"><pre> 73</pre></span><pre>    valid arguments is its own list. The first value in the list is the</pre></div>
<div class="cov"><span class="num"><pre> 74</pre></span><pre>    type of the return argument. The rest of the arguments are the</pre></div>
<div class="cov"><span class="num"><pre> 75</pre></span><pre>    types of the data that must be passed in.</pre></div>
<div class="skip"><span class="num"><pre> 76</pre></span><pre>    </pre></div>
<div class="cov"><span class="num"><pre> 77</pre></span><pre>    In the last method in the example above, since the method can</pre></div>
<div class="cov"><span class="num"><pre> 78</pre></span><pre>    optionally take an integer value both sets of valid parameter lists</pre></div>
<div class="cov"><span class="num"><pre> 79</pre></span><pre>    should be provided.</pre></div>
<div class="skip"><span class="num"><pre> 80</pre></span><pre>    </pre></div>
<div class="cov"><span class="num"><pre> 81</pre></span><pre>    Valid types that can be checked in the signature and their</pre></div>
<div class="cov"><span class="num"><pre> 82</pre></span><pre>    corresponding Python types::</pre></div>
<div class="skip"><span class="num"><pre> 83</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre> 84</pre></span><pre>        'string' - str</pre></div>
<div class="cov"><span class="num"><pre> 85</pre></span><pre>        'array' - list</pre></div>
<div class="cov"><span class="num"><pre> 86</pre></span><pre>        'boolean' - bool</pre></div>
<div class="cov"><span class="num"><pre> 87</pre></span><pre>        'int' - int</pre></div>
<div class="cov"><span class="num"><pre> 88</pre></span><pre>        'double' - float</pre></div>
<div class="cov"><span class="num"><pre> 89</pre></span><pre>        'struct' - dict</pre></div>
<div class="cov"><span class="num"><pre> 90</pre></span><pre>        'dateTime.iso8601' - xmlrpclib.DateTime</pre></div>
<div class="cov"><span class="num"><pre> 91</pre></span><pre>        'base64' - xmlrpclib.Binary</pre></div>
<div class="skip"><span class="num"><pre> 92</pre></span><pre>    </pre></div>
<div class="cov"><span class="num"><pre> 93</pre></span><pre>    The class variable ``allow_none`` is passed to xmlrpclib.dumps;</pre></div>
<div class="cov"><span class="num"><pre> 94</pre></span><pre>    enabling it allows translating ``None`` to XML (an extension to the</pre></div>
<div class="cov"><span class="num"><pre> 95</pre></span><pre>    XML-RPC specification)</pre></div>
<div class="skip"><span class="num"><pre> 96</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre> 97</pre></span><pre>    .. note::</pre></div>
<div class="skip"><span class="num"><pre> 98</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre> 99</pre></span><pre>        Requiring a signature is optional.</pre></div>
<div class="skip"><span class="num"><pre>100</pre></span><pre>    </pre></div>
<div class="cov"><span class="num"><pre>101</pre></span><pre>    &quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre>102</pre></span><pre>    allow_none = False</pre></div>
<div class="cov"><span class="num"><pre>103</pre></span><pre>    max_body_length = 4194304</pre></div>
<div class="skip"><span class="num"><pre>104</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>105</pre></span><pre>    def _get_method_args(self):</pre></div>
<div class="cov"><span class="num"><pre>106</pre></span><pre>        return self.rpc_kargs</pre></div>
<div class="skip"><span class="num"><pre>107</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>108</pre></span><pre>    def __call__(self, environ, start_response):</pre></div>
<div class="cov"><span class="num"><pre>109</pre></span><pre>        &quot;&quot;&quot;Parse an XMLRPC body for the method, and call it with the</pre></div>
<div class="cov"><span class="num"><pre>110</pre></span><pre>        appropriate arguments&quot;&quot;&quot;</pre></div>
<div class="skip"><span class="num"><pre>111</pre></span><pre>        # Pull out the length, return an error if there is no valid</pre></div>
<div class="skip"><span class="num"><pre>112</pre></span><pre>        # length or if the length is larger than the max_body_length.</pre></div>
<div class="cov"><span class="num"><pre>113</pre></span><pre>        log_debug = self._pylons_log_debug</pre></div>
<div class="cov"><span class="num"><pre>114</pre></span><pre>        length = environ.get('CONTENT_LENGTH')</pre></div>
<div class="cov"><span class="num"><pre>115</pre></span><pre>        if length:</pre></div>
<div class="cov"><span class="num"><pre>116</pre></span><pre>            length = int(length)</pre></div>
<div class="cov"><span class="num"><pre>117</pre></span><pre>        else:</pre></div>
<div class="skip"><span class="num"><pre>118</pre></span><pre>            # No valid Content-Length header found</pre></div>
<div class="cov"><span class="num"><pre>119</pre></span><pre>            if log_debug:</pre></div>
<div class="cov"><span class="num"><pre>120</pre></span><pre>                log.debug(&quot;No Content-Length found, returning 411 error&quot;)</pre></div>
<div class="cov"><span class="num"><pre>121</pre></span><pre>            abort(411)</pre></div>
<div class="cov"><span class="num"><pre>122</pre></span><pre>        if length &gt; self.max_body_length or length == 0:</pre></div>
<div class="cov"><span class="num"><pre>123</pre></span><pre>            if log_debug:</pre></div>
<div class="cov"><span class="num"><pre>124</pre></span><pre>                log.debug(&quot;Content-Length larger than max body length. Max: &quot;</pre></div>
<div class="cov"><span class="num"><pre>125</pre></span><pre>                          &quot;%s, Sent: %s. Returning 413 error&quot;,</pre></div>
<div class="cov"><span class="num"><pre>126</pre></span><pre>                          self.max_body_length, length)</pre></div>
<div class="cov"><span class="num"><pre>127</pre></span><pre>            abort(413, &quot;XML body too large&quot;)</pre></div>
<div class="skip"><span class="num"><pre>128</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>129</pre></span><pre>        body = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH']))</pre></div>
<div class="cov"><span class="num"><pre>130</pre></span><pre>        rpc_args, orig_method = xmlrpclib.loads(body)</pre></div>
<div class="skip"><span class="num"><pre>131</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>132</pre></span><pre>        method = self._find_method_name(orig_method)</pre></div>
<div class="cov"><span class="num"><pre>133</pre></span><pre>        func = self._find_method(method)</pre></div>
<div class="cov"><span class="num"><pre>134</pre></span><pre>        if not func:</pre></div>
<div class="cov"><span class="num"><pre>135</pre></span><pre>            if log_debug:</pre></div>
<div class="cov"><span class="num"><pre>136</pre></span><pre>                log.debug(&quot;Method: %r not found, returning xmlrpc fault&quot;,</pre></div>
<div class="cov"><span class="num"><pre>137</pre></span><pre>                          method)</pre></div>
<div class="cov"><span class="num"><pre>138</pre></span><pre>            return xmlrpc_fault(0, &quot;No such method name %r&quot; %</pre></div>
<div class="cov"><span class="num"><pre>139</pre></span><pre>                                method)(environ, start_response)</pre></div>
<div class="skip"><span class="num"><pre>140</pre></span><pre></pre></div>
<div class="skip"><span class="num"><pre>141</pre></span><pre>        # Signature checking for params</pre></div>
<div class="cov"><span class="num"><pre>142</pre></span><pre>        if hasattr(func, 'signature'):</pre></div>
<div class="cov"><span class="num"><pre>143</pre></span><pre>            if log_debug:</pre></div>
<div class="cov"><span class="num"><pre>144</pre></span><pre>                log.debug(&quot;Checking XMLRPC argument signature&quot;)</pre></div>
<div class="cov"><span class="num"><pre>145</pre></span><pre>            valid_args = False</pre></div>
<div class="cov"><span class="num"><pre>146</pre></span><pre>            params = xmlrpc_sig(rpc_args)</pre></div>
<div class="cov"><span class="num"><pre>147</pre></span><pre>            for sig in func.signature:</pre></div>
<div class="skip"><span class="num"><pre>148</pre></span><pre>                # Next sig if we don't have the same amount of args</pre></div>
<div class="cov"><span class="num"><pre>149</pre></span><pre>                if len(sig)-1 != len(rpc_args):</pre></div>
<div class="cov"><span class="num"><pre>150</pre></span><pre>                    continue</pre></div>
<div class="skip"><span class="num"><pre>151</pre></span><pre></pre></div>
<div class="skip"><span class="num"><pre>152</pre></span><pre>                # If the params match, we're valid</pre></div>
<div class="cov"><span class="num"><pre>153</pre></span><pre>                if params == sig[1:]:</pre></div>
<div class="cov"><span class="num"><pre>154</pre></span><pre>                    valid_args = True</pre></div>
<div class="cov"><span class="num"><pre>155</pre></span><pre>                    break</pre></div>
<div class="skip"><span class="num"><pre>156</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>157</pre></span><pre>            if not valid_args:</pre></div>
<div class="cov"><span class="num"><pre>158</pre></span><pre>                if log_debug:</pre></div>
<div class="cov"><span class="num"><pre>159</pre></span><pre>                    log.debug(&quot;Bad argument signature recieved, returning &quot;</pre></div>
<div class="cov"><span class="num"><pre>160</pre></span><pre>                              &quot;xmlrpc fault&quot;)</pre></div>
<div class="cov"><span class="num"><pre>161</pre></span><pre>                msg = (&quot;Incorrect argument signature. %r recieved does not &quot;</pre></div>
<div class="cov"><span class="num"><pre>162</pre></span><pre>                       &quot;match %r signature for method %r&quot; % \</pre></div>
<div class="cov"><span class="num"><pre>163</pre></span><pre>                           (params, func.signature, orig_method))</pre></div>
<div class="cov"><span class="num"><pre>164</pre></span><pre>                return xmlrpc_fault(0, msg)(environ, start_response)</pre></div>
<div class="skip"><span class="num"><pre>165</pre></span><pre></pre></div>
<div class="skip"><span class="num"><pre>166</pre></span><pre>        # Change the arg list into a keyword dict based off the arg</pre></div>
<div class="skip"><span class="num"><pre>167</pre></span><pre>        # names in the functions definition</pre></div>
<div class="cov"><span class="num"><pre>168</pre></span><pre>        arglist = inspect.getargspec(func)[0][1:]</pre></div>
<div class="cov"><span class="num"><pre>169</pre></span><pre>        kargs = dict(zip(arglist, rpc_args))</pre></div>
<div class="cov"><span class="num"><pre>170</pre></span><pre>        kargs['action'], kargs['environ'] = method, environ</pre></div>
<div class="cov"><span class="num"><pre>171</pre></span><pre>        kargs['start_response'] = start_response</pre></div>
<div class="cov"><span class="num"><pre>172</pre></span><pre>        self.rpc_kargs = kargs</pre></div>
<div class="cov"><span class="num"><pre>173</pre></span><pre>        self._func = func</pre></div>
<div class="skip"><span class="num"><pre>174</pre></span><pre>        </pre></div>
<div class="skip"><span class="num"><pre>175</pre></span><pre>        # Now that we know the method is valid, and the args are valid,</pre></div>
<div class="skip"><span class="num"><pre>176</pre></span><pre>        # we can dispatch control to the default WSGIController</pre></div>
<div class="cov"><span class="num"><pre>177</pre></span><pre>        status = []</pre></div>
<div class="cov"><span class="num"><pre>178</pre></span><pre>        headers = []</pre></div>
<div class="cov"><span class="num"><pre>179</pre></span><pre>        exc_info = []</pre></div>
<div class="cov"><span class="num"><pre>180</pre></span><pre>        def change_content(new_status, new_headers, new_exc_info=None):</pre></div>
<div class="cov"><span class="num"><pre>181</pre></span><pre>            status.append(new_status)</pre></div>
<div class="cov"><span class="num"><pre>182</pre></span><pre>            headers.extend(new_headers)</pre></div>
<div class="cov"><span class="num"><pre>183</pre></span><pre>            exc_info.append(new_exc_info)</pre></div>
<div class="cov"><span class="num"><pre>184</pre></span><pre>        output = WSGIController.__call__(self, environ, change_content)</pre></div>
<div class="cov"><span class="num"><pre>185</pre></span><pre>        output = list(output)</pre></div>
<div class="cov"><span class="num"><pre>186</pre></span><pre>        headers.append(('Content-Length', str(len(output[0]))))</pre></div>
<div class="cov"><span class="num"><pre>187</pre></span><pre>        replace_header(headers, 'Content-Type', 'text/xml')</pre></div>
<div class="cov"><span class="num"><pre>188</pre></span><pre>        start_response(status[0], headers, exc_info[0])</pre></div>
<div class="cov"><span class="num"><pre>189</pre></span><pre>        return output</pre></div>
<div class="skip"><span class="num"><pre>190</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>191</pre></span><pre>    def _dispatch_call(self):</pre></div>
<div class="cov"><span class="num"><pre>192</pre></span><pre>        &quot;&quot;&quot;Dispatch the call to the function chosen by __call__&quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre>193</pre></span><pre>        raw_response = self._inspect_call(self._func)</pre></div>
<div class="cov"><span class="num"><pre>194</pre></span><pre>        if not isinstance(raw_response, xmlrpclib.Fault):</pre></div>
<div class="cov"><span class="num"><pre>195</pre></span><pre>            raw_response = (raw_response,)</pre></div>
<div class="skip"><span class="num"><pre>196</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>197</pre></span><pre>        response = xmlrpclib.dumps(raw_response, methodresponse=True,</pre></div>
<div class="cov"><span class="num"><pre>198</pre></span><pre>                                   allow_none=self.allow_none)</pre></div>
<div class="cov"><span class="num"><pre>199</pre></span><pre>        return response</pre></div>
<div class="skip"><span class="num"><pre>200</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>201</pre></span><pre>    def _find_method(self, name):</pre></div>
<div class="cov"><span class="num"><pre>202</pre></span><pre>        &quot;&quot;&quot;Locate a method in the controller by the specified name and</pre></div>
<div class="cov"><span class="num"><pre>203</pre></span><pre>        return it&quot;&quot;&quot;</pre></div>
<div class="skip"><span class="num"><pre>204</pre></span><pre>        # Keep private methods private</pre></div>
<div class="cov"><span class="num"><pre>205</pre></span><pre>        if name.startswith('_'):</pre></div>
<div class="cov"><span class="num"><pre>206</pre></span><pre>            if self._pylons_log_debug:</pre></div>
<div class="cov"><span class="num"><pre>207</pre></span><pre>                log.debug(&quot;Action starts with _, private action not allowed&quot;)</pre></div>
<div class="cov"><span class="num"><pre>208</pre></span><pre>            return</pre></div>
<div class="skip"><span class="num"><pre>209</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>210</pre></span><pre>        if self._pylons_log_debug:</pre></div>
<div class="cov"><span class="num"><pre>211</pre></span><pre>            log.debug(&quot;Looking for XMLRPC method: %r&quot;, name)</pre></div>
<div class="cov"><span class="num"><pre>212</pre></span><pre>        try:</pre></div>
<div class="cov"><span class="num"><pre>213</pre></span><pre>            func = getattr(self, name, None)</pre></div>
<div class="cov"><span class="num"><pre>214</pre></span><pre>        except UnicodeEncodeError:</pre></div>
<div class="cov"><span class="num"><pre>215</pre></span><pre>            return</pre></div>
<div class="cov"><span class="num"><pre>216</pre></span><pre>        if isinstance(func, types.MethodType):</pre></div>
<div class="cov"><span class="num"><pre>217</pre></span><pre>            return func</pre></div>
<div class="skip"><span class="num"><pre>218</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>219</pre></span><pre>    def _find_method_name(self, name):</pre></div>
<div class="cov"><span class="num"><pre>220</pre></span><pre>        &quot;&quot;&quot;Locate a method in the controller by the appropriate name</pre></div>
<div class="skip"><span class="num"><pre>221</pre></span><pre>        </pre></div>
<div class="cov"><span class="num"><pre>222</pre></span><pre>        By default, this translates method names like </pre></div>
<div class="cov"><span class="num"><pre>223</pre></span><pre>        'system.methodHelp' into 'system_methodHelp'.</pre></div>
<div class="skip"><span class="num"><pre>224</pre></span><pre>        </pre></div>
<div class="cov"><span class="num"><pre>225</pre></span><pre>        &quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre>226</pre></span><pre>        return name.replace('.', '_')</pre></div>
<div class="skip"><span class="num"><pre>227</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>228</pre></span><pre>    def _publish_method_name(self, name):</pre></div>
<div class="cov"><span class="num"><pre>229</pre></span><pre>        &quot;&quot;&quot;Translate an internal method name to a publicly viewable one</pre></div>
<div class="skip"><span class="num"><pre>230</pre></span><pre>        </pre></div>
<div class="cov"><span class="num"><pre>231</pre></span><pre>        By default, this translates internal method names like</pre></div>
<div class="cov"><span class="num"><pre>232</pre></span><pre>        'blog_view' into 'blog.view'.</pre></div>
<div class="skip"><span class="num"><pre>233</pre></span><pre>        </pre></div>
<div class="cov"><span class="num"><pre>234</pre></span><pre>        &quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre>235</pre></span><pre>        return name.replace('_', '.')</pre></div>
<div class="skip"><span class="num"><pre>236</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>237</pre></span><pre>    def system_listMethods(self):</pre></div>
<div class="cov"><span class="num"><pre>238</pre></span><pre>        &quot;&quot;&quot;Returns a list of XML-RPC methods for this XML-RPC resource&quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre>239</pre></span><pre>        methods = []</pre></div>
<div class="cov"><span class="num"><pre>240</pre></span><pre>        for method in dir(self):</pre></div>
<div class="cov"><span class="num"><pre>241</pre></span><pre>            meth = getattr(self, method)</pre></div>
<div class="skip"><span class="num"><pre>242</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>243</pre></span><pre>            if not method.startswith('_') and isinstance(meth,</pre></div>
<div class="cov"><span class="num"><pre>244</pre></span><pre>                                                         types.MethodType):</pre></div>
<div class="cov"><span class="num"><pre>245</pre></span><pre>                methods.append(self._publish_method_name(method))</pre></div>
<div class="cov"><span class="num"><pre>246</pre></span><pre>        return methods</pre></div>
<div class="cov"><span class="num"><pre>247</pre></span><pre>    system_listMethods.signature = [['array']]</pre></div>
<div class="skip"><span class="num"><pre>248</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>249</pre></span><pre>    def system_methodSignature(self, name):</pre></div>
<div class="cov"><span class="num"><pre>250</pre></span><pre>        &quot;&quot;&quot;Returns an array of array's for the valid signatures for a</pre></div>
<div class="cov"><span class="num"><pre>251</pre></span><pre>        method.</pre></div>
<div class="skip"><span class="num"><pre>252</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>253</pre></span><pre>        The first value of each array is the return value of the</pre></div>
<div class="cov"><span class="num"><pre>254</pre></span><pre>        method. The result is an array to indicate multiple signatures</pre></div>
<div class="cov"><span class="num"><pre>255</pre></span><pre>        a method may be capable of.</pre></div>
<div class="skip"><span class="num"><pre>256</pre></span><pre>        </pre></div>
<div class="cov"><span class="num"><pre>257</pre></span><pre>        &quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre>258</pre></span><pre>        method = self._find_method(self._find_method_name(name))</pre></div>
<div class="cov"><span class="num"><pre>259</pre></span><pre>        if method:</pre></div>
<div class="cov"><span class="num"><pre>260</pre></span><pre>            return getattr(method, 'signature', '')</pre></div>
<div class="cov"><span class="num"><pre>261</pre></span><pre>        else:</pre></div>
<div class="cov"><span class="num"><pre>262</pre></span><pre>            return xmlrpclib.Fault(0, 'No such method name')</pre></div>
<div class="cov"><span class="num"><pre>263</pre></span><pre>    system_methodSignature.signature = [['array', 'string'],</pre></div>
<div class="cov"><span class="num"><pre>264</pre></span><pre>                                        ['string', 'string']]</pre></div>
<div class="skip"><span class="num"><pre>265</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>266</pre></span><pre>    def system_methodHelp(self, name):</pre></div>
<div class="cov"><span class="num"><pre>267</pre></span><pre>        &quot;&quot;&quot;Returns the documentation for a method&quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre>268</pre></span><pre>        method = self._find_method(self._find_method_name(name))</pre></div>
<div class="cov"><span class="num"><pre>269</pre></span><pre>        if method:</pre></div>
<div class="cov"><span class="num"><pre>270</pre></span><pre>            help = MethodHelp.getdoc(method)</pre></div>
<div class="cov"><span class="num"><pre>271</pre></span><pre>            sig = getattr(method, 'signature', None)</pre></div>
<div class="cov"><span class="num"><pre>272</pre></span><pre>            if sig:</pre></div>
<div class="cov"><span class="num"><pre>273</pre></span><pre>                help += &quot;\n\nMethod signature: %s&quot; % sig</pre></div>
<div class="cov"><span class="num"><pre>274</pre></span><pre>            return help</pre></div>
<div class="cov"><span class="num"><pre>275</pre></span><pre>        return xmlrpclib.Fault(0, &quot;No such method name&quot;)</pre></div>
<div class="cov"><span class="num"><pre>276</pre></span><pre>    system_methodHelp.signature = [['string', 'string']]</pre></div>
<div class="skip"><span class="num"><pre>277</pre></span><pre></pre></div>
<div class="skip"><span class="num"><pre>278</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>279</pre></span><pre>class MethodHelp(object):</pre></div>
<div class="cov"><span class="num"><pre>280</pre></span><pre>    &quot;&quot;&quot;Wrapper for formatting doc strings from XMLRPCController</pre></div>
<div class="cov"><span class="num"><pre>281</pre></span><pre>    methods&quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre>282</pre></span><pre>    def __init__(self, doc):</pre></div>
<div class="cov"><span class="num"><pre>283</pre></span><pre>        self.__doc__ = doc</pre></div>
<div class="skip"><span class="num"><pre>284</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>285</pre></span><pre>    def getdoc(method):</pre></div>
<div class="cov"><span class="num"><pre>286</pre></span><pre>        &quot;&quot;&quot;Return a formatted doc string, via inspect.getdoc, from the</pre></div>
<div class="cov"><span class="num"><pre>287</pre></span><pre>        specified XMLRPCController method</pre></div>
<div class="skip"><span class="num"><pre>288</pre></span><pre></pre></div>
<div class="cov"><span class="num"><pre>289</pre></span><pre>        The method's help attribute is used if it exists, otherwise the</pre></div>
<div class="cov"><span class="num"><pre>290</pre></span><pre>        method's doc string is used.</pre></div>
<div class="cov"><span class="num"><pre>291</pre></span><pre>        &quot;&quot;&quot;</pre></div>
<div class="cov"><span class="num"><pre>292</pre></span><pre>        help = getattr(method, 'help', None)</pre></div>
<div class="cov"><span class="num"><pre>293</pre></span><pre>        if help is None:</pre></div>
<div class="cov"><span class="num"><pre>294</pre></span><pre>            help = method.__doc__</pre></div>
<div class="cov"><span class="num"><pre>295</pre></span><pre>        doc = inspect.getdoc(MethodHelp(help))</pre></div>
<div class="cov"><span class="num"><pre>296</pre></span><pre>        if doc is None:</pre></div>
<div class="cov"><span class="num"><pre>297</pre></span><pre>            return ''</pre></div>
<div class="cov"><span class="num"><pre>298</pre></span><pre>        return doc</pre></div>
<div class="cov"><span class="num"><pre>299</pre></span><pre>    getdoc = staticmethod(getdoc)</pre></div>
<div class="skip"><span class="num"><pre>300</pre></span><pre></pre></div>
</div>
</body>
</html>