eNotSupported, sanity_check, cookie_path
from App.Dialogs import MessageDialog
from zExceptions import BadRequest
+from zExceptions import Unauthorized
import sys
import warnings
from cgi import escape
+from urllib import unquote
from OFS import Moniker
from ZODB.POSException import ConflictError
import OFS.subscribers
-from webdav.NullResource import NullResource
from zope.event import notify
from zope.lifecycleevent import ObjectCopiedEvent
try :
from zope.component.factory import Factory
from Acquisition import aq_base, aq_inner, aq_parent
-from types import StringType
+from types import StringType, NoneType
from Products.CMFCore.permissions import ListFolderContents, View, ViewManagementScreens,\
ManageProperties, AddPortalFolders, AddPortalContent,\
ManagePortal, ModifyPortalContent
from permissions import DeletePortalContents, DeleteObjects, DeleteOwnedObjects, SetLocalRoles, CheckMemberPermission
from Products.CMFCore.utils import _checkPermission, getToolByName
+from Products.CMFCore.utils import getUtilityByInterfaceName
from Products.CMFCore.CMFCatalogAware import CMFCatalogAware
from Products.CMFCore.PortalFolder import PortalFolder, ContentFilter
+from Products.CMFCore.interfaces import IDublinCore
from Products.CMFDefault.DublinCore import DefaultDublinCoreImpl
from zope.interface import implements
from utils import _checkMemberPermission
from utils import Message as _
+from utils import makeValidId
from Globals import InitializeClass
from AccessControl import ClassSecurityInfo
+from ZServer import LARGE_FILE_THRESHOLD
+from webdav.interfaces import IWriteLock
+from webdav.common import Locked
+from webdav.common import PreconditionFailed
+from zope.contenttype import guess_content_type
class PlinnFolder(CMFCatalogAware, PortalFolder, DefaultDublinCoreImpl) :
def __init__( self, id, title='' ) :
PortalFolder.__init__(self, id)
DefaultDublinCoreImpl.__init__(self, title = title)
-
- def __getitem__(self, key):
- if key in self:
- return self._getOb(key, None)
- request = getattr(self, 'REQUEST', None)
- if not isinstance(request, (str, NoneType)):
- method=request.get('REQUEST_METHOD', 'GET')
- if (request.maybe_webdav_client and
- method not in ('GET', 'POST')):
- return NullResource(self, key, request).__of__(self)
- raise KeyError, key
-
-
+
security.declarePublic('allowedContentTypes')
def allowedContentTypes(self):
"""
""" query catalog and returns brains of contents.
Requires ExtendedPathIndex
"""
- ctool = getToolByName(self, 'portal_catalog')
+ ctool = getUtilityByInterfaceName('Products.CMFCore.interfaces.ICatalogTool')
contentFilter['path'] = {'query':'/'.join(self.getPhysicalPath()),
'depth':1}
- return ctool(sort_on='position', **contentFilter)
-
+ return ctool(sort_on='position', **contentFilter)
security.declarePublic('synContentValues')
def synContentValues(self):
if REQUEST is not None:
return self.folder_contents( # XXX: ick!
self, REQUEST, portal_status_message="Folder added")
+
+
+ security.declareProtected(AddPortalContent, 'put_upload')
+ def put_upload(self, REQUEST, RESPONSE):
+ """ Upload a content thru webdav put method.
+ The default behavior (NullRessource.PUT + PortalFolder.PUT_factory)
+ disallow files names with '_' at the begining.
+ """
+
+ self.dav__init(REQUEST, RESPONSE)
+ fileName = unquote(REQUEST.getHeader('X-File-Name', ''))
+ validId = makeValidId(self, fileName, allow_dup=True)
+
+ ifhdr = REQUEST.get_header('If', '')
+ if self.wl_isLocked():
+ if ifhdr:
+ self.dav__simpleifhandler(REQUEST, RESPONSE, col=1)
+ else:
+ raise Locked
+ elif ifhdr:
+ raise PreconditionFailed
+
+ if int(REQUEST.get('CONTENT_LENGTH') or 0) > LARGE_FILE_THRESHOLD:
+ file = REQUEST['BODYFILE']
+ body = file.read(LARGE_FILE_THRESHOLD)
+ file.seek(0)
+ else:
+ body = REQUEST.get('BODY', '')
+
+ typ=REQUEST.get_header('content-type', None)
+ if typ is None:
+ typ, enc=guess_content_type(validId, body)
+
+ if self.checkIdAvailable(validId) :
+ try :
+ ob = self.PUT_factory(validId, typ, body)
+ self._setObject(validId, ob)
+ ob = self._getOb(validId)
+ except ValueError : # maybe "Disallowed subobject type". Fallback to file type.
+ validId = self.invokeFactory('File', validId)
+ ob = self._getOb(validId)
+ if IDublinCore.providedBy(ob) :
+ ob.editMetadata(title=fileName,
+ format=typ)
+ httpRespCode = 201
+ else :
+ httpRespCode = 200
+ ob = self._getOb(validId)
+
+ # We call _verifyObjectPaste with verify_src=0, to see if the
+ # user can create this type of object (and we don't need to
+ # check the clipboard.
+ try:
+ self._verifyObjectPaste(ob.__of__(self), 0)
+ except CopyError:
+ sMsg = 'Unable to create object of class %s in %s: %s' % \
+ (ob.__class__, repr(self), sys.exc_info()[1],)
+ raise Unauthorized, sMsg
+
+ ob.PUT(REQUEST, RESPONSE)
+ ob.orig_name = fileName
+
+ # get method from ob created / refreshed
+ ti = ob.getTypeInfo()
+ method_id = ti.queryMethodID('jsupload_snippet')
+ meth = getattr(ob, method_id) if method_id else None
+ if not meth :
+ # get method from container that receive uploaded content
+ ti = self.getTypeInfo()
+ method_id = ti.queryMethodID('jsupload_snippet')
+ meth = getattr(self, method_id) if method_id else lambda ob : 'Not implemented'
+
+ RESPONSE.setStatus(httpRespCode)
+ RESPONSE.setHeader('Content-Type', 'text/xml;;charset=utf-8')
+ return '<fragment>%s</fragment>' % meth(ob).strip()
# ## overload to maintain ownership if authenticated user has 'Manage portal' permission