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

Source Code for Module gavo.web.vosi

  1  """ 
  2  VOSI renderers. 
  3   
  4  These are really three different renderers for each service.  IVOA wants 
  5  it this way (in effect, since they are supposed to be three different 
  6  capabilities). 
  7  """ 
  8   
  9  #c Copyright 2008-2019, the GAVO project 
 10  #c 
 11  #c This program is free software, covered by the GNU GPL.  See the 
 12  #c COPYING file in the source distribution. 
 13   
 14   
 15  from nevow import inevow 
 16  from nevow import rend 
 17  from twisted.internet import threads 
 18   
 19  from gavo import base 
 20  from gavo import registry 
 21  from gavo import svcs 
 22  from gavo import utils 
 23  from gavo.base import meta 
 24  from gavo.registry import capabilities 
 25  from gavo.registry import tableset 
 26  from gavo.registry.model import VS 
 27  from gavo.utils.stanxml import Element, registerPrefix, schemaURL, xsiPrefix 
 28  from gavo.utils.stanxml import write as writeXML 
 29  from gavo.web import grend 
 30   
 31   
 32  registerPrefix("avl", "http://www.ivoa.net/xml/VOSIAvailability/v1.0", 
 33          schemaURL("VOSIAvailability-v1.0.xsd")) 
 34  registerPrefix("cap", "http://www.ivoa.net/xml/VOSICapabilities/v1.0", 
 35          schemaURL("VOSICapabilities-v1.0.xsd")) 
 36  registerPrefix("vtm", "http://www.ivoa.net/xml/VOSITables/v1.0", 
 37          schemaURL("VOSITables-v1.0.xsd")) 
 38   
 39   
 40   
41 -class VOSIRenderer(grend.ServiceBasedPage):
42 """An abstract base for renderers handling VOSI requests. 43 44 All of these return some sort of XML and are legal on all services. 45 46 The actual documents returned are defined in _getTree(request)->deferred 47 firing stanxml. 48 """ 49 checkedRenderer = False 50
51 - def renderHTTP(self, ctx):
52 request = inevow.IRequest(ctx) 53 request.setHeader("content-type", "text/xml") 54 return threads.deferToThread(self._getTree, request 55 ).addCallback(self._shipout, ctx 56 ).addErrback(self._sendError, request)
57
58 - def _shipout(self, response, ctx):
59 return utils.xmlrender(response, 60 "<?xml-stylesheet href='/static/xsl/vosi.xsl' type='text/xsl'?>")
61
62 - def _sendError(self, failure, request):
63 request.setResponseCode(500) 64 request.setHeader("content-type", "text/plain") 65 request.write("Sorry -- we're experiencing severe problems.\n") 66 request.write("If you are reading this, you can help us by\n") 67 request.write("reporting the following to gavo@ari.uni-heidelberg.de:\n") 68 failure.printBriefTraceback(file=request) 69 return ""
70
71 - def _getTree(self, request):
72 raise ValueError("_getTree has not been overridden.")
73 74 75 ############ The VOSI data models (no better place for it yet) 76 77
78 -class AVL(object):
79 """The container for elements from the VOSI availability schema. 80 """
81 - class AVLElement(Element):
82 _prefix = "avl"
83
84 - class availability(AVLElement):
86 - class available(AVLElement): pass
87 - class upSince(AVLElement): pass
88 - class downAt(AVLElement): pass
89 - class backAt(AVLElement): pass
90 - class note(AVLElement): pass
91 92
93 -class CAP(object):
94 """The container for element from the VOSI capabilities schema. 95 """
96 - class CAPElement(Element):
97 _prefix = "cap"
98
99 - class capabilities(CAPElement):
100 _mayBeEmpty = True
101 102
103 -class VTM(object):
104 """The container for element from the VOSI tableset schema. 105 """
106 - class VTMElement(Element):
107 _prefix = "vtm"
108
109 - class tableset(VTMElement):
110 _mayBeEmpty = True
111
112 - class table(VTMElement, VS.table):
113 _mayBeEmpty = True 114 _local = False
115 116 117 118 SF = meta.stanFactory 119 120 _availabilityBuilder = meta.ModelBasedBuilder([ 121 ('available', SF(AVL.available)), 122 ('upSince', SF(AVL.upSince)), 123 ('_scheduledDowntime', SF(AVL.downAt)), 124 ('backAt', SF(AVL.backAt)), 125 ('availability_note', SF(AVL.note)), 126 ]) 127 128 129 ############ The actual VOSI renderers 130
131 -class VOSIAvailabilityRenderer(VOSIRenderer):
132 """A renderer for a VOSI availability endpoint. 133 134 An endpoint with this renderer is automatically registered for 135 every service. The answers can be configured using the admin 136 renderer. 137 """ 138 name = "availability" 139
140 - def _getTree(self, request):
144 145
146 -class VOSICapabilityRenderer(VOSIRenderer):
147 """A renderer for a VOSI capability endpoint. 148 149 An endpoint with this renderer is automatically registered for 150 every service. The responses contain information on what renderers 151 ("interfaces") are available for a service and what properties they have. 152 """ 153 name = "capabilities" 154
155 - def _getTree(self, request):
156 root = CAP.capabilities() 157 158 for pub in self.service.getPublicationsForSet(None): 159 try: 160 root = root[capabilities.getCapabilityElement(pub)] 161 except Exception: 162 base.ui.notifyError("Error while creating VOSI capability" 163 " for %s"%(self.service.getURL(pub.render, absolute=False))) 164 165 return root
166 167
168 -class VOSITableResponse(rend.Page):
169 """A resource building a VOSI tableset for a single table. 170 171 This is returned as a child resource of VOSITablesetRenderer. 172 """
173 - def __init__(self, tableDef):
174 self.tableDef = tableDef
175
176 - def renderHTTP(self, ctx):
177 return threads.deferToThread(self._getTree, ctx 178 ).addCallback(self._renderTree, ctx)
179
180 - def _getTree(self, ctx):
181 return tableset.getTableForTableDef(self.tableDef, [], 182 rootElement=VTM.table)
183
184 - def _renderTree(self, tree, ctx):
185 request = inevow.IRequest(ctx) 186 request.setHeader("content-type", "text/xml") 187 writeXML(tree, request) 188 return ""
189 190
191 -class VOSITablesetRenderer(VOSIRenderer):
192 """A renderer for a VOSI table metadata endpoint. 193 194 An endpoint with this renderer is automatically registered for 195 every service. The responses contain information on the tables 196 exposed by a given service. 197 """ 198 name = "tableMetadata" 199
200 - def _getTree(self, request):
201 detail = request.args.get("detail", 202 [base.getConfig("ivoa", "vositabledetail")])[0] 203 204 root = registry.getTablesetForService(self.service, 205 rootElement=VTM.tableset, suppressBodies=detail=="min") 206 return root
207
208 - def locateChild(self, ctx, segments):
209 if len(segments)==1 and segments[0]=="": 210 return self, () 211 212 # since our table names cannot contain slashes, the full name needs 213 # to be in one segment. 214 if len(segments)>1: 215 raise svcs.UnknownURI("VOSI tables resources have no children") 216 tableName = segments[0].lower() 217 218 for td in self.service.getTableSet(): 219 if td.getQName().lower()==tableName: 220 return VOSITableResponse(td), () 221 222 raise svcs.UnknownURI("No table %s on this service."%tableName)
223