appypod-rattail/gen/plone25/mixins/PodTemplateMixin.py
2010-02-01 11:09:26 +01:00

112 lines
5.3 KiB
Python

# ------------------------------------------------------------------------------
import os, os.path, time, unicodedata
from appy.shared import mimeTypes
from appy.gen.plone25.mixins import AbstractMixin
from StringIO import StringIO
# ------------------------------------------------------------------------------
class PodError(Exception): pass
# ------------------------------------------------------------------------------
def getOsTempFolder():
tmp = '/tmp'
if os.path.exists(tmp) and os.path.isdir(tmp):
res = tmp
elif os.environ.has_key('TMP'):
res = os.environ['TMP']
elif os.environ.has_key('TEMP'):
res = os.environ['TEMP']
else:
raise "Sorry, I can't find a temp folder on your machine."
return res
# Error-related constants ------------------------------------------------------
POD_ERROR = 'An error occurred while generating the document. Please check ' \
'the following things if you wanted to generate the document in ' \
'PDF, DOC or RTF: (1) OpenOffice is started in server mode on ' \
'the port you should have specified in the PloneMeeting ' \
'configuration (go to Site setup-> PloneMeeting configuration); ' \
'(2) if the Python interpreter running Zope and ' \
'Plone is not able to discuss with OpenOffice (it does not have ' \
'"uno" installed - check it by typing "import uno" at the Python ' \
'prompt) please specify, in the PloneMeeting configuration, ' \
'the path to a UNO-enabled Python interpreter (ie, the Python ' \
'interpreter included in the OpenOffice distribution, or, if ' \
'your server runs Ubuntu, the standard Python interpreter ' \
'installed in /usr/bin/python). Here is the error as reported ' \
'by the appy.pod library:\n\n %s'
DELETE_TEMP_DOC_ERROR = 'A temporary document could not be removed. %s.'
# ------------------------------------------------------------------------------
class PodTemplateMixin(AbstractMixin):
_appy_meta_type = 'podtemplate'
unwantedChars = ('\\', '/', ':', '*', '?', '"', '<', '>', '|', ' ')
def _getFileName(self, obj):
'''Returns a valid, clean fileName for the document generated from
p_self for p_obj.'''
res = u'%s-%s' % (obj.Title().decode('utf-8'),
self.Title().decode('utf-8'))
# Remove accents
res = unicodedata.normalize('NFKD', res).encode("ascii", "ignore")
# Remove unwanted chars (ie, chars that are not valid in file names
# under Windows)
finalRes = ''
for char in res:
if char not in self.unwantedChars:
finalRes += char
return finalRes
def generateDocument(self, obj):
'''Generates a document from this template, for object p_obj.'''
appySelf = self._appy_getWrapper(force=True)
appName = self.getProductConfig().PROJECTNAME
appModule = getattr(self.getProductConfig(), appName)
# Temporary file where to generate the result
tempFileName = '%s/%s_%f.%s' % (
getOsTempFolder(), obj.UID(), time.time(), self.getPodFormat())
# Define parameters to pass to the appy.pod renderer
currentUser = self.portal_membership.getAuthenticatedMember()
podContext = {'self': obj._appy_getWrapper(force=True),
'user': currentUser,
'podTemplate': appySelf,
'now': self.getProductConfig().DateTime(),
'projectFolder': os.path.dirname(appModule.__file__)
}
rendererParams = {'template': StringIO(appySelf.podTemplate.content),
'context': podContext,
'result': tempFileName }
if appySelf.tool.unoEnabledPython:
rendererParams['pythonWithUnoPath'] = appySelf.tool.unoEnabledPython
if appySelf.tool.openOfficePort:
rendererParams['ooPort'] = appySelf.tool.openOfficePort
# Launch the renderer
import appy.pod
from appy.pod.renderer import Renderer
try:
renderer = Renderer(**rendererParams)
renderer.run()
except appy.pod.PodError, pe:
if not os.path.exists(tempFileName):
# In some (most?) cases, when OO returns an error, the result is
# nevertheless generated.
raise PodError(POD_ERROR % str(pe))
# Open the temp file on the filesystem
f = file(tempFileName, 'rb')
res = f.read()
fileName = self._getFileName(obj)
response = obj.REQUEST.RESPONSE
response.setHeader('Content-Type', mimeTypes[self.getPodFormat()])
response.setHeader('Content-Disposition', 'inline;filename="%s.%s"'\
% (fileName, self.getPodFormat()))
f.close()
# Returns the doc and removes the temp file
try:
os.remove(tempFileName)
except OSError, oe:
self.getProductConfig().logger.warn(DELETE_TEMP_DOC_ERROR % str(oe))
except IOError, ie:
self.getProductConfig().logger.warn(DELETE_TEMP_DOC_ERROR % str(ie))
return res
# ------------------------------------------------------------------------------