| Index: third_party/twisted_8_1/twisted/web/woven/template.py
|
| diff --git a/third_party/twisted_8_1/twisted/web/woven/template.py b/third_party/twisted_8_1/twisted/web/woven/template.py
|
| deleted file mode 100644
|
| index a25ab435824eed0c3923b686c03b5d6246fcc9c8..0000000000000000000000000000000000000000
|
| --- a/third_party/twisted_8_1/twisted/web/woven/template.py
|
| +++ /dev/null
|
| @@ -1,374 +0,0 @@
|
| -# -*- test-case-name: twisted.web.test.test_woven -*-
|
| -#
|
| -# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
|
| -# See LICENSE for details.
|
| -
|
| -
|
| -"""
|
| -DOMTemplate
|
| -
|
| -Most templating systems provide commands that you embed
|
| -in the HTML to repeat elements, include fragments from other
|
| -files, etc. This works fairly well for simple constructs and people
|
| -tend to get a false sense of simplicity from this. However, in my
|
| -experience, as soon as the programmer wants to make the logic
|
| -even slightly more complicated, the templating system must be
|
| -bent and abused in ways it was never meant to be used.
|
| -
|
| -The theory behind DOMTemplate is that Python code instead
|
| -of template syntax in the HTML should be used to manipulate
|
| -the structure of the HTML. DOMTemplate uses the DOM, a w3c
|
| -standard tree-based representation of an HTML document that
|
| -provides an API that allows you to traverse nodes in the tree,
|
| -examine their attributes, move, add, and delete them. It is a
|
| -fairly low level API, meaning it takes quite a bit of code to get
|
| -a bit done, but it is standard -- learn the DOM once, you can
|
| -use it from ActionScript, JavaScript, Java, C++, whatever.
|
| -
|
| -A DOMTemplate subclass must do two things: indicate which
|
| -template it wants to use, and indicate which elements it is
|
| -interested in.
|
| -
|
| -A short example::
|
| -
|
| - | class Test(DOMTemplate):
|
| - | template = '''
|
| - | <html><head><title>Foo</title></head><body>
|
| - |
|
| - | <div view="Test">
|
| - | This test node will be replaced
|
| - | </div>
|
| - |
|
| - | </body></html>
|
| - | '''
|
| - |
|
| - | def factory_test(self, request, node):
|
| - | '''
|
| - | The test method will be called with the request and the
|
| - | DOM node that the test method was associated with.
|
| - | '''
|
| - | # self.d has been bound to the main DOM "document" object
|
| - | newNode = self.d.createTextNode("Testing, 1,2,3")
|
| - |
|
| - | # Replace the test node with our single new text node
|
| - | return newNode
|
| -"""
|
| -
|
| -import warnings
|
| -
|
| -try:
|
| - import cPickle as pickle
|
| -except ImportError:
|
| - import pickle
|
| -
|
| -import string, os, sys, stat, types
|
| -from twisted.web import microdom
|
| -
|
| -from twisted.python import components
|
| -from twisted.web import resource, html
|
| -from twisted.web.resource import Resource
|
| -from twisted.web.woven import controller, utils, interfaces
|
| -
|
| -from twisted.internet import defer
|
| -from twisted.python import failure
|
| -from twisted.internet import reactor, defer
|
| -from twisted.python import log
|
| -from zope.interface import implements, Interface
|
| -
|
| -from twisted.web.server import NOT_DONE_YET
|
| -STOP_RENDERING = 1
|
| -RESTART_RENDERING = 2
|
| -
|
| -
|
| -
|
| -class INodeMutator(Interface):
|
| - """A component that implements NodeMutator knows how to mutate
|
| - DOM based on the instructions in the object it wraps.
|
| - """
|
| - def generate(request, node):
|
| - """The generate method should do the work of mutating the DOM
|
| - based on the object this adapter wraps.
|
| - """
|
| - pass
|
| -
|
| -
|
| -class NodeMutator:
|
| - implements(INodeMutator)
|
| - def __init__(self, data):
|
| - self.data = data
|
| -
|
| -class NodeNodeMutator(NodeMutator):
|
| - """A NodeNodeMutator replaces the node that is passed in to generate
|
| - with the node it adapts.
|
| - """
|
| - def __init__(self, data):
|
| - assert data is not None
|
| - NodeMutator.__init__(self, data)
|
| -
|
| - def generate(self, request, node):
|
| - if self.data is not node:
|
| - parent = node.parentNode
|
| - if parent:
|
| - parent.replaceChild(self.data, node)
|
| - else:
|
| - log.msg("Warning: There was no parent for node %s; node not mutated." % node)
|
| - return self.data
|
| -
|
| -
|
| -class NoneNodeMutator(NodeMutator):
|
| - def generate(self, request, node):
|
| - return node # do nothing
|
| - child = request.d.createTextNode("None")
|
| - node.parentNode.replaceChild(child, node)
|
| -
|
| -
|
| -class StringNodeMutator(NodeMutator):
|
| - """A StringNodeMutator replaces the node that is passed in to generate
|
| - with the string it adapts.
|
| - """
|
| - def generate(self, request, node):
|
| - if self.data:
|
| - try:
|
| - child = microdom.parseString(self.data)
|
| - except Exception, e:
|
| - log.msg("Error parsing return value, probably invalid xml:", e)
|
| - child = request.d.createTextNode(self.data)
|
| - else:
|
| - child = request.d.createTextNode(self.data)
|
| - nodeMutator = NodeNodeMutator(child)
|
| - return nodeMutator.generate(request, node)
|
| -
|
| -
|
| -components.registerAdapter(NodeNodeMutator, microdom.Node, INodeMutator)
|
| -components.registerAdapter(NoneNodeMutator, type(None), INodeMutator)
|
| -components.registerAdapter(StringNodeMutator, type(""), INodeMutator)
|
| -
|
| -
|
| -class DOMTemplate(Resource):
|
| - """A resource that renders pages using DOM."""
|
| -
|
| - isLeaf = 1
|
| - templateFile = ''
|
| - templateDirectory = ''
|
| - template = ''
|
| - _cachedTemplate = None
|
| -
|
| - def __init__(self, templateFile = None):
|
| - """
|
| - @param templateFile: The name of a file containing a template.
|
| - @type templateFile: String
|
| - """
|
| - Resource.__init__(self)
|
| - if templateFile:
|
| - self.templateFile = templateFile
|
| -
|
| - self.outstandingCallbacks = 0
|
| - self.failed = 0
|
| -
|
| - def render(self, request):
|
| - template = self.getTemplate(request)
|
| - if template:
|
| - self.d = microdom.parseString(template)
|
| - else:
|
| - if not self.templateFile:
|
| - raise AttributeError, "%s does not define self.templateFile to operate on" % self.__class__
|
| - self.d = self.lookupTemplate(request)
|
| - self.handleDocument(request, self.d)
|
| - return NOT_DONE_YET
|
| -
|
| - def getTemplate(self, request):
|
| - """
|
| - Override this if you want to have your subclass look up its template
|
| - using a different method.
|
| - """
|
| - return self.template
|
| -
|
| - def lookupTemplate(self, request):
|
| - """
|
| - Use acquisition to look up the template named by self.templateFile,
|
| - located anywhere above this object in the heirarchy, and use it
|
| - as the template. The first time the template is used it is cached
|
| - for speed.
|
| - """
|
| - if self.template:
|
| - return microdom.parseString(self.template)
|
| - if not self.templateDirectory:
|
| - mod = sys.modules[self.__module__]
|
| - if hasattr(mod, '__file__'):
|
| - self.templateDirectory = os.path.split(mod.__file__)[0]
|
| - # First see if templateDirectory + templateFile is a file
|
| - templatePath = os.path.join(self.templateDirectory, self.templateFile)
|
| - # Check to see if there is an already compiled copy of it
|
| - templateName = os.path.splitext(self.templateFile)[0]
|
| - compiledTemplateName = '.' + templateName + '.pxp'
|
| - compiledTemplatePath = os.path.join(self.templateDirectory, compiledTemplateName)
|
| - # No? Compile and save it
|
| - if (not os.path.exists(compiledTemplatePath) or
|
| - os.stat(compiledTemplatePath)[stat.ST_MTIME] < os.stat(templatePath)[stat.ST_MTIME]):
|
| - compiledTemplate = microdom.parse(templatePath)
|
| - pickle.dump(compiledTemplate, open(compiledTemplatePath, 'wb'), 1)
|
| - else:
|
| - compiledTemplate = pickle.load(open(compiledTemplatePath, "rb"))
|
| - return compiledTemplate
|
| -
|
| - def setUp(self, request, document):
|
| - pass
|
| -
|
| - def handleDocument(self, request, document):
|
| - """
|
| - Handle the root node, and send the page if there are no
|
| - outstanding callbacks when it returns.
|
| - """
|
| - try:
|
| - request.d = document
|
| - self.setUp(request, document)
|
| - # Don't let outstandingCallbacks get to 0 until the
|
| - # entire tree has been recursed
|
| - # If you don't do this, and any callback has already
|
| - # completed by the time the dispatchResultCallback
|
| - # is added in dispachResult, then sendPage will be
|
| - # called prematurely within dispatchResultCallback
|
| - # resulting in much gnashing of teeth.
|
| - self.outstandingCallbacks += 1
|
| - for node in document.childNodes:
|
| - request.currentParent = node
|
| - self.handleNode(request, node)
|
| - self.outstandingCallbacks -= 1
|
| - if not self.outstandingCallbacks:
|
| - return self.sendPage(request)
|
| - except:
|
| - self.renderFailure(None, request)
|
| -
|
| - def dispatchResult(self, request, node, result):
|
| - """
|
| - Check a given result from handling a node and hand it to a process*
|
| - method which will convert the result into a node and insert it
|
| - into the DOM tree. Return the new node.
|
| - """
|
| - if not isinstance(result, defer.Deferred):
|
| - adapter = INodeMutator(result, None)
|
| - if adapter is None:
|
| - raise NotImplementedError(
|
| - "Your factory method returned %s, but there is no "
|
| - "INodeMutator adapter registerred for %s." %
|
| - (result, getattr(result, "__class__",
|
| - None) or type(result)))
|
| - result = adapter.generate(request, node)
|
| - if isinstance(result, defer.Deferred):
|
| - self.outstandingCallbacks += 1
|
| - result.addCallback(self.dispatchResultCallback, request, node)
|
| - result.addErrback(self.renderFailure, request)
|
| - # Got to wait until the callback comes in
|
| - return result
|
| -
|
| - def recurseChildren(self, request, node):
|
| - """
|
| - If this node has children, handle them.
|
| - """
|
| - request.currentParent = node
|
| - if not node: return
|
| - if type(node.childNodes) == type(""): return
|
| - if node.hasChildNodes():
|
| - for child in node.childNodes:
|
| - self.handleNode(request, child)
|
| -
|
| - def dispatchResultCallback(self, result, request, node):
|
| - """
|
| - Deal with a callback from a deferred, dispatching the result
|
| - and recursing children.
|
| - """
|
| - self.outstandingCallbacks -= 1
|
| - node = self.dispatchResult(request, node, result)
|
| - self.recurseChildren(request, node)
|
| - if not self.outstandingCallbacks:
|
| - return self.sendPage(request)
|
| -
|
| - def handleNode(self, request, node):
|
| - """
|
| - Handle a single node by looking up a method for it, calling the method
|
| - and dispatching the result.
|
| -
|
| - Also, handle all childNodes of this node using recursion.
|
| - """
|
| - if not hasattr(node, 'getAttribute'): # text node?
|
| - return node
|
| -
|
| - viewName = node.getAttribute('view')
|
| - if viewName:
|
| - method = getattr(self, "factory_" + viewName, None)
|
| - if not method:
|
| - raise NotImplementedError, "You specified view name %s on a node, but no factory_%s method was found." % (viewName, viewName)
|
| -
|
| - result = method(request, node)
|
| - node = self.dispatchResult(request, node, result)
|
| -
|
| - if not isinstance(node, defer.Deferred):
|
| - self.recurseChildren(request, node)
|
| -
|
| - def sendPage(self, request):
|
| - """
|
| - Send the results of the DOM mutation to the browser.
|
| - """
|
| - page = str(self.d.toxml())
|
| - request.write(page)
|
| - request.finish()
|
| - return page
|
| -
|
| - def renderFailure(self, failure, request):
|
| - try:
|
| - xml = request.d.toxml()
|
| - except:
|
| - xml = ""
|
| -# if not hasattr(request, 'channel'):
|
| -# log.msg("The request got away from me before I could render an error page.")
|
| -# log.err(failure)
|
| -# return failure
|
| - if not self.failed:
|
| - self.failed = 1
|
| - if failure:
|
| - request.write("<html><head><title>%s: %s</title></head><body>\n" % (html.escape(str(failure.type)), html.escape(str(failure.value))))
|
| - else:
|
| - request.write("<html><head><title>Failure!</title></head><body>\n")
|
| - utils.renderFailure(failure, request)
|
| - request.write("<h3>Here is the partially processed DOM:</h3>")
|
| - request.write("\n<pre>\n")
|
| - request.write(html.escape(xml))
|
| - request.write("\n</pre>\n")
|
| - request.write("</body></html>")
|
| - request.finish()
|
| - return failure
|
| -
|
| -##########################################
|
| -# Deprecation zone
|
| -# Wear a hard hat
|
| -##########################################
|
| -
|
| -
|
| -# DOMView is now deprecated since the functionality was merged into domtemplate
|
| -DOMView = DOMTemplate
|
| -
|
| -# DOMController is now renamed woven.controller.Controller
|
| -class DOMController(controller.Controller, Resource):
|
| - """
|
| - A simple controller that automatically passes responsibility on to the view
|
| - class registered for the model. You can override render to perform
|
| - more advanced template lookup logic.
|
| - """
|
| -
|
| - def __init__(self, *args, **kwargs):
|
| - log.msg("DeprecationWarning: DOMController is deprecated; it has been renamed twisted.web.woven.controller.Controller.\n")
|
| - controller.Controller.__init__(self, *args, **kwargs)
|
| - Resource.__init__(self)
|
| -
|
| - def setUp(self, request):
|
| - pass
|
| -
|
| - def render(self, request):
|
| - self.setUp(request)
|
| - self.view = interfaces.IView(self.model, None)
|
| - self.view.setController(self)
|
| - return self.view.render(request)
|
| -
|
| - def process(self, request, **kwargs):
|
| - log.msg("Processing results: ", kwargs)
|
| - return RESTART_RENDERING
|
|
|