コード例 #1
0
ファイル: livepage.py プロジェクト: comfuture/numbler
 def _actuallySend(self, scripts):
     output = self.outputConduit
     written = []
     def writer(write):
         #print "WRITER", write
         written.append(write)
     def finisher(finish):
         towrite = '\n'.join(written)
         jslog("<<<<<<\n%s\n" % towrite)
         output.callback(towrite)
     flat.flattenFactory(scripts, self.outputContext, writer, finisher)
     self.outputConduit = None
     self.outputContext = None
コード例 #2
0
ファイル: livepage.py プロジェクト: NonPlayerCtrl/FreePLC_IDE
    def _actuallySend(self, scripts):
        output = self.outputConduit
        written = []

        def writer(write):
            #print "WRITER", write
            written.append(write)

        def finisher(finish):
            towrite = '\n'.join(written)
            jslog("<<<<<<\n%s\n" % towrite)
            output.callback(towrite)

        flat.flattenFactory(scripts, self.outputContext, writer, finisher)
        self.outputConduit = None
        self.outputContext = None
コード例 #3
0
ファイル: url.py プロジェクト: calston/tums
 def renderHTTP(self, ctx):
     # The URL may contain deferreds so we need to flatten it using
     # flattenFactory that will collect the bits into the bits list and
     # call flattened to finish.
     bits = []
     def flattened(spam):
         # Join the bits to make a complete URL.
         u = ''.join(bits)
         # It might also be relative so resolve it against the current URL
         # and flatten it again.
         u = flat.flatten(URL.fromContext(ctx).click(u), ctx)
         return redirectTo(u, inevow.IRequest(ctx))
     return flat.flattenFactory(self.original, ctx, bits.append, flattened)
コード例 #4
0
ファイル: url.py プロジェクト: perkinslr/nevow-py3
 def renderHTTP(self, ctx):
     # The URL may contain deferreds so we need to flatten it using
     # flattenFactory that will collect the bits into the bits list and
     # call flattened to finish.
     bits = []
     def flattened(spam):
         # Join the bits to make a complete URL.
         u = ''.join(bits)
         # It might also be relative so resolve it against the current URL
         # and flatten it again.
         u = flat.flatten(URL.fromContext(ctx).click(u), ctx)
         return redirectTo(u, inevow.IRequest(ctx))
     return flat.flattenFactory(self.original, ctx, bits.append, flattened)
コード例 #5
0
ファイル: rend.py プロジェクト: msdemlei/nevow
class Page(Fragment, ConfigurableFactory, ChildLookupMixin):
    """A page is the main Nevow resource and renders a document loaded
    via the document factory (docFactory).
    """

    implements(inevow.IResource)

    buffered = False

    beforeRender = None
    afterRender = None
    addSlash = None

    flattenFactory = lambda self, *args: flat.flattenFactory(*args)

    def renderHTTP(self, ctx):
        if self.beforeRender is not None:
            return util.maybeDeferred(self.beforeRender, ctx).addCallback(
                lambda result, ctx: self._renderHTTP(ctx), ctx)
        return self._renderHTTP(ctx)

    def _renderHTTP(self, ctx):
        request = inevow.IRequest(ctx)
        ## XXX request is really ctx now, change the name here
        if self.addSlash and inevow.ICurrentSegments(ctx)[-1] != '':
            request.redirect(str(request.URLPath().child('')))
            return ''

        log.msg(http_render=None, uri=request.uri)

        self.rememberStuff(ctx)

        def finishRequest():
            carryover = request.args.get('_nevow_carryover_', [None])[0]
            if carryover is not None and carryover in _CARRYOVER:
                del _CARRYOVER[carryover]
            if self.afterRender is not None:
                return util.maybeDeferred(self.afterRender, ctx)

        if self.buffered:
            io = StringIO()
            writer = io.write

            def finisher(result):
                request.write(io.getvalue())
                return util.maybeDeferred(finishRequest).addCallback(
                    lambda r: result)
        else:
            writer = request.write

            def finisher(result):
                return util.maybeDeferred(finishRequest).addCallback(
                    lambda r: result)

        preprocessors = _getPreprocessors(self)
        doc = self.docFactory.load(ctx, preprocessors)
        ctx = WovenContext(ctx, tags.invisible[doc])

        return self.flattenFactory(doc, ctx, writer, finisher)

    def rememberStuff(self, ctx):
        Fragment.rememberStuff(self, ctx)
        ctx.remember(self, inevow.IResource)

    def renderString(self, ctx=None):
        """Render this page outside of the context of a web request, returning
        a Deferred which will result in a string.

        If twisted is not installed, this method will return a string result immediately,
        and this method is equivalent to renderSynchronously.
        """
        io = StringIO()
        writer = io.write

        def finisher(result):
            return io.getvalue()

        ctx = PageContext(parent=ctx, tag=self)
        self.rememberStuff(ctx)
        doc = self.docFactory.load(ctx)
        ctx = WovenContext(ctx, tags.invisible[doc])

        return self.flattenFactory(doc, ctx, writer, finisher)

    def renderSynchronously(self, ctx=None):
        """Render this page synchronously, returning a string result immediately.
        Raise an exception if a Deferred is required to complete the rendering
        process.
        """
        io = StringIO()

        ctx = PageContext(parent=ctx, tag=self)
        self.rememberStuff(ctx)
        doc = self.docFactory.load(ctx)
        ctx = WovenContext(ctx, tags.invisible[doc])

        def raiseAlways(item):
            raise NotImplementedError("renderSynchronously can not support"
                                      " rendering: %s" % (item, ))

        list(flat.iterflatten(doc, ctx, io.write, raiseAlways))

        return io.getvalue()

    def child_(self, ctx):
        """When addSlash is True, a page rendered at a url with no
        trailing slash and a page rendered at a url with a trailing
        slash will be identical. addSlash is useful for the root
        resource of a site or directory-like resources.
        """
        # Only allow an empty child, by default, if it's on the end
        # and we're a directoryish resource (addSlash = True)
        if self.addSlash and len(inevow.IRemainingSegments(ctx)) == 1:
            return self
        return None

    def webFormPost(self, request, res, configurable, ctx, bindingName, args):
        """Accept a web form post, either redisplaying the original form (with
        errors) if validation fails, or redirecting to the appropriate location after
        the post succeeds. This hook exists specifically for formless.

        New in 0.5, _nevow_carryover_ is only used if an autocallable method
        returns a result that needs to be carried over.

        New in 0.5, autocallables may return a nevow.url.URL or URLOverlay
        instance rather than setting IRedirectAfterPost on the request.

        New in 0.5, autocallables may return a Page instance to have that Page
        instance rendered at the post target URL with no redirects at all. Useful
        for multi-step wizards.
        """
        def redirectAfterPost(aspects):
            hand = aspects.get(inevow.IHand)
            refpath = None
            if hand is not None:
                if isinstance(hand, Page):
                    refpath = url.here
                    if 'freeform_hand' not in inevow.IRequest(ctx).prepath:
                        refpath = refpath.child('freeform_hand')
                if isinstance(hand, (url.URL, url.URLOverlay)):
                    refpath, hand = hand, None

            if refpath is None:
                redirectAfterPost = request.getComponent(
                    iformless.IRedirectAfterPost, None)
                if redirectAfterPost is None:
                    ref = request.getHeader('referer')
                    if ref:
                        refpath = url.URL.fromString(ref)
                    else:
                        refpath = url.here
                else:
                    warnings.warn(
                        "[0.5] IRedirectAfterPost is deprecated. Return a URL instance from your autocallable instead.",
                        DeprecationWarning, 2)
                    ## Use the redirectAfterPost url
                    ref = str(redirectAfterPost)
                    refpath = url.URL.fromString(ref)

            if hand is not None or aspects.get(
                    iformless.IFormErrors) is not None:
                magicCookie = '%s%s%s' % (now(), request.getClientIP(),
                                          random.random())
                refpath = refpath.replace('_nevow_carryover_', magicCookie)
                _CARRYOVER[magicCookie] = C = tpc.Componentized()
                for k, v in aspects.items():
                    C.setComponent(k, v)

            destination = flat.flatten(refpath, ctx)
            request.redirect(destination)
            from nevow import static
            return static.Data('You posted a form to %s' % bindingName,
                               'text/plain'), ()

        return util.maybeDeferred(
            configurable.postForm, ctx, bindingName, args).addCallback(
                self.onPostSuccess, request, ctx, bindingName,
                redirectAfterPost).addErrback(self.onPostFailure, request, ctx,
                                              bindingName, redirectAfterPost)

    def onPostSuccess(self, result, request, ctx, bindingName,
                      redirectAfterPost):
        if result is None:
            message = "%s success." % formless.nameToLabel(bindingName)
        else:
            message = result

        return redirectAfterPost({
            inevow.IHand: result,
            inevow.IStatusMessage: message
        })

    def onPostFailure(self, reason, request, ctx, bindingName,
                      redirectAfterPost):
        reason.trap(formless.ValidateError)
        return redirectAfterPost(
            {iformless.IFormErrors: {
                bindingName: reason.value
            }})
コード例 #6
0
class JsonPage(rend.Page):

    flattenFactory = lambda self, *args: flat.flattenFactory(*args)
    addSlash = True

    def renderHTTP(self, ctx):
        request = inevow.IRequest(ctx)
        if inevow.ICurrentSegments(ctx)[-1] != '':
            request.redirect(request.URLPath().child(''))
            return ''
        request.setHeader("Content-Type", "application/json; charset=UTF-8")
        d = defer.maybeDeferred(self.data_json, ctx, None)
        d.addCallback(lambda x: self.render_json(ctx, x))
        return d

    def render_json(self, ctx, data):
        """Render the given data in a proper JSON string"""
        def sanitize(data, d=None):
            """Nevow JSON serializer is not able to handle some types.

            We convert those types in proper types:
             - string to unicode string
             - PgSQL result set into list
             - handling of deferreds
            """
            if type(data) in [list, tuple] or \
                    (PgSQL and isinstance(data, PgSQL.PgResultSet)):
                return [sanitize(x, d) for x in data]
            if PgSQL and isinstance(data, PgSQL.PgBooleanType):
                if data:
                    return u"true"
                return u"false"
            if type(data) == str:
                return unicode(data, errors='ignore')
            if isinstance(data, rend.Fragment):
                io = StringIO()
                writer = io.write
                finisher = lambda result: io.getvalue()
                newctx = context.PageContext(parent=ctx, tag=data)
                data.rememberStuff(newctx)
                doc = data.docFactory.load()
                newctx = context.WovenContext(newctx, T.invisible[doc])
                fl = self.flattenFactory(doc, newctx, writer, finisher)
                fl.addCallback(sanitize, None)
                d.append(fl)
                return fl
            if isinstance(data, defer.Deferred):
                if data.called:
                    return sanitize(data.result)
                return data
            if isinstance(data, failure.Failure):
                return unicode(
                    "<span class='error'>An error occured (%s)</span>" %
                    data.getErrorMessage(),
                    errors='ignore')
            return data

        def serialize(data):
            return json.serialize(sanitize(data))

        d = []
        data = sanitize(data, d)
        d = defer.DeferredList(d)
        d.addCallback(lambda x: serialize(data))
        return d
コード例 #7
0
class Page(Fragment, ConfigurableFactory, ChildLookupMixin):
    """A page is the main Nevow resource and renders a document loaded
    via the document factory (docFactory).
    """

    __implements__ = Fragment.__implements__, inevow.IResource, ConfigurableFactory.__implements__

    buffered = False

    beforeRender = None
    afterRender = None
    addSlash = None

    flattenFactory = lambda self, *args: flat.flattenFactory(*args)

    def renderHTTP(self, ctx):
        if self.beforeRender is not None:
            return util.maybeDeferred(self.beforeRender, ctx).addCallback(
                lambda result, ctx: self._renderHTTP(ctx), ctx)
        return self._renderHTTP(ctx)

    def _renderHTTP(self, ctx):
        request = inevow.IRequest(ctx)
        ## XXX request is really ctx now, change the name here
        if self.addSlash and inevow.ICurrentSegments(ctx)[-1] != '':
            request.redirect(request.URLPath().child(''))
            return ''

        log.msg(http_render=None, uri=request.uri)

        self.rememberStuff(ctx)

        def finishRequest():
            carryover = request.args.get('_nevow_carryover_', [None])[0]
            if carryover is not None and _CARRYOVER.has_key(carryover):
                del _CARRYOVER[carryover]
            if self.afterRender is not None:
                return util.maybeDeferred(self.afterRender, ctx)

        if self.buffered:
            io = StringIO()
            writer = io.write

            def finisher(result):
                request.write(io.getvalue())
                return util.maybeDeferred(finishRequest).addCallback(
                    lambda r: result)
        else:
            writer = request.write

            def finisher(result):
                return util.maybeDeferred(finishRequest).addCallback(
                    lambda r: result)

        doc = self.docFactory.load(ctx)
        ctx = WovenContext(ctx, tags.invisible[doc])

        return self.flattenFactory(doc, ctx, writer, finisher)

    def rememberStuff(self, ctx):
        Fragment.rememberStuff(self, ctx)
        ctx.remember(self, inevow.IResource)

    def renderString(self):
        """Render this page outside of the context of a web request, returning
        a Deferred which will result in a string.

        If twisted is not installed, this method will return a string result immediately,
        and this method is equivalent to renderSynchronously.
        """
        io = StringIO()
        writer = io.write

        def finisher(result):
            return io.getvalue()

        ctx = PageContext(tag=self)
        self.rememberStuff(ctx)
        doc = self.docFactory.load(ctx)
        ctx = WovenContext(ctx, tags.invisible[doc])

        return self.flattenFactory(doc, ctx, writer, finisher)

    def renderSynchronously(self):
        """Render this page synchronously, returning a string result immediately.
        Raise an exception if a Deferred is required to complete the rendering
        process.
        """
        io = StringIO()

        ctx = PageContext(tag=self)
        self.rememberStuff(ctx)
        doc = self.docFactory.load(ctx)
        ctx = WovenContext(ctx, tags.invisible[doc])

        def raiseAlways(item):
            raise NotImplementedError("renderSynchronously can not support"
                                      " rendering: %s" % (item, ))

        list(flat.iterflatten(doc, ctx, io.write, raiseAlways))

        return io.getvalue()

    def child_(self, ctx):
        """When addSlash is True, a page rendered at a url with no
        trailing slash and a page rendered at a url with a trailing
        slash will be identical. addSlash is useful for the root
        resource of a site or directory-like resources.
        """
        # Only allow an empty child, by default, if it's on the end
        # and we're a directoryish resource (addSlash = True)
        if self.addSlash and len(inevow.IRemainingSegments(ctx)) == 1:
            return self

        # After deprecation is removed, this should return None
        warnings.warn(
            "Allowing an empty child ('/') of resources automatically is "
            "deprecated. If the class '%s' is a directory-index-like resource, "
            "please add addSlash=True to the class definition." %
            (self.__class__), DeprecationWarning, 2)

        return self

    def webFormPost(self, request, res, configurable, ctx, bindingName, args):
        def redirectAfterPost(aspects):
            redirectAfterPost = request.getComponent(
                iformless.IRedirectAfterPost, None)
            if redirectAfterPost is None:
                ref = request.getHeader('referer') or ''
            else:
                ## Use the redirectAfterPost url
                ref = str(redirectAfterPost)
            from nevow import url
            refpath = url.URL.fromString(ref)
            magicCookie = '%s%s%s' % (now(), request.getClientIP(),
                                      random.random())
            refpath = refpath.replace('_nevow_carryover_', magicCookie)
            _CARRYOVER[magicCookie] = C = compy.Componentized(aspects)
            request.redirect(str(refpath))
            from nevow import static
            return static.Data('You posted a form to %s' % bindingName,
                               'text/plain'), ()

        return util.maybeDeferred(
            configurable.postForm, ctx, bindingName, args).addCallback(
                self.onPostSuccess, request, ctx, bindingName,
                redirectAfterPost).addErrback(self.onPostFailure, request, ctx,
                                              bindingName, redirectAfterPost)

    def onPostSuccess(self, result, request, ctx, bindingName,
                      redirectAfterPost):
        if result is None:
            message = "%s success." % formless.nameToLabel(bindingName)
        else:
            message = result

        return redirectAfterPost({
            inevow.IHand: result,
            inevow.IStatusMessage: message
        })

    def onPostFailure(self, reason, request, ctx, bindingName,
                      redirectAfterPost):
        reason.trap(formless.ValidateError)
        return redirectAfterPost(
            {iformless.IFormErrors: {
                bindingName: reason.value
            }})
コード例 #8
0
ファイル: _flat.py プロジェクト: NonPlayerCtrl/FreePLC_IDE
def _flatten(request, root, slotData, renderFactory, inAttribute, inXML):
    """
    Make C{root} slightly more flat by yielding all or part of it as strings or
    generators.

    @param request: A request object which will be passed to
        L{IRenderable.render}.

    @param root: An object to be made flatter.  This may be of type C{unicode},
        C{str}, L{raw}, L{Proto}, L{xml}, L{slot}, L{_PrecompiledSlot}, L{Tag},
        L{URL}, L{tuple}, L{list}, L{GeneratorType}, L{Entity}, L{Deferred}, or
        it may be an object which is adaptable to L{IRenderable}.  Deprecated
        backwards-compatibility support is also present for objects adaptable
        to L{IRenderer} or for which a flattener has been registered via
        L{registerFlattener}.

    @param slotData: A C{list} of C{dict} mapping C{str} slot names to data
        with which those slots will be replaced.

    @param inAttribute: A flag which, if set, indicates that C{str} and
        C{unicode} instances encountered must be quoted as for XML tag
        attribute values.

    @param inXML: A flag which, if set, indicates that C{str} and C{unicode}
        instances encountered must be quoted as for XML text node data.

    @return: An iterator which yields C{str}, L{Deferred}, and more iterators
        of the same type.
    """
    if isinstance(root, unicode):
        root = root.encode('utf-8')
    elif isinstance(root, WovenContext):
        # WovenContext is supported via the getFlattener case, but that is a
        # very slow case.  Checking here is an optimization.  It also lets us
        # avoid the deprecation warning which would be emitted whenever a
        # precompiled document was flattened, since those contain WovenContexts
        # for tags with render directives. -exarkun
        inAttribute = root.isAttrib
        inXML = True
        root = root.tag

    if isinstance(root, raw):
        root = str(root)
        if inAttribute:
            root = root.replace('"', '&quot;')
        yield root
    elif isinstance(root, Proto):
        root = str(root)
        if root:
            if root in allowSingleton:
                yield '<' + root + ' />'
            else:
                yield '<' + root + '></' + root + '>'
    elif isinstance(root, str):
        yield escapedData(root, inAttribute, inXML)
    elif isinstance(root, slot):
        slotValue = _getSlotValue(root.name, slotData)
        yield _flatten(request, slotValue, slotData, renderFactory,
                       inAttribute, inXML)
    elif isinstance(root, _PrecompiledSlot):
        slotValue = _getSlotValue(root.name, slotData)
        yield _flatten(request, slotValue, slotData, renderFactory,
                       root.isAttrib, inXML)
    elif isinstance(root, Tag):
        if root.pattern is Unset or root.pattern is None:
            slotData.append(root.slotData)
            if root.render is Unset:
                if not root.tagName:
                    for element in _flatten(request, root.children,
                                            slotData, renderFactory,
                                            False, True):
                        yield element
                else:
                    yield '<'
                    if isinstance(root.tagName, unicode):
                        tagName = root.tagName.encode('ascii')
                    else:
                        tagName = str(root.tagName)
                    yield tagName
                    for k, v in root.attributes.iteritems():
                        if isinstance(k, unicode):
                            k = k.encode('ascii')
                        yield " " + k + "=\""
                        for element in _flatten(request, v, slotData,
                                                renderFactory, True, True):
                            yield element
                        yield "\""
                    if root.children or tagName not in allowSingleton:
                        yield '>'
                        for element in _flatten(request, root.children,
                                                slotData, renderFactory,
                                                False, True):
                            yield element
                        yield '</' + tagName + '>'
                    else:
                        yield ' />'
            else:
                if isinstance(root.render, directive):
                    rendererName = root.render.name
                else:
                    rendererName = root.render
                root = root.clone(False)
                del root._specials['render']
                result = renderFactory.renderer(rendererName)(request, root)
                yield _flatten(request, result, slotData, renderFactory, None,
                               inXML)
            slotData.pop()
    elif isinstance(root, URL):
        yield escapedData(str(root), inAttribute, inXML)
    elif isinstance(root, (tuple, list, GeneratorType)):
        for element in root:
            yield _flatten(request, element, slotData, renderFactory,
                           inAttribute, inXML)
    elif isinstance(root, Entity):
        yield '&#'
        yield root.num
        yield ';'
    elif isinstance(root, xml):
        if isinstance(root.content, unicode):
            yield root.content.encode('utf-8')
        else:
            yield root.content
    elif isinstance(root, Deferred):
        yield root.addCallback(
            lambda result: (result, _flatten(request, result, slotData,
                                             renderFactory, inAttribute,
                                             inXML)))
    else:
        renderable = IRenderable(root, None)
        if renderable is not None:
            # [] for the slotData parameter of this call to _flatten means
            # slots returned by this renderable's render method won't be filled
            # with data which has so far accumulated in the slotData stack.
            # This seems like a reasonable thing to me, since a renderable is a
            # piece of Python code.  It should be isolated from this other
            # stuff, which is primarily data. -exarkun
            yield _flatten(request, renderable.render(request), [], renderable,
                           inAttribute, inXML)
        else:
            renderer = IRenderer(root, None)
            if renderer is not None:
                ctx = _ctxForRequest(request, slotData, None, inAttribute)
                results = []
                synchronous = []
                flattened = flattenFactory(renderer, ctx, results.append,
                                           lambda ign: None)
                def cbFlattened(result):
                    synchronous.append(None)
                    return (result, (str(s) for s in results))
                flattened.addCallback(cbFlattened)
                if synchronous:
                    yield ''.join(map(str, results))
                else:
                    yield flattened
            else:
                flattener = getFlattener(root)
                if flattener is not None:
                    ctx = _ctxForRequest(request, slotData, renderFactory,
                                         inAttribute)
                    yield _flatten(request, flattener(root, ctx), slotData,
                                   renderFactory, False, False)
                else:
                    raise UnsupportedType(root)