[Erp5-report] r29497 - in /erp5/trunk/products/ERP5: Converter/ Converter/bin/ Tool/
nobody at svn.erp5.org
nobody at svn.erp5.org
Fri Oct 9 02:06:24 CEST 2009
Author: jp
Date: Fri Oct 9 02:06:24 2009
New Revision: 29497
URL: http://svn.erp5.org?rev=29497&view=rev
Log:
RFC - New experimental conversion tool skeleton. WIll replace oood and portal_transforms with a single tool which handles both conversion and metadata. In Phase 1, uses a single tool which calls itself through XML-RPC. In Phase 2, will be splitted into a tool and WSGI service.
Added:
erp5/trunk/products/ERP5/Converter/
erp5/trunk/products/ERP5/Converter/Converter.py
erp5/trunk/products/ERP5/Converter/OpenOffice.py
erp5/trunk/products/ERP5/Converter/bin/
erp5/trunk/products/ERP5/Converter/bin/openoffice.convert
erp5/trunk/products/ERP5/Tool/ConversionTool.py
Added: erp5/trunk/products/ERP5/Converter/Converter.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Converter/Converter.py?rev=29497&view=auto
==============================================================================
--- erp5/trunk/products/ERP5/Converter/Converter.py (added)
+++ erp5/trunk/products/ERP5/Converter/Converter.py [utf8] Fri Oct 9 02:06:24 2009
@@ -1,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+class Converter:
+ """
+ Converter classes implement document conversion
+ from a given format to another format.
+
+ ARCHITECTURE: because most document processing
+ software, and potentially libraries, are unstable,
+ do not always support multithreading and may lead
+ to memory leaks, the recommend approach to create
+ a Converter is to simply execute a command with
+ popenX in a separate process and return the result.
+ """
+
+ # Introspection API Implementation
+ def getSourceFormatItemList(self):
+ """
+ Return the list of supported input format
+ (format, name)
+ """
+ raise NotImplementedError
+
+ def getDestinationFormatItemList(self):
+ """
+ Return the list of supported output format
+ (format, name)
+ """
+ raise NotImplementedError
+
+ # Conversion API Implementation
+ def convertFile(self, file, source_format, destination_format):
+ """
+ """
+ raise NotImplementedError
+
+ def getFileMetadataItemList(self, file, source_format):
+ """
+ """
+ raise NotImplementedError
+
+ def updateFileMetadata(self, file, source_format, **kw):
+ """
+ """
+ raise NotImplementedError
Added: erp5/trunk/products/ERP5/Converter/OpenOffice.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Converter/OpenOffice.py?rev=29497&view=auto
==============================================================================
--- erp5/trunk/products/ERP5/Converter/OpenOffice.py (added)
+++ erp5/trunk/products/ERP5/Converter/OpenOffice.py [utf8] Fri Oct 9 02:06:24 2009
@@ -1,0 +1,63 @@
+# -*- coding: utf-8 -*-
+
+MAX_LAUNCH = 100
+
+class OpenOffice:
+
+ # Private methods
+ def _getAvailableOpenOfficeInstancePort(self):
+ """
+ This method starts a collection of
+ headless OpenOffice in bacground and attaches
+ them to the server process. Each time
+ a headless Openoffice is returned, a counter
+ is incremented. After MAX_LAUNCH times,
+ the server is closed and recreated.
+
+ The method returns a port number
+ """
+
+ def _getCommand(self, param):
+ """
+ """
+ return "/usr/bin/openoffice.convert %s"
+
+ # Introspection API Implementation
+ def getSourceFormatItemList(self):
+ """
+ Return the list of supported input format
+ (format, name)
+ """
+ port = self._getAvailableOpenOfficeInstancePort()
+
+ def getDestinationFormatItemList(self):
+ """
+ Return the list of supported output format
+ (format, name)
+ """
+ port = self._getAvailableOpenOfficeInstancePort()
+
+ # Conversion API Implementation
+ def convertFile(self, file, source_format, destination_format):
+ """
+ """
+ # XXX - just call a command line (python script)
+ # which does all the work
+ port = self._getAvailableOpenOfficeInstancePort()
+ input, output = popen(self._getCommand('--convert'), file)
+
+ def getFileMetadataItemList(self, file, source_format):
+ """
+ """
+ # XXX - just call a command line (python script)
+ # which does all the work
+ port = self._getAvailableOpenOfficeInstancePort()
+ input, output = popen(self._getCommand('--metadata'), file)
+
+ def updateFileMetadata(self, file, source_format, **kw):
+ """
+ """
+ # XXX - just call a command line (python script)
+ # which does all the work
+ port = self._getAvailableOpenOfficeInstancePort()
+ input, output = popen(self._getCommand('--update'), file)
Added: erp5/trunk/products/ERP5/Converter/bin/openoffice.convert
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Converter/bin/openoffice.convert?rev=29497&view=auto
==============================================================================
--- erp5/trunk/products/ERP5/Converter/bin/openoffice.convert (added)
+++ erp5/trunk/products/ERP5/Converter/bin/openoffice.convert [utf8] Fri Oct 9 02:06:24 2009
@@ -1,0 +1,9 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import pyuno
+
+# Invoke OpenOffice with appropriate port number provided by OpenOffice converter
+
+
+# Return result
Added: erp5/trunk/products/ERP5/Tool/ConversionTool.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Tool/ConversionTool.py?rev=29497&view=auto
==============================================================================
--- erp5/trunk/products/ERP5/Tool/ConversionTool.py (added)
+++ erp5/trunk/products/ERP5/Tool/ConversionTool.py [utf8] Fri Oct 9 02:06:24 2009
@@ -1,0 +1,183 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
+# Jean-Paul Smets-Solanes <jp at nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# garantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# 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.
+#
+##############################################################################
+
+from Products.CMFCore.utils import getToolByName
+
+from AccessControl import ClassSecurityInfo
+from Globals import InitializeClass, DTMLFile
+from Products.CMFCore.utils import getToolByName
+from Products.ERP5Type import Permissions
+from Products.ERP5Type.Tool.BaseTool import BaseTool
+
+from Products.ERP5 import _dtmldir
+
+from zLOG import LOG
+
+class ConversionTool(BaseTool):
+ """
+ The ConversionTool class will provide in the future an
+ API to unify file conversion and metadata handling in ERP5.
+
+ The first version consists of a tool which acts both as central
+ point for conversion services and metadata handling services
+ for all ERP5 Document classes and scripts, as well as a Web
+ Service for external applications.
+
+ The Tool calls itself, through XML-RPC protocol. A dedicated
+ Zope instance can be setup for handling conversions.
+
+ In the future, the tool will be splitted in 2 parts:
+ - a Tool
+ - a WSGI service
+
+ The tool reuses the portal_web_services to connect through
+ XML-RPC to the conversion server.
+
+ ARCHITECTURE PHASE 1: all Converter classes are stored
+ in the Converter directory part of ERP5 Product. The tool
+ serves both as caller and recipient, and calls itself
+ through XML-RPC.
+
+ ARCHITECTURE PHASE 2: all Converter classes are moved to
+ a dedicated directory in /usr/share/oood/converter
+ (or new name). The Web Service API is moved away from
+ ConverterTool class and turned to a WSGI independent service
+
+ NOTE: this class is experimental and is subject to be removed
+ NOTE2: the code is only pseudo-code
+ """
+ id = 'portal_conversions'
+ meta_type = 'ERP5 Conversion Tool'
+ portal_type = 'Conversion Tool'
+ allowed_types = ()
+
+ # Declarative Security
+ security = ClassSecurityInfo()
+
+ #
+ # ZMI methods
+ #
+ security.declareProtected( Permissions.ManagePortal, 'manage_overview' )
+ manage_overview = DTMLFile( 'explainConversionTool', _dtmldir )
+
+ def filtered_meta_types(self, user=None):
+ # Filters the list of available meta types.
+ all = SolverTool.inheritedAttribute('filtered_meta_types')(self)
+ meta_types = []
+ for meta_type in self.all_meta_types():
+ if meta_type['name'] in self.allowed_types:
+ meta_types.append(meta_type)
+ return meta_types
+
+ def tpValues(self):
+ """ show the content in the left pane of the ZMI """
+ return self.objectValues()
+
+ # Internal API - called by Document classes and scripts
+ def convert(self, file, source_format, destination_format, zip=False):
+ """
+ Returns the converted file in the given format
+
+ zip parameter can be specified to return the result of conversion
+ in the form of a zip archive (which may contain multiple parts).
+ This can be useful to convert a single ODF file to HMTL
+ and png images.
+ """
+ # Just call XML-RPC
+ preference_tool = getToolByName(self, 'portal_preferences')
+ web_service_tool = getToolByName(self, 'portal_web_services')
+ conversion_url = preference_tool.getPreferredConversionServiceUrl()
+ conversion_service = web_service_tool.connect(conversion_url)
+ # XXX - no exception handling - wrong
+ return conversion_service.convertFile(file, source_format, destination_format)
+
+
+ def getMetadataDict(self, file, source_format):
+ """
+ Returns a dict of metadata values for the
+ document. The structure of this dict is "unpredictable"
+ and follows the convention of each file.
+ """
+ # Just call XML-RPC
+ preference_tool = getToolByName(self, 'portal_preferences')
+ web_service_tool = getToolByName(self, 'portal_web_services')
+ conversion_url = preference_tool.getPreferredConversionServiceUrl()
+ conversion_service = web_service_tool.connect(conversion_url)
+ # XXX - no exception handling - wrong
+ return conversion_service.getFileMetadataItemList(file, source_format)
+
+
+ def updateMetadata(self, file, source_format, **kw):
+ """
+ Updates the file in the given source_format
+ with provided metadata and return the resulting new file
+ """
+ # Just call XML-RPC
+ preference_tool = getToolByName(self, 'portal_preferences')
+ web_service_tool = getToolByName(self, 'portal_web_services')
+ conversion_url = preference_tool.getPreferredConversionServiceUrl()
+ conversion_service = web_service_tool.connect(conversion_url)
+ # XXX - no exception handling - wrong
+ return conversion_service.updateFileMetadata(file, source_format, **kw)
+
+
+ # Web Service API - called by any application through XML-RPC
+ # Will be removed in the future and moved to WSGI service
+ def convertFile(self, file, source_format, destination_format, zip=False):
+ """
+ Returns the converted file in the given format
+ """
+ converter = self._findConverter(source_format, destination_format)
+ return converter.convertFile(file, source_format, destination_format, zip=zip)
+
+
+ def getFileMetadataItemList(self, file, source_format):
+ """
+ Returns a list key, value pairs representing the
+ metadata values for the document. The structure of this
+ list is "unpredictable" and follows the convention of each file.
+ """
+ converter = self._findConverter(source_format, destination_format)
+ return converter.getFileMetadataItemList(file, source_format)
+
+
+ def updateFileMetadata(self, file, source_format, **kw):
+ """
+ Updates the file in the given source_format
+ with provided metadata and return the resulting new file
+ """
+ converter = self._findConverter(source_format, destination_format)
+ return converter.updateFileMetadata(file, source_format, destination_format, zip=zip)
+
+ # Private methods
+ def _findConverter(self, source_format, destination_format):
+ """
+ Browses all converter classes, initialised the repository of
+ converters and finds the appropriate class
+ """
More information about the Erp5-report
mailing list