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

Unified Diff: third_party/twisted_8_1/twisted/web/widgets.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 side-by-side diff with in-line comments
Download patch
Index: third_party/twisted_8_1/twisted/web/widgets.py
diff --git a/third_party/twisted_8_1/twisted/web/widgets.py b/third_party/twisted_8_1/twisted/web/widgets.py
deleted file mode 100644
index de2af70c8809b201294579d1c757ed5a86c25b75..0000000000000000000000000000000000000000
--- a/third_party/twisted_8_1/twisted/web/widgets.py
+++ /dev/null
@@ -1,1050 +0,0 @@
-# -*- test-case-name: twisted.web.test.test_web -*-
-#
-# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-
-"""A twisted web component framework.
-
-This module is DEPRECATED.
-"""
-
-import warnings
-warnings.warn("This module is deprecated, please use Woven instead.", DeprecationWarning)
-
-# System Imports
-import string, time, types, traceback, pprint, sys, os
-import linecache
-import re
-from cStringIO import StringIO
-
-# Twisted Imports
-from twisted.python import failure, log, rebuild, reflect, util
-from twisted.internet import defer
-from twisted.web import http
-
-# Sibling Imports
-import html, resource, error
-import util as webutil
-
-#backwards compatibility
-from util import formatFailure, htmlrepr, htmlUnknown, htmlDict, htmlList,\
- htmlInst, htmlString, htmlReprTypes
-
-
-
-from server import NOT_DONE_YET
-
-True = (1==1)
-False = not True
-
-
-# magic value that sez a widget needs to take over the whole page.
-
-FORGET_IT = 99
-
-def listify(x):
- return [x]
-def _ellipsize(x):
- y = repr(x)
- if len(y) > 1024:
- return y[:1024]+"..."
- return y
-
-
-class Widget:
- """A component of a web page.
- """
- title = None
- def getTitle(self, request):
- return self.title or reflect.qual(self.__class__)
-
- def display(self, request):
- """Implement me to represent your widget.
-
- I must return a list of strings and twisted.internet.defer.Deferred
- instances.
- """
- raise NotImplementedError("%s.display" % reflect.qual(self.__class__))
-
-class StreamWidget(Widget):
- """A 'streamable' component of a webpage.
- """
-
- def stream(self, write, request):
- """Call 'write' multiple times with a string argument to represent this widget.
- """
- raise NotImplementedError("%s.stream" % reflect.qual(self.__class__))
-
- def display(self, request):
- """Produce a list containing a single string.
- """
- l = []
- try:
- result = self.stream(l.append, request)
- if result is not None:
- return result
- return l
- except:
- return [webutil.formatFailure(failure.Failure())]
-
-class WidgetMixin(Widget):
- """A mix-in wrapper for a Widget.
-
- This mixin can be used to wrap functionality in any other widget with a
- method of your choosing. It is designed to be used for mix-in classes that
- can be mixed in to Form, StreamWidget, Presentation, etc, to augment the
- data available to the 'display' methods of those classes, usually by adding
- it to a Session.
- """
-
- def display(self):
- raise NotImplementedError("%s.display" % self.__class__)
-
- def displayMixedWidget(self, request):
- for base in reflect.allYourBase(self.__class__):
- if issubclass(base, Widget) and not issubclass(base, WidgetMixin):
- return base.display(self, request)
-
-class Presentation(Widget):
- """I am a widget which formats a template with interspersed python expressions.
- """
- template = '''
- Hello, %%%%world%%%%.
- '''
- world = "you didn't assign to the 'template' attribute"
- def __init__(self, template=None, filename=None):
- if filename:
- self.template = open(filename).read()
- elif template:
- self.template = template
- self.variables = {}
- self.tmpl = string.split(self.template, "%%%%")
-
- def addClassVars(self, namespace, Class):
- for base in Class.__bases__:
- # Traverse only superclasses that know about Presentation.
- if issubclass(base, Presentation) and base is not Presentation:
- self.addClassVars(namespace, base)
- # 'lower' classes in the class heirarchy take precedence.
- for k in Class.__dict__.keys():
- namespace[k] = getattr(self, k)
-
- def addVariables(self, namespace, request):
- self.addClassVars(namespace, self.__class__)
-
- def prePresent(self, request):
- """Perform any tasks which must be done before presenting the page.
- """
-
- def formatTraceback(self, tb):
- return [html.PRE(tb)]
-
- def streamCall(self, call, *args, **kw):
- """Utility: Call a method like StreamWidget's 'stream'.
- """
- io = StringIO()
- apply(call, (io.write,) + args, kw)
- return io.getvalue()
-
- def display(self, request):
- tm = []
- flip = 0
- namespace = {}
- self.prePresent(request)
- self.addVariables(namespace, request)
- # This variable may not be obscured...
- namespace['request'] = request
- namespace['self'] = self
- for elem in self.tmpl:
- flip = not flip
- if flip:
- if elem:
- tm.append(elem)
- else:
- try:
- x = eval(elem, namespace, namespace)
- except:
- log.deferr()
- tm.append(webutil.formatFailure(failure.Failure()))
- else:
- if isinstance(x, types.ListType):
- tm.extend(x)
- elif isinstance(x, Widget):
- val = x.display(request)
- if not isinstance(val, types.ListType):
- raise Exception("%s.display did not return a list, it returned %s!" % (x.__class__, repr(val)))
- tm.extend(val)
- else:
- # Only two allowed types here should be deferred and
- # string.
- tm.append(x)
- return tm
-
-
-def htmlFor_hidden(write, name, value):
- write('<INPUT TYPE="hidden" NAME="%s" VALUE="%s" />' % (name, value))
-
-def htmlFor_file(write, name, value):
- write('<INPUT SIZE="60" TYPE="file" NAME="%s" />' % name)
-
-def htmlFor_string(write, name, value):
- write('<INPUT SIZE="60" TYPE="text" NAME="%s" VALUE="%s" />' % (name, value))
-
-def htmlFor_password(write, name, value):
- write('<INPUT SIZE="60" TYPE="password" NAME="%s" />' % name)
-
-def htmlFor_text(write, name, value):
- write('<textarea COLS="60" ROWS="10" NAME="%s" WRAP="virtual">%s</textarea>' % (name, value))
-
-def htmlFor_menu(write, name, value, allowMultiple=False):
- "Value of the format [(optionName, displayName[, selected]), ...]"
-
- write(' <select NAME="%s"%s>\n' %
- (name, (allowMultiple and " multiple") or ''))
-
- for v in value:
- optionName, displayName, selected = util.padTo(3, v)
- selected = (selected and " selected") or ''
- write(' <option VALUE="%s"%s>%s</option>\n' %
- (optionName, selected, displayName))
- if not value:
- write(' <option VALUE=""></option>\n')
- write(" </select>\n")
-
-def htmlFor_multimenu(write, name, value):
- "Value of the format [(optionName, displayName[, selected]), ...]"
- return htmlFor_menu(write, name, value, True)
-
-def htmlFor_checkbox(write, name, value):
- "A checkbox."
- if value:
- value = 'checked = "1"'
- else:
- value = ''
- write('<INPUT TYPE="checkbox" NAME="__checkboxes__" VALUE="%s" %s />\n' % (name, value))
-
-def htmlFor_checkgroup(write, name, value):
- "A check-group."
- for optionName, displayName, checked in value:
- checked = (checked and 'checked = "1"') or ''
- write('<INPUT TYPE="checkbox" NAME="%s" VALUE="%s" %s />%s<br />\n' % (name, optionName, checked, displayName))
-
-def htmlFor_radio(write, name, value):
- "A radio button group."
- for optionName, displayName, checked in value:
- checked = (checked and 'checked = "1"') or ''
- write('<INPUT TYPE="radio" NAME="%s" VALUE="%s" %s />%s<br />\n' % (name, optionName, checked, displayName))
-
-class FormInputError(Exception):
- pass
-
-class Form(Widget):
- """I am a web form.
-
- In order to use me, you probably want to set self.formFields (or override
- 'getFormFields') and override 'process'. In order to demonstrate how this
- is done, here is a small sample Form subclass::
-
- | from twisted.web import widgets
- | class HelloForm(widgets.Form):
- | formFields = [
- | ['string', 'Who to greet?', 'whoToGreet', 'World',
- | 'This is for choosing who to greet.'],
- | ['menu', 'How to greet?', 'how', [('cheerfully', 'with a smile'),
- | ('sullenly', 'without enthusiasm'),
- | ('spontaneously', 'on the spur of the moment')]]
- | 'This is for choosing how to greet them.']
- | def process(self, write, request, submit, whoToGreet, how):
- | write('The web wakes up and %s says, \"Hello, %s!\"' % (how, whoToGreet))
-
- If you load this widget, you will see that it displays a form with 2 inputs
- derived from data in formFields. Note the argument names to 'process':
- after 'write' and 'request', they are the same as the 3rd elements ('Input
- Name' parameters) of the formFields list.
- """
-
- formGen = {
- 'hidden': htmlFor_hidden,
- 'file': htmlFor_file,
- 'string': htmlFor_string,
- 'int': htmlFor_string,
- 'float': htmlFor_string,
- 'text': htmlFor_text,
- 'menu': htmlFor_menu,
- 'multimenu': htmlFor_multimenu,
- 'password': htmlFor_password,
- 'checkbox': htmlFor_checkbox,
- 'checkgroup': htmlFor_checkgroup,
- 'radio': htmlFor_radio,
- }
-
- formParse = {
- 'int': int,
- 'float': float,
- }
-
- formFields = [
- ]
-
- # do we raise an error when we get extra args or not?
- formAcceptExtraArgs = 0
-
- def getFormFields(self, request, fieldSet = None):
- """I return a list of lists describing this form, or a Deferred.
-
- This information is used both to display the form and to process it.
- The list is in the following format::
-
- | [['Input Type', 'Display Name', 'Input Name', 'Input Value', 'Description'],
- | ['Input Type 2', 'Display Name 2', 'Input Name 2', 'Input Value 2', 'Description 2']
- | ...]
-
- Valid values for 'Input Type' are:
-
- - 'hidden': a hidden field that contains a string that the user won't change
-
- - 'string': a short string
-
- - 'int': an integer, e.g. 1, 0, 25 or -23
-
- - 'float': a float, e.g. 1.0, 2, -3.45, or 28.4324231
-
- - 'text': a longer text field, suitable for entering paragraphs
-
- - 'menu': an HTML SELECT input, a list of choices
-
- - 'multimenu': an HTML SELECT input allowing multiple choices
-
- - 'checkgroup': a group of checkboxes
-
- - 'radio': a group of radio buttons
-
- - 'password': a 'string' field where the contents are not visible as the user types
-
- - 'file': a file-upload form (EXPERIMENTAL)
-
- 'Display Name' is a descriptive string that will be used to
- identify the field to the user.
-
- The 'Input Name' must be a legal Python identifier that describes both
- the value's name on the HTML form and the name of an argument to
- 'self.process()'.
-
- The 'Input Value' is usually a string, but its value can depend on the
- 'Input Type'. 'int' it is an integer, 'menu' it is a list of pairs of
- strings, representing (value, name) pairs for the menu options. Input
- value for 'checkgroup' and 'radio' should be a list of ('inputName',
- 'Display Name', 'checked') triplets.
-
- The 'Description' field is an (optional) string which describes the form
- item to the user.
-
- If this result is statically determined for your Form subclass, you can
- assign it to FormSubclass.formFields; if you need to determine it
- dynamically, you can override this method.
-
- Note: In many cases it is desirable to use user input for defaults in
- the form rather than those supplied by your calculations, which is what
- this method will do to self.formFields. If this is the case for you,
- but you still need to dynamically calculate some fields, pass your
- results back through this method by doing::
-
- | def getFormFields(self, request):
- | myFormFields = [self.myFieldCalculator()]
- | return widgets.Form.getFormFields(self, request, myFormFields)
-
- """
- fields = []
- if fieldSet is None:
- fieldSet = self.formFields
- if not self.shouldProcess(request):
- return fieldSet
-
- for field in fieldSet:
- if len(field)==5:
- inputType, displayName, inputName, inputValue, description = field
- else:
- inputType, displayName, inputName, inputValue = field
- description = ""
-
- if inputType == 'checkbox':
- if request.args.has_key('__checkboxes__'):
- if inputName in request.args['__checkboxes__']:
- inputValue = 1
- else:
- inputValue = 0
- else:
- inputValue = 0
- elif inputType in ('checkgroup', 'radio'):
- if request.args.has_key(inputName):
- keys = request.args[inputName]
- else:
- keys = []
- iv = inputValue
- inputValue = []
- for optionName, optionDisplayName, checked in iv:
- checked = optionName in keys
- inputValue.append([optionName, optionDisplayName, checked])
- elif request.args.has_key(inputName):
- iv = request.args[inputName][0]
- if inputType in ['menu', 'multimenu']:
- if iv in inputValue:
- inputValue.remove(iv)
- inputValue.insert(0, iv)
- else:
- inputValue = iv
- fields.append([inputType, displayName, inputName, inputValue, description])
- return fields
-
- submitNames = ['Submit']
- actionURI = ''
-
- def format(self, form, write, request):
- """I display an HTML FORM according to the result of self.getFormFields.
- """
- write('<form ENCTYPE="multipart/form-data" METHOD="post" ACTION="%s">\n'
- '<table BORDER="0">\n' % (self.actionURI or request.uri))
-
- for field in form:
- if len(field) == 5:
- inputType, displayName, inputName, inputValue, description = field
- else:
- inputType, displayName, inputName, inputValue = field
- description = ""
- write('<tr>\n<td ALIGN="right" VALIGN="top"><B>%s</B></td>\n'
- '<td VALIGN="%s">\n' %
- (displayName, ((inputType == 'text') and 'top') or 'middle'))
- self.formGen[inputType](write, inputName, inputValue)
- write('\n<br />\n<font size="-1">%s</font></td>\n</tr>\n' % description)
-
-
- write('<tr><td></td><td ALIGN="left"><hr />\n')
- for submitName in self.submitNames:
- write('<INPUT TYPE="submit" NAME="submit" VALUE="%s" />\n' % submitName)
- write('</td></tr>\n</table>\n'
- '<INPUT TYPE="hidden" NAME="__formtype__" VALUE="%s" />\n'
- % (reflect.qual(self.__class__)))
- fid = self.getFormID()
- if fid:
- write('<INPUT TYPE="hidden" NAME="__formid__" VALUE="%s" />\n' % fid)
- write("</form>\n")
-
- def getFormID(self):
- """Override me: I disambiguate between multiple forms of the same type.
-
- In order to determine which form an HTTP POST request is for, you must
- have some unique identifier which distinguishes your form from other
- forms of the same class. An example of such a unique identifier would
- be: on a page with multiple FrobConf forms, each FrobConf form refers
- to a particular Frobnitz instance, which has a unique id(). The
- FrobConf form's getFormID would probably look like this::
-
- | def getFormID(self):
- | return str(id(self.frobnitz))
-
- By default, this method will return None, since distinct Form instances
- may be identical as far as the application is concerned.
- """
-
- def process(self, write, request, submit, **kw):
- """Override me: I process a form.
-
- I will only be called when the correct form input data to process this
- form has been received.
-
- I take a variable number of arguments, beginning with 'write',
- 'request', and 'submit'. 'write' is a callable object that will append
- a string to the response, 'request' is a twisted.web.request.Request
- instance, and 'submit' is the name of the submit action taken.
-
- The remainder of my arguments must be correctly named. They will each be named after one of the
-
- """
- write("<pre>Submit: %s <br /> %s</pre>" % (submit, html.PRE(pprint.PrettyPrinter().pformat(kw))))
-
- def _doProcess(self, form, write, request):
- """(internal) Prepare arguments for self.process.
- """
- args = request.args.copy()
- kw = {}
- for field in form:
- inputType, displayName, inputName, inputValue = field[:4]
- if inputType == 'checkbox':
- if request.args.has_key('__checkboxes__'):
- if inputName in request.args['__checkboxes__']:
- formData = 1
- else:
- formData = 0
- else:
- formData = 0
- elif inputType in ['checkgroup', 'radio', 'multimenu']:
- if args.has_key(inputName):
- formData = args[inputName]
- del args[inputName]
- else:
- formData = []
- else:
- if not args.has_key(inputName):
- raise FormInputError("missing field %s." % repr(inputName))
- formData = args[inputName]
- del args[inputName]
- if not len(formData) == 1:
- raise FormInputError("multiple values for field %s." %repr(inputName))
- formData = formData[0]
- method = self.formParse.get(inputType)
- if method:
- try:
- formData = method(formData)
- except:
- raise FormInputError("%s: %s" % (displayName, "error"))
- kw[inputName] = formData
- submitAction = args.get('submit')
- if submitAction:
- submitAction = submitAction[0]
- for field in ['submit', '__formtype__', '__checkboxes__']:
- if args.has_key(field):
- del args[field]
- if args and not self.formAcceptExtraArgs:
- raise FormInputError("unknown fields: %s" % repr(args))
- return apply(self.process, (write, request, submitAction), kw)
-
- def formatError(self,error):
- """Format an error message.
-
- By default, this will make the message appear in red, bold italics.
- """
- return '<font color="#f00"><b><i>%s</i></b></font><br />\n' % error
-
- def shouldProcess(self, request):
- args = request.args
- fid = self.getFormID()
- return (args and # there are arguments to the request
- args.has_key('__formtype__') and # this is a widgets.Form request
- args['__formtype__'][0] == reflect.qual(self.__class__) and # it is for a form of my type
- ((not fid) or # I am only allowed one form per page
- (args.has_key('__formid__') and # if I distinguish myself from others, the request must too
- args['__formid__'][0] == fid))) # I am in fact the same
-
- def tryAgain(self, err, req):
- """Utility method for re-drawing the form with an error message.
-
- This is handy in forms that process Deferred results. Normally you can
- just raise a FormInputError() and this will happen by default.
-
- """
- l = []
- w = l.append
- w(self.formatError(err))
- self.format(self.getFormFields(req), w, req)
- return l
-
- def display(self, request):
- """Display the form."""
- form = self.getFormFields(request)
- if isinstance(form, defer.Deferred):
- if self.shouldProcess(request):
- form.addCallback(lambda form, f=self._displayProcess, r=request: f(r, form))
- else:
- form.addCallback(lambda form, f=self._displayFormat, r=request: f(r, form))
- return [form]
- else:
- if self.shouldProcess(request):
- return self._displayProcess(request, form)
- else:
- return self._displayFormat(request, form)
-
- def _displayProcess(self, request, form):
- l = []
- write = l.append
- try:
- val = self._doProcess(form, write, request)
- if val:
- l.extend(val)
- except FormInputError, fie:
- write(self.formatError(str(fie)))
- return l
-
- def _displayFormat(self, request, form):
- l = []
- self.format(form, l.append, request)
- return l
-
-
-
-class DataWidget(Widget):
- def __init__(self, data):
- self.data = data
- def display(self, request):
- return [self.data]
-
-class Time(Widget):
- def display(self, request):
- return [time.ctime(time.time())]
-
-class Container(Widget):
- def __init__(self, *widgets):
- self.widgets = widgets
-
- def display(self, request):
- value = []
- for widget in self.widgets:
- d = widget.display(request)
- value.extend(d)
- return value
-
-class _RequestDeferral:
- def __init__(self):
- self.deferred = defer.Deferred()
- self.io = StringIO()
- self.write = self.io.write
-
- def finish(self):
- self.deferred.callback([self.io.getvalue()])
-
-def possiblyDeferWidget(widget, request):
- # web in my head get it out get it out
- try:
- disp = widget.display(request)
- # if this widget wants to defer anything -- well, I guess we've got to
- # defer it.
- for elem in disp:
- if isinstance(elem, defer.Deferred):
- req = _RequestDeferral()
- RenderSession(disp, req)
- return req.deferred
- return string.join(disp, '')
- except:
- io = StringIO()
- traceback.print_exc(file=io)
- return html.PRE(io.getvalue())
-
-class RenderSession:
- """I handle rendering of a list of deferreds, outputting their
- results in correct order."""
-
- class Sentinel:
- pass
-
- def __init__(self, lst, request):
- self.lst = lst
- self.request = request
- self.needsHeaders = 0
- self.beforeBody = 1
- self.forgotten = 0
- self.pauseList = []
- for i in range(len(self.lst)):
- item = self.lst[i]
- if isinstance(item, defer.Deferred):
- self._addDeferred(item, self.lst, i)
- self.keepRendering()
-
- def _addDeferred(self, deferred, lst, idx):
- sentinel = self.Sentinel()
- if hasattr(deferred, 'needsHeader'):
- # You might want to set a header from a deferred, in which
- # case you have to set an attribute -- needsHeader.
- self.needsHeaders = self.needsHeaders + 1
- args = (sentinel, 1)
- else:
- args = (sentinel, 0)
- lst[idx] = sentinel, deferred
- deferred.pause()
- self.pauseList.append(deferred)
- deferred.addCallbacks(self.callback, self.callback,
- callbackArgs=args, errbackArgs=args)
-
-
- def callback(self, result, sentinel, decNeedsHeaders):
- if self.forgotten:
- return
- if result != FORGET_IT:
- self.needsHeaders = self.needsHeaders - decNeedsHeaders
- else:
- result = [FORGET_IT]
-
- # Make sure result is a sequence,
- if not type(result) in (types.ListType, types.TupleType):
- result = [result]
-
- # If the deferred does not wish to produce its result all at
- # once, it can give us a partial result as
- # (NOT_DONE_YET, partial_result)
- ## XXX: How would a deferred go about producing the result in multiple
- ## stages?? --glyph
- if result[0] is NOT_DONE_YET:
- done = 0
- result = result[1]
- if not type(result) in (types.ListType, types.TupleType):
- result = [result]
- else:
- done = 1
-
- for i in xrange(len(result)):
- item = result[i]
- if isinstance(item, defer.Deferred):
- self._addDeferred(item, result, i)
-
- for position in range(len(self.lst)):
- item = self.lst[position]
- if type(item) is types.TupleType and len(item) > 0:
- if item[0] is sentinel:
- break
- else:
- raise AssertionError('Sentinel for Deferred not found!')
-
- if done:
- self.lst[position:position+1] = result
- else:
- self.lst[position:position] = result
-
- self.keepRendering()
-
-
- def keepRendering(self):
- while self.pauseList:
- pl = self.pauseList
- self.pauseList = []
- for deferred in pl:
- deferred.unpause()
- return
-
- if self.needsHeaders:
- # short circuit actual rendering process until we're sure no
- # more deferreds need to set headers...
- return
-
- assert self.lst is not None, "This shouldn't happen."
- while 1:
- item = self.lst[0]
- if self.beforeBody and FORGET_IT in self.lst:
- # If I haven't moved yet, and the widget wants to take
- # over the page, let it do so!
- self.forgotten = 1
- return
-
- if isinstance(item, types.StringType):
- self.beforeBody = 0
- self.request.write(item)
- elif type(item) is types.TupleType and len(item) > 0:
- if isinstance(item[0], self.Sentinel):
- return
- elif isinstance(item, failure.Failure):
- self.request.write(webutil.formatFailure(item))
- else:
- self.beforeBody = 0
- unknown = html.PRE(repr(item))
- self.request.write("RENDERING UNKNOWN: %s" % unknown)
-
- del self.lst[0]
- if len(self.lst) == 0:
- self.lst = None
- self.request.finish()
- return
-
-
-## XXX: is this needed?
-class WidgetResource(resource.Resource):
- def __init__(self, widget):
- self.widget = widget
- resource.Resource.__init__(self)
-
- def render(self, request):
- RenderSession(self.widget.display(request), request)
- return NOT_DONE_YET
-
-
-class Page(resource.Resource, Presentation):
-
- def __init__(self):
- resource.Resource.__init__(self)
- Presentation.__init__(self)
-
- def render(self, request):
- displayed = self.display(request)
- RenderSession(displayed, request)
- return NOT_DONE_YET
-
-
-class WidgetPage(Page):
- """
- I am a Page that takes a Widget in its constructor, and displays that
- Widget wrapped up in a simple HTML template.
- """
- stylesheet = '''
- a
- {
- font-family: Lucida, Verdana, Helvetica, Arial, sans-serif;
- color: #369;
- text-decoration: none;
- }
-
- th
- {
- font-family: Lucida, Verdana, Helvetica, Arial, sans-serif;
- font-weight: bold;
- text-decoration: none;
- text-align: left;
- }
-
- pre, code
- {
- font-family: "Courier New", Courier, monospace;
- }
-
- p, body, td, ol, ul, menu, blockquote, div
- {
- font-family: Lucida, Verdana, Helvetica, Arial, sans-serif;
- color: #000;
- }
- '''
-
- template = '''<html>
- <head>
- <title>%%%%self.title%%%%</title>
- <style>
- %%%%self.stylesheet%%%%
- </style>
- <base href="%%%%request.prePathURL()%%%%">
- </head>
-
- <body>
- <h1>%%%%self.title%%%%</h1>
- %%%%self.widget%%%%
- </body>
- </html>
- '''
-
- title = 'No Title'
- widget = 'No Widget'
-
- def __init__(self, widget):
- Page.__init__(self)
- self.widget = widget
- if hasattr(widget, 'stylesheet'):
- self.stylesheet = widget.stylesheet
-
- def prePresent(self, request):
- self.title = self.widget.getTitle(request)
-
- def render(self, request):
- displayed = self.display(request)
- RenderSession(displayed, request)
- return NOT_DONE_YET
-
-class Gadget(resource.Resource):
- """I am a collection of Widgets, to be rendered through a Page Factory.
- self.pageFactory should be a Resource that takes a Widget in its
- constructor. The default is twisted.web.widgets.WidgetPage.
- """
-
- isLeaf = 0
-
- def __init__(self):
- resource.Resource.__init__(self)
- self.widgets = {}
- self.files = []
- self.modules = []
- self.paths = {}
-
- def render(self, request):
- #Redirect to view this entity as a collection.
- request.setResponseCode(http.FOUND)
- # TODO who says it's not https?
- request.setHeader("location","http%s://%s%s/" % (
- request.isSecure() and 's' or '',
- request.getHeader("host"),
- (string.split(request.uri,'?')[0])))
- return "NO DICE!"
-
- def putWidget(self, path, widget):
- """
- Gadget.putWidget(path, widget)
- Add a Widget to this Gadget. It will be rendered through the
- pageFactory associated with this Gadget, whenever 'path' is requested.
- """
- self.widgets[path] = widget
-
- #this is an obsolete function
- def addFile(self, path):
- """
- Gadget.addFile(path)
- Add a static path to this Gadget. This method is obsolete, use
- Gadget.putPath instead.
- """
-
- log.msg("Gadget.addFile() is deprecated.")
- self.paths[path] = path
-
- def putPath(self, path, pathname):
- """
- Gadget.putPath(path, pathname)
- Add a static path to this Gadget. Whenever 'path' is requested,
- twisted.web.static.File(pathname) is sent.
- """
- self.paths[path] = pathname
-
- def getWidget(self, path, request):
- return self.widgets.get(path)
-
- def pageFactory(self, *args, **kwargs):
- """
- Gadget.pageFactory(*args, **kwargs) -> Resource
- By default, this method returns self.page(*args, **kwargs). It
- is only for backwards-compatibility -- you should set the 'pageFactory'
- attribute on your Gadget inside of its __init__ method.
- """
- #XXX: delete this after a while.
- if hasattr(self, "page"):
- log.msg("Gadget.page is deprecated, use Gadget.pageFactory instead")
- return apply(self.page, args, kwargs)
- else:
- return apply(WidgetPage, args, kwargs)
-
- def getChild(self, path, request):
- if path == '':
- # ZOOP!
- if isinstance(self, Widget):
- return self.pageFactory(self)
- widget = self.getWidget(path, request)
- if widget:
- if isinstance(widget, resource.Resource):
- return widget
- else:
- p = self.pageFactory(widget)
- p.isLeaf = getattr(widget,'isLeaf',0)
- return p
- elif self.paths.has_key(path):
- prefix = getattr(sys.modules[self.__module__], '__file__', '')
- if prefix:
- prefix = os.path.abspath(os.path.dirname(prefix))
- return static.File(os.path.join(prefix, self.paths[path]))
-
- elif path == '__reload__':
- return self.pageFactory(Reloader(map(reflect.namedModule, [self.__module__] + self.modules)))
- else:
- return error.NoResource("No such child resource in gadget.")
-
-
-class TitleBox(Presentation):
-
- template = '''\
-<table %%%%self.widthOption%%%% cellpadding="1" cellspacing="0" border="0"><tr>\
-<td bgcolor="%%%%self.borderColor%%%%"><center><font color="%%%%self.titleTextColor%%%%">%%%%self.title%%%%</font></center>\
-<table width="100%" cellpadding="3" cellspacing="0" border="0"><tr>\
-<td bgcolor="%%%%self.boxColor%%%%"><font color="%%%%self.boxTextColor%%%%">%%%%self.widget%%%%</font></td>\
-</tr></table></td></tr></table>\
-'''
-
- borderColor = '#000000'
- titleTextColor = '#ffffff'
- boxTextColor = '#000000'
- boxColor = '#ffffff'
- widthOption = 'width="100%"'
-
- title = 'No Title'
- widget = 'No Widget'
-
- def __init__(self, title, widget):
- """Wrap a widget with a given title.
- """
- self.widget = widget
- self.title = title
- Presentation.__init__(self)
-
-
-class Reloader(Presentation):
- template = '''
- Reloading...
- <ul>
- %%%%reload(request)%%%%
- </ul> ... reloaded!
- '''
- def __init__(self, modules):
- Presentation.__init__(self)
- self.modules = modules
-
- def reload(self, request):
- request.redirect("..")
- x = []
- write = x.append
- for module in self.modules:
- rebuild.rebuild(module)
- write('<li>reloaded %s<br />' % module.__name__)
- return x
-
-class Sidebar(StreamWidget):
- bar = [
- ['Twisted',
- ['mirror', 'http://coopweb.org/ssd/twisted/'],
- ['mailing list', 'cgi-bin/mailman/listinfo/twisted-python']
- ]
- ]
-
- headingColor = 'ffffff'
- headingTextColor = '000000'
- activeHeadingColor = '000000'
- activeHeadingTextColor = 'ffffff'
- sectionColor = '000088'
- sectionTextColor = '008888'
- activeSectionColor = '0000ff'
- activeSectionTextColor = '00ffff'
-
- def __init__(self, highlightHeading, highlightSection):
- self.highlightHeading = highlightHeading
- self.highlightSection = highlightSection
-
- def getList(self):
- return self.bar
-
- def stream(self, write, request):
- write("<table width=120 cellspacing=1 cellpadding=1 border=0>")
- for each in self.getList():
- if each[0] == self.highlightHeading:
- headingColor = self.activeHeadingColor
- headingTextColor = self.activeHeadingTextColor
- canHighlight = 1
- else:
- headingColor = self.headingColor
- headingTextColor = self.headingTextColor
- canHighlight = 0
- write('<tr><td colspan=2 bgcolor="#%s"><font color="%s">'
- '<strong>%s</strong>'
- '</font></td></td></tr>\n' % (headingColor, headingTextColor, each[0]))
- for name, link in each[1:]:
- if canHighlight and (name == self.highlightSection):
- sectionColor = self.activeSectionColor
- sectionTextColor = self.activeSectionTextColor
- else:
- sectionColor = self.sectionColor
- sectionTextColor = self.sectionTextColor
- write('<tr><td align=right bgcolor="#%s" width=6>-</td>'
- '<td bgcolor="#%s"><a href="%s"><font color="#%s">%s'
- '</font></a></td></tr>'
- % (sectionColor, sectionColor, request.sibLink(link), sectionTextColor, name))
- write("</table>")
-
-# moved from template.py
-from twisted.web.woven import template
-from twisted.python import components
-
-class WebWidgetNodeMutator(template.NodeMutator):
- """A WebWidgetNodeMutator replaces the node that is passed in to generate
- with the result of generating the twisted.web.widget instance it adapts.
- """
- def generate(self, request, node):
- widget = self.data
- displayed = widget.display(request)
- try:
- html = string.join(displayed)
- except:
- pr = Presentation()
- pr.tmpl = displayed
- #strList = pr.display(request)
- html = string.join(displayed)
- stringMutator = template.StringNodeMutator(html)
- return stringMutator.generate(request, node)
-
-components.registerAdapter(WebWidgetNodeMutator, Widget, template.INodeMutator)
-
-import static
« no previous file with comments | « third_party/twisted_8_1/twisted/web/vhost.py ('k') | third_party/twisted_8_1/twisted/web/woven/FlashConduit.fla » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698