[pod] Added param Renderer.raiseOnError (False by default), that, if True, will force the Renderer to raise an error instead of dumping it into a note in the pod result.

This commit is contained in:
Gaetan Delannay 2014-06-23 12:54:32 +02:00
parent 114223a114
commit f8f3c0e865
6 changed files with 75 additions and 61 deletions

View file

@ -450,6 +450,9 @@ class BaseMixin:
if isNew and initiator:
return self.goto(initiator.getUrl(page=initiatorPage, nav=''))
return self.goto(obj.getUrl())
# Get the current page name. We keep it in "pageName" because rq['page']
# can be changed by m_getAppyPhases called below.
pageName = rq['page']
if buttonClicked == 'previous':
# Go to the previous page for this object.
# We recompute the list of phases and pages because things
@ -459,7 +462,7 @@ class BaseMixin:
# pages may not be available in "edit" mode, so we return the edit
# or view pages depending on page.show.
phaseObj = self.getAppyPhases(currentOnly=True, layoutType='edit')
pageName, pageInfo = phaseObj.getPreviousPage(rq['page'])
pageName, pageInfo = phaseObj.getPreviousPage(pageName)
if pageName:
# Return to the edit or view page?
if pageInfo.showOnEdit:
@ -476,10 +479,8 @@ class BaseMixin:
return self.goto(obj.getUrl(inPopup=inPopup))
if buttonClicked == 'next':
# Go to the next page for this object.
# We remember page name, because the next method may set a new
# current page if the current one is not visible anymore.
phaseObj = self.getAppyPhases(currentOnly=True, layoutType='edit')
pageName, pageInfo = phaseObj.getNextPage(rq['page'])
pageName, pageInfo = phaseObj.getNextPage(pageName)
if pageName:
# Return to the edit or view page?
if pageInfo.showOnEdit:

View file

@ -46,8 +46,6 @@ class BufferAction:
# content. If 'from', we must dump what comes from the 'from' part of
# the action (='fromExpr')
self.fromExpr = fromExpr
# When an error occurs, must we raise it or write it into the buffer?
self.raiseErrors = not self.buffer.pod
# Several actions may co-exist for the same buffer, as a chain of
# BufferAction instances, defined via the following attribute.
self.subAction = None
@ -59,8 +57,8 @@ class BufferAction:
def manageError(self, result, context, errorMessage, dumpTb=True):
'''Manage the encountered error: dump it into the buffer or raise an
exception if self.raiseErrors is True.'''
if self.raiseErrors:
exception.'''
if self.buffer.env.raiseOnError:
if not self.buffer.pod:
# Add in the error message the line nb where the errors occurs
# within the PX.

View file

@ -224,7 +224,11 @@ class FileBuffer(Buffer):
if escape: self.dumpContent(res)
else: self.write(res)
except Exception, e:
PodError.dump(self, EVAL_EXPR_ERROR % (expression, e), dumpTb=False)
if not self.env.raiseOnError:
PodError.dump(self, EVAL_EXPR_ERROR % (expression, e),
dumpTb=False)
else:
raise Exception(EVAL_EXPR_ERROR % (expression, e))
def addAttributes(self):
# Into a FileBuffer, it is not possible to insert Attributes. Every
@ -666,10 +670,10 @@ class MemoryBuffer(Buffer):
if escape: result.dumpContent(res)
else: result.write(res)
except Exception, e:
if self.pod:
if not self.env.raiseOnError:
PodError.dump(result, EVAL_EXPR_ERROR % (
evalEntry.expr, e), dumpTb=False)
else: # px
else:
raise Exception(EVAL_EXPR_ERROR %(evalEntry.expr,e))
elif isinstance(evalEntry, Attributes) or \
isinstance(evalEntry, Attribute):

View file

@ -107,6 +107,9 @@ class PodEnvironment(OdfEnvironment):
self.currentOdsHook = None
# Names of some tags, that we will compute after namespace propagation
self.tags = None
# When an error occurs, must we raise it or write it into he current
# buffer?
self.raiseOnError = None # Will be initialized by PodParser.__init__
def getTable(self):
'''Gets the currently parsed table.'''
@ -219,6 +222,7 @@ class PodEnvironment(OdfEnvironment):
class PodParser(OdfParser):
def __init__(self, env, caller):
OdfParser.__init__(self, env, caller)
env.raiseOnError = caller.raiseOnError
def endDocument(self):
self.env.currentBuffer.content.close()

View file

@ -101,21 +101,21 @@ class Renderer:
def __init__(self, template, context, result, pythonWithUnoPath=None,
ooPort=2002, stylesMapping={}, forceOoCall=False,
finalizeFunction=None, overwriteExisting=False,
imageResolver=None):
raiseOnError=False, imageResolver=None):
'''This Python Open Document Renderer (PodRenderer) loads a document
template (p_template) which is an ODT file with some elements
written in Python. Based on this template and some Python objects
defined in p_context, the renderer generates an ODT file
(p_result) that instantiates the p_template and fills it with objects
from the p_context.
template (p_template) which is an ODT file with some elements written
in Python. Based on this template and some Python objects defined in
p_context, the renderer generates an ODT file (p_result) that
instantiates the p_template and fills it with objects from the
p_context.
- If p_result does not end with .odt, the Renderer
will call LibreOffice to perform a conversion. If p_forceOoCall is
True, even if p_result ends with .odt, LibreOffice will be called, not
for performing a conversion, but for updating some elements like
indexes (table of contents, etc) and sections containing links to
external files (which is the case, for example, if you use the
default function "document").
- If p_result does not end with .odt, the Renderer will call
LibreOffice to perform a conversion. If p_forceOoCall is True, even
if p_result ends with .odt, LibreOffice will be called, not for
performing a conversion, but for updating some elements like indexes
(table of contents, etc) and sections containing links to externa
files (which is the case, for example, if you use the default
function "document").
- If the Python interpreter which runs the current script is not
UNO-enabled, this script will run, in another process, a UNO-enabled
@ -137,6 +137,10 @@ class Renderer:
the result file. Else, an exception will be thrown if the result file
already exists.
- If p_raiseOnError is False (the default value), any error encountered
during the generation of the result file will be dumped into it, as
a Python traceback within a note. Else, the error will be raised.
- p_imageResolver allows POD to retrieve images, from "img" tags within
XHTML content. Indeed, POD may not be able (ie, may not have the
permission to) perform a HTTP GET on those images. Currently, the
@ -156,6 +160,7 @@ class Renderer:
self.forceOoCall = forceOoCall
self.finalizeFunction = finalizeFunction
self.overwriteExisting = overwriteExisting
self.raiseOnError = raiseOnError
self.imageResolver = imageResolver
# Remember potential files or images that will be included through
# "do ... from document" statements: we will need to declare them in
@ -424,17 +429,20 @@ class Renderer:
# Public interface
def run(self):
'''Renders the result.'''
# Remember which parser is running
self.currentParser = self.contentParser
# Create the resulting content.xml
self.currentParser.parse(self.contentXml)
self.currentParser = self.stylesParser
# Create the resulting styles.xml
self.currentParser.parse(self.stylesXml)
# Patch META-INF/manifest.xml
self.patchManifest()
# Re-zip the result
self.finalize()
try:
# Remember which parser is running
self.currentParser = self.contentParser
# Create the resulting content.xml
self.currentParser.parse(self.contentXml)
self.currentParser = self.stylesParser
# Create the resulting styles.xml
self.currentParser.parse(self.stylesXml)
# Patch META-INF/manifest.xml
self.patchManifest()
# Re-zip the result
self.finalize()
finally:
FolderDeleter.delete(self.tempFolder)
def getStyles(self):
'''Returns a dict of the styles that are defined into the template.'''
@ -582,31 +590,28 @@ class Renderer:
resultZip.writestr(zInfo, '')
resultZip.close()
resultType = os.path.splitext(self.result)[1].strip('.')
try:
if (resultType in self.templateTypes) and not self.forceOoCall:
# Simply move the ODT result to the result
os.rename(resultName, self.result)
else:
if resultType not in FILE_TYPES:
raise PodError(BAD_RESULT_TYPE % (
self.result, FILE_TYPES.keys()))
# Call LibreOffice to perform the conversion or document update.
output = self.callLibreOffice(resultName, resultType)
# I (should) have the result. Move it to the correct name.
resPrefix = os.path.splitext(resultName)[0]
if resultType in self.templateTypes:
# converter.py has (normally!) created a second file
# suffixed .res.[resultType]
finalResultName = '%s.res.%s' % (resPrefix, resultType)
if not os.path.exists(finalResultName):
finalResultName = resultName
# In this case OO in server mode could not be called to
# update indexes, sections, etc.
else:
finalResultName = '%s.%s' % (resPrefix, resultType)
if (resultType in self.templateTypes) and not self.forceOoCall:
# Simply move the ODT result to the result
os.rename(resultName, self.result)
else:
if resultType not in FILE_TYPES:
raise PodError(BAD_RESULT_TYPE % (
self.result, FILE_TYPES.keys()))
# Call LibreOffice to perform the conversion or document update.
output = self.callLibreOffice(resultName, resultType)
# I (should) have the result. Move it to the correct name.
resPrefix = os.path.splitext(resultName)[0]
if resultType in self.templateTypes:
# converter.py has (normally!) created a second file
# suffixed .res.[resultType]
finalResultName = '%s.res.%s' % (resPrefix, resultType)
if not os.path.exists(finalResultName):
raise PodError(CONVERT_ERROR % output)
os.rename(finalResultName, self.result)
finally:
FolderDeleter.delete(self.tempFolder)
finalResultName = resultName
# In this case OO in server mode could not be called to
# update indexes, sections, etc.
else:
finalResultName = '%s.%s' % (resPrefix, resultType)
if not os.path.exists(finalResultName):
raise PodError(CONVERT_ERROR % output)
os.rename(finalResultName, self.result)
# ------------------------------------------------------------------------------

View file

@ -30,6 +30,8 @@ class PxEnvironment(XmlEnvironment):
# XmlParser for better performance. Indeed, the base parser and env
# process namespaces, and we do not need this for the PX parser.
self.currentElem = None
# Exceptions are always raised (for pod, it is not the case)
self.raiseOnError = True
def addSubBuffer(self):
subBuffer = self.currentBuffer.addSubBuffer()