def handleSegment(self, result, request, path, pageContext): if result is errorMarker: return errorMarker newres, newpath = result # If the child resource is None then display a 404 page if newres is None: from nevow.rend import FourOhFour return context.PageContext(tag=FourOhFour(), parent=pageContext) # If we got a deferred then we need to call back later, once the # child is actually available. if isinstance(newres, defer.Deferred): return newres.addCallback( lambda actualRes: self.handleSegment( (actualRes, newpath), request, path, pageContext)) # # FIX A GIANT LEAK. Is this code really useful anyway? # newres = inevow.IResource(newres)#, persist=True) if newres is pageContext.tag: assert not newpath is path, "URL traversal cycle detected when attempting to locateChild %r from resource %r." % (path, pageContext.tag) assert len(newpath) < len(path), "Infinite loop impending..." ## We found a Resource... update the request.prepath and postpath for x in xrange(len(path) - len(newpath)): if request.postpath: request.prepath.append(request.postpath.pop(0)) ## Create a context object to represent this new resource ctx = context.PageContext(tag=newres, parent=pageContext) ctx.remember(tuple(request.prepath), inevow.ICurrentSegments) ctx.remember(tuple(request.postpath), inevow.IRemainingSegments) res = newres path = newpath if not path: return ctx return defer.maybeDeferred( res.locateChild, ctx, path ).addErrback( processingFailed, request, ctx ).addCallback( self.handleSegment, request, path, ctx )
def _formatOutput(self, res, ctx): """actually delivers the whole document. This is basically nevow's rend.Page._renderHTTP, changed to provide less blocks. """ request = inevow.IRequest(ctx) if isinstance(res.original, tuple): # core returned a complete document (mime and string) mime, payload = res.original request.setHeader("content-type", mime) request.setHeader( 'content-disposition', 'attachment; filename=result%s' % common.getExtForMime(mime)) return streaming.streamOut(lambda f: f.write(payload), request) self.result = res if "response" in self.service.templates: self.customTemplate = self.service.getTemplate("response") ctx = context.PageContext(parent=ctx, tag=self) self.rememberStuff(ctx) doc = self.docFactory.load(ctx) ctx = context.WovenContext(ctx, T.invisible[doc]) return deliverYielding(doc, ctx, request)
def _cbFinishRender(self, html, ctx): """ Callback for the page rendering process having completed. @param html: Either the content of the response body (L{bytes}) or a marker that an exception occurred and has already been handled or an object adaptable to L{IResource} to use to render the response. """ if self._lostConnection: # No response can be sent at this point. pass elif isinstance(html, str): self.write(toBytes(html)) self.finishRequest(True) elif isinstance(html, bytes): self.write(html) self.finishRequest(True) elif html is errorMarker: ## Error webpage has already been rendered and finish called pass else: res = inevow.IResource(html) pageContext = context.PageContext(tag=res, parent=ctx) return self.gotPageContext(pageContext) return html
def gotPageContext(self, pageContext): if pageContext is errorMarker: return None html = pageContext.tag.renderHTTP(pageContext) if isinstance(html, util.Deferred): # This is a deferred object # Let us return it synchronously # (wsgi has nothing to do with sync, async) # XXX: Is this correct? html = html.result # FIXME: I dunno what to do when a generator comes .. # Perhaps, it may generate non-str? I dunno if type(html) is types.GeneratorType: html = ''.join(list(html)) if html is errorMarker: ## Error webpage has already been rendered and finish called pass elif isinstance(html, str): return html else: res = inevow.IResource(html, None) if res is not None: pageContext = context.PageContext(tag=res, parent=pageContext) return self.gotPageContext(pageContext) else: # import traceback; traceback.print_stack() print >> sys.stderr, "html is not a string: %s on %s" % ( str(html), pageContext.tag) return html
def deferredRender(res): defres = req() d = res.renderHTTP( context.PageContext(tag=res, parent=context.RequestContext(tag=defres))) def accumulated(result, req): return req.accumulator return d.addCallback(accumulated, defres)
def getPageContextForRequestContext(self, ctx): """Retrieve a resource from this site for a particular request. The resource will be wrapped in a PageContext which keeps track of how the resource was located. """ path = inevow.IRemainingSegments(ctx) res = inevow.IResource(self.resource) pageContext = context.PageContext(tag=res, parent=ctx) return self.handleSegment(res.locateChild(pageContext, path), ctx.tag, path, pageContext)
def _cbFinishRender(self, html, ctx): if isinstance(html, str): self.write(html) self.finishRequest(True) elif html is errorMarker: ## Error webpage has already been rendered and finish called pass else: res = inevow.IResource(html) pageContext = context.PageContext(tag=res, parent=ctx) return self.gotPageContext(pageContext) return html
def deferredRender(res, req): d = util.maybeDeferred(res.renderHTTP, context.PageContext( tag=res, parent=context.RequestContext( tag=req))) def done(result): if isinstance(result, str): req.write(result) return req d.addCallback(done) return d
def deferredRender(res): defres = req() d = util.maybeDeferred( res.renderHTTP, context.PageContext(tag=res, parent=context.RequestContext(tag=defres))) def done(result): if isinstance(result, str): defres.write(result) defres.d.callback(defres.accumulator) return result d.addCallback(done) return unittest.deferredResult(defres.d, 1)
def _cbFinishRender(self, html, ctx): if isinstance(html, str): self.write(html) server.Request.finish(self) elif html is errorMarker: ## Error webpage has already been rendered and finish called pass else: res = inevow.IResource(html, None) if res is not None: pageContext = context.PageContext(tag=res, parent=ctx) return self.gotPageContext(pageContext) else: print "html is not a string: %s on %s" % (str(html), ctx.tag) server.Request.finish(self) return html
def _doRender(page, ctx): """returns a deferred firing the result of page.renderHTTP(ctx). This is a helper for our nevow simulation. """ request = inevow.IRequest(ctx) if not hasattr(page, "renderHTTP"): return _requestDone(page, request, ctx) d = defer.maybeDeferred(page.renderHTTP, context.PageContext( tag=page, parent=context.RequestContext(tag=request))) d.addCallback(_requestDone, request, ctx) d.addErrback(_renderCrashAndBurn, ctx) return d
def makePage(self, content): _ = i18n.Translator(translator=mockTranslator) page = rend.Page( docFactory=loaders.stan(tags.invisible(render=tags.directive('i18n'))[content])) page.render_i18n = i18n.render(_) doc = page.docFactory.load() ctx = context.WovenContext(context.PageContext(tag=page), tags.invisible[doc]) page.rememberStuff(ctx) io = StringIO() writer = io.write def finisher(result): return io.getvalue() return page.flattenFactory(doc, ctx, writer, finisher)
def deferredRender(res, request=None): if request is None: request = testutil.AccumulatingFakeRequest() d = util.maybeDeferred( res.renderHTTP, context.PageContext(tag=res, parent=context.RequestContext(tag=request))) def done(result): if isinstance(result, str): request.write(result) request.d.callback(request.accumulator) return result d.addCallback(done) return request.d
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 renderIt(self): req = testutil.FakeRequest() self.r.renderHTTP(context.PageContext(tag=self.r, parent=context.RequestContext(tag=req))) return req
def setupContext(self, *args, **kw): ctx = test_flatstan.Base.setupContext(self, *args, **kw) return context.PageContext(tag=tags.html(), parent=ctx)
def test_page(self): page = context.PageContext(tag=1) page.remember(1, inevow.IData) ctx = context.WovenContext(page, tags.invisible()) self.assertEquals(ctx.locate(inevow.IData), 1) self.assertEquals(ctx.locate(inevow.IData, depth=-1), 1)