[pod+gen] Added POD rendering based on ODS templates. Integrated with gen.
This commit is contained in:
		
							parent
							
								
									d5d99b67eb
								
							
						
					
					
						commit
						43261fde60
					
				
					 8 changed files with 144 additions and 92 deletions
				
			
		|  | @ -272,6 +272,12 @@ class ZopeInstaller: | |||
|                                             appyType.template) | ||||
|                     if os.path.exists(fileName): | ||||
|                         setattr(appyTool, attrName, fileName) | ||||
|                         # If the template is ods, set the default format to ods | ||||
|                         # (because default is odt) | ||||
|                         if fileName.endswith('.ods'): | ||||
|                             formats = appyTool.getAttributeName('formats', | ||||
|                                                        appyClass, appyType.name) | ||||
|                             setattr(appyTool, formats, ['ods']) | ||||
|                         appyTool.log('Imported "%s" in the tool in ' \ | ||||
|                                      'attribute "%s"'% (fileName, attrName)) | ||||
|                     else: | ||||
|  |  | |||
|  | @ -94,6 +94,8 @@ appyLabels = [ | |||
|  ('pdf', 'PDF'), | ||||
|  ('doc', 'DOC'), | ||||
|  ('rtf', 'RTF'), | ||||
|  ('ods', 'ODS'), | ||||
|  ('xls', 'XLS'), | ||||
|  ('front_page_text', 'Welcome to this Appy-powered site.'), | ||||
|  ('captcha_text', 'Please type "${text}" (without the double quotes) in the ' \ | ||||
|                   'field besides, but without the character at position ' \ | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								gen/ui/ods.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gen/ui/ods.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 731 B | 
							
								
								
									
										
											BIN
										
									
								
								gen/ui/xls.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gen/ui/xls.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 314 B | 
|  | @ -54,7 +54,7 @@ class ToolWrapper(AbstractWrapper): | |||
|                         (user.o.absolute_url(), user.title,access)) | ||||
|         return res + '\n'.join(rows) + '</table>' | ||||
| 
 | ||||
|     podOutputFormats = ('odt', 'pdf', 'doc', 'rtf') | ||||
|     podOutputFormats = ('odt', 'pdf', 'doc', 'rtf', 'ods', 'xls') | ||||
|     def getPodOutputFormats(self): | ||||
|         '''Gets the available output formats for POD documents.''' | ||||
|         return [(of, self.translate(of)) for of in self.podOutputFormats] | ||||
|  | @ -185,4 +185,36 @@ class ToolWrapper(AbstractWrapper): | |||
|             except Exception, e: | ||||
|                 failed.append(startObject) | ||||
|             return nb, failed | ||||
| 
 | ||||
|     def validate(self, new, errors): | ||||
|         '''Validates that uploaded POD templates and output types are | ||||
|            compatible.''' | ||||
|         page = self.request.get('page', 'main') | ||||
|         if page == 'documents': | ||||
|             # Check that uploaded templates and output formats are compatible. | ||||
|             for fieldName in dir(new): | ||||
|                 # Ignore fields which are not POD templates. | ||||
|                 if not fieldName.startswith('podTemplate'): continue | ||||
|                 # Get the file name, either from the newly uploaded file or | ||||
|                 # from the existing file stored in the database. | ||||
|                 if getattr(new, fieldName): | ||||
|                     fileName = getattr(new, fieldName).filename | ||||
|                 else: | ||||
|                     fileName = getattr(self, fieldName).name | ||||
|                 # Get the extension of the uploaded file. | ||||
|                 ext = os.path.splitext(fileName)[1][1:] | ||||
|                 # Get the chosen output formats for this template. | ||||
|                 formatsFieldName = 'formatsFor%s' % fieldName[14:] | ||||
|                 formats = getattr(new, formatsFieldName) | ||||
|                 error = False | ||||
|                 if ext == 'odt': | ||||
|                     error = ('ods' in formats) or ('xls' in formats) | ||||
|                 elif ext == 'ods': | ||||
|                     error = ('odt' in formats) or ('pdf' in formats) or \ | ||||
|                             ('doc' in formats) or ('rtf' in formats) | ||||
|                 if error: | ||||
|                     msg = 'This (these) format(s) cannot be used with ' \ | ||||
|                           'this template.' | ||||
|                     setattr(errors, formatsFieldName, msg) | ||||
|         return self._callCustom('validate', new, errors) | ||||
| # ------------------------------------------------------------------------------ | ||||
|  |  | |||
|  | @ -51,15 +51,15 @@ DOC_NOT_FOUND = 'Document "%s" was not found.' | |||
| URL_NOT_FOUND = 'Doc URL "%s" is wrong. %s' | ||||
| BAD_RESULT_TYPE = 'Bad result type "%s". Available types are %s.' | ||||
| CANNOT_WRITE_RESULT = 'I cannot write result "%s". %s' | ||||
| CONNECT_ERROR = 'Could not connect to OpenOffice on port %d. UNO ' \ | ||||
|                 '(OpenOffice API) says: %s.' | ||||
| CONNECT_ERROR = 'Could not connect to LibreOffice on port %d. UNO ' \ | ||||
|                 '(LibreOffice API) says: %s.' | ||||
| 
 | ||||
| # Some constants --------------------------------------------------------------- | ||||
| DEFAULT_PORT = 2002 | ||||
| 
 | ||||
| # ------------------------------------------------------------------------------ | ||||
| class Converter: | ||||
|     '''Converts a document readable by OpenOffice into pdf, doc, txt, rtf...''' | ||||
|     '''Converts a document readable by LibreOffice into pdf, doc, txt, rtf...''' | ||||
|     exeVariants = ('soffice.exe', 'soffice') | ||||
|     pathReplacements = {'program files': 'progra~1', | ||||
|                         'openoffice.org 1': 'openof~1', | ||||
|  | @ -72,9 +72,9 @@ class Converter: | |||
|         self.resultType = resultType | ||||
|         self.resultFilter = self.getResultFilter() | ||||
|         self.resultUrl = self.getResultUrl() | ||||
|         self.ooContext = None | ||||
|         self.oo = None # The OpenOffice application object | ||||
|         self.doc = None # The OpenOffice loaded document | ||||
|         self.loContext = None | ||||
|         self.oo = None # The LibreOffice application object | ||||
|         self.doc = None # The LibreOffice loaded document | ||||
| 
 | ||||
|     def getInputUrls(self, docPath): | ||||
|         '''Returns the absolute path of the input file. In fact, it returns a | ||||
|  | @ -100,7 +100,7 @@ class Converter: | |||
|         return res | ||||
| 
 | ||||
|     def getResultUrl(self): | ||||
|         '''Returns the path of the result file in the format needed by OO. If | ||||
|         '''Returns the path of the result file in the format needed by LO. If | ||||
|            the result type and the input type are the same (ie the user wants to | ||||
|            refresh indexes or some other action and not perform a real | ||||
|            conversion), the result file is named | ||||
|  | @ -126,7 +126,7 @@ class Converter: | |||
|             raise ConverterError(CANNOT_WRITE_RESULT % (res, ioe)) | ||||
| 
 | ||||
|     def connect(self): | ||||
|         '''Connects to OpenOffice''' | ||||
|         '''Connects to LibreOffice''' | ||||
|         if os.name == 'nt': | ||||
|             import socket | ||||
|         import uno | ||||
|  | @ -138,17 +138,17 @@ class Converter: | |||
|             resolver = localContext.ServiceManager.createInstanceWithContext( | ||||
|                 "com.sun.star.bridge.UnoUrlResolver", localContext) | ||||
|             # Connect to the running office | ||||
|             self.ooContext = resolver.resolve( | ||||
|             self.loContext = resolver.resolve( | ||||
|                 'uno:socket,host=localhost,port=%d;urp;StarOffice.' \ | ||||
|                 'ComponentContext' % self.port) | ||||
|             # Is seems that we can't define a timeout for this method. | ||||
|             # I need it because, for example, when a web server already listens | ||||
|             # to the given port (thus, not a OpenOffice instance), this method | ||||
|             # to the given port (thus, not a LibreOffice instance), this method | ||||
|             # blocks. | ||||
|             smgr = self.ooContext.ServiceManager | ||||
|             smgr = self.loContext.ServiceManager | ||||
|             # Get the central desktop object | ||||
|             self.oo = smgr.createInstanceWithContext( | ||||
|                 'com.sun.star.frame.Desktop', self.ooContext) | ||||
|                 'com.sun.star.frame.Desktop', self.loContext) | ||||
|         except NoConnectException, nce: | ||||
|             raise ConverterError(CONNECT_ERROR % (self.port, nce)) | ||||
| 
 | ||||
|  | @ -220,7 +220,7 @@ class Converter: | |||
|             raise ConverterError(URL_NOT_FOUND % (self.docPath, iae)) | ||||
| 
 | ||||
|     def convertDocument(self): | ||||
|         '''Calls OO to perform a document conversion. Note that the conversion | ||||
|         '''Calls LO to perform a document conversion. Note that the conversion | ||||
|            is not really done if the source and target documents have the same | ||||
|            type.''' | ||||
|         properties = [] | ||||
|  | @ -238,7 +238,7 @@ class Converter: | |||
|         self.doc.storeToURL(self.resultUrl, tuple(properties)) | ||||
| 
 | ||||
|     def run(self): | ||||
|         '''Connects to OO, does the job and disconnects.''' | ||||
|         '''Connects to LO, does the job and disconnects.''' | ||||
|         self.connect() | ||||
|         self.loadDocument() | ||||
|         self.convertDocument() | ||||
|  | @ -257,12 +257,12 @@ class ConverterScript: | |||
|             '   and   outputType is the output format, that must be one of\n' \ | ||||
|             '         %s.\n' \ | ||||
|             ' "python" should be a UNO-enabled Python interpreter (ie the ' \ | ||||
|             '  one which is included in the OpenOffice.org distribution).' % \ | ||||
|             '  one which is included in the LibreOffice distribution).' % \ | ||||
|             str(FILE_TYPES.keys()) | ||||
|     def run(self): | ||||
|         optParser = OptionParser(usage=ConverterScript.usage) | ||||
|         optParser.add_option("-p", "--port", dest="port", | ||||
|                              help="The port on which OpenOffice runs " \ | ||||
|                              help="The port on which LibreOffice runs " \ | ||||
|                              "Default is %d." % DEFAULT_PORT, | ||||
|                              default=DEFAULT_PORT, metavar="PORT", type='int') | ||||
|         (options, args) = optParser.parse_args() | ||||
|  |  | |||
							
								
								
									
										141
									
								
								pod/renderer.py
									
										
									
									
									
								
							
							
						
						
									
										141
									
								
								pod/renderer.py
									
										
									
									
									
								
							|  | @ -23,7 +23,7 @@ from UserDict import UserDict | |||
| 
 | ||||
| import appy.pod, time, cgi | ||||
| from appy.pod import PodError | ||||
| from appy.shared import mimeTypesExts | ||||
| from appy.shared import mimeTypes, mimeTypesExts | ||||
| from appy.shared.xml_parser import XmlElement | ||||
| from appy.shared.utils import FolderDeleter, executeCommand | ||||
| from appy.shared.utils import FileWrapper | ||||
|  | @ -40,10 +40,10 @@ RESULT_FILE_EXISTS = 'Result file "%s" exists.' | |||
| CANT_WRITE_RESULT = 'I cannot write result file "%s". %s' | ||||
| CANT_WRITE_TEMP_FOLDER = 'I cannot create temp folder "%s". %s' | ||||
| NO_PY_PATH = 'Extension of result file is "%s". In order to perform ' \ | ||||
|              'conversion from ODT to this format we need to call OpenOffice. ' \ | ||||
|              'conversion from ODT to this format we need to call LibreOffice. ' \ | ||||
|              'But the Python interpreter which runs the current script does ' \ | ||||
|              'not know UNO, the library that allows to connect to ' \ | ||||
|              'OpenOffice in server mode. If you can\'t install UNO in this ' \ | ||||
|              'LibreOffice in server mode. If you can\'t install UNO in this ' \ | ||||
|              'Python interpreter, you can specify, in parameter ' \ | ||||
|              '"pythonWithUnoPath", the path to a UNO-enabled Python ' \ | ||||
|              'interpreter. One such interpreter may be found in ' \ | ||||
|  | @ -57,12 +57,11 @@ BLANKS_IN_PATH = 'Blanks were found in path "%s". Please use the DOS-names ' \ | |||
| BAD_RESULT_TYPE = 'Result "%s" has a wrong extension. Allowed extensions ' \ | ||||
|                   'are: "%s".' | ||||
| CONVERT_ERROR = 'An error occurred during the conversion. %s' | ||||
| BAD_OO_PORT = 'Bad OpenOffice port "%s". Make sure it is an integer.' | ||||
| BAD_OO_PORT = 'Bad LibreOffice port "%s". Make sure it is an integer.' | ||||
| XHTML_ERROR = 'An error occurred while rendering XHTML content.' | ||||
| WARNING_INCOMPLETE_ODT = 'Warning: your ODT file may not be complete (ie ' \ | ||||
|                          'imported documents may not be present). This is ' \ | ||||
|                          'because we could not connect to OpenOffice in ' \ | ||||
|                          'server mode: %s' | ||||
| WARNING_INCOMPLETE_OD = 'Warning: your OpenDocument file may not be complete ' \ | ||||
|   '(ie imported documents may not be present). This is because we could not ' \ | ||||
|   'connect to LibreOffice in server mode: %s' | ||||
| DOC_NOT_SPECIFIED = 'Please specify a document to import, either with a ' \ | ||||
|                     'stream (parameter "content") or with a path (parameter ' \ | ||||
|                     '"at")' | ||||
|  | @ -92,6 +91,8 @@ STYLES_POD_FONTS = '<@style@:font-face @style@:name="PodStarSymbol" ' \ | |||
| 
 | ||||
| # ------------------------------------------------------------------------------ | ||||
| class Renderer: | ||||
|     templateTypes = ('odt', 'ods') # Types of POD templates | ||||
| 
 | ||||
|     def __init__(self, template, context, result, pythonWithUnoPath=None, | ||||
|                  ooPort=2002, stylesMapping={}, forceOoCall=False, | ||||
|                  finalizeFunction=None, overwriteExisting=False, | ||||
|  | @ -416,20 +417,9 @@ class Renderer: | |||
|                 FolderDeleter.delete(self.tempFolder) | ||||
|             raise po | ||||
| 
 | ||||
|     def reportProblem(self, msg, resultType): | ||||
|         '''When trying to call OO in server mode for producing ODT | ||||
|            (=forceOoCall=True), if an error occurs we still have an ODT to | ||||
|            return to the user. So we produce a warning instead of raising an | ||||
|            error.''' | ||||
|         if (resultType == 'odt') and self.forceOoCall: | ||||
|             print WARNING_INCOMPLETE_ODT % msg | ||||
|         else: | ||||
|             raise msg | ||||
| 
 | ||||
|     def callOpenOffice(self, resultOdtName, resultType): | ||||
|         '''Call Open Office in server mode to convert or update the ODT | ||||
|            result.''' | ||||
|         ooOutput = '' | ||||
|     def callLibreOffice(self, resultName, resultType): | ||||
|         '''Call LibreOffice in server mode to convert or update the result.''' | ||||
|         loOutput = '' | ||||
|         try: | ||||
|             if (not isinstance(self.ooPort, int)) and \ | ||||
|                (not isinstance(self.ooPort, long)): | ||||
|  | @ -437,7 +427,7 @@ class Renderer: | |||
|             try: | ||||
|                 from appy.pod.converter import Converter, ConverterError | ||||
|                 try: | ||||
|                     Converter(resultOdtName, resultType, self.ooPort).run() | ||||
|                     Converter(resultName, resultType, self.ooPort).run() | ||||
|                 except ConverterError, ce: | ||||
|                     raise PodError(CONVERT_ERROR % str(ce)) | ||||
|             except ImportError: | ||||
|  | @ -449,35 +439,54 @@ class Renderer: | |||
|                     raise PodError(BLANKS_IN_PATH % self.pyPath) | ||||
|                 if not os.path.isfile(self.pyPath): | ||||
|                     raise PodError(PY_PATH_NOT_FILE % self.pyPath) | ||||
|                 if resultOdtName.find(' ') != -1: | ||||
|                     qResultOdtName = '"%s"' % resultOdtName | ||||
|                 if resultName.find(' ') != -1: | ||||
|                     qResultName = '"%s"' % resultName | ||||
|                 else: | ||||
|                     qResultOdtName = resultOdtName | ||||
|                     qResultName = resultName | ||||
|                 convScript = '%s/converter.py' % \ | ||||
|                             os.path.dirname(appy.pod.__file__) | ||||
|                 if convScript.find(' ') != -1: | ||||
|                     convScript = '"%s"' % convScript | ||||
|                 cmd = '%s %s %s %s -p%d' % \ | ||||
|                     (self.pyPath, convScript, qResultOdtName, resultType, | ||||
|                     (self.pyPath, convScript, qResultName, resultType, | ||||
|                     self.ooPort) | ||||
|                 ooOutput = executeCommand(cmd) | ||||
|                 loOutput = executeCommand(cmd) | ||||
|         except PodError, pe: | ||||
|             # When trying to call OO in server mode for producing | ||||
|             # ODT (=forceOoCall=True), if an error occurs we still | ||||
|             # have an ODT to return to the user. So we produce a | ||||
|             # warning instead of raising an error. | ||||
|             if (resultType == 'odt') and self.forceOoCall: | ||||
|                 print WARNING_INCOMPLETE_ODT % str(pe) | ||||
|             # When trying to call LO in server mode for producing ODT or ODS | ||||
|             # (=forceOoCall=True), if an error occurs we have nevertheless | ||||
|             # an ODT or ODS to return to the user. So we produce a warning | ||||
|             # instead of raising an error. | ||||
|             if (resultType in self.templateTypes) and self.forceOoCall: | ||||
|                 print WARNING_INCOMPLETE_OD % str(pe) | ||||
|             else: | ||||
|                 raise pe | ||||
|         return ooOutput | ||||
|         return loOutput | ||||
| 
 | ||||
|     def getTemplateType(self): | ||||
|         '''Identifies the type of the pod template in self.template | ||||
|            (ods or odt). If self.template is a string, it is a file name and we | ||||
|            simply get its extension. Else, it is a binary file in a StringIO | ||||
|            instance, and we seek the mime type from the first bytes.''' | ||||
|         if isinstance(self.template, basestring): | ||||
|             res = os.path.splitext(self.template)[1][1:] | ||||
|         else: | ||||
|             # A StringIO instance | ||||
|             self.template.seek(0) | ||||
|             firstBytes = self.template.read(90) | ||||
|             firstBytes = firstBytes[firstBytes.index('mimetype')+8:] | ||||
|             if firstBytes.startswith(mimeTypes['ods']): | ||||
|                 res = 'ods' | ||||
|             else: | ||||
|                 # We suppose this is ODT | ||||
|                 res = 'odt' | ||||
|         return res | ||||
| 
 | ||||
|     def finalize(self): | ||||
|         '''Re-zip the result and potentially call OpenOffice if target format is | ||||
|            not ODT or if forceOoCall is True.''' | ||||
|         for odtFile in ('content.xml', 'styles.xml'): | ||||
|             shutil.copy(os.path.join(self.tempFolder, odtFile), | ||||
|                         os.path.join(self.unzipFolder, odtFile)) | ||||
|         '''Re-zip the result and potentially call LibreOffice if target format | ||||
|            is not among self.templateTypes or if forceOoCall is True.''' | ||||
|         for innerFile in ('content.xml', 'styles.xml'): | ||||
|             shutil.copy(os.path.join(self.tempFolder, innerFile), | ||||
|                         os.path.join(self.unzipFolder, innerFile)) | ||||
|         # Insert dynamic styles | ||||
|         contentXml = os.path.join(self.unzipFolder, 'content.xml') | ||||
|         f = file(contentXml) | ||||
|  | @ -493,27 +502,28 @@ class Renderer: | |||
|                 self.finalizeFunction(self.unzipFolder) | ||||
|             except Exception, e: | ||||
|                 print WARNING_FINALIZE_ERROR % str(e) | ||||
|         # Re-zip the result. | ||||
|         resExt = os.path.splitext(self.template)[1] | ||||
|         resultOdtName = os.path.join(self.tempFolder, 'result%s' % resExt) | ||||
|         # Re-zip the result, first as an OpenDocument file of the same type as | ||||
|         # the POD template (odt, ods...) | ||||
|         resultExt = self.getTemplateType() | ||||
|         resultName = os.path.join(self.tempFolder, 'result.%s' % resultExt) | ||||
|         try: | ||||
|             resultOdt = zipfile.ZipFile(resultOdtName,'w', zipfile.ZIP_DEFLATED) | ||||
|             resultZip = zipfile.ZipFile(resultName, 'w', zipfile.ZIP_DEFLATED) | ||||
|         except RuntimeError: | ||||
|             resultOdt = zipfile.ZipFile(resultOdtName,'w') | ||||
|             resultZip = zipfile.ZipFile(resultName,'w') | ||||
|         # Insert first the file "mimetype" (uncompressed), in order to be | ||||
|         # compliant with the OpenDocument Format specification, section 17.4, | ||||
|         # that expresses this restriction. Else, libraries like "magic", under | ||||
|         # Linux/Unix, are unable to detect the correct mimetype for a pod result | ||||
|         # (it simply recognizes it as a "application/zip" and not a | ||||
|         # "application/vnd.oasis.opendocument.text)". | ||||
|         resultOdt.write(os.path.join(self.unzipFolder, 'mimetype'), | ||||
|         resultZip.write(os.path.join(self.unzipFolder, 'mimetype'), | ||||
|                         'mimetype', zipfile.ZIP_STORED) | ||||
|         for dir, dirnames, filenames in os.walk(self.unzipFolder): | ||||
|             for f in filenames: | ||||
|                 folderName = dir[len(self.unzipFolder)+1:] | ||||
|                 # Ignore file "mimetype" that was already inserted. | ||||
|                 if (folderName == '') and (f == 'mimetype'): continue | ||||
|                 resultOdt.write(os.path.join(dir, f), | ||||
|                 resultZip.write(os.path.join(dir, f), | ||||
|                                 os.path.join(folderName, f)) | ||||
|             if not dirnames and not filenames: | ||||
|                 # This is an empty leaf folder. We must create an entry in the | ||||
|  | @ -521,35 +531,34 @@ class Renderer: | |||
|                 folderName = dir[len(self.unzipFolder):] | ||||
|                 zInfo = zipfile.ZipInfo("%s/" % folderName,time.localtime()[:6]) | ||||
|                 zInfo.external_attr = 48 | ||||
|                 resultOdt.writestr(zInfo, '') | ||||
|         resultOdt.close() | ||||
|         resultType = os.path.splitext(self.result)[1] | ||||
|                 resultZip.writestr(zInfo, '') | ||||
|         resultZip.close() | ||||
|         resultType = os.path.splitext(self.result)[1].strip('.') | ||||
|         try: | ||||
|             if (resultType == '.odt') and not self.forceOoCall: | ||||
|             if (resultType in self.templateTypes) and not self.forceOoCall: | ||||
|                 # Simply move the ODT result to the result | ||||
|                 os.rename(resultOdtName, self.result) | ||||
|                 os.rename(resultName, self.result) | ||||
|             else: | ||||
|                 if resultType.startswith('.'): resultType = resultType[1:] | ||||
|                 if not resultType in FILE_TYPES.keys(): | ||||
|                 if resultType not in FILE_TYPES: | ||||
|                     raise PodError(BAD_RESULT_TYPE % ( | ||||
|                         self.result, FILE_TYPES.keys())) | ||||
|                 # Call OpenOffice to perform the conversion or document update | ||||
|                 output = self.callOpenOffice(resultOdtName, resultType) | ||||
|                 # I (should) have the result. Move it to the correct name | ||||
|                 resPrefix = os.path.splitext(resultOdtName)[0] + '.' | ||||
|                 if resultType == 'odt': | ||||
|                 # 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.odt | ||||
|                     resultName = resPrefix + 'res.odt' | ||||
|                     if not os.path.exists(resultName): | ||||
|                         resultName = resultOdtName | ||||
|                     # 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: | ||||
|                     resultName = resPrefix + resultType | ||||
|                 if not os.path.exists(resultName): | ||||
|                     finalResultName = '%s.%s' % (resPrefix, resultType) | ||||
|                 if not os.path.exists(finalResultName): | ||||
|                     raise PodError(CONVERT_ERROR % output) | ||||
|                 os.rename(resultName, self.result) | ||||
|                 os.rename(finalResultName, self.result) | ||||
|         finally: | ||||
|             FolderDeleter.delete(self.tempFolder) | ||||
| # ------------------------------------------------------------------------------ | ||||
|  |  | |||
|  | @ -4,20 +4,23 @@ import os.path | |||
| 
 | ||||
| # ------------------------------------------------------------------------------ | ||||
| appyPath = os.path.realpath(os.path.dirname(appy.__file__)) | ||||
| mimeTypes = {'odt': 'application/vnd.oasis.opendocument.text', | ||||
| od = 'application/vnd.oasis.opendocument' | ||||
| mimeTypes = {'odt': '%s.text' % od, | ||||
|              'ods': '%s.spreadsheet' % od, | ||||
|              'doc': 'application/msword', | ||||
|              'rtf': 'text/rtf', | ||||
|              'pdf': 'application/pdf' | ||||
|              } | ||||
| mimeTypesExts = { | ||||
|              'application/vnd.oasis.opendocument.text': 'odt', | ||||
|              'application/msword'                     : 'doc', | ||||
|              'text/rtf'                               : 'rtf', | ||||
|              'application/pdf'                        : 'pdf', | ||||
|              'image/png'                              : 'png', | ||||
|              'image/jpeg'                             : 'jpg', | ||||
|              'image/pjpeg'                            : 'jpg', | ||||
|              'image/gif'                              : 'gif' | ||||
|              '%s.text' % od:        'odt', | ||||
|              '%s.spreadsheet' % od: 'ods', | ||||
|              'application/msword':  'doc', | ||||
|              'text/rtf':            'rtf', | ||||
|              'application/pdf':     'pdf', | ||||
|              'image/png':           'png', | ||||
|              'image/jpeg':          'jpg', | ||||
|              'image/pjpeg':         'jpg', | ||||
|              'image/gif':           'gif' | ||||
|              } | ||||
| 
 | ||||
| # ------------------------------------------------------------------------------ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Gaetan Delannay
						Gaetan Delannay