diff --git a/Products/PlonePAS/browser/configure.zcml b/Products/PlonePAS/browser/configure.zcml index a18f818f..f8e6749d 100644 --- a/Products/PlonePAS/browser/configure.zcml +++ b/Products/PlonePAS/browser/configure.zcml @@ -1,34 +1,36 @@ - + + id="PAS.SearchPrincipals" + title="Search for principals" + /> + /> + /> + /> diff --git a/Products/PlonePAS/browser/info.py b/Products/PlonePAS/browser/info.py index 68b70f6a..353228f0 100644 --- a/Products/PlonePAS/browser/info.py +++ b/Products/PlonePAS/browser/info.py @@ -1,16 +1,17 @@ -from zope.interface import implements +# -*- coding: utf-8 -*- +from zope.interface import implementer from plone.memoize.instance import memoize - from Acquisition import aq_inner from Products.PlonePAS.interfaces.browser import IPASInfoView +from Products.PluggableAuthService.interfaces.plugins import IExtractionPlugin from Products.PluggableAuthService.interfaces.plugins \ - import IExtractionPlugin, ILoginPasswordExtractionPlugin + import ILoginPasswordExtractionPlugin from Products.CMFCore.utils import getToolByName from Products.Five import BrowserView +@implementer(IPASInfoView) class PASInfoView(BrowserView): - implements(IPASInfoView) def checkExtractorForInterface(self, interface): acl = getToolByName(aq_inner(self.context), "acl_users") diff --git a/Products/PlonePAS/browser/member.py b/Products/PlonePAS/browser/member.py index cc71fd27..b0fcfa6f 100644 --- a/Products/PlonePAS/browser/member.py +++ b/Products/PlonePAS/browser/member.py @@ -1,14 +1,13 @@ -from plone.memoize.instance import memoize -from zope.interface import implements -from zope.publisher.browser import BrowserView - +# -*- coding: utf-8 -*- from Products.CMFCore.utils import getToolByName - from Products.PlonePAS.interfaces.browser import IPASMemberView +from plone.memoize.instance import memoize +from zope.interface import implementer +from zope.publisher.browser import BrowserView +@implementer(IPASMemberView) class PASMemberView(BrowserView): - implements(IPASMemberView) @memoize def info(self, userid=None): @@ -16,9 +15,15 @@ def info(self, userid=None): result = pm.getMemberInfo(memberId=userid) if result is None: # No such member: removed? We return something useful anyway. - return {'username': userid, 'description': '', 'language': '', - 'home_page': '', 'name_or_id': userid, 'location': '', - 'fullname': ''} + return { + 'username': userid, + 'description': '', + 'language': '', + 'home_page': '', + 'name_or_id': userid, + 'location': '', + 'fullname': '' + } result['name_or_id'] = result.get('fullname') or \ result.get('username') or userid return result diff --git a/Products/PlonePAS/browser/search.py b/Products/PlonePAS/browser/search.py index e19d64de..b2d0b007 100644 --- a/Products/PlonePAS/browser/search.py +++ b/Products/PlonePAS/browser/search.py @@ -1,13 +1,14 @@ -from zope.interface import implements -from zope.component import queryUtility -from Products.Five import BrowserView +# -*- coding: utf-8 -*- from Products.CMFCore.utils import getToolByName -from plone.i18n.normalizer.interfaces import IIDNormalizer +from Products.Five import BrowserView from Products.PlonePAS.interfaces.browser import IPASSearchView +from plone.i18n.normalizer.interfaces import IIDNormalizer +from zope.component import queryUtility +from zope.interface import implementer +@implementer(IPASSearchView) class PASSearchView(BrowserView): - implements(IPASSearchView) @staticmethod def extractCriteriaFromRequest(request): diff --git a/Products/PlonePAS/config.py b/Products/PlonePAS/config.py index 0b202aa4..87c86cc7 100644 --- a/Products/PlonePAS/config.py +++ b/Products/PlonePAS/config.py @@ -12,11 +12,13 @@ } # Settings for member image resize quality +HAS_PIL = True try: from PIL import Image PIL_SCALING_ALGO = Image.ANTIALIAS except ImportError: PIL_SCALING_ALGO = None + HAS_PIL = False PIL_QUALITY = 88 MEMBER_IMAGE_SCALE = (75, 100) diff --git a/Products/PlonePAS/sheet.py b/Products/PlonePAS/sheet.py index 77d4e174..8b050833 100644 --- a/Products/PlonePAS/sheet.py +++ b/Products/PlonePAS/sheet.py @@ -1,22 +1,16 @@ +# -*- coding: utf-8 -*- """ Add Mutable Property Sheets and Schema Mutable Property Sheets to PAS also a property schema type registry which is extensible. """ - -from types import StringTypes, IntType -from types import LongType, FloatType, InstanceType - -from zope.component import getUtility -from zope.interface import implements - -from DateTime.DateTime import DateTime from Products.CMFCore.interfaces import ISiteRoot - -from Products.PluggableAuthService.UserPropertySheet import _SequenceTypes -from Products.PluggableAuthService.UserPropertySheet import UserPropertySheet from Products.PlonePAS.interfaces.propertysheets import IMutablePropertySheet +from Products.PluggableAuthService.UserPropertySheet import UserPropertySheet +from Products.PluggableAuthService.UserPropertySheet import _SequenceTypes +from zope.component import getUtility +from zope.interface import implementer class PropertyValueError(ValueError): @@ -48,38 +42,62 @@ def validate(self, property_type, value): return inspector(value) PropertySchema = PropertySchemaTypeMap() -PropertySchema.addType('string', lambda x: x is None or type(x) in StringTypes) -PropertySchema.addType('text', lambda x: x is None or type(x) in StringTypes) -PropertySchema.addType('boolean', lambda x: 1) # anything can be boolean -PropertySchema.addType('int', lambda x: x is None or type(x) is IntType) -PropertySchema.addType('long', lambda x: x is None or type(x) is LongType) -PropertySchema.addType('float', lambda x: x is None or type(x) is FloatType) -PropertySchema.addType('lines', - lambda x: x is None or type(x) in _SequenceTypes) -PropertySchema.addType('selection', - lambda x: x is None or type(x) in StringTypes) -PropertySchema.addType('multiple selection', - lambda x: x is None or type(x) in _SequenceTypes) -PropertySchema.addType('date', - lambda x: 1 or x is None \ - or type(x) is InstanceType \ - and isinstance(x, DateTime)) +PropertySchema.addType( + 'string', + lambda x: x is None or isinstance(x, basestring) +) +PropertySchema.addType( + 'text', + lambda x: x is None or isinstance(x, basestring) +) +PropertySchema.addType( + 'boolean', + lambda x: 1 # anything can be boolean +) +PropertySchema.addType( + 'int', + lambda x: x is None or isinstance(x, int) +) +PropertySchema.addType( + 'long', + lambda x: x is None or isinstance(x, long) +) +PropertySchema.addType( + 'float', + lambda x: x is None or isinstance(x, float) +) +PropertySchema.addType( + 'lines', + lambda x: x is None or isinstance(x, _SequenceTypes) +) +PropertySchema.addType( + 'selection', + lambda x: x is None or isinstance(x, basestring) +) +PropertySchema.addType( + 'multiple selection', + lambda x: x is None or isinstance(x, _SequenceTypes) +) +PropertySchema.addType( + 'date', + lambda x: 1 +) validateValue = PropertySchema.validate +@implementer(IMutablePropertySheet) class MutablePropertySheet(UserPropertySheet): - implements(IMutablePropertySheet) - def validateProperty(self, id, value): - if not id in self._properties: + if id not in self._properties: raise PropertyValueError('No such property found on this schema') proptype = self.getPropertyType(id) if not validateValue(proptype, value): - raise PropertyValueError("Invalid value (%s) for " - "property '%s' of type %s" - % (value, id, proptype)) + raise PropertyValueError( + "Invalid value (%s) for property '%s' of type %s" % + (value, id, proptype) + ) def setProperty(self, user, id, value): self.validateProperty(id, value) diff --git a/Products/PlonePAS/tools/membership.py b/Products/PlonePAS/tools/membership.py index 80af29df..4fe629fd 100644 --- a/Products/PlonePAS/tools/membership.py +++ b/Products/PlonePAS/tools/membership.py @@ -21,6 +21,7 @@ from Products.CMFCore.permissions import View from Products.CMFCore.utils import _checkPermission from Products.CMFCore.utils import getToolByName +from Products.PlonePAS.config import HAS_PIL from Products.PlonePAS.events import UserInitialLoginInEvent from Products.PlonePAS.events import UserLoggedInEvent from Products.PlonePAS.events import UserLoggedOutEvent @@ -736,14 +737,13 @@ def getBadMembers(self): portrait_data = str(portrait.data) if portrait_data == '': continue - try: - import PIL - except ImportError: + if not HAS_PIL: raise RuntimeError( 'No Python Imaging Libraries (PIL) found. ' - 'Unable to validate profile image.' + 'Unable to validate profile image. ' ) try: + import PIL PIL.Image.open(StringIO(portrait_data)) except ConflictError: pass