- """ Plinn Folder """
-
- implements(IContentish)
-
- security = ClassSecurityInfo()
-
- manage_options = PortalFolder.manage_options
-
- ## change security for inherited methods
- security.declareProtected(AddPortalContent, 'manage_pasteObjects')
-
- def __init__( self, id, title='' ) :
- PortalFolder.__init__(self, id)
- DefaultDublinCoreImpl.__init__(self, title = title)
-
- security.declarePublic('allowedContentTypes')
- def allowedContentTypes(self):
- """
- List type info objects for types which can be added in this folder.
- Types can be filtered using the localContentTypes attribute.
- """
- allowedTypes = PortalFolder.allowedContentTypes(self)
- if hasattr(self, 'localContentTypes'):
- allowedTypes = [t for t in allowedTypes if t.title in self.localContentTypes]
- return allowedTypes
-
- security.declareProtected(View, 'objectIdCanBeDeleted')
- def objectIdCanBeDeleted(self, id) :
- """ Check permissions and ownership and return True
- if current user can delete object id.
- """
- if _checkPermission(DeleteObjects, self) : # std zope perm
- return True
-
- elif _checkPermission(DeletePortalContents, self):
- mtool = getToolByName(self, 'portal_membership')
- authMember = mtool.getAuthenticatedMember()
- ob = getattr(self, id)
- if authMember.allowed(ob, object_roles=['Owner'] ) and \
- _checkPermission(DeleteOwnedObjects, ob) : return True
-
- else :
- return False
-
-
- security.declareProtected(DeletePortalContents, 'manage_delObjects')
- def manage_delObjects(self, ids=[], REQUEST=None):
- """Delete subordinate objects.
- A member can delete his owned contents (if he has the 'Delete Portal Contents' permission)
- without 'Delete objects' permission in this folder.
- Return skipped object ids.
- """
- notOwned = []
- if _checkPermission(DeleteObjects, self) : # std zope perm
- PortalFolder.manage_delObjects(self, ids=ids, REQUEST=REQUEST)
- else :
- mtool = getToolByName(self, 'portal_membership')
- authMember = mtool.getAuthenticatedMember()
- owned = []
- if type(ids) == StringType :
- ids = [ids]
- for id in ids :
- ob = self._getOb(id)
- if authMember.allowed(ob, object_roles=['Owner'] ) and \
- _checkPermission(DeleteOwnedObjects, ob) : owned.append(id)
- else : notOwned.append(id)
- if owned :
- PortalFolder.manage_delObjects(self, ids=owned, REQUEST=REQUEST)
-
- if REQUEST is not None:
- return self.manage_main(
- self, REQUEST,
- manage_tabs_message='Object(s) deleted.',
- update_menu=1)
- return notOwned
-
-
- security.declareProtected(AddPortalContent, 'manage_renameObjects')
- def manage_renameObjects(self, ids=[], new_ids=[], REQUEST=None) :
- """ Rename subordinate objects
- A member can rename his owned contents if he has the 'Modify Portal Content' permission.
- Returns skippend object ids.
- """
- if len(ids) != len(new_ids):
- raise BadRequest(_('Please rename each listed object.'))
-
- if _checkPermission(ViewManagementScreens, self) : # std zope perm
- return super(PlinnFolder, self).manage_renameObjects(ids, new_ids, REQUEST)
-
- mtool = getToolByName(self, 'portal_membership')
- authMember = mtool.getAuthenticatedMember()
- skiped = []
- for id, new_id in zip(ids, new_ids) :
- if id == new_id : continue
-
- ob = self._getOb(id)
- if authMember.allowed(ob, object_roles=['Owner'] ) and \
- _checkPermission(ModifyPortalContent, ob) :
- self.manage_renameObject(id, new_id)
- else :
- skiped.append(id)
-
- if REQUEST is not None :
- return self.manage_main(self, REQUEST, update_menu=1)
-
- return skiped
-
-
- security.declareProtected(ListFolderContents, 'listFolderContents')
- def listFolderContents( self, contentFilter=None ):
- """ List viewable contentish and folderish sub-objects.
- """
- items = self.contentItems(filter=contentFilter)
- l = []
- for id, obj in items:
- if _checkPermission(View, obj) :
- l.append(obj)
-
- return l
-
-
- security.declareProtected(ListFolderContents, 'listNearestFolderContents')
- def listNearestFolderContents(self, contentFilter=None, userid=None, sorted=False) :
- """ Return folder contents and traverse
- recursively unaccessfull sub folders to find
- accessible contents.
- """
-
- filt = {}
- if contentFilter :
- filt = contentFilter.copy()
- ctool = getToolByName(self, 'portal_catalog')
- mtool = getToolByName(self, 'portal_membership')
-
- if userid and _checkPermission(CheckMemberPermission, getToolByName(self, 'portal_url').getPortalObject()) :
- checkFunc = lambda perm, ob : _checkMemberPermission(userid, View, ob)
- filt['allowedRolesAndUsers'] = ctool._listAllowedRolesAndUsers( mtool.getMemberById(userid) )
- else :
- checkFunc = _checkPermission
- filt['allowedRolesAndUsers'] = ctool._listAllowedRolesAndUsers( mtool.getAuthenticatedMember() )
-
-
- # copy from CMFCore.PortalFolder.PortalFolder._filteredItems
- pt = filt.get('portal_type', [])
- if type(pt) is type(''):
- pt = [pt]
- types_tool = getToolByName(self, 'portal_types')
- allowed_types = types_tool.listContentTypes()
- if not pt:
- pt = allowed_types
- else:
- pt = [t for t in pt if t in allowed_types]
- if not pt:
- # After filtering, no types remain, so nothing should be
- # returned.
- return []
- filt['portal_type'] = pt
- #---
-
- query = ContentFilter(**filt)
- nearestObjects = []
-
- for o in self.objectValues() :
- if query(o) :
- if checkFunc(View, o):
- nearestObjects.append(o)
- elif getattr(o.aq_self,'isAnObjectManager', False):
- nearestObjects.extend(_getDeepObjects(self, ctool, o, filter=filt))
-
- if sorted and len(nearestObjects) > 0 :
- key, reverse = self.getDefaultSorting()
- if key != 'position' :
- indexCallable = callable(getattr(nearestObjects[0], key))
- if indexCallable :
- sortfunc = lambda a, b : cmp(getattr(a, key)(), getattr(b, key)())
- else :
- sortfunc = lambda a, b : cmp(getattr(a, key), getattr(b, key))
- nearestObjects.sort(cmp=sortfunc, reverse=reverse)
-
- return nearestObjects
-
- security.declareProtected(ListFolderContents, 'listCatalogedContents')
- def listCatalogedContents(self, contentFilter={}):
- """ query catalog and returns brains of contents.
- Requires ExtendedPathIndex
- """
- ctool = getToolByName(self, 'portal_catalog')
- contentFilter['path'] = {'query':'/'.join(self.getPhysicalPath()),
- 'depth':1}
- return ctool(sort_on='position', **contentFilter)
-
-
- security.declarePublic('synContentValues')
- def synContentValues(self):
- # value for syndication
- return self.listNearestFolderContents()
-
- security.declareProtected(View, 'SearchableText')
- def SearchableText(self) :
- """ for full text indexation
- """
- return '%s %s' % (self.title, self.description)
-
- security.declareProtected(AddPortalFolders, 'manage_addPlinnFolder')
- def manage_addPlinnFolder(self, id, title='', REQUEST=None):
- """Add a new PortalFolder object with id *id*.
- """
- ob=PlinnFolder(id, title)
- # from CMFCore.PortalFolder.PortalFolder :-)
- self._setObject(id, ob)
- if REQUEST is not None:
- return self.folder_contents( # XXX: ick!
- self, REQUEST, portal_status_message="Folder added")
-
-
+ """ Plinn Folder """
+
+ implements(IContentish)
+
+ security = ClassSecurityInfo()
+
+ manage_options = PortalFolder.manage_options
+
+ ## change security for inherited methods
+ security.declareProtected(AddPortalContent, 'manage_pasteObjects')
+
+ def __init__( self, id, title='' ) :
+ PortalFolder.__init__(self, id)
+ DefaultDublinCoreImpl.__init__(self, title = title)
+
+ security.declarePublic('allowedContentTypes')
+ def allowedContentTypes(self):
+ """
+ List type info objects for types which can be added in this folder.
+ Types can be filtered using the localContentTypes attribute.
+ """
+ allowedTypes = PortalFolder.allowedContentTypes(self)
+ if hasattr(self, 'localContentTypes'):
+ allowedTypes = [t for t in allowedTypes if t.title in self.localContentTypes]
+ return allowedTypes
+
+ security.declareProtected(View, 'objectIdCanBeDeleted')
+ def objectIdCanBeDeleted(self, id) :
+ """ Check permissions and ownership and return True
+ if current user can delete object id.
+ """
+ if _checkPermission(DeleteObjects, self) : # std zope perm
+ return True
+
+ elif _checkPermission(DeletePortalContents, self):
+ mtool = getToolByName(self, 'portal_membership')
+ authMember = mtool.getAuthenticatedMember()
+ ob = getattr(self, id)
+ if authMember.allowed(ob, object_roles=['Owner'] ) and \
+ _checkPermission(DeleteOwnedObjects, ob) : return True
+
+ else :
+ return False
+
+
+ security.declareProtected(DeletePortalContents, 'manage_delObjects')
+ def manage_delObjects(self, ids=[], REQUEST=None):
+ """Delete subordinate objects.
+ A member can delete his owned contents (if he has the 'Delete Portal Contents' permission)
+ without 'Delete objects' permission in this folder.
+ Return skipped object ids.
+ """
+ notOwned = []
+ if _checkPermission(DeleteObjects, self) : # std zope perm
+ PortalFolder.manage_delObjects(self, ids=ids, REQUEST=REQUEST)
+ else :
+ mtool = getToolByName(self, 'portal_membership')
+ authMember = mtool.getAuthenticatedMember()
+ owned = []
+ if type(ids) == StringType :
+ ids = [ids]
+ for id in ids :
+ ob = self._getOb(id)
+ if authMember.allowed(ob, object_roles=['Owner'] ) and \
+ _checkPermission(DeleteOwnedObjects, ob) : owned.append(id)
+ else : notOwned.append(id)
+ if owned :
+ PortalFolder.manage_delObjects(self, ids=owned, REQUEST=REQUEST)
+
+ if REQUEST is not None:
+ return self.manage_main(
+ self, REQUEST,
+ manage_tabs_message='Object(s) deleted.',
+ update_menu=1)
+ return notOwned
+
+
+ security.declareProtected(AddPortalContent, 'manage_renameObjects')
+ def manage_renameObjects(self, ids=[], new_ids=[], REQUEST=None) :
+ """ Rename subordinate objects
+ A member can rename his owned contents if he has the 'Modify Portal Content' permission.
+ Returns skippend object ids.
+ """
+ if len(ids) != len(new_ids):
+ raise BadRequest(_('Please rename each listed object.'))
+
+ if _checkPermission(ViewManagementScreens, self) : # std zope perm
+ return super(PlinnFolder, self).manage_renameObjects(ids, new_ids, REQUEST)
+
+ mtool = getToolByName(self, 'portal_membership')
+ authMember = mtool.getAuthenticatedMember()
+ skiped = []
+ for id, new_id in zip(ids, new_ids) :
+ if id == new_id : continue
+
+ ob = self._getOb(id)
+ if authMember.allowed(ob, object_roles=['Owner'] ) and \
+ _checkPermission(ModifyPortalContent, ob) :
+ self.manage_renameObject(id, new_id)
+ else :
+ skiped.append(id)
+
+ if REQUEST is not None :
+ return self.manage_main(self, REQUEST, update_menu=1)
+
+ return skiped
+
+
+ security.declareProtected(ListFolderContents, 'listFolderContents')
+ def listFolderContents( self, contentFilter=None ):
+ """ List viewable contentish and folderish sub-objects.
+ """
+ items = self.contentItems(filter=contentFilter)
+ l = []
+ for id, obj in items:
+ if _checkPermission(View, obj) :
+ l.append(obj)
+
+ return l
+
+
+ security.declareProtected(ListFolderContents, 'listNearestFolderContents')
+ def listNearestFolderContents(self, contentFilter=None, userid=None, sorted=False) :
+ """ Return folder contents and traverse
+ recursively unaccessfull sub folders to find
+ accessible contents.
+ """
+
+ filt = {}
+ if contentFilter :
+ filt = contentFilter.copy()
+ ctool = getToolByName(self, 'portal_catalog')
+ mtool = getToolByName(self, 'portal_membership')
+
+ if userid and _checkPermission(CheckMemberPermission, getToolByName(self, 'portal_url').getPortalObject()) :
+ checkFunc = lambda perm, ob : _checkMemberPermission(userid, View, ob)
+ filt['allowedRolesAndUsers'] = ctool._listAllowedRolesAndUsers( mtool.getMemberById(userid) )
+ else :
+ checkFunc = _checkPermission
+ filt['allowedRolesAndUsers'] = ctool._listAllowedRolesAndUsers( mtool.getAuthenticatedMember() )
+
+
+ # copy from CMFCore.PortalFolder.PortalFolder._filteredItems
+ pt = filt.get('portal_type', [])
+ if type(pt) is type(''):
+ pt = [pt]
+ types_tool = getToolByName(self, 'portal_types')
+ allowed_types = types_tool.listContentTypes()
+ if not pt:
+ pt = allowed_types
+ else:
+ pt = [t for t in pt if t in allowed_types]
+ if not pt:
+ # After filtering, no types remain, so nothing should be
+ # returned.
+ return []
+ filt['portal_type'] = pt
+ #---
+
+ query = ContentFilter(**filt)
+ nearestObjects = []
+
+ for o in self.objectValues() :
+ if query(o) :
+ if checkFunc(View, o):
+ nearestObjects.append(o)
+ elif getattr(o.aq_self,'isAnObjectManager', False):
+ nearestObjects.extend(_getDeepObjects(self, ctool, o, filter=filt))
+
+ if sorted and len(nearestObjects) > 0 :
+ key, reverse = self.getDefaultSorting()
+ if key != 'position' :
+ indexCallable = callable(getattr(nearestObjects[0], key))
+ if indexCallable :
+ sortfunc = lambda a, b : cmp(getattr(a, key)(), getattr(b, key)())
+ else :
+ sortfunc = lambda a, b : cmp(getattr(a, key), getattr(b, key))
+ nearestObjects.sort(cmp=sortfunc, reverse=reverse)
+
+ return nearestObjects
+
+ security.declareProtected(ListFolderContents, 'listCatalogedContents')
+ def listCatalogedContents(self, contentFilter={}):
+ """ query catalog and returns brains of contents.
+ Requires ExtendedPathIndex
+ """
+ ctool = getUtilityByInterfaceName('Products.CMFCore.interfaces.ICatalogTool')
+ contentFilter['path'] = {'query':'/'.join(self.getPhysicalPath()),
+ 'depth':1}
+ if not contentFilter.has_key('sort_on') :
+ contentFilter['sort_index'] = 'position'
+ return ctool(**contentFilter)
+
+ security.declarePublic('synContentValues')
+ def synContentValues(self):
+ # value for syndication
+ return self.listNearestFolderContents()
+
+ security.declareProtected(View, 'SearchableText')
+ def SearchableText(self) :
+ """ for full text indexation
+ """
+ return '%s %s' % (self.title, self.description)
+
+ security.declareProtected(AddPortalFolders, 'manage_addPlinnFolder')
+ def manage_addPlinnFolder(self, id, title='', REQUEST=None):
+ """Add a new PortalFolder object with id *id*.
+ """
+ ob=PlinnFolder(id, title)
+ # from CMFCore.PortalFolder.PortalFolder :-)
+ self._setObject(id, ob)
+ 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()
+
+