Commit 7bfdde2a authored by Mame Coumba Sall's avatar Mame Coumba Sall

-Modified interface of convertable to add new method that only returns

the authorized formats for conversion.
-Implement mixin for convertable, text_convertable,base_convertable,
html_convertable, metadata_discoverable and document



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@34090 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 29d7d2c2
...@@ -109,3 +109,10 @@ class IConvertable(Interface): ...@@ -109,3 +109,10 @@ class IConvertable(Interface):
where format is an extension (ex. 'png') which can be where format is an extension (ex. 'png') which can be
passed to IConvertable.convert or to IDownloadable.index_html passed to IConvertable.convert or to IDownloadable.index_html
""" """
def getPermittedTargetFormatItemList():
"""
Returns the list of authorized formats for conversion
in the form of tuples. For each format, checks
if the current user can convert the current
document into that format.
"""
\ No newline at end of file
# -*- 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.
#
##############################################################################
import md5
import string
import xmlrpclib, base64, re, zipfile, cStringIO
from xmlrpclib import Fault
from xmlrpclib import Transport
from xmlrpclib import SafeTransport
from Acquisition import aq_base
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
from Products.ERP5Type.Base import WorkflowMethod
from zLOG import LOG
from Products.ERP5Type.Cache import CachingMethod
# Mixin import
from Products.ERP5.mixin.convertable import ConvertableMixin
class BaseConvertableMixin:
"""
This class provides a generic implementation of IBaseConvertable.
"""
# Declarative security
security = ClassSecurityInfo()
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declareProtected(Permissions.AccessContentsInformation, 'hasBaseData')
def hasBaseData(self):
"""
A TextDocument store its data in the "text_content" property. Since
there is no such thing as base_data in TextDocument, having base_data
is equivalent to having some text_content.
"""
return self.hasTextContent()
def convertFile(self, **kw): # XXX - It it really useful to explicitly define ?
"""
Workflow transition invoked when conversion occurs.
"""
convertFile = WorkflowMethod(convertFile)
security.declareProtected(Permissions.ModifyPortalContent, 'convertToBaseFormat')
def convertToBaseFormat(self, **kw):
"""
Converts the content of the document to a base format
which is later used for all conversions. This method
is common to all kinds of documents and handles
exceptions in a unified way.
Implementation is delegated to _convertToBaseFormat which
must be overloaded by subclasses of Document which
need a base format.
convertToBaseFormat is called upon file upload, document
ingestion by the processing_status_workflow.
NOTE: the data of the base format conversion should be stored
using the base_data property. Refer to Document.py propertysheet.
Use accessors (getBaseData, setBaseData, hasBaseData, etc.)
"""
if getattr(self, 'hasData', None) is not None and not self.hasData():
# Empty document cannot be converted
return
try:
message = self._convertToBaseFormat() # Call implemetation method
self.clearConversionCache() # Conversion cache is now invalid
if message is None:
# XXX Need to translate.
message = 'Converted to %s.' % self.getBaseContentType()
self.convertFile(comment=message) # Invoke workflow method
except NotImplementedError:
message = ''
return message
def _convertToBaseFormat(self):
"""
"""
raise NotImplementedError
security.declareProtected(Permissions.AccessContentsInformation,
'getMetadataMappingDict')
def getMetadataMappingDict(self):
"""
Return a dict of metadata mapping used to update base metadata of the
document
"""
try:
method = self._getTypeBasedMethod('getMetadataMappingDict')
except KeyError, AttributeError:
method = None
if method is not None:
return method()
else:
return {}
security.declareProtected(Permissions.ModifyPortalContent, 'updateBaseMetadata')
def updateBaseMetadata(self, **kw):
"""
Update the base format data with the latest properties entered
by the user. For example, if title is changed in ERP5 interface,
the base format file should be updated accordingly.
Default implementation does nothing. Refer to OOoDocument class
for an example of implementation.
"""
pass
\ No newline at end of file
# -*- 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.
#
##############################################################################
import md5
import string
import xmlrpclib, base64, re, zipfile, cStringIO
from xmlrpclib import Fault
from xmlrpclib import Transport
from xmlrpclib import SafeTransport
from Acquisition import aq_base
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
from Products.ERP5Type.Base import WorkflowMethod
from zLOG import LOG
from Products.ERP5Type.Cache import CachingMethod
def makeSortedTuple(kw):
items = kw.items()
items.sort()
return tuple(items)
class ConvertableMixin:
"""
This class provides a generic implementation of IConvertable.
This class provides a generic API to store in the ZODB
various converted versions of a file or of a string.
Versions are stored in dictionaries; the class stores also
generation time of every format and its mime-type string.
Format can be a string or a tuple (e.g. format, resolution).
"""
# Declarative security
security = ClassSecurityInfo()
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Conversion methods
security.declareProtected(Permissions.AccessContentsInformation, 'convert')
def convert(self, format, **kw):
"""
Main content conversion function, returns result which should
be returned and stored in cache.
format - the format specied in the form of an extension
string (ex. jpeg, html, text, txt, etc.)
**kw can be various things - e.g. resolution
Default implementation returns an empty string (html, text)
or raises an error.
TODO:
- implement guards API so that conversion to certain
formats require certain permission
"""
# Raise an error if the format is not permitted
if not self.isTargetFormatPermitted(format):
raise Unauthorized("User does not have enough permission to access document"
" in %s format" % (format or 'original'))
if format == 'html':
return 'text/html', '' # XXX - Why ?
if format in ('text', 'txt'):
return 'text/plain', '' # XXX - Why ?
raise NotImplementedError
security.declareProtected(Permissions.View,'isTargetFormatAllowed')
def isTargetFormatAllowed(self,format):
"""
Checks if the current document can be converted
to the specified target format.
format -- the target conversion format specified either as an
extension (ex. 'png') or as a mime type
string (ex. 'text/plain')
"""
return format in self.getTargetFormatList()
security.declareProtected(Permissions.View,'isTargetFormatPermitted')
def isTargetFormatPermitted(self, format):
"""
Checks if the current user can convert the current document
into the specified target format.
"""
method = self._getTypeBasedMethod('isTargetFormatPermitted',
fallback_script_id='Document_isTargetFormatPermitted')
return method(format)
security.declareProtected(Permissions.View,'getTargetFormatItemList')
def getTargetFormatItemList(self):
"""
Returns the list of acceptable formats for conversion
in the form of tuples which can be used for example for
listfield in ERP5Form. Each tuple in the list has the form
(title, format) where format is an extension (ex. 'png')
which can be passed to IConvertable.convert or to
IDownloadable.index_html and title is a string which
can be translated and displayed to the user.
Example of result:
[('ODF Drawing', 'odg'), ('ODF Drawing Template', 'otg'),
('OpenOffice.org 1.0 Drawing', 'sxd')]
"""
return self.getAllowedTargetItemList()
security.declareProtected(Permissions.View,'getTargetFormatTitleList')
def getTargetFormatTitleList(self):
"""
Returns the list of titles of acceptable formats for conversion
as a list of strings which can be translated and displayed
to the user.
"""
return map(lambda x: x[0], self.getTargetFormatItemList())
security.declareProtected(Permissions.View,'getTargetFormatList')
def getTargetFormatList(self):
"""
Returns the list of acceptable formats for conversion
where format is an extension (ex. 'png') which can be
passed to IConvertable.convert or to IDownloadable.index_html
"""
return map(lambda x: x[1], self.getTargetFormatItemList())
security.declareProtected(Permissions.View,'getPermittedTargetFormatItemList')
def getPermittedTargetFormatItemList(self):
"""
Returns the list of authorized formats for conversion
in the form of tuples. For each format, checks
if the current user can convert the current
document into that format.
"""
authorized_format_list = []
format_list = self.getTargetFormatItemList()
for format in format_list:
if self.isTargetFormatPermitted(format[1]):
authorized_format_list.append(format)
return authorized_format_list
\ No newline at end of file
# -*- 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.
#
##############################################################################
import md5
import string
import xmlrpclib, base64, re, zipfile, cStringIO
from xmlrpclib import Fault
from xmlrpclib import Transport
from xmlrpclib import SafeTransport
from Acquisition import aq_base
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
from Products.ERP5Type.Base import WorkflowMethod
from zLOG import LOG
from Products.ERP5Type.Cache import CachingMethod
#Mixin import
from Products.ERP5.mixin.convertable import ConvertableMixin
from Products.ERP5.mixin.cached_convertable import CachedConvertableMixin
class DocumentMixin(ConvertableMixin, CachedConvertableMixin):
"""
This class provides a generic implementation of IDocument.
"""
# Declarative security
security = ClassSecurityInfo()
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declareProtected(Permissions.AccessContentsInformation,
'isSupportBaseDataConversion')
def isSupportBaseDataConversion(self):
"""
"""
return False
\ No newline at end of file
# -*- 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.
#
##############################################################################
import md5
import string
import xmlrpclib, base64, re, zipfile, cStringIO
from xmlrpclib import Fault
from xmlrpclib import Transport
from xmlrpclib import SafeTransport
from Acquisition import aq_base
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
from Products.ERP5Type.Base import WorkflowMethod
from zLOG import LOG
from Products.ERP5Type.Cache import CachingMethod
# Mixin import
from Products.ERP5.mixin.convertable import ConvertableMixin
from Products.ERP5.mixin.cached_convertable import CachedConvertableMixin
class HTMLConvertableMixin(CachedConvertableMixin):
"""
This class provides a generic implementation of IHTMLConvertable.
"""
# Declarative security
security = ClassSecurityInfo()
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declarePrivate('_asHTML')
def _asHTML(self, **kw):
"""
A private method which converts to HTML. This method
is the one to override in subclasses.
"""
if not self.hasBaseData():
raise ConversionError('This document has not been processed yet.')
try:
# FIXME: no substitution may occur in this case.
mime, data = self.getConversion(format='base-html')
return data
except KeyError:
kw['format'] = 'html'
mime, html = self.convert(**kw)
return html
security.declareProtected(Permissions.View, 'asEntireHTML')
def asEntireHTML(self, **kw):
"""
Returns a complete HTML representation of the document
(with body tags, etc.). Adds if necessary a base
tag so that the document can be displayed in an iframe
or standalone.
Actual conversion is delegated to _asHTML
"""
html = self._asHTML(**kw)
if self.getUrlString():
# If a URL is defined, add the base tag
# if base is defined yet.
html = str(html)
if not html.find('<base') >= 0:
base = '<base href="%s">' % self.getContentBaseURL()
html = html.replace('<head>', '<head>%s' % base)
self.setConversion(html, mime='text/html', format='base-html')
return html
security.declareProtected(Permissions.View, 'asStrippedHTML')
def asStrippedHTML(self, **kw):
"""
Returns a stripped HTML representation of the document
(without html and body tags, etc.) which can be used to inline
a preview of the document.
"""
if not self.hasBaseData():
return ''
try:
# FIXME: no substitution may occur in this case.
mime, data = self.getConversion(format='stripped-html')
return data
except KeyError:
kw['format'] = 'html'
mime, html = self.convert(**kw)
return self._stripHTML(str(html))
def _guessEncoding(self, string):
"""
Try to guess the encoding for this string.
Returns None if no encoding can be guessed.
"""
try:
import chardet
except ImportError:
return None
return chardet.detect(string).get('encoding', None)
def _stripHTML(self, html, charset=None):
"""
A private method which can be reused by subclasses
to strip HTML content
"""
body_list = re.findall(self.body_parser, str(html))
if len(body_list):
stripped_html = body_list[0]
else:
stripped_html = html
# find charset and convert to utf-8
charset_list = self.charset_parser.findall(str(html)) # XXX - Not efficient if this
# is datastream instance but hard to do better
if charset and not charset_list:
# Use optional parameter is we can not find encoding in HTML
charset_list = [charset]
if charset_list and charset_list[0] not in ('utf-8', 'UTF-8'):
try:
stripped_html = unicode(str(stripped_html),
charset_list[0]).encode('utf-8')
except (UnicodeDecodeError, LookupError):
return str(stripped_html)
return stripped_html
\ No newline at end of file
# -*- 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.
#
##############################################################################
import md5
import string
import xmlrpclib, base64, re, zipfile, cStringIO
from xmlrpclib import Fault
from xmlrpclib import Transport
from xmlrpclib import SafeTransport
from Acquisition import aq_base
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
from Products.ERP5Type.Base import WorkflowMethod
from zLOG import LOG
from Products.ERP5Type.Cache import CachingMethod
# Mixin import
from Products.ERP5.mixin.convertable import ConvertableMixin
from Products.ERP5.mixin.html_convertable import HTMLConvertableMixin
class MetadataDiscoverableMixin(HTMLConvertableMixin):
"""
This class provides a generic implementation of IMetadataDiscoverable.
"""
# Declarative security
security = ClassSecurityInfo()
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declareProtected(Permissions.AccessContentsInformation, 'getContentInformation')
def getContentInformation(self):
"""
Returns the content information from the HTML conversion.
The default implementation tries to build a dictionnary
from the HTML conversion of the document and extract
the document title.
"""
result = {}
html = self.asEntireHTML()
if not html: return result
title_list = re.findall(self.title_parser, str(html))
if title_list:
result['title'] = title_list[0]
return result
\ No newline at end of file
# -*- 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.
#
##############################################################################
import md5
import string
import xmlrpclib, base64, re, zipfile, cStringIO
from xmlrpclib import Fault
from xmlrpclib import Transport
from xmlrpclib import SafeTransport
from Acquisition import aq_base
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
from Products.ERP5Type.Base import WorkflowMethod
from zLOG import LOG
from Products.ERP5Type.Cache import CachingMethod
# Mixin import
from Products.ERP5.mixin.convertable import ConvertableMixin
class TextConvertableMixin:
"""
This class provides a generic implementation of ITextConvertable.
This class provides a generic API to store in the ZODB
various converted versions of a file or of a string.
Versions are stored in dictionaries; the class stores also
generation time of every format and its mime-type string.
Format can be a string or a tuple (e.g. format, resolution).
"""
# Declarative security
security = ClassSecurityInfo()
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declareProtected(Permissions.View, 'asText')
def asText(self, **kw):
"""
Text Convertable interface specification
Documents which implement the ITextConvertable interface
can be converted to plain text.
Converts the content of the document to a textual representation.
"""
kw['format'] = 'txt'
mime, data = self.convert(**kw)
return str(data)
security.declareProtected(Permissions.View, 'asSubjectText')
def asSubjectText(self, **kw):
"""
Converts the subject of the document to a textual representation.
"""
subject = self.getSubject()
if not subject:
# XXX not sure if this fallback is a good idea.
subject = self.getTitle()
if subject is None:
subject = ''
return str(subject)
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment