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

Side by Side Diff: third_party/twisted_8_1/twisted/web/woven/view.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 from __future__ import nested_scopes
8
9 __version__ = "$Revision: 1.91 $"[11:-2]
10
11 # Sibling imports
12 import interfaces
13 import utils
14 import controller
15 from utils import doSendPage
16 import model
17
18 # Twisted imports
19 from twisted.internet import defer
20 from twisted.python import components
21 from twisted.python import log
22 from twisted.web import resource, microdom, html, error
23 from twisted.web.server import NOT_DONE_YET
24 from zope.interface import implements
25
26 try:
27 import cPickle as pickle
28 except ImportError:
29 import pickle
30
31 import os
32 import sys
33 import stat
34 import warnings
35 import types
36
37
38 def peek(stack):
39 if stack is None:
40 return None
41 it = None
42 while it is None and stack is not None:
43 it, stack = stack
44 return it
45
46
47 def poke(stack, new):
48 it, stack = stack
49 return (new, stack)
50
51
52 def filterStack(stack):
53 returnVal = []
54 while stack is not None:
55 it, stack = stack
56 if it is not None:
57 returnVal.append(it)
58 return returnVal
59
60
61 def viewFactory(viewClass):
62 return lambda request, node, model: viewClass(model)
63
64 def viewMethod(viewClass):
65 return lambda self, request, node, model: viewClass(model)
66
67
68 templateCache = {}
69
70
71 class View:
72 implements(resource.IResource, interfaces.IView)
73 # wvfactory_xxx method signature: request, node, model; returns Widget
74 # wvupdate_xxx method signature: request, widget, data; mutates widget
75 # based on data (not necessarily an IModel;
76 # has been unwrapped at this point)
77
78 wantsAllNotifications = 0
79 templateFile = ''
80 templateDirectory = ''
81 template = ''
82
83 isLeaf = 1
84
85 def getChild(self, path, request):
86 return error.NoResource("No such child resource.")
87
88 def getChildWithDefault(self, path, request):
89 return self.getChild(path, request)
90
91 viewLibraries = []
92 setupStacks = 1
93 livePage = 0
94 doneCallback = None
95 templateNode = None
96 def __init__(self, m, templateFile=None, templateDirectory=None, template=No ne, controller=None, doneCallback=None, modelStack=None, viewStack=None, control lerStack=None):
97 """
98 A view must be told what its model is, and may be told what its
99 controller is, but can also look up its controller if none specified.
100 """
101 if not interfaces.IModel.providedBy(m):
102 m = model.adaptToIModel(m, None, None)
103 self.model = self.mainModel = m
104 # It's the responsibility of the calling code to make sure
105 # setController is called on this view before it's rendered.
106 self.controller = None
107 self.subviews = {}
108 if self.setupStacks:
109 self.modelStack = None
110 self.viewStack = None
111 self.controllerStack = None
112 if doneCallback is None and self.doneCallback is None:
113 self.doneCallback = doSendPage
114 else:
115 print "DoneCallback", doneCallback
116 self.doneCallback = doneCallback
117 if template is not None:
118 self.template = template
119 if templateFile is not None:
120 self.templateFile = templateFile
121 if templateDirectory is not None:
122 self.templateDirectory = templateDirectory
123
124 self.outstandingCallbacks = 0
125 self.outstandingNodes = []
126 self.failed = 0
127 self.setupMethods = []
128
129 def setupAllStacks(self):
130 self.modelStack = (self.model, None)
131 self.controllerStack = (self.controller, (input, None))
132 self.setupViewStack()
133
134 def setUp(self, request, d):
135 pass
136
137 def setupViewStack(self):
138 self.viewStack = None
139 if widgets not in self.viewLibraries:
140 self.viewLibraries.append(widgets)
141 for library in self.viewLibraries:
142 if not hasattr(library, 'getSubview'):
143 library.getSubview = utils.createGetFunction(library)
144 self.viewStack = (library, self.viewStack)
145 self.viewStack = (self, self.viewStack)
146
147 def importViewLibrary(self, namespace):
148 self.viewLibraries.append(namespace)
149 return self
150
151 def render(self, request, doneCallback=None):
152 if not getattr(request, 'currentId', 0):
153 request.currentId = 0
154 request.currentPage = self
155 if self.controller is None:
156 self.controller = controller.Controller(self.model)
157 if doneCallback is not None:
158 self.doneCallback = doneCallback
159 else:
160 self.doneCallback = doSendPage
161 self.setupAllStacks()
162 template = self.getTemplate(request)
163 if template:
164 self.d = microdom.parseString(template, caseInsensitive=0, preserveC ase=0)
165 else:
166 if not self.templateFile:
167 raise AttributeError, "%s does not define self.templateFile to o perate on" % self.__class__
168 self.d = self.lookupTemplate(request)
169 request.d = self.d
170 self.handleDocument(request, self.d)
171 return NOT_DONE_YET
172
173 def getTemplate(self, request):
174 """
175 Override this if you want to have your subclass look up its template
176 using a different method.
177 """
178 return self.template
179
180 def lookupTemplate(self, request):
181 """
182 Use acquisition to look up the template named by self.templateFile,
183 located anywhere above this object in the heirarchy, and use it
184 as the template. The first time the template is used it is cached
185 for speed.
186 """
187 if self.template:
188 return microdom.parseString(self.template, caseInsensitive=0, preser veCase=0)
189 if not self.templateDirectory:
190 mod = sys.modules[self.__module__]
191 if hasattr(mod, '__file__'):
192 self.templateDirectory = os.path.split(mod.__file__)[0]
193 # First see if templateDirectory + templateFile is a file
194 templatePath = os.path.join(self.templateDirectory, self.templateFile)
195 if not os.path.exists(templatePath):
196 raise RuntimeError, "The template %r was not found." % templatePath
197 # Check to see if there is an already parsed copy of it
198 mtime = os.path.getmtime(templatePath)
199 cachedTemplate = templateCache.get(templatePath, None)
200 compiledTemplate = None
201
202 if cachedTemplate is not None:
203 if cachedTemplate[0] == mtime:
204 compiledTemplate = templateCache[templatePath][1].cloneNode(deep =1)
205
206 if compiledTemplate is None:
207 compiledTemplate = microdom.parse(templatePath, caseInsensitive=0, p reserveCase=0)
208 templateCache[templatePath] = (mtime, compiledTemplate.cloneNode(dee p=1))
209 return compiledTemplate
210
211 def handleDocument(self, request, document):
212 """Handle the root node, and send the page if there are no
213 outstanding callbacks when it returns.
214 """
215 try:
216 request.d = document
217 self.setUp(request, document)
218 # Don't let outstandingCallbacks get to 0 until the
219 # entire tree has been recursed
220 # If you don't do this, and any callback has already
221 # completed by the time the dispatchResultCallback
222 # is added in dispachResult, then sendPage will be
223 # called prematurely within dispatchResultCallback
224 # resulting in much gnashing of teeth.
225 self.outstandingNodes = document.childNodes[:] + [1]
226 self.outstandingNodes.reverse()
227
228 self.outstandingCallbacks += 1
229 self.handleOutstanding(request)
230 self.outstandingCallbacks -= 1
231 if not self.outstandingCallbacks:
232 return self.sendPage(request)
233 except:
234 self.renderFailure(None, request)
235
236 def handleOutstanding(self, request):
237 while self.outstandingNodes:
238 node = self.outstandingNodes.pop()
239 if node is 1:
240 self.modelStack = self.modelStack[1]
241 self.viewStack = self.viewStack[1]
242 if self.controllerStack is not None:
243 controller, self.controllerStack = self.controllerStack
244 if controller is not None:
245 controller.exit(request)
246 attrs = getattr(node, 'attributes', None)
247 if (attrs is not None and
248 (attrs.get('model') or attrs.get('view') or attrs.get('controller')) ):
249 self.outstandingNodes.append(1)
250 self.handleNode(request, node)
251 else:
252 if attrs is not None and (attrs.get('view') or attrs.get('contro ller')):
253 self.outstandingNodes.append(node)
254 if hasattr(node, 'childNodes') and node.childNodes:
255 self.recurseChildren(request, node)
256
257 def recurseChildren(self, request, node):
258 """If this node has children, handle them.
259 """
260 new = node.childNodes[:]
261 new.reverse()
262 self.outstandingNodes.extend(new)
263
264 def dispatchResult(self, request, node, result):
265 """Check a given result from handling a node and look up a NodeMutator
266 adapter which will convert the result into a node and insert it
267 into the DOM tree. Return the new node.
268 """
269 if not isinstance(result, defer.Deferred):
270 if node.parentNode is not None:
271 node.parentNode.replaceChild(result, node)
272 else:
273 raise RuntimeError, "We're dying here, please report this immedi ately"
274 else:
275 self.outstandingCallbacks += 1
276 result.addCallback(self.dispatchResultCallback, request, node)
277 result.addErrback(self.renderFailure, request)
278 # Got to wait until the callback comes in
279 return result
280
281 def modelChanged(self, changed):
282 """Rerender this view, because our model has changed.
283 """
284 # arg. this needs to go away.
285 request = changed.get('request', None)
286 oldNode = self.node
287 #import pdb; pdb.set_trace()
288 newNode = self.generate(request, oldNode)
289 returnNode = self.dispatchResult(request, oldNode, newNode)
290 self.handleNewNode(request, returnNode)
291 self.handleOutstanding(request)
292 self.controller.domChanged(request, self, returnNode)
293
294 def generate(self, request, node):
295 """Allow a view to be used like a widget. Will look up the template
296 file and return it in place of the incoming node.
297 """
298 newNode = self.lookupTemplate(request).childNodes[0]
299 newNode.setAttribute('id', 'woven_id_%s' % id(self))
300 self.node = newNode
301 return newNode
302
303 def setController(self, controller):
304 self.controller = controller
305 self.controllerStack = (controller, self.controllerStack)
306
307 def setNode(self, node):
308 if self.templateNode == None:
309 self.templateNode = node
310 self.node = node
311
312 def setSubmodel(self, name):
313 self.submodel = name
314
315 def getNodeModel(self, request, node, submodel):
316 """
317 Get the model object associated with this node. If this node has a
318 model= attribute, call getSubmodel on the current model object.
319 If not, return the top of the model stack.
320 """
321 parent = None
322 if submodel:
323 if submodel == '.':
324 m = peek(self.modelStack)
325 else:
326 modelStack = self.modelStack
327 while modelStack is not None:
328 parent, modelStack = modelStack
329 if parent is None:
330 continue
331 m = parent.lookupSubmodel(request, submodel)
332 if m is not None:
333 #print "model", m
334 break
335 else:
336 raise Exception("Node had a model=%s "
337 "attribute, but the submodel was not "
338 "found in %s." % (submodel,
339 filterStack(self.modelStack)))
340 else:
341 m = None
342 self.modelStack = (m, self.modelStack)
343 if m is not None:
344 # print "M NAME", m.name
345 # if parent is not m:
346 # m.parent = parent
347 # if not getattr(m, 'name', None):
348 # m.name = submodel
349 return m
350 #print `submodel`, self.getTopOfModelStack()
351 if submodel:
352 return peek(self.modelStack)
353 return None
354
355 def getNodeController(self, request, node, submodel, model):
356 """
357 Get a controller object to handle this node. If the node has no
358 controller= attribute, first check to see if there is an IController
359 adapter for our model.
360 """
361 controllerName = node.attributes.get('controller')
362 controller = None
363
364 if model is None:
365 model = peek(self.modelStack)
366
367 # Look up a controller factory.
368 if controllerName:
369 #if not node.hasAttribute('name'):
370 # warnings.warn("POTENTIAL ERROR: %s had a controller, but not a "
371 # "'name' attribute." % node)
372 controllerStack = self.controllerStack
373 while controllerStack is not None:
374 namespace, controllerStack = controllerStack
375 if namespace is None:
376 continue
377 controller = namespace.getSubcontroller(request, node, model, co ntrollerName)
378 if controller is not None:
379 break
380 else:
381 raise NotImplementedError("You specified controller name %s on "
382 "a node, but no wcfactory_%s method "
383 "was found in %s." % (controllerName,
384 controllerName,
385 filterStack(self.controllerStack)
386 ))
387 elif node.attributes.get("model"):
388 # If no "controller" attribute was specified on the node, see if
389 # there is a IController adapter registerred for the model.
390 controller = interfaces.IController(
391 model,
392 None)
393
394 return controller
395
396
397 def getSubview(self, request, node, model, viewName):
398 """Get a sub-view from me.
399
400 @returns: L{widgets.Widget}
401 """
402 view = None
403 vm = getattr(self, 'wvfactory_' + viewName, None)
404 if vm is None:
405 vm = getattr(self, 'factory_' + viewName, None)
406 if vm is not None:
407 warnings.warn("factory_ methods are deprecated; please use "
408 "wvfactory_ instead", DeprecationWarning)
409 if vm:
410 if vm.func_code.co_argcount == 3 and not type(vm) == types.LambdaTyp e:
411 warnings.warn("wvfactory_ methods take (request, node, "
412 "model) instead of (request, node) now. \n"
413 "Please instantiate your widgets with a "
414 "reference to model instead of self.model",
415 DeprecationWarning)
416 self.model = model
417 view = vm(request, node)
418 self.model = self.mainModel
419 else:
420 view = vm(request, node, model)
421
422 setupMethod = getattr(self, 'wvupdate_' + viewName, None)
423 if setupMethod:
424 if view is None:
425 view = widgets.Widget(model)
426 view.setupMethods.append(setupMethod)
427 return view
428
429
430 def getNodeView(self, request, node, submodel, model):
431 view = None
432 viewName = node.attributes.get('view')
433
434 if model is None:
435 model = peek(self.modelStack)
436
437 # Look up a view factory.
438 if viewName:
439 viewStack = self.viewStack
440 while viewStack is not None:
441 namespace, viewStack = viewStack
442 if namespace is None:
443 continue
444 try:
445 view = namespace.getSubview(request, node, model, viewName)
446 except AttributeError:
447 # Was that from something in the viewStack that didn't
448 # have a getSubview?
449 if not hasattr(namespace, "getSubview"):
450 log.msg("Warning: There is no getSubview on %r" %
451 (namespace,))
452 continue
453 else:
454 # No, something else is really broken.
455 raise
456 if view is not None:
457 break
458 else:
459 raise NotImplementedError(
460 "You specified view name %s on a node %s, but no "
461 "wvfactory_%s method was found in %s. (Or maybe they were "
462 "found but they returned None.)" % (
463 viewName, node, viewName,
464 filterStack(self.viewStack)))
465 elif node.attributes.get("model"):
466 # If no "view" attribute was specified on the node, see if there
467 # is a IView adapter registerred for the model.
468 # First, see if the model is Componentized.
469 if isinstance(model, components.Componentized):
470 view = model.getAdapter(interfaces.IView)
471 if not view and hasattr(model, '__class__'):
472 view = interfaces.IView(model, None)
473
474 return view
475
476 def handleNode(self, request, node):
477 submodelName = node.attributes.get('model')
478 if submodelName is None:
479 submodelName = ""
480 model = self.getNodeModel(request, node, submodelName)
481 view = self.getNodeView(request, node, submodelName, model)
482 controller = self.getNodeController(request, node, submodelName, model)
483 if view or controller:
484 if model is None:
485 model = peek(self.modelStack)
486 if not view or not isinstance(view, View):
487 view = widgets.DefaultWidget(model)
488
489 if not controller:
490 controller = input.DefaultHandler(model)
491
492 prevView, stack = self.viewStack
493 while isinstance(prevView, widgets.DefaultWidget) and stack is not N one:
494 prevView, stack = stack
495 if prevView is None:
496 prevMod = None
497 else:
498 prevMod = prevView.model
499 if model is not prevMod and not isinstance(view, widgets.DefaultWidg et):
500 model.addView(view)
501 submodelList = [x.name for x in filterStack(self.modelStack) if x.na me]
502 submodelList.reverse()
503 submodelName = '/'.join(submodelList)
504 if not getattr(view, 'submodel', None):
505 view.submodel = submodelName
506
507 theId = node.attributes.get("id")
508 if self.livePage and not theId:
509 theId = "woven_id_%d" % id(view)
510 view.setupMethods.append(utils.createSetIdFunction(theId))
511 view.outgoingId = theId
512 #print "SET AN ID", theId
513 self.subviews[theId] = view
514 view.parent = peek(self.viewStack)
515 view.parent.subviews[theId] = view
516 # If a Widget was constructed directly with a model that so far
517 # is not in modelspace, we should put it on the stack so other
518 # Widgets below this one can find it.
519 if view.model is not peek(self.modelStack):
520 self.modelStack = poke(self.modelStack, view.model)
521
522 cParent = peek(self.controllerStack)
523 if controller._parent is None or cParent != controller:
524 controller._parent = cParent
525
526 self.controllerStack = (controller, self.controllerStack)
527 self.viewStack = (view, self.viewStack)
528
529 view.viewStack = self.viewStack
530 view.controllerStack = self.controllerStack
531 view.modelStack = self.modelStack
532
533 view.setController(controller)
534 view.setNode(node)
535
536 if not getattr(controller, 'submodel', None):
537 controller.setSubmodel(submodelName)
538
539 controller.setView(view)
540 controller.setNode(node)
541
542 controllerResult = controller.handle(request)
543 if controllerResult is not None:
544 ## It's a deferred
545 controller
546 self.outstandingCallbacks += 1
547 controllerResult.addCallback(
548 self.handleControllerResults,
549 request,
550 node,
551 controller,
552 view)
553 controllerResult.addErrback(self.renderFailure, request)
554 else:
555 viewResult = view.generate(request, node)
556 returnNode = self.dispatchResult(request, node, viewResult)
557 self.handleNewNode(request, returnNode)
558 else:
559 self.controllerStack = (controller, self.controllerStack)
560 self.viewStack = (view, self.viewStack)
561
562 def handleControllerResults(self,
563 controllerResult, request, node, controller, view):
564 """Handle a deferred from a controller.
565 """
566 self.outstandingCallbacks -= 1
567 if isinstance(controllerResult, defer.Deferred):
568 self.outstandingCallbacks += 1
569 controllerResult.addCallback(
570 self.handleControllerResults,
571 request,
572 node,
573 controller,
574 view)
575 controllerResult.addErrback(self.renderFailure, request)
576 else:
577 viewResult = view.generate(request, node)
578 returnNode = self.dispatchResult(request, node, viewResult)
579 self.handleNewNode(request, returnNode)
580 return controllerResult
581
582 def handleNewNode(self, request, returnNode):
583 if not isinstance(returnNode, defer.Deferred):
584 self.recurseChildren(request, returnNode)
585 else:
586 # TODO: Need to handle deferreds here?
587 pass
588
589 def sendPage(self, request):
590 """
591 Check to see if handlers recorded any errors before sending the page
592 """
593 self.doneCallback(self, self.d, request)
594
595 def setSubviewFactory(self, name, factory, setup=None, *args, **kwargs):
596 setattr(self, "wvfactory_" + name, lambda request, node, m:
597 factory(m, *args, **kwargs))
598 if setup:
599 setattr(self, "wvupdate_" + name, setup)
600
601 def __setitem__(self, key, value):
602 pass
603
604 def unlinkViews(self):
605 #print "unlinking views"
606 self.model.removeView(self)
607 for key, value in self.subviews.items():
608 value.unlinkViews()
609 # value.model.removeView(value)
610
611 def dispatchResultCallback(self, result, request, node):
612 """Deal with a callback from a deferred, checking to see if it is
613 ok to send the page yet or not.
614 """
615 self.outstandingCallbacks -= 1
616 #node = self.dispatchResult(request, node, result)
617 #self.recurseChildren(request, node)
618 if not self.outstandingCallbacks:
619 self.sendPage(request)
620 return result
621
622 def renderFailure(self, failure, request):
623 try:
624 xml = request.d.toprettyxml()
625 except:
626 xml = ""
627 # if not hasattr(request, 'channel'):
628 # log.msg("The request got away from me before I could render an err or page.")
629 # log.err(failure)
630 # return failure
631 if not self.failed:
632 self.failed = 1
633 if failure:
634 request.write("<html><head><title>%s: %s</title></head><body>\n" % (html.escape(str(failure.type)), html.escape(str(failure.value))))
635 else:
636 request.write("<html><head><title>Failure!</title></head><body>\ n")
637 utils.renderFailure(failure, request)
638 request.write("<h3>Here is the partially processed DOM:</h3>")
639 request.write("\n<pre>\n")
640 request.write(html.escape(xml))
641 request.write("\n</pre>\n")
642 request.write("</body></html>")
643 request.finish()
644 return failure
645
646 class LiveView(View):
647 livePage = 1
648 def wvfactory_webConduitGlue(self, request, node, m):
649 if request.getHeader("user-agent").count("MSIE"):
650 return View(m, templateFile="FlashConduitGlue.html")
651 else:
652 return View(m, templateFile="WebConduitGlue.html")
653
654 def wvupdate_woven_flashConduitSessionView(self, request, wid, mod):
655 #print "updating flash thingie"
656 uid = request.getSession().uid
657 n = wid.templateNode
658 if n.attributes.has_key('src'):
659 n.attributes['src'] = n.attributes.get('src') + '?twisted_session=' + str(uid)
660 else:
661 n.attributes['value'] = n.attributes.get('value') + '?twisted_sessio n=' + str(uid)
662 #print wid.templateNode.toxml()
663
664
665 #backwards compatibility
666 WView = View
667
668
669 def registerViewForModel(view, model):
670 """
671 Registers `view' as an adapter of `model' for L{interfaces.IView}.
672 """
673 components.registerAdapter(view, model, interfaces.IView)
674 # adapter = resource.IResource(model, None)
675 # if adapter is None and resource.IResource.providedBy(view):
676 # components.registerAdapter(view, model, resource.IResource)
677
678
679
680 #sibling imports::
681
682 # If no widget/handler was found in the container controller or view, these
683 # modules will be searched.
684
685 import input
686 import widgets
687
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/web/woven/utils.py ('k') | third_party/twisted_8_1/twisted/web/woven/widgets.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698