Commit afdf69df authored by Nicolas Delaby's avatar Nicolas Delaby

Use mixin

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@35222 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 2ebe1efe
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
# #
############################################################################## ##############################################################################
import re, sys import re, sys, os
from operator import add from operator import add
from zLOG import LOG from zLOG import LOG
from AccessControl import ClassSecurityInfo, getSecurityManager from AccessControl import ClassSecurityInfo, getSecurityManager
...@@ -38,9 +38,9 @@ from Products.ERP5Type.Globals import get_request ...@@ -38,9 +38,9 @@ from Products.ERP5Type.Globals import get_request
from Products.CMFCore.utils import getToolByName, _checkPermission from Products.CMFCore.utils import getToolByName, _checkPermission
from Products.ERP5Type import Permissions, PropertySheet, interfaces from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Type.DateUtils import convertDateToHour, number_of_hours_in_day, number_of_hours_in_year from Products.ERP5Type.DateUtils import convertDateToHour,\
number_of_hours_in_day, number_of_hours_in_year
from Products.ERP5Type.Utils import convertToUpperCase from Products.ERP5Type.Utils import convertToUpperCase
from Products.ERP5Type.Base import WorkflowMethod
from Products.ERP5Type.TransactionalVariable import getTransactionalVariable from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from Products.ERP5Type.ExtensibleTraversable import ExtensibleTraversableMixIn from Products.ERP5Type.ExtensibleTraversable import ExtensibleTraversableMixIn
from Products.ERP5Type.Cache import getReadOnlyTransactionCache from Products.ERP5Type.Cache import getReadOnlyTransactionCache
...@@ -50,12 +50,14 @@ from Products.ERP5Type.UnrestrictedMethod import unrestricted_apply ...@@ -50,12 +50,14 @@ from Products.ERP5Type.UnrestrictedMethod import unrestricted_apply
from Products.ZSQLCatalog.SQLCatalog import SQLQuery from Products.ZSQLCatalog.SQLCatalog import SQLQuery
from AccessControl import Unauthorized from AccessControl import Unauthorized
import zope.interface import zope.interface
import cStringIO
from OFS.Image import Pdata
from Products.PythonScripts.Utility import allow_class from Products.PythonScripts.Utility import allow_class
import tempfile
from subprocess import Popen, PIPE
# Mixin Import # Mixin Import
from Products.ERP5.mixin.cached_convertable import CachedConvertableMixin from Products.ERP5.mixin.cached_convertable import CachedConvertableMixin
from Products.ERP5.mixin.text_convertable import TextConvertableMixin
from Products.ERP5.mixin.downloadable import DownloadableMixin
_MARKER = [] _MARKER = []
VALID_ORDER_KEY_LIST = ('user_login', 'content', 'file_name', 'input') VALID_ORDER_KEY_LIST = ('user_login', 'content', 'file_name', 'input')
...@@ -314,7 +316,9 @@ class UpdateMixIn: ...@@ -314,7 +316,9 @@ class UpdateMixIn:
return method() return method()
class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, SnapshotMixin, UpdateMixIn): class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin,
SnapshotMixin, UpdateMixIn, TextConvertableMixin,
DownloadableMixin):
"""Document is an abstract class with all methods related to document """Document is an abstract class with all methods related to document
management in ERP5. This includes searchable text, explicit relations, management in ERP5. This includes searchable text, explicit relations,
implicit relations, metadata, versions, languages, etc. implicit relations, metadata, versions, languages, etc.
...@@ -519,38 +523,9 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S ...@@ -519,38 +523,9 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S
) )
searchable_property_list = ('asText', 'title', 'description', 'id', 'reference', searchable_property_list = ('asText', 'title', 'description', 'id', 'reference',
'version', 'short_title', 'version', 'short_title', 'subject',
'subject', 'source_reference',) 'source_reference', 'source_project_title')
### Content processing methods
security.declareProtected(Permissions.View, 'index_html')
def index_html(self, REQUEST, RESPONSE, format=None, **kw):
"""
We follow here the standard Zope API for files and images
and extend it to support format conversion. The idea
is that an image which ID is "something.jpg" should
ne directly accessible through the URL
/a/b/something.jpg. The same is true for a file and
for any document type which primary purpose is to
be used by a helper application rather than displayed
as HTML in a web browser. Exceptions to this approach
include Web Pages which are intended to be primarily rendered
withing the layout of a Web Site or withing a standard ERP5 page.
Please refer to the index_html of TextDocument.
Should return appropriate format (calling convert
if necessary) and set headers.
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
TODO:
- implement guards API so that conversion to certain
formats require certain permission
"""
raise NotImplementedError
security.declareProtected(Permissions.View, 'getSearchableText') security.declareProtected(Permissions.View, 'getSearchableText')
def getSearchableText(self, md=None): def getSearchableText(self, md=None):
...@@ -594,6 +569,8 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S ...@@ -594,6 +569,8 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S
# Compatibility with CMF Catalog # Compatibility with CMF Catalog
SearchableText = getSearchableText SearchableText = getSearchableText
index_html = DownloadableMixin.index_html
security.declareProtected(Permissions.AccessContentsInformation, 'isExternalDocument') security.declareProtected(Permissions.AccessContentsInformation, 'isExternalDocument')
def isExternalDocument(self): def isExternalDocument(self):
""" """
...@@ -1014,16 +991,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S ...@@ -1014,16 +991,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S
# disappear within a given transaction # disappear within a given transaction
return kw return kw
security.declareProtected(Permissions.AccessContentsInformation, 'getStandardFileName')
def getStandardFileName(self):
"""
Returns the document coordinates as a standard file name. This
method is the reverse of getPropertyDictFromFileName.
"""
method = self._getTypeBasedMethod('getStandardFileName',
fallback_script_id = 'Document_getStandardFileName')
return method()
### Metadata disovery and ingestion methods ### Metadata disovery and ingestion methods
security.declareProtected(Permissions.ModifyPortalContent, 'discoverMetadata') security.declareProtected(Permissions.ModifyPortalContent, 'discoverMetadata')
def discoverMetadata(self, file_name=None, user_login=None): def discoverMetadata(self, file_name=None, user_login=None):
...@@ -1107,10 +1074,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S ...@@ -1107,10 +1074,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S
- implement guards API so that conversion to certain - implement guards API so that conversion to certain
formats require certain permission formats require certain permission
""" """
if format == 'html':
return 'text/html', '' # XXX - Why ?
if format in ('text', 'txt'):
return 'text/plain', '' # XXX - Why ?
raise NotImplementedError raise NotImplementedError
security.declareProtected(Permissions.View, 'asSubjectText') security.declareProtected(Permissions.View, 'asSubjectText')
...@@ -1124,15 +1087,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S ...@@ -1124,15 +1087,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S
subject = self.getTitle('') subject = self.getTitle('')
return str(subject) return str(subject)
security.declareProtected(Permissions.View, 'asText')
def asText(self, **kw):
"""
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, 'asEntireHTML') security.declareProtected(Permissions.View, 'asEntireHTML')
def asEntireHTML(self, **kw): def asEntireHTML(self, **kw):
""" """
...@@ -1160,8 +1114,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S ...@@ -1160,8 +1114,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S
A private method which converts to HTML. This method A private method which converts to HTML. This method
is the one to override in subclasses. is the one to override in subclasses.
""" """
if not self.hasBaseData():
raise ConversionError('This document has not been processed yet.')
kw['format'] = 'html' kw['format'] = 'html'
mime, html = self.convert(**kw) mime, html = self.convert(**kw)
return html return html
...@@ -1264,11 +1216,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S ...@@ -1264,11 +1216,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S
message = '' message = ''
return message return message
def _convertToBaseFormat(self):
"""
"""
raise NotImplementedError
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'isSupportBaseDataConversion') 'isSupportBaseDataConversion')
def isSupportBaseDataConversion(self): def isSupportBaseDataConversion(self):
...@@ -1276,12 +1223,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S ...@@ -1276,12 +1223,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S
""" """
return False return False
def convertFile(self, **kw): # XXX - It it really useful to explicitly define ?
"""
Workflow transition invoked when conversion occurs.
"""
convertFile = WorkflowMethod(convertFile)
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getMetadataMappingDict') 'getMetadataMappingDict')
def getMetadataMappingDict(self): def getMetadataMappingDict(self):
...@@ -1298,18 +1239,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S ...@@ -1298,18 +1239,6 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S
else: else:
return {} 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
# Transformation API # Transformation API
security.declareProtected(Permissions.ModifyPortalContent, 'populateContent') security.declareProtected(Permissions.ModifyPortalContent, 'populateContent')
def populateContent(self): def populateContent(self):
...@@ -1390,61 +1319,3 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S ...@@ -1390,61 +1319,3 @@ class Document(PermanentURLMixIn, XMLObject, UrlMixIn, CachedConvertableMixin, S
# but not in http://www.some.site/at # but not in http://www.some.site/at
base_url = '/'.join(base_url_list[:-1]) base_url = '/'.join(base_url_list[:-1])
return base_url return base_url
security.declareProtected(Permissions.ModifyPortalContent, '_setBaseData')
def _setBaseData(self, data):
"""
XXX - it is really wrong to put this method here since not
all documents are subclasses of "File". Instead, there should
be a interface for all classes which can convert their data
to a base format.
"""
if not isinstance(data, Pdata) and data is not None:
file = cStringIO.StringIO(data)
data, size = self._read_data(file)
self._baseSetBaseData(data)
security.declareProtected(Permissions.AccessContentsInformation,
'getBaseData')
def getBaseData(self, default=None):
"""return BaseData as str."""
base_data = self._baseGetBaseData()
if base_data is None:
return None
else:
return str(base_data)
security.declareProtected(Permissions.ModifyPortalContent, '_setData')
def _setData(self, data):
"""
XXX - it is really wrong to put this method here since not
all documents are subclasses of "File". Instead, there should
be a interface for all classes which can act as a File.
"""
size = None
# update_data use len(data) when size is None, which breaks this method.
# define size = 0 will prevent len be use and keep the consistency of
# getData() and setData()
if data is None:
size = 0
if not isinstance(data, Pdata) and data is not None:
file = cStringIO.StringIO(data)
data, size = self._read_data(file)
if getattr(self, 'update_data', None) is not None:
# We call this method to make sure size is set and caches reset
self.update_data(data, size=size)
else:
self._baseSetData(data) # XXX - It would be better to always use this accessor
self.size=size # Using accessor or caching method would be better
self.ZCacheable_invalidate()
self.ZCacheable_set(None)
self.http__refreshEtag()
security.declareProtected(Permissions.AccessContentsInformation, 'getData')
def getData(self, default=None):
"""return Data as str."""
data = self._baseGetData()
if data is None:
return None
else:
return str(data)
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