preliminary support for SVG (used with XQuery in supplied example)

This commit is contained in:
sebd 2005-05-17 15:07:45 +00:00
parent 164ba65d48
commit 3ee673c273
6 changed files with 166 additions and 25 deletions

View File

@ -35,6 +35,9 @@ For Tidy <http://tidy.sourceforge.net/> support, add packages:
and install Python library uTidyLib <http://utidylib.berlios.de/>:
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
------------

View File

@ -1,6 +1,7 @@
<?xml version="1.0"?>
<configuration xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<pidFilePath>expression.pid</pidFilePath>
<module name="expression.modules.svg"/>
<module name="expression.modules.dbxmldatabases">
<environment dbHome="db"/>
<container name="test.dbxml"/>

View File

@ -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")

View File

@ -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 <p>.
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 <p>.
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)

68
src/modules/svg.py Normal file
View File

@ -0,0 +1,68 @@
# -*- coding: UTF-8 -*-
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Ducoulombier <sebastien.ducoulombier@lesdeveloppementsdurables.com>
#
# 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("""<?xml version="1.0"?>\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)

View File

@ -0,0 +1,30 @@
<?xml version="1.0"?>
<yep:xquery xmlns:yep="http://www.entrouvert.org/namespaces/expression/0.0">
<svg width="512pt" height="512pt" xmlns="http://www.w3.org/2000/svg">
{
for $t at $c in collection("test.dbxml")/*/*/text()
return <text
xml:space="preserve"
style="font-size:64;
font-style:normal;
font-variant:normal;
font-weight:bold;
font-stretch:normal;
fill:#f7b4bb;
fill-opacity:1;
fill-rule:nonzero;
stroke:#000000;
stroke-width:0.3;
stroke-linecap:round;
stroke-linejoin:round;
stroke-miterlimit:4;
stroke-opacity:1;
font-family:Bitstream Vera Sans;
text-anchor:left;
writing-mode:lr;"
x="0"
y="{64 * $c}"
>{$t}</text>
}
</svg>
</yep:xquery>