Commit 12e4cc8b authored by Bryton Lacquement's avatar Bryton Lacquement 🚪

Get rid of Products.CMFDefault.{File.File,Portal.CMFSite}

parent 956599fa
...@@ -17,6 +17,8 @@ Save, download or return generated PDF Document ...@@ -17,6 +17,8 @@ Save, download or return generated PDF Document
# doc_pdf_file pdf content to store # doc_pdf_file pdf content to store
# doc_aggregate_list not applicable (only used for events) # doc_aggregate_list not applicable (only used for events)
from io import BytesIO
if doc_save: if doc_save:
dms_module = getattr(context, 'document_module', None) dms_module = getattr(context, 'document_module', None)
if dms_module is not None: if dms_module is not None:
...@@ -31,7 +33,7 @@ if doc_save: ...@@ -31,7 +33,7 @@ if doc_save:
) )
document.edit( document.edit(
source_reference=''.join([doc_reference, '.pdf']), source_reference=''.join([doc_reference, '.pdf']),
file=doc_pdf_file file=BytesIO(doc_pdf_file)
) )
document.setContentType("application/pdf") document.setContentType("application/pdf")
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
# #
############################################################################## ##############################################################################
from DateTime import DateTime
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Base import WorkflowMethod from Products.ERP5Type.Base import WorkflowMethod
from Products.ERP5Type import Permissions, PropertySheet from Products.ERP5Type import Permissions, PropertySheet
...@@ -34,8 +35,7 @@ from Products.ERP5.Document.Document import Document, VALID_TEXT_FORMAT_LIST ...@@ -34,8 +35,7 @@ from Products.ERP5.Document.Document import Document, VALID_TEXT_FORMAT_LIST
from Products.ERP5.Document.Document import VALID_IMAGE_FORMAT_LIST from Products.ERP5.Document.Document import VALID_IMAGE_FORMAT_LIST
from Products.ERP5.Document.Document import ConversionError from Products.ERP5.Document.Document import ConversionError
from Products.ERP5Type.Base import Base, removeIContentishInterface from Products.ERP5Type.Base import Base, removeIContentishInterface
from Products.CMFDefault.File import File as CMFFile from OFS.Image import File as OFS_File
from OFS.Image import Pdata
from cStringIO import StringIO from cStringIO import StringIO
from Products.ERP5Type.Utils import deprecated from Products.ERP5Type.Utils import deprecated
...@@ -48,7 +48,7 @@ def _unpackData(data): ...@@ -48,7 +48,7 @@ def _unpackData(data):
_MARKER = object() _MARKER = object()
class File(Document, CMFFile): class File(Document, OFS_File):
""" """
A File can contain raw data which can be uploaded and downloaded. A File can contain raw data which can be uploaded and downloaded.
It is the root class of Image, OOoDocument (ERP5OOo product), It is the root class of Image, OOoDocument (ERP5OOo product),
...@@ -112,7 +112,13 @@ class File(Document, CMFFile): ...@@ -112,7 +112,13 @@ class File(Document, CMFFile):
filename = kw.get('filename') filename = kw.get('filename')
if filename: if filename:
self._setFilename(filename) self._setFilename(filename)
if self._isNotEmpty(file_object): if file_object is not None:
# XXX: Rather than doing nothing if empty, consider changing:
# - _update_image_info to clear metadata
# - interactions to do nothing (or else?)
file_object.seek(0, 2)
if file_object.tell():
file_object.seek(0)
self._setFile(file_object, precondition=precondition) self._setFile(file_object, precondition=precondition)
Base._edit(self, **kw) Base._edit(self, **kw)
...@@ -140,11 +146,17 @@ class File(Document, CMFFile): ...@@ -140,11 +146,17 @@ class File(Document, CMFFile):
return None return None
def _setFile(self, data, precondition=None): def _setFile(self, data, precondition=None):
if data is not None and self.hasData() and \ if data is not None and \
str(data.read()) == str(self.getData()): str(data.read()) == (self.hasData() and str(self.getData())):
# Same data as previous, no need to change it's content # Same data as previous, no need to change its content
return return
CMFFile._edit(self, precondition=precondition, file=data)
# from Products.CMFDefault.File
if precondition: self.precondition = precondition
elif self.precondition: del self.precondition
if data is not None and data.tell():
data.seek(0)
self.manage_upload(data)
security.declareProtected(Permissions.ModifyPortalContent,'setFile') security.declareProtected(Permissions.ModifyPortalContent,'setFile')
def setFile(self, data, precondition=None): def setFile(self, data, precondition=None):
...@@ -192,11 +204,16 @@ class File(Document, CMFFile): ...@@ -192,11 +204,16 @@ class File(Document, CMFFile):
return str(data) return str(data)
# DAV Support # DAV Support
PUT = CMFFile.PUT security.declareProtected(Permissions.ModifyPortalContent, 'PUT')
def PUT(self, REQUEST, RESPONSE):
"""from Products.CMFDefault.File"""
OFS_File.PUT(self, REQUEST, RESPONSE)
self.reindexObject()
security.declareProtected(Permissions.FTPAccess, 'manage_FTPstat', security.declareProtected(Permissions.FTPAccess, 'manage_FTPstat',
'manage_FTPlist') 'manage_FTPlist')
manage_FTPlist = CMFFile.manage_FTPlist manage_FTPlist = OFS_File.manage_FTPlist
manage_FTPstat = CMFFile.manage_FTPstat manage_FTPstat = OFS_File.manage_FTPstat
security.declareProtected(Permissions.AccessContentsInformation, 'getMimeTypeAndContent') security.declareProtected(Permissions.AccessContentsInformation, 'getMimeTypeAndContent')
def getMimeTypeAndContent(self): def getMimeTypeAndContent(self):
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
Portal class Portal class
""" """
from DateTime import DateTime
from six.moves import map from six.moves import map
import threading import threading
from weakref import ref as weakref from weakref import ref as weakref
...@@ -26,7 +27,7 @@ from Products.SiteErrorLog.SiteErrorLog import manage_addErrorLog ...@@ -26,7 +27,7 @@ from Products.SiteErrorLog.SiteErrorLog import manage_addErrorLog
from ZPublisher import BeforeTraverse from ZPublisher import BeforeTraverse
from ZPublisher.BaseRequest import RequestContainer from ZPublisher.BaseRequest import RequestContainer
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.CMFDefault.Portal import CMFSite from Products.CMFCore.PortalObject import PortalObjectBase
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5Type.Core.Folder import FolderMixIn from Products.ERP5Type.Core.Folder import FolderMixIn
from Acquisition import aq_base from Acquisition import aq_base
...@@ -230,7 +231,7 @@ getSite, setSite = _site() ...@@ -230,7 +231,7 @@ getSite, setSite = _site()
_missing_tools_registered = None _missing_tools_registered = None
class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin): class ERP5Site(FolderMixIn, PortalObjectBase, CacheCookieMixin):
""" """
The *only* function this class should have is to help in the setup The *only* function this class should have is to help in the setup
of a new ERP5. It should not assist in the functionality at all. of a new ERP5. It should not assist in the functionality at all.
...@@ -271,6 +272,15 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin): ...@@ -271,6 +272,15 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation) security.declareObjectProtected(Permissions.AccessContentsInformation)
def __init__(self, id):
PortalObjectBase.__init__(self, id)
self.creation_date = DateTime()
security.declarePrivate('reindexObject')
def reindexObject(self, idxs=[]):
"""from Products.CMFDefault.Portal"""
pass
security.declarePublic('isSubtreeIndexable') security.declarePublic('isSubtreeIndexable')
def isSubtreeIndexable(self): def isSubtreeIndexable(self):
""" """
...@@ -409,7 +419,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin): ...@@ -409,7 +419,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
return self.index_html() return self.index_html()
def __of__(self, parent): def __of__(self, parent):
self = CMFSite.__of__(self, parent) self = PortalObjectBase.__of__(self, parent)
# Use a transactional variable for performance reason, # Use a transactional variable for performance reason,
# since ERP5Site.__of__ is called quite often. # since ERP5Site.__of__ is called quite often.
tv = getTransactionalVariable() tv = getTransactionalVariable()
...@@ -479,7 +489,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin): ...@@ -479,7 +489,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
path_item_list=path_item_list, path_item_list=path_item_list,
new_id=new_id) new_id=new_id)
# Rename the object # Rename the object
return CMFSite.manage_renameObject(self, id=id, new_id=new_id, return PortalObjectBase.manage_renameObject(self, id=id, new_id=new_id,
REQUEST=REQUEST) REQUEST=REQUEST)
...@@ -597,7 +607,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin): ...@@ -597,7 +607,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
# _getProperty is missing, but since there are no protected properties # _getProperty is missing, but since there are no protected properties
# on an ERP5 Site, we can just use getProperty instead. # on an ERP5 Site, we can just use getProperty instead.
_getProperty = CMFSite.getProperty _getProperty = PortalObjectBase.getProperty
security.declareProtected(Permissions.AccessContentsInformation, 'getUid') security.declareProtected(Permissions.AccessContentsInformation, 'getUid')
def getUid(self): def getUid(self):
...@@ -711,7 +721,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin): ...@@ -711,7 +721,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
email_from_address, email_from_name, email_from_address, email_from_name,
validate_email validate_email
): ):
CMFSite.setupDefaultProperties(self, p, title, description, PortalObjectBase.setupDefaultProperties(self, p, title, description,
email_from_address, email_from_name, email_from_address, email_from_name,
validate_email) validate_email)
...@@ -1862,7 +1872,7 @@ factory_type_information = () # No original CMF portal_types installed by defaul ...@@ -1862,7 +1872,7 @@ factory_type_information = () # No original CMF portal_types installed by defaul
class PortalGenerator: class PortalGenerator:
klass = CMFSite klass = PortalObjectBase
def setupTools(self, p): def setupTools(self, p):
"""Set up initial tools""" """Set up initial tools"""
......
...@@ -680,10 +680,9 @@ class TestDocument(TestDocumentMixin): ...@@ -680,10 +680,9 @@ class TestDocument(TestDocumentMixin):
for document_type in portal.getPortalDocumentTypeList(): for document_type in portal.getPortalDocumentTypeList():
module = portal.getDefaultModule(document_type) module = portal.getDefaultModule(document_type)
obj = module.newContent(portal_type=document_type) obj = module.newContent(portal_type=document_type)
self.assertNotEquals(obj.getCreationDate(), self.assertIsInstance(portal.creation_date, DateTime)
module.getCreationDate()) self.assertLess(portal.creation_date, obj.getCreationDate())
self.assertNotEquals(obj.getCreationDate(), self.assertIsNone(module.getCreationDate())
portal.CreationDate())
def test_06_ProcessingStateOfAClonedDocument(self): def test_06_ProcessingStateOfAClonedDocument(self):
""" """
...@@ -2884,7 +2883,7 @@ class TestDocumentWithSecurity(TestDocumentMixin): ...@@ -2884,7 +2883,7 @@ class TestDocumentWithSecurity(TestDocumentMixin):
reference='Foo_001', reference='Foo_001',
title='Foo_OO1') title='Foo_OO1')
f = makeFileUpload('Foo_001.odt') f = makeFileUpload('Foo_001.odt')
text_document.edit(file=f.read()) text_document.edit(file=f)
f.close() f.close()
self.tic() self.tic()
......
...@@ -83,7 +83,6 @@ from CopySupport import CopyContainer, CopyError,\ ...@@ -83,7 +83,6 @@ from CopySupport import CopyContainer, CopyError,\
from Errors import DeferredCatalogError, UnsupportedWorkflowMethod from Errors import DeferredCatalogError, UnsupportedWorkflowMethod
from Products.CMFActivity.ActiveObject import ActiveObject from Products.CMFActivity.ActiveObject import ActiveObject
from Products.ERP5Type.Accessor.Accessor import Accessor as Method from Products.ERP5Type.Accessor.Accessor import Accessor as Method
from Products.ERP5Type.Accessor.TypeDefinition import asDate
from Products.ERP5Type.Message import Message from Products.ERP5Type.Message import Message
from Products.ERP5Type.ConsistencyMessage import ConsistencyMessage from Products.ERP5Type.ConsistencyMessage import ConsistencyMessage
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod, super_user from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod, super_user
...@@ -3226,9 +3225,8 @@ class Base( CopyContainer, ...@@ -3226,9 +3225,8 @@ class Base( CopyContainer,
if history) if history)
except ValueError: except ValueError:
pass pass
if getattr(aq_base(self), 'CreationDate', None) is not None: if getattr(aq_base(self), 'creation_date', None):
return asDate(self.CreationDate()) return self.creation_date.toZone(DateTime().timezone())
return None # JPS-XXX - try to find a way to return a creation date instead of None
security.declareProtected(Permissions.AccessContentsInformation, 'getModificationDate') security.declareProtected(Permissions.AccessContentsInformation, 'getModificationDate')
def getModificationDate(self): def getModificationDate(self):
...@@ -3257,7 +3255,13 @@ class Base( CopyContainer, ...@@ -3257,7 +3255,13 @@ class Base( CopyContainer,
# Return a copy of history time, to prevent modification # Return a copy of history time, to prevent modification
return DateTime(max_date) return DateTime(max_date)
if self._p_serial: if self._p_serial:
return DateTime(TimeStamp(self._p_serial).timeTime()) return DateTime(self._p_mtime)
security.declareProtected(Permissions.AccessContentsInformation, 'modified')
def modified(self):
warnings.warn('modified is a deprecated alias to getModificationDate.',
DeprecationWarning)
return self.getModificationDate()
# Layout management # Layout management
security.declareProtected(Permissions.AccessContentsInformation, 'getApplicableLayout') security.declareProtected(Permissions.AccessContentsInformation, 'getApplicableLayout')
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
import collections import collections
import email import email
from io import BytesIO
import re import re
import transaction import transaction
from lxml import html from lxml import html
...@@ -80,7 +81,7 @@ class TextContent: ...@@ -80,7 +81,7 @@ class TextContent:
headers = self.parseHeadersFromText(body) headers = self.parseHeadersFromText(body)
content_type = REQUEST.get_header('Content-Type', '') content_type = REQUEST.get_header('Content-Type', '')
headers.setdefault('content_type', content_type) headers.setdefault('content_type', content_type)
headers['file'] = body headers['file'] = BytesIO(body)
self._edit(**headers) self._edit(**headers)
except ResourceLockedError, msg: except ResourceLockedError, msg:
transaction.abort() transaction.abort()
......
...@@ -38,6 +38,7 @@ import transaction ...@@ -38,6 +38,7 @@ import transaction
from random import randint from random import randint
from unittest import expectedFailure from unittest import expectedFailure
from Acquisition import aq_base from Acquisition import aq_base
from DateTime import DateTime
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import DummyLocalizer from Products.ERP5Type.tests.utils import DummyLocalizer
from zLOG import INFO from zLOG import INFO
...@@ -2590,8 +2591,9 @@ class TestERP5Type(PropertySheetTestCase, LogInterceptor): ...@@ -2590,8 +2591,9 @@ class TestERP5Type(PropertySheetTestCase, LogInterceptor):
portal = self.getPortalObject() portal = self.getPortalObject()
folder = self.getOrganisationModule() folder = self.getOrganisationModule()
object = folder.newContent(portal_type='Organisation') object = folder.newContent(portal_type='Organisation')
self.assertNotEquals(object.getCreationDate(), portal.CreationDate()) self.assertIsInstance(portal.creation_date, DateTime)
self.assertNotEquals(object.getCreationDate(), folder.getCreationDate()) self.assertLess(portal.creation_date, object.getCreationDate())
self.assertIsNone(folder.getCreationDate())
def test_copyWithoutModificationRight(self): def test_copyWithoutModificationRight(self):
""" """
......
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