Source code for gavo.web.constantrender
"""
Renderer not reacting too strongly on user input.
There's StaticRender just delivering certain files from within a service,
and there's FixedPageRenderer that just formats a defined template.
"""
#c Copyright 2008-2023, the GAVO project <gavo@ari.uni-heidelberg.de>
#c
#c This program is free software, covered by the GNU GPL. See the
#c COPYING file in the source distribution.
import os
from twisted.web import server
from twisted.web import static
from gavo import base
from gavo import svcs
from gavo.web import grend
from gavo.web import ifpages
from gavo.web import weberrors
[docs]class StaticRenderer(grend.ServiceBasedPage):
"""A renderer that just hands through files.
The standard operation here is to set a staticData property pointing
to a resdir-relative directory used to serve files for. Indices
for directories are created.
You can define a root resource by giving an indexFile property on
the service. Note in particular that you can use an index file
with an extension of shtml. This lets you use nevow templates, but
since metadata will be taken from the global context, that's
probably not terribly useful. You are probably looking for the fixed
renderer if you find yourself needing this.
"""
name = "static"
defaultType = "text/html"
def __init__(self, request, service):
grend.ServiceBasedPage.__init__(self, request, service)
try:
self.indexFile = os.path.join(service.rd.resdir,
service.getProperty("indexFile"))
except base.NotFoundError:
self.indexFile = None
try:
self.staticPath = os.path.join(service.rd.resdir,
service.getProperty("staticData"))
except base.NotFoundError:
self.staticPath = None
[docs] @classmethod
def isBrowseable(self, service):
return service.getProperty("indexFile", None)
[docs] @classmethod
def isCacheable(cls, segments, request):
return False
[docs] def render(self, request):
if not request.uri.endswith(b"/"):
# only render these as directories
raise svcs.WebRedirect(request.uri+b"/")
if self.indexFile:
try:
return ifpages.StaticFile(self.indexFile, self.rd).render(request)
except os.error as ex:
raise base.NotFoundError(self.indexFile, "File", "file system",
hint=str(ex))
else:
if self.staticPath is None:
raise svcs.ForbiddenURI("No static data on this service")
return ifpages.DirectoryLister(self.staticPath).render(request)
[docs] def getChild(self, name, request):
segments = request.popSegments(name)
if segments==[""]:
return self
if self.staticPath is None:
raise svcs.ForbiddenURI("No static data on this service")
relPath = "/".join(segments)
destName = os.path.join(self.staticPath, relPath)
# make sure destName actually is below staticPath so stupid
# tricks with .. or similar don't work on us
if not os.path.abspath(destName).startswith(
os.path.abspath(self.staticPath)):
raise svcs.ForbiddenURI("%s is not located below staticData"%
destName)
if os.path.isdir(destName):
if not destName.endswith("/"):
raise svcs.WebRedirect(request.uri+b"/")
return static.File(destName).directoryListing()
elif os.path.isfile(destName):
return ifpages.StaticFile(destName, self.rd,
defaultType=self.defaultType)
else:
raise svcs.UnknownURI("No %s available here."%relPath)
[docs]class HiPSRenderer(StaticRenderer):
"""A static renderer with a few amenities for HiPS trees.
To make this work, set the service's staticData property
"""
name = "hips"
# for the benefit of properties
defaultType = "text/plain"
urlUse = "base"
def __init__(self, request, service):
super().__init__(request, service)
self.indexFile = os.path.join(self.staticPath, "index.html")
[docs] @classmethod
def isCacheable(cls, segments, request):
return False
[docs] @classmethod
def isBrowseable(self, service):
return True