From 3ee673c2731c3f95398f6999df70ab73cb8bb16b Mon Sep 17 00:00:00 2001 From: sebd <> Date: Tue, 17 May 2005 15:07:45 +0000 Subject: [PATCH] preliminary support for SVG (used with XQuery in supplied example) --- README.quickstart | 3 ++ config-dbxmltest.xml | 1 + src/core/namespaces.py | 6 +++ src/modules/dbxmldatabases.py | 83 ++++++++++++++++++++++++---------- src/modules/svg.py | 68 ++++++++++++++++++++++++++++ vhosts/dbxmltest/xquerysvg.xml | 30 ++++++++++++ 6 files changed, 166 insertions(+), 25 deletions(-) create mode 100644 src/modules/svg.py create mode 100644 vhosts/dbxmltest/xquerysvg.xml diff --git a/README.quickstart b/README.quickstart index 2c42e5f..8e75ae4 100644 --- a/README.quickstart +++ b/README.quickstart @@ -35,6 +35,9 @@ For Tidy support, add packages: and install Python library uTidyLib : python setup.py install --prefix /usr/local +For SVG support, you need package svg2png, add this to /etc/apt/sources.list: +deb http://cairographics.org/packages/debian/ unstable/ + CVS Checkout ------------ diff --git a/config-dbxmltest.xml b/config-dbxmltest.xml index f46c169..eb158b8 100644 --- a/config-dbxmltest.xml +++ b/config-dbxmltest.xml @@ -1,6 +1,7 @@ expression.pid + diff --git a/src/core/namespaces.py b/src/core/namespaces.py index c462b86..37f504f 100644 --- a/src/core/namespaces.py +++ b/src/core/namespaces.py @@ -28,6 +28,8 @@ _names = {} _uris = {} nsList = [] +nsFromName = {} +nsFromUri = {} class Namespace(object): @@ -40,6 +42,8 @@ class Namespace(object): _names[uri] = name _uris[name] = uri nsList.append(self) + nsFromName[name] = self + nsFromUri[uri] = self def getName(uri): @@ -60,9 +64,11 @@ html = Namespace("html", "http://www.w3.org/1999/xhtml") mail = Namespace("mail", "http://www.entrouvert.org/namespaces/email/0.0") md = Namespace("md", "urn:liberty:metadata:2003-08") ooo = Namespace("ooo", "http://openoffice.org/2000/office") +svg = Namespace("svg", "http://www.w3.org/2000/svg") xforms = Namespace("xforms", "http://www.w3.org/2002/xforms") xhtml2 = Namespace("xhtml2", "http://www.w3.org/2002/06/xhtml2") xsd = Namespace("xsd", "http://www.w3.org/2001/XMLSchema") xslt = Namespace("xslt", "http://www.w3.org/1999/XSL/Transform") xsi = Namespace("xsi", "http://www.w3.org/2001/XMLSchema-instance") yep = Namespace("yep", "http://www.entrouvert.org/namespaces/expression/0.0") + diff --git a/src/modules/dbxmldatabases.py b/src/modules/dbxmldatabases.py index ea454a1..f47673d 100644 --- a/src/modules/dbxmldatabases.py +++ b/src/modules/dbxmldatabases.py @@ -37,6 +37,7 @@ import libxml2 import expression.core.elements as elements import expression.core.environs as environs import expression.core.dataholders as dataholders +import expression.core.faults as faults import expression.core.html as html import expression.core.logs as logs import expression.core.namespaces as namespaces @@ -90,41 +91,73 @@ class DbXmlDatabase(dataholders.DataHolder): class XQuery(things.Thing): """ Element xquery contains an XQuery expression to be evaluated. """ + _results = None + _errorMessage = None + + def __init__(self, *a, **b): + super(XQuery, self).__init__(*a, **b) + self._results = None + self._errorMessage = None + + def getResults(self): + """ Evaluates the content of this element as an XQuery expression + and returns results. + """ + if self._results is None: + manager = DbXmlDatabase._manager + queryContext = manager.createQueryContext() + childNodes = self.evaluateXpath("*") + query = childNodes[0].serialize() + try: + self._results = manager.query(query, queryContext) + except RuntimeError, e: + logs.error("XQuery failed: %s" % e) + logs.error("Query was: %s" % query) + self._errorMessage = e + return self._results + def generateXml(self, layout): """ Appends "layout" with the result of this query """ - manager = DbXmlDatabase._manager - queryContext = manager.createQueryContext() - try: - results = manager.query(self.node.content, queryContext) - except RuntimeError, e: - logs.error("Error in query: %s" % e) - layout.append(html.p(_("Error in query: %s") % e)) + # output is not an XML document, let's try it as a list of docs. + result = self.getResults() + if result is None: return False - output = "\n".join([value.asString() for value in results]) + results.reset() try: - doc = libxml2.readDoc(output, None, None, 0) + div = html.div() + for value in results: + doc = libxml2.readDoc(value.asString(), None, None, 0) + element = self.newElement(doc.getRootElement()) + element.generateXml(div) + layout.append(div) except libxml2.treeError: - # output is not an XML document, let's try it as a list of docs. + # values are not whole XML docs. Let's put them in

. results.reset() + div = html.div() + for value in results: + div.append(html.p(value.asString())) + layout.append(div) + + def styled(self): + """ Handles HTTP GET. + """ + command = environs.getVar("httpCommand") + if command == "GET": + results = self.getResults() + if results is None: + raise faults.PathNotFound("") # FIXME: display error message + output = "\n".join([value.asString() for value in results]).strip() + logs.debug("results: %s" % output) try: - div = html.div() - for value in results: - doc = libxml2.readDoc(value.asString(), None, None, 0) - element = self.newElement(doc.getRootElement()) - element.generateXml(div) - layout.append(div) - print div.serialize() + doc = libxml2.readDoc(output, None, None, 0) except libxml2.treeError: - # values are not whole XML docs. Let's put them in

. - results.reset() - div = html.div() - for value in results: - div.append(html.p(value.asString())) - layout.append(div) + return super(XQuery, self).styled() + element = self.newElement(doc.getRootElement()) + element.doHttpGet() else: - layout.append(doc.getRootElement()) - return True + raise faults.PathNotFound("") + elements.registerElement(namespaces.yep.uri, "xquery", XQuery) diff --git a/src/modules/svg.py b/src/modules/svg.py new file mode 100644 index 0000000..2fd4745 --- /dev/null +++ b/src/modules/svg.py @@ -0,0 +1,68 @@ +# -*- coding: UTF-8 -*- + + +# Expression +# By: Frederic Peters +# Emmanuel Raviart +# Sébastien Ducoulombier +# +# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +"""SVG Module""" + + +import os +import tempfile + +import expression.core.elements as elements +import expression.core.environs as environs +import expression.core.dataholders as dataholders +import expression.core.logs as logs +import expression.core.namespaces as namespaces +import expression.core.things as things + + +class SVGHolder(dataholders.StaticDataHolder): + """ An Xml document file that gets returned as a PNG file. """ + + def getDataFile(self): + """ Renders the PNG file, and returns its content. + """ + filename = self.getAbsolutePathName() + cachefile = filename + ".cache" + #FIXME : test whether the filename is more recent than the cache file. If so, return the cache file, else regenerate it first. + os.system("svg2png %s %s" % (filename, cachefile)) + return open(cachefile) + + +class SVG(things.Thing): + """ Element svg that contains an SVG document to be rendered. + """ + def doHttpGet(self): + """ Renders the PNG file and HTTP-returns its content. + """ + file = tempfile.NamedTemporaryFile() + file.write("""\n%s""" % self.serialize()) + file.flush() + outfile = file.name + ".temp" + os.system("svg2png < %s > %s" % (file.name, outfile)) + environs.getVar("httpRequestHandler").outputData(open(outfile).read(), mimeType = "image/png") + os.unlink(outfile) + + +elements.registerElement(namespaces.svg.uri, "svg", SVG) diff --git a/vhosts/dbxmltest/xquerysvg.xml b/vhosts/dbxmltest/xquerysvg.xml new file mode 100644 index 0000000..d1641ca --- /dev/null +++ b/vhosts/dbxmltest/xquerysvg.xml @@ -0,0 +1,30 @@ + + + + { + for $t at $c in collection("test.dbxml")/*/*/text() + return {$t} + } + +