Bugfix in new.py; added new user management.

This commit is contained in:
Gaetan Delannay 2010-09-02 16:16:08 +02:00
parent fa974239f3
commit eb52c1bb7d
30 changed files with 842 additions and 397 deletions

View file

@ -18,33 +18,10 @@ POD_ERROR = 'An error occurred while generating the document. Please ' \
# ------------------------------------------------------------------------------
class FlavourMixin(AbstractMixin):
_appy_meta_type = 'Flavour'
def getPortalType(self, metaTypeOrAppyType):
def getPortalType(self, metaTypeOrAppyClass):
'''Returns the name of the portal_type that is based on
p_metaTypeOrAppyType in this flavour.'''
res = metaTypeOrAppyType
isPredefined = False
isAppy = False
appName = self.getProductConfig().PROJECTNAME
if not isinstance(res, basestring):
res = ClassDescriptor.getClassName(res)
isAppy = True
if res.find('Extensions_appyWrappers') != -1:
isPredefined = True
elems = res.split('_')
res = '%s%s' % (elems[1], elems[4])
elif isAppy and issubclass(metaTypeOrAppyType, appy.gen.Tool):
# This is the custom tool
isPredefined = True
res = '%sTool' % appName
elif isAppy and issubclass(metaTypeOrAppyType, appy.gen.Flavour):
# This is the custom Flavour
isPredefined = True
res = '%sFlavour' % appName
if not isPredefined:
number = self.appy().number
if number != 1:
res = '%s_%d' % (res, number)
return res
return self.getParentNode().getPortalType(metaTypeOrAppyClass)
def registerPortalTypes(self):
'''Registers, into portal_types, the portal types which are specific

View file

@ -1,8 +1,9 @@
# ------------------------------------------------------------------------------
import re, os, os.path, Cookie
from appy.shared.utils import getOsTempFolder
import appy.gen
from appy.gen import Type, Search, Selection
from appy.gen.utils import SomeObjects, sequenceTypes
from appy.gen.utils import SomeObjects, sequenceTypes, getClassName
from appy.gen.plone25.mixins import AbstractMixin
from appy.gen.plone25.mixins.FlavourMixin import FlavourMixin
from appy.gen.plone25.wrappers import AbstractWrapper
@ -13,6 +14,17 @@ jsMessages = ('no_elem_selected', 'delete_confirm')
# ------------------------------------------------------------------------------
class ToolMixin(AbstractMixin):
_appy_meta_type = 'Tool'
def getPortalType(self, metaTypeOrAppyClass):
'''Returns the name of the portal_type that is based on
p_metaTypeOrAppyType in this flavour.'''
appName = self.getProductConfig().PROJECTNAME
if not isinstance(metaTypeOrAppyClass, basestring):
res = getClassName(metaTypeOrAppyClass, appName)
if res.find('Extensions_appyWrappers') != -1:
elems = res.split('_')
res = '%s%s' % (elems[1], elems[4])
return res
def getFlavour(self, contextObjOrPortalType, appy=False):
'''Gets the flavour that corresponds to p_contextObjOrPortalType.'''
if isinstance(contextObjOrPortalType, basestring):

View file

@ -0,0 +1,7 @@
# ------------------------------------------------------------------------------
from appy.gen.plone25.mixins import AbstractMixin
# ------------------------------------------------------------------------------
class UserMixin(AbstractMixin):
_appy_meta_type = 'UserMixin'
# ------------------------------------------------------------------------------

View file

@ -8,7 +8,7 @@
# ------------------------------------------------------------------------------
import os, os.path, types, mimetypes
import appy.gen
from appy.gen import Type, String, Selection
from appy.gen import Type, String, Selection, Role
from appy.gen.utils import *
from appy.gen.layout import Table, defaultPageLayouts
from appy.gen.plone25.descriptors import ClassDescriptor
@ -338,14 +338,30 @@ class AbstractMixin:
i = res.startNumber
# Is it possible and more efficient to perform a single query in
# uid_catalog and get the result in the order of specified uids?
toUnlink = []
while i < (res.startNumber + res.batchSize):
if i >= res.totalNumber: break
refUid = sortedUids[i]
refObject = self.uid_catalog(UID=refUid)[0].getObject()
i += 1
tool = self.getTool()
if refObject.meta_type != tool.getPortalType(appyType.klass):
toUnlink.append(refObject)
continue
if not ploneObjects:
refObject = refObject.appy()
res.objects.append(refObject)
i += 1
# Unlink dummy linked objects
if toUnlink:
suffix = '%s%s' % (fieldName[0].upper(), fieldName[1:])
exec 'linkedObjects = self.get%s()' % suffix
for dummyObject in toUnlink:
linkedObjects.remove(dummyObject)
self.getProductConfig().logger.warn('DB error: Ref %s.%s ' \
'contains a %s instance "%s". It was removed.' % \
(self.meta_type, fieldName, dummyObject.meta_type,
dummyObject.getId()))
exec 'self.set%s(linkedObjects)' % suffix
if res.objects and noListIfSingleObj:
if appyType.multiplicity[1] == 1:
res.objects = res.objects[0]
@ -413,18 +429,6 @@ class AbstractMixin:
res = sortedObjectsUids.index(obj.UID())
return res
def getAppyRefPortalType(self, fieldName):
'''Gets the portal type of objects linked to me through Ref field named
p_fieldName.'''
appyType = self.getAppyType(fieldName)
tool = self.getTool()
if self._appy_meta_type == 'Flavour':
flavour = self.appy()
else:
portalTypeName = self._appy_getPortalType(self.REQUEST)
flavour = tool.getFlavour(portalTypeName)
return self._appy_getAtType(appyType.klass, flavour)
def getAppyType(self, name, asDict=False, className=None):
'''Returns the Appy type named p_name. If no p_className is defined, the
field is supposed to belong to self's class.'''
@ -696,10 +700,10 @@ class AbstractMixin:
# Get the corresponding Appy transition
transition = workflow._transitionsMapping[transitionName]
user = self.portal_membership.getAuthenticatedMember()
if isinstance(transition.condition, basestring):
if isinstance(transition.condition, Role):
# It is a role. Transition may be triggered if the user has this
# role.
res = user.has_role(transition.condition, self)
res = user.has_role(transition.condition.name, self)
elif type(transition.condition) == types.FunctionType:
res = transition.condition(workflow, self.appy())
elif type(transition.condition) in (tuple, list):
@ -843,28 +847,6 @@ class AbstractMixin:
rq.appyWrappers[uid] = wrapper
return wrapper
def _appy_getAtType(self, appyClass, flavour=None):
'''Gets the name of the Archetypes class that corresponds to
p_appyClass (which is a Python class coming from the user
application). If p_flavour is specified, the method returns the name
of the specific Archetypes class in this flavour (ie suffixed with
the flavour number).'''
res = ClassDescriptor.getClassName(appyClass)
appName = self.getProductConfig().PROJECTNAME
if res.find('Extensions_appyWrappers') != -1:
# This is not a content type defined Maybe I am a tool or flavour
res = appName + appyClass.__name__
elif issubclass(appyClass, appy.gen.Tool):
# This is the custom tool
res = '%sTool' % appName
elif issubclass(appyClass, appy.gen.Flavour):
# This is the custom Flavour
res = '%sFlavour' % appName
else:
if flavour and flavour.number != 1:
res += '_%d' % flavour.number
return res
def _appy_getRefsBack(self, fieldName, relName, ploneObjects=False,
noListIfSingleObj=False):
'''This method returns the list of objects linked to this one
@ -927,19 +909,14 @@ class AbstractMixin:
if appyType.type != 'Ref': continue
if appyType.isBack or appyType.link: continue
# Indeed, no possibility to create objects with such Ref
refContentTypeName = self.getAppyRefPortalType(appyType.name)
refContentType = getattr(self.portal_types, refContentTypeName)
refMetaType = refContentType.content_meta_type
if refMetaType not in addPermissions: continue
# Indeed, there is no specific "add" permission is defined for tool
# and flavour, for example.
appyClass = refContentType.wrapperClass.__bases__[-1]
refType = self.getTool().getPortalType(appyType.klass)
if refType not in addPermissions: continue
# Get roles that may add this content type
creators = getattr(appyClass, 'creators', None)
creators = getattr(appyType.klass, 'creators', None)
if not creators:
creators = self.getProductConfig().defaultAddRoles
# Add those creators to the list of creators for this meta_type
addPermission = addPermissions[refMetaType]
addPermission = addPermissions[refType]
if addPermission in allCreators:
allCreators[addPermission] = allCreators[\
addPermission].union(creators)