# -*- coding: utf-8 -*- ############################################################################## # # Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved. # Jean-Paul Smets-Solanes <jp@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 AccessControl import ClassSecurityInfo from Products.CMFCore.utils import getToolByName from Products.ERP5Type import Permissions from Products.ERP5Type.Globals import InitializeClass, DTMLFile 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 """