Commit 5c7d50d5 authored by Julien Muchembled's avatar Julien Muchembled

Fix webdav support when used to upload embedded files

Also cleanup and optimize PUT & ContributionTool

This reverts commit eaf12293.
parent 03f09669
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionDefinition" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>activate_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value>
<list>
<string>Document_setFilenameAndContentType</string>
</list>
</value>
</item>
<item>
<key> <string>before_commit_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Document_PUT</string> </value>
</item>
<item>
<key> <string>method_id</string> </key>
<value>
<list>
<string>PUT</string>
</list>
</value>
</item>
<item>
<key> <string>once_per_transaction</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>temporary_document_disallowed</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>document = state_change[\'object\']\n
portal = document.getPortalObject()\n
\n
filename = document.getId()\n
document.setFilename(filename)\n
content_type = portal.mimetypes_registry.lookupExtension(filename)\n
\n
if content_type is not None:\n
document.setContentType(str(content_type))\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Document_setFilenameAndContentType</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
990 991
\ No newline at end of file \ No newline at end of file
...@@ -151,7 +151,6 @@ class ContributionTool(BaseTool): ...@@ -151,7 +151,6 @@ class ContributionTool(BaseTool):
kw['filename'] = kw['file_name'] kw['filename'] = kw['file_name']
del(kw['file_name']) del(kw['file_name'])
filename = kw.get('filename', None) filename = kw.get('filename', None)
portal_type = kw.get('portal_type')
temp_object = kw.get('temp_object', False) temp_object = kw.get('temp_object', False)
document = None document = None
...@@ -161,42 +160,55 @@ class ContributionTool(BaseTool): ...@@ -161,42 +160,55 @@ class ContributionTool(BaseTool):
# Container may disappear, be smoother by passing default value # Container may disappear, be smoother by passing default value
container = portal.restrictedTraverse(container_path, None) container = portal.restrictedTraverse(container_path, None)
# Try to find the filename # Try to find the filename
content_type = None
if not url: if not url:
# check if file was provided # check if file was provided
file_object = kw.get('file') file_object = kw.get('file')
if file_object is not None: if file_object is not None:
if not filename: if not filename:
filename = file_object.filename filename = getattr(file_object, 'filename', None)
else: else:
# some channels supply data and file-name separately # some channels supply data and file-name separately
# this is the case for example for email ingestion # this is the case for example for email ingestion
# in this case, we build a file wrapper for it # in this case, we build a file wrapper for it
data = kw.get('data') try:
if data is not None and filename: data = kw.pop('data')
except KeyError:
raise ValueError('data must be provided')
if data is not None:
file_object = cStringIO.StringIO() file_object = cStringIO.StringIO()
file_object.write(data) file_object.write(data)
file_object.seek(0) file_object.seek(0)
kw['file'] = file_object kw['file'] = file_object
del kw['data'] content_type = kw.pop('content_type', None)
else:
raise TypeError, 'data and filename must be provided'
else: else:
file_object, filename, content_type = self._openURL(url) file_object, filename, content_type = self._openURL(url)
if content_type: content_type = kw.pop('content_type', None) or content_type
kw['content_type'] = content_type
kw['file'] = file_object kw['file'] = file_object
if not filename:
raise ValueError('filename must be provided')
if not content_type: if not content_type:
# fallback to a default content_type according provided # fallback to a default content_type according provided
# filename # filename
content_type = self.guessMimeTypeFromFilename(filename) content_type = self.guessMimeTypeFromFilename(filename)
if content_type:
kw['content_type'] = content_type
portal_type = kw.pop('portal_type', None)
if not portal_type:
if container is None or container.isModuleType():
# Guess it with help of portal_contribution_registry
portal_type = portal.portal_contribution_registry.findPortalTypeName(
filename=filename, content_type=content_type)
else:
portal_type = 'Embedded File'
if portal_type and container is not None: if container is not None:
# Simplify things here and return a document immediately # Simplify things here and return a document immediately
# XXX Nicolas: This will break support of WebDAV # XXX Nicolas: This will break support of WebDAV
# if _setObject is not called # if _setObject is not called
document = container.newContent(id=document_id, **kw) document = container.newContent(document_id, portal_type, **kw)
if discover_metadata: if discover_metadata:
document.activate(after_path_and_method_id=(document.getPath(), document.activate(after_path_and_method_id=(document.getPath(),
('convertToBaseFormat', 'Document_tryToConvertToBaseFormat')))\ ('convertToBaseFormat', 'Document_tryToConvertToBaseFormat')))\
...@@ -206,24 +218,14 @@ class ContributionTool(BaseTool): ...@@ -206,24 +218,14 @@ class ContributionTool(BaseTool):
return document return document
# If the portal_type was provided, we can go faster # If the portal_type was provided, we can go faster
if portal_type and container is None: if portal_type:
# We know the portal_type, let us find the default module # We know the portal_type, let us find the default module
# and use it as container # and use it as container
try: try:
container = portal.getDefaultModule(portal_type) container = portal.getDefaultModule(portal_type)
except ValueError: except ValueError:
container = None pass
# From here, there is no hope unless a file was provided
if file_object is None:
raise ValueError, "No data provided"
if portal_type is None:
# Guess it with help of portal_contribution_registry
registry = portal.portal_contribution_registry
portal_type = registry.findPortalTypeName(filename=filename,
content_type=content_type)
# #
# Check if same file is already exists. if it exists, then update it. # Check if same file is already exists. if it exists, then update it.
# #
...@@ -247,12 +249,9 @@ class ContributionTool(BaseTool): ...@@ -247,12 +249,9 @@ class ContributionTool(BaseTool):
# Temp objects use the standard newContent from Folder # Temp objects use the standard newContent from Folder
if temp_object: if temp_object:
# For temp_object creation, use the standard method # For temp_object creation, use the standard method
kw['portal_type'] = portal_type return BaseTool.newContent(self, portal_type=portal_type, **kw)
return BaseTool.newContent(self, **kw)
# Then put the file inside ourselves for a short while # Then put the file inside ourselves for a short while
if container_path is not None:
container = self.getPortalObject().restrictedTraverse(container_path)
document = self._setObject(document_id, None, portal_type=portal_type, document = self._setObject(document_id, None, portal_type=portal_type,
user_login=user_login, container=container, user_login=user_login, container=container,
discover_metadata=discover_metadata, discover_metadata=discover_metadata,
...@@ -270,7 +269,7 @@ class ContributionTool(BaseTool): ...@@ -270,7 +269,7 @@ class ContributionTool(BaseTool):
# Allow reindexing, reindex it and return the document # Allow reindexing, reindex it and return the document
try: try:
delattr(document, 'isIndexable') del document.isIndexable
except AttributeError: except AttributeError:
# Document does not have such attribute # Document does not have such attribute
pass pass
......
...@@ -44,7 +44,6 @@ from Products.ERP5Type.CopySupport import CopyContainer ...@@ -44,7 +44,6 @@ from Products.ERP5Type.CopySupport import CopyContainer
from Products.ERP5Type import PropertySheet from Products.ERP5Type import PropertySheet
from Products.ERP5Type.XMLExportImport import Folder_asXML from Products.ERP5Type.XMLExportImport import Folder_asXML
from Products.ERP5Type.Utils import sortValueList from Products.ERP5Type.Utils import sortValueList
from Products.ERP5Type.WebDAVSupport import Folder as WebDAVFolder
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
try: try:
...@@ -454,7 +453,7 @@ BTREE_HANDLER = 1 ...@@ -454,7 +453,7 @@ BTREE_HANDLER = 1
HBTREE_HANDLER = 2 HBTREE_HANDLER = 2
class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn, WebDAVFolder): class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn):
""" """
A Folder is a subclass of Base but not of XMLObject. A Folder is a subclass of Base but not of XMLObject.
Folders are not considered as documents and are therefore Folders are not considered as documents and are therefore
...@@ -518,7 +517,7 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn, ...@@ -518,7 +517,7 @@ class Folder(CopyContainer, CMFBTreeFolder, CMFHBTreeFolder, Base, FolderMixIn,
Title = Base.Title Title = Base.Title
_setPropValue = Base._setPropValue _setPropValue = Base._setPropValue
_propertyMap = Base._propertyMap # are there any others XXX ? _propertyMap = Base._propertyMap # are there any others XXX ?
PUT_factory = WebDAVFolder.PUT_factory PUT_factory = None
# XXX Prevent inheritance from PortalFolderBase # XXX Prevent inheritance from PortalFolderBase
description = None description = None
......
...@@ -200,36 +200,48 @@ class TextContent: ...@@ -200,36 +200,48 @@ class TextContent:
""" Used for FTP and apparently the ZMI now too """ """ Used for FTP and apparently the ZMI now too """
return len(self.manage_FTPget()) return len(self.manage_FTPget())
from webdav.common import Locked, PreconditionFailed
class Folder: from webdav.interfaces import IWriteLock
""" from webdav.NullResource import NullResource
Taken from CMFCore.PortalFolder from zope.contenttype import guess_content_type
""" NullResource_PUT = NullResource.PUT
def PUT_factory( self, name, typ, body ):
""" Factory for PUT requests to objects which do not yet exist. def PUT(self, REQUEST, RESPONSE):
"""Create a new non-collection resource.
Used by NullResource.PUT. """
if getattr(self.__parent__, 'PUT_factory', None) is not None: # BBB
Returns -- Bare and empty object of the appropriate type (or None, if return NullResource_PUT(self, REQUEST, RESPONSE)
we don't know what to do)
""" self.dav__init(REQUEST, RESPONSE)
portal = self.getPortalObject()
registry = portal.portal_contribution_registry name = self.__name__
portal_type = registry.findPortalTypeName(filename=name, parent = self.__parent__
content_type=typ)
if portal_type is None: ifhdr = REQUEST.get_header('If', '')
return None if IWriteLock.providedBy(parent) and parent.wl_isLocked():
if ifhdr:
# The code bellow is inspired from ERP5Type.Core.Folder.newContent parent.dav__simpleifhandler(REQUEST, RESPONSE, col=1)
pt = self._getTypesTool() else:
myType = pt.getTypeInfo(self) # There was no If header at all, and our parent is locked,
if myType is not None and not myType.allowType( portal_type ) and \ # so we fail here
'portal_contributions' not in self.getPhysicalPath(): raise Locked
raise ValueError('Disallowed subobject type: %s' % portal_type) elif ifhdr:
container = portal.getDefaultModule(portal_type) # There was an If header, but the parent is not locked
pt.constructContent(type_name=portal_type, raise PreconditionFailed
container=container,
id=name) # <ERP5>
# XXX: Do we really want to force 'id'
document = container._getOb(name) # when PUT is called on Contribution Tool ?
return document kw = {'id': name, 'data': None, 'filename': name}
contribution_tool = parent.getPortalObject().portal_contributions
if aq_base(contribution_tool) is not aq_base(parent):
kw.update(container=parent, discover_metadata=False)
ob = contribution_tool.newContent(**kw)
# </ERP5>
ob.PUT(REQUEST, RESPONSE)
RESPONSE.setStatus(201)
RESPONSE.setBody('')
return RESPONSE
NullResource.PUT = PUT
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