Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Side by Side Diff: third_party/twisted_8_1/twisted/web/woven/input.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.web.test.test_woven -*-
2 #
3 # Copyright (c) 2001-2004 Twisted Matrix Laboratories.
4 # See LICENSE for details.
5
6
7 # dominput
8
9 import os
10 import inspect
11
12 from twisted.internet import defer
13 from twisted.python import log
14 from twisted.python.reflect import qual
15
16 from twisted.web import domhelpers
17 from twisted.web.woven import template, controller, utils
18
19 __version__ = "$Revision: 1.34 $"[11:-2]
20
21 controllerFactory = controller.controllerFactory
22
23
24 class InputHandler(controller.Controller):
25 """
26 An InputHandler is like a controller, but it operates on something
27 contained inside of C{self.model} instead of directly on C{self.model}.
28 For example, a Handler whose C{model} has been set to C{"foo"} will handle
29 C{self.model.foo}.
30
31 The handler's job is to interpret the request and:
32
33 1. Check for valid input
34 2. If the input is valid, update the model
35 3. Use any special API of the view widget to change the view (other
36 than what the view updates automatically from the model) e.g. in the
37 case of an error, tell the view to report an error to the user
38 4. Return a success value; by default these values are simply recorded
39 and the page is rendered, but these values could be used to determine
40 what page to display next, etc.
41 """
42 invalidErrorText = "Error!"
43 setupStacks = 0
44 def __init__(self, model=None,
45 parent=None,
46 name=None,
47 check=None,
48 commit = None,
49 invalidErrorText = None,
50 submodel=None,
51 controllerStack=None):
52 self.controllerStack = controllerStack
53 controller.Controller.__init__(self, model)
54 self._check = check
55 self._commit = commit
56 self._errback = None
57 self._parent = parent
58 if invalidErrorText is not None:
59 self.invalidErrorText = invalidErrorText
60 if submodel is not None:
61 self.submodel = submodel
62 if name is not None:
63 self.inputName = name
64
65 def initialize(self):
66 pass
67
68 def setNode(self, node):
69 self.node = node
70
71 def getInput(self, request):
72 """
73 Return the data associated with this handler from the request, if any.
74 """
75 name = getattr(self, 'inputName', self.submodel)
76 input = request.args.get(name, None)
77 if input:
78 return input
79
80 def handle(self, request):
81 self.initialize()
82 data = self.getInput(request)
83 success = self.check(request, data)
84 if isinstance(success, defer.Deferred):
85 success.addCallback(self.dispatchCheckResult, request, data)
86 success.addErrback(utils.renderFailure, request)
87 return success
88 self.dispatchCheckResult(success, request, data)
89
90 def dispatchCheckResult(self, success, request, data):
91 if success is not None:
92 if success:
93 result = self.handleValid(request, data)
94 else:
95 result = self.handleInvalid(request, data)
96 if isinstance(result, defer.Deferred):
97 return result
98
99 def check(self, request, data):
100 """
101 Check whether the input in the request is valid for this handler
102 and return a boolean indicating validity.
103 """
104 if self._check is None:
105 raise NotImplementedError(qual(self.__class__)+'.check')
106 # self._check is probably a bound method or simple function that
107 # doesn't have a reference to this InputHandler; pass it
108 return self._check(self, request, data)
109
110 def handleValid(self, request, data):
111 """
112 It has been determined that the input for this handler is valid;
113 however, that does not mean the entire form is valid.
114 """
115 self._parent.aggregateValid(request, self, data)
116
117 def aggregateValid(self, request, inputhandler, data):
118 """By default we just pass the method calls all the way up to the root
119 Controller. However, an intelligent InputHandler could override this
120 and implement a state machine that waits for all data to be collected
121 and then fires.
122 """
123 self._parent.aggregateValid(request, inputhandler, data)
124
125 def handleInvalid(self, request, data):
126 """
127 Once it has been determined that the input is invalid, we should
128 tell our view to report this fact to the user.
129 """
130 self._parent.aggregateInvalid(request, self, data)
131 self.view.setError(request, self.invalidErrorText)
132
133 def aggregateInvalid(self, request, inputhandler, data):
134 """By default we just pass this method call all the way up to the root
135 Controller.
136 """
137 self._parent.aggregateInvalid(request, inputhandler, data)
138
139 def commit(self, request, node, data):
140 """
141 It has been determined that the input for the entire form is completely
142 valid; it is now safe for all handlers to commit changes to the model.
143 """
144 if self._commit is None:
145 data = str(data)
146 if data != self.view.getData():
147 self.model.setData(data)
148 self.model.notify({'request': request, self.submodel: data})
149 else:
150 func = self._commit
151 if hasattr(func, 'im_func'):
152 func = func.im_func
153 args, varargs, varkw, defaults = inspect.getargspec(func)
154 if args[1] == 'request':
155 self._commit(request, data)
156 else:
157 self._commit(data)
158
159
160 class DefaultHandler(InputHandler):
161 def handle(self, request):
162 """
163 By default, we don't do anything
164 """
165 pass
166
167
168 class SingleValue(InputHandler):
169 def getInput(self, request):
170 name = getattr(self, 'inputName', self.submodel)
171 input = request.args.get(name, None)
172 if input:
173 return input[0]
174
175
176 class Anything(SingleValue):
177 """
178 Handle anything except for None
179 """
180 def check(self, request, data):
181 if data is not None:
182 return 1
183 return None
184
185
186 class Integer(SingleValue):
187 """
188 Only allow a single integer
189 """
190 def check(self, request, data):
191 if data is None: return None
192 try:
193 int(data)
194 return 1
195 except (TypeError, ValueError):
196 return 0
197
198 def handleInvalid(self, request, data):
199 self.invalidErrorText = "%s is not an integer. Please enter an integer." % data
200 SingleValue.handleInvalid(self, request, data)
201
202
203 class Float(SingleValue):
204 """
205 Only allow a single float
206 """
207 def check(self, request, data):
208 if data is None: return None
209 try:
210 float(data)
211 return 1
212 except (TypeError, ValueError):
213 return 0
214
215 def handleInvalid(self, request, data):
216 self.invalidErrorText = "%s is not an float. Please enter a float." % da ta
217 SingleValue.handleInvalid(self, request, data)
218
219
220 class List(InputHandler):
221 def check(self, request, data):
222 return None
223
224
225 class DictAggregator(Anything):
226 """An InputHandler for a <form> tag, for triggering a function
227 when all of the form's individual inputs have been validated.
228 Also for use gathering a dict of arguments to pass to a parent's
229 aggregateValid if no commit function is passed.
230
231 Usage example::
232 <form controller="theForm" action="">
233 <input controller="Integer"
234 view="InputText" model="anInteger" />
235 <input controller="Anything"
236 view="InputText" model="aString" />
237 <input type="submit" />
238 </form>
239
240 def theCommitFunction(anInteger=None, aString=None):
241 '''Note how the keyword arguments match up with the leaf model
242 names above
243 '''
244 print "Yay", anInteger, aString
245
246 class CMyController(controller.Controller):
247 def wcfactory_theForm(self, request, node, m):
248 return input.FormAggregator(m, commit=theCommitFunction)
249 """
250 def aggregateValid(self, request, inputhandler, data):
251 """Aggregate valid input from inputhandlers below us, into a dictionary.
252 """
253 self._valid[inputhandler] = data
254
255 def aggregateInvalid(self, request, inputhandler, data):
256 self._invalid[inputhandler] = data
257
258 def exit(self, request):
259 """This is the node complete message
260 """
261 if self._commit:
262 # Introspect the commit function to see what
263 # keyword arguments it takes
264 func = self._commit
265 if hasattr(func, 'im_func'):
266 func = func.im_func
267 args, varargs, varkw, defaults = inspect.getargspec(
268 func)
269 wantsRequest = len(args) > 1 and args[1] == 'request'
270
271 if self._invalid:
272 # whoops error!!!1
273 if self._errback:
274 self._errback(request, self._invalid)
275 elif self._valid:
276 # We've got all the input
277 # Gather it into a dict and call the commit function
278 results = {}
279 for item in self._valid:
280 results[item.model.name] = self._valid[item]
281 if self._commit:
282 if wantsRequest:
283 self._commit(request, **results)
284 else:
285 self._commit(**results)
286 else:
287 self._parent.aggregateValid(request, self, results)
288 return results
289
290
291 class ListAggregator(Anything):
292 def aggregateValid(self, request, inputhandler, data):
293 """Aggregate valid input from inputhandlers below us into a
294 list until we have all input from controllers below us to pass
295 to the commit function that was passed to the constructor or
296 our parent's aggregateValid.
297 """
298 if not hasattr(self, '_validList'):
299 self._validList = []
300 self._validList.append(data)
301
302 def aggregateInvalid(self, request, inputhandler, data):
303 if not hasattr(self, '_invalidList'):
304 self._invalidList = []
305 self._invalidList.append(data)
306
307 def exit(self, request):
308 if self._commit:
309 # Introspect the commit function to see what
310 #arguments it takes
311 func = self._commit
312 if hasattr(func, 'im_func'):
313 func = func.im_func
314 args, varargs, varkw, defaults = inspect.getargspec(func)
315 self.numArgs = len(args)
316 wantsRequest = args[1] == 'request'
317 if wantsRequest:
318 numArgs -= 1
319 else:
320 # Introspect the template to see if we still have
321 # controllers that will be giving us input
322
323 # aggregateValid is called before the view renders the node, so
324 # we can count the number of controllers below us the first time
325 # we are called
326 if not hasattr(self, 'numArgs'):
327 self.numArgs = len(domhelpers.findElementsWithAttributeShallow(
328 self.view.node, "controller"))
329
330 if self._invalidList:
331 self._parent.aggregateInvalid(request, self, self._invalidList)
332 else:
333 if self._commit:
334 if wantsRequest:
335 self._commit(request, *self._validList)
336 else:
337 self._commit(*self._validList)
338 self._parent.aggregateValid(request, self, self._invalidList)
339
340 def commit(self, request, node, data):
341 """If we're using the ListAggregator, we don't want the list of items
342 to be rerendered
343 xxx Need to have a "node complete" message sent to the controller
344 so we can reset state, so controllers can be re-run or ignore input the second time
345 """
346 pass
347
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/web/woven/guard.py ('k') | third_party/twisted_8_1/twisted/web/woven/interfaces.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698