Package gavo :: Package web :: Module constantrender
[frames] | no frames]

Source Code for Module gavo.web.constantrender

  1  """ 
  2  Renderer not reacting too strongly on user input. 
  3   
  4  There's StaticRender just delivering certain files from within a service, 
  5  and there's FixedPageRenderer that just formats a defined template. 
  6  """ 
  7   
  8  #c Copyright 2008-2019, the GAVO project 
  9  #c 
 10  #c This program is free software, covered by the GNU GPL.  See the 
 11  #c COPYING file in the source distribution. 
 12   
 13   
 14  import os 
 15   
 16  from nevow import flat 
 17  from nevow import inevow 
 18  from nevow import static 
 19  from nevow import tags as T 
 20   
 21  from gavo import base 
 22  from gavo import svcs 
 23  from gavo.web import grend 
 24  from gavo.web import ifpages 
 25   
 26  __docformat__ = "restructuredtext en" 
27 28 -class StaticRenderer(grend.ServiceBasedPage):
29 """A renderer that just hands through files. 30 31 The standard operation here is to set a staticData property pointing 32 to a resdir-relative directory used to serve files for. Indices 33 for directories are created. 34 35 You can define a root resource by giving an indexFile property on 36 the service. Note in particular that you can use an index file 37 with an extension of shtml. This lets you use nevow templates, but 38 since metadata will be taken from the global context, that's 39 probably not terribly useful. You are probably looking for the fixed 40 renderer if you find yourself needing this. 41 """ 42 name = "static" 43
44 - def __init__(self, ctx, service):
45 grend.ServiceBasedPage.__init__(self, ctx, service) 46 try: 47 self.indexFile = os.path.join(service.rd.resdir, 48 service.getProperty("indexFile")) 49 except base.NotFoundError: 50 self.indexFile = None 51 try: 52 self.staticPath = os.path.join(service.rd.resdir, 53 service.getProperty("staticData")) 54 except base.NotFoundError: 55 self.staticPath = None
56 57 @classmethod
58 - def isBrowseable(self, service):
59 return service.getProperty("indexFile", None)
60 61 @classmethod
62 - def isCacheable(cls, segments, request):
63 return False
64
65 - def renderHTTP(self, ctx):
66 """The resource itself is the indexFile or the directory listing. 67 """ 68 # make sure there always is a slash at the end of any URL 69 # that points to any sort of index file (TODO: parse the URL?) 70 request = inevow.IRequest(ctx) 71 basePath = request.uri.split("?")[0] 72 if basePath.endswith("static/"): 73 if self.indexFile: 74 return ifpages.StaticFile(self.indexFile, self.rd) 75 else: 76 return static.File(self.staticPath).directoryListing() 77 78 elif basePath.endswith("static"): 79 raise svcs.WebRedirect(request.uri+"/") 80 81 else: 82 raise svcs.WebRedirect(request.uri.rstrip("/")+"/static/")
83
84 - def locateChild(self, ctx, segments):
85 if len(segments)==1 and not segments[0]: 86 return self, () 87 88 if self.staticPath is None: 89 raise svcs.ForbiddenURI("No static data on this service") 90 91 relPath = "/".join(segments) 92 destName = os.path.join(self.staticPath, relPath) 93 94 # make sure destName actually is below staticPath so stupid 95 # tricks with .. or similar don't work on us 96 if not os.path.abspath(destName).startswith( 97 os.path.abspath(self.staticPath)): 98 raise svcs.ForbiddenURI("%s is not located below staticData"% 99 destName) 100 101 if os.path.isdir(destName): 102 if not destName.endswith("/"): 103 raise svcs.WebRedirect(inevow.IRequest(ctx).uri+"/") 104 return static.File(destName).directoryListing(), () 105 106 elif os.path.isfile(destName): 107 return ifpages.StaticFile(destName, self.rd), () 108 109 else: 110 raise svcs.UnknownURI("No %s available here."%relPath)
111
112 113 -class FixedPageRenderer(grend.CustomTemplateMixin, grend.ServiceBasedPage):
114 """A renderer that renders a single template. 115 116 Use something like ``<template key="fixed">res/ft.html</template>`` 117 in the enclosing service to tell the fixed renderer where to get 118 this template from. 119 120 In the template, you can fetch parameters from the URL using 121 something like ``<n:invisible n:data="parameter FOO" n:render="string"/>``; 122 you can also define new render and data functions on the 123 service using customRF and customDF. 124 125 This is, in particular, used for the data center's root page. 126 127 The fixed renderer is intended for non- or slowly changing content. 128 It is annotated as cachable, which means that DaCHS will in general 129 only render it once and then cache it. If the render functions 130 change independently of the RD, use the volatile renderer. 131 132 Built-in services for such browser apps should go through the //run 133 RD. 134 """ 135 name = "fixed" 136
137 - def __init__(self, ctx, service):
138 grend.ServiceBasedPage.__init__(self, ctx, service) 139 self.customTemplate = None 140 try: 141 self.customTemplate = self.service.getTemplate("fixed") 142 except KeyError: 143 raise base.ui.logOldExc( 144 svcs.UnknownURI("fixed renderer needs a 'fixed' template"))
145
146 - def render_voplotArea(self, ctx, data):
147 """fills out the variable attributes of a voplot object with 148 stuff from config. 149 """ 150 # Incredibly, firefox about 2.x requires archive before code. 151 # so, we need to hack this. 152 baseURL = base.makeAbsoluteURL("/static/voplot") 153 res = flat.flatten(ctx.tag, ctx) 154 return T.xml(res.replace( 155 "<object", '<object archive="%s/voplot.jar"'%baseURL))
156
157 - def data_parameter(self, parName):
158 """lets you insert an URL parameter into the template. 159 160 Non-existing parameters are returned as an empty string. 161 """ 162 def getParameter(ctx, data): 163 return inevow.IRequest(ctx).args.get(parName, [""])[0]
164 return getParameter
165 166 @classmethod
167 - def isCacheable(cls, segments, request):
168 return True
169 170 @classmethod
171 - def isBrowseable(self, service):
172 return True
173
174 175 -class VolatilePageRenderer(FixedPageRenderer):
176 """A renderer rendering a single template with fast-changing results. 177 178 This is like the fixed renderer, except that the results are not cached. 179 """ 180 name = "volatile" 181 182 @classmethod
183 - def isCacheable(cls, segments, request):
184 return False
185