~landscape/zope3/newer-from-ztk

« back to all changes in this revision

Viewing changes to src/twisted/web/woven/view.py

  • Committer: Thomas Hervé
  • Date: 2009-07-08 13:52:04 UTC
  • Revision ID: thomas@canonical.com-20090708135204-df5eesrthifpylf8
Remove twisted copy

Show diffs side-by-side

added added

removed removed

Lines of Context:
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=None, controller=None, doneCallback=None, modelStack=None, viewStack=None, controllerStack=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, preserveCase=0)
165
 
        else:
166
 
            if not self.templateFile:
167
 
                raise AttributeError, "%s does not define self.templateFile to operate 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, preserveCase=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, preserveCase=0)
208
 
            templateCache[templatePath] = (mtime, compiledTemplate.cloneNode(deep=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('controller')):
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 immediately"
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, controllerName)
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.LambdaType:
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 None:
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.DefaultWidget):
500
 
                model.addView(view)
501
 
            submodelList = [x.name for x in filterStack(self.modelStack) if x.name]
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 error 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_session=' + 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