DesktopStatusBar utilisé en tant qu'id plutôt que class.
[Plinn.git] / Folder.py
index 76d4ee1..2458bf1 100644 (file)
--- a/Folder.py
+++ b/Folder.py
@@ -27,13 +27,13 @@ from OFS.CopySupport import CopyError, eNoData, _cb_decode, eInvalid, eNotFound,
                             eNotSupported, sanity_check, cookie_path
 from App.Dialogs import MessageDialog
 from zExceptions import BadRequest
                             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 OFS import Moniker
 from ZODB.POSException import ConflictError
 import OFS.subscribers
 import sys
 import warnings
 from cgi import escape
 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.event import notify
 from zope.lifecycleevent import ObjectCopiedEvent
 try :
@@ -54,6 +54,7 @@ from Products.CMFCore.permissions import ListFolderContents, View, ViewManagemen
                                          ManagePortal, ModifyPortalContent
 from permissions import DeletePortalContents, DeleteObjects, DeleteOwnedObjects, SetLocalRoles, CheckMemberPermission
 from Products.CMFCore.utils import _checkPermission, getToolByName
                                          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.CMFDefault.DublinCore import DefaultDublinCoreImpl
 from Products.CMFCore.CMFCatalogAware import CMFCatalogAware
 from Products.CMFCore.PortalFolder import PortalFolder, ContentFilter
 from Products.CMFDefault.DublinCore import DefaultDublinCoreImpl
@@ -66,6 +67,11 @@ from utils import Message as _
 from utils import makeValidId
 from Globals import InitializeClass
 from AccessControl import ClassSecurityInfo
 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) :
 
 
 class PlinnFolder(CMFCatalogAware, PortalFolder, DefaultDublinCoreImpl) :
@@ -83,20 +89,7 @@ class PlinnFolder(CMFCatalogAware, PortalFolder, DefaultDublinCoreImpl) :
     def __init__( self, id, title='' ) :
         PortalFolder.__init__(self, id)
         DefaultDublinCoreImpl.__init__(self, title = title)
     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')):
-                id = makeValidId(self, key)
-                return NullResource(self, id, request).__of__(self)
-        raise KeyError, key
-    
-        
+            
     security.declarePublic('allowedContentTypes')
     def allowedContentTypes(self):
         """
     security.declarePublic('allowedContentTypes')
     def allowedContentTypes(self):
         """
@@ -268,11 +261,10 @@ class PlinnFolder(CMFCatalogAware, PortalFolder, DefaultDublinCoreImpl) :
         """ query catalog and returns brains of contents.
             Requires ExtendedPathIndex
         """
         """ 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}
         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):
 
     security.declarePublic('synContentValues')
     def synContentValues(self):
@@ -295,6 +287,69 @@ class PlinnFolder(CMFCatalogAware, PortalFolder, DefaultDublinCoreImpl) :
         if REQUEST is not None:
             return self.folder_contents( # XXX: ick!
                 self, REQUEST, portal_status_message="Folder added")
         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 = 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) :
+            ob = self.PUT_factory(validId, typ, body)
+            self._setObject(validId, ob)
+            ob = self._getOb(validId)
+            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
+        
+        
+        ti = ob.getTypeInfo()
+        method_id = ti.queryMethodID('jsupload_snippet')
+        meth = method_id and getattr(ob, method_id) or (lambda : 'Not implemented')
+        RESPONSE.setStatus(httpRespCode)
+        RESPONSE.setHeader('Content-Type', 'text/xml;;charset=utf-8')
+        return '<fragment>%s></fragment>' % meth().strip()
 
     
 #   ## overload to maintain ownership if authenticated user has 'Manage portal' permission
 
     
 #   ## overload to maintain ownership if authenticated user has 'Manage portal' permission