def writeVOTable(outputFile): """writes a VOTable representation of the SvcResult instance data to request. """ if "tablecoding" not in contextOpts: contextOpts["tablecoding"] = { True: "td", False: "binary" }[data.queryMeta["tdEnc"]] if "version" not in contextOpts: contextOpts["version"] = data.queryMeta.get("VOTableVersion") votablewrite.writeAsVOTable( data.original, outputFile, ctx=votablewrite.VOTableContext(**contextOpts)) return ""
def writeResultTo(format, res, outF): # special-case votable formats to handle overflow conditions and such if format.startswith("votable"): # the following duplicates a mapping from votablewrite; that's # bad, and I should figure out a way to teach formats.format # whatever is needed to let it do what we're doing here. Meanwhile: enc = { "votable": "binary", "votableb2": "binary2", "votabletd": "td", }.get(format, "td") oe = None if getattr(res, "setLimit", None) is not None: oe = votable.OverflowElement(res.setLimit, votable.V.INFO(name="QUERY_STATUS", value="OVERFLOW")) ctx = votablewrite.VOTableContext( tablecoding=enc, acquireSamples=False, overflowElement=oe) votablewrite.writeAsVOTable(res, outF, ctx) else: formats.formatData(format, res, outF, acquireSamples=False)
def runForMeta(self, service, inputTable, queryMeta): """returns a rendered VOTable containing the datalinks. """ try: ctx = votablewrite.VOTableContext(tablecoding="td") vot = V.VOTABLE[self.getDatalinksResource(ctx, service), self._iterAccessResources(ctx, service)] if "text/html" in queryMeta["accept"]: # we believe it's a web browser; let it do stylesheet magic destMime = "text/xml" else: destMime = self.datalinkType destMime = str(inputTable.getParam("RESPONSEFORMAT") or destMime) if destMime == "votable": destMime = self.datalinkType res = (destMime, "<?xml-stylesheet href='/static/xsl/" "datalink-to-html.xsl' type='text/xsl'?>" + vot.render()) return res finally: self.finalize()
def getDatalinksResource(self, ctx, service): """returns a VOTable RESOURCE element with the data links. This does not contain the actual service definition elements, but it does contain references to them. You must pass in a VOTable context object ctx (for the management of ids). If this is the entire content of the VOTable, use votablewrite.VOTableContext() there. """ internalLinks = [] internalLinks.extend( LinkDef(s.pubDID, service.getURL(s.rendName), serviceType=ctx.getOrMakeIdFor(s), semantics="#proc") for s in self.datalinkEndpoints) for d in self.descriptors: # for all descriptors that are products, make a full dataset # available through the data access, possibly also adding a preview. if not isinstance(d, ProductDescriptor): continue if hasattr(d, "suppressAutoLinks"): continue # if the accref is a datalink document, go through dlget itself. if d.mime == "application/x-votable+xml;content=datalink": internalLinks.append( LinkDef(d.pubDID, service.getURL("dlget") + "?ID=%s" % urllib.quote(d.pubDID), description="The full dataset.", contentType=products.guessMediaType(d.accref), contentLength=d.estimateSize(), semantics="#this")) else: internalLinks.append( LinkDef(d.pubDID, products.makeProductLink(d.accref), description="The full dataset.", contentType=d.mime, contentLength=d.estimateSize(), semantics="#this")) if getattr(d, "preview", None): if d.preview.startswith("http"): previewLink = d.preview else: previewLink = products.makeProductLink( products.RAccref(d.accref, inputDict={"preview": True})) # TODO: preview mime is None for AUTO previews, and there's # not much we can do about it. Or is there? internalLinks.append( LinkDef(d.pubDID, previewLink, description="A preview for the dataset.", contentType=d.previewMime, semantics="#preview")) data = rsc.makeData( base.caches.getRD("//datalink").getById("make_response"), forceSource=self.datalinkLinks + internalLinks + self.errors) data.setMeta("_type", "results") return votablewrite.makeResource( votablewrite.VOTableContext(tablecoding="td"), data)
def _run_queryData(self, service, inputTable, queryMeta): format = inputTable.getParam("FORMAT") or "" if format.lower() == "metadata": return self._makeMetadata(service) limits = [ q for q in (inputTable.getParam("MAXREC", None), inputTable.getParam("TOP")) if q ] if not limits: limits = [base.getConfig("ivoa", "dalDefaultLimit")] limit = min(min(limits), base.getConfig("ivoa", "dalHardLimit")) queryMeta["dbLimit"] = limit res = svcs.DBCore.run(self, service, inputTable, queryMeta) if len(res) == limit: queryStatus = "OVERFLOW" queryStatusBody = ( "Exactly %s rows were returned. This means your" " query probably reached the match limit. Increase MAXREC." % limit) else: queryStatus = "OK" queryStatusBody = "" self._addPreviewLinks(res) # We wrap our result into a data instance since we need to set the # result type data = rsc.wrapTable(res) data.setMeta("_type", "results") data.addMeta("_votableRootAttributes", 'xmlns:ssa="http://www.ivoa.net/xml/DalSsap/v1.0"') # The returnRaw property is a hack, mainly for unit testing; # The renderer would have to add the QUERY_STATUS here. if service.getProperty("returnData", False): return data # we fix tablecoding to td for now since nobody seems to like # binary tables and we don't have huge tables here. votCtx = votablewrite.VOTableContext(tablecoding="td") vot = votablewrite.makeVOTable(data, votCtx) pubDIDId = votCtx.getIdFor(res.tableDef.getColumnByName("ssa_pubDID")) resElement = vot.getChildDict()["RESOURCE"][0] resElement[ V.INFO(name="SERVICE_PROTOCOL", value=self.ssapVersion)["SSAP"], V.INFO(name="QUERY_STATUS", value=queryStatus)[queryStatusBody]] datalinkId = service.getProperty("datalink", None) if datalinkId and res: dlService = self.rd.getById(datalinkId) dlCore = getDatalinkCore(dlService, res) # new and shiny datalink (keep) # (we're just using endpoint 0; it should a the sync service) dlEndpoint = dlCore.datalinkEndpoints[0] vot[dlEndpoint.asVOT(votCtx, dlService.getURL(dlEndpoint.rendName), linkIdTo=pubDIDId)] # Also point to the dl metadata service vot[V.RESOURCE(type="meta", utype="adhoc:service")[ V.PARAM(name="standardID", datatype="char", arraysize="*", value="ivo://ivoa.net/std/DataLink#links-1.0"), V.PARAM(name="accessURL", datatype="char", arraysize="*", value=self.rd.getById(datalinkId).getURL("dlmeta")), V.GROUP(name="inputParams")[V.PARAM( name="ID", datatype="char", arraysize="*", ref=pubDIDId, ucd="meta.id;meta.main" )[V.LINK(content_role="ddl:id-source", value="#" + pubDIDId)]]]] return "application/x-votable+xml", votable.asString(vot)