1 # -*- coding: utf-8 -*-
2 #######################################################################################
3 # Plinn - http://plinn.org #
4 # Copyright (C) 2005-2007 BenoƮt PIN <benoit.pin@ensmp.fr> #
6 # This program is free software; you can redistribute it and/or #
7 # modify it under the terms of the GNU General Public License #
8 # as published by the Free Software Foundation; either version 2 #
9 # of the License, or (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program; if not, write to the Free Software #
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
19 #######################################################################################
20 """ Plinn public utilities
21 $Id: utils.py 1534 2009-09-07 11:05:57Z pin $
22 $URL: http://svn.cri.ensmp.fr/svn/Plinn/branches/CMF-2.1/utils.py $
27 from types
import StringType
28 from random
import randrange
29 from Acquisition
import aq_base
30 from AccessControl
.PermissionRole
import rolesForPermissionOn
31 from AccessControl
import ModuleSecurityInfo
32 from AccessControl
import getSecurityManager
33 from AccessControl
.User
import UnrestrictedUser
34 from OFS
.CopySupport
import _cb_decode
, _cb_encode
, cookie_path
35 from Products
.CMFCore
.utils
import getToolByName
, getUtilityByInterfaceName
36 from Products
.CMFCore
.exceptions
import BadRequest
37 from Products
.Utf8Splitter
.Utf8Splitter
import Utf8Utils
38 from Globals
import REPLACEABLE
, NOT_REPLACEABLE
, UNIQUE
39 #from Products.PageTemplates.GlobalTranslationService import getGlobalTranslationService
40 from zope
.i18n
.interfaces
import IUserPreferredLanguages
41 from zope
.i18nmessageid
import MessageFactory
42 from zope
.component
.interfaces
import ComponentLookupError
43 from zope
.dottedname
.resolve
import resolve
as resolve_dotted_name
44 from zope
.component
import queryAdapter
48 security
= ModuleSecurityInfo( 'Products.Plinn.utils' )
50 security
.declarePublic('thisObjectComeFromPortalSkin')
51 def thisObjectComeFromPortalSkin(ob
, portal
=None):
52 """ check if ob comes from portal_skins """
54 portal
= getToolByName(ob
, 'portal_url')
55 portal
= portal
.getPortalObject()
57 if ob
.aq_self
== portal
.aq_self
:
64 sob
= getattr(portal
, obId
, None)
68 elif not(sob
.aq_inner
.aq_self
is ob
.aq_inner
.aq_self
) :
77 security
.declarePublic('listActionProviders_')
78 def listActionProviders_(context
) :
79 atool
= getToolByName(context
, 'portal_actions')
80 return atool
.listActionProviders()
82 def capitalizeCompoundGivenName(givenName
) :
83 givenName
= givenName
.strip()
84 givenNames
= ' '.join(givenName
.split('-')).split()
85 givenNameCapitalized
= '-'.join(map(string
.capitalize
, givenNames
))
86 return givenNameCapitalized
89 def formatFullName(memberName
, memberGivenName
, memberId
, nameBefore
=1) :
91 if memberName
and memberGivenName
:
93 memberFullName
= memberName
.capitalize() + ' ' + capitalizeCompoundGivenName(memberGivenName
)
95 memberFullName
= capitalizeCompoundGivenName(memberGivenName
) + ' ' + memberName
.capitalize()
97 elif memberName
and not memberGivenName
:
98 memberFullName
= memberName
.capitalize()
100 elif not memberName
and memberGivenName
:
101 memberFullName
= capitalizeCompoundGivenName(memberGivenName
)
104 memberFullName
= memberId
106 return memberFullName
108 # from OFS.ObjectManager #63
109 bad_url_chars
= re
.compile(r
'[^a-zA-Z0-9-_~,.$\(\)@]')
111 security
.declarePublic('makeValidId')
112 def makeValidId(self
, id, allow_dup
=0):
113 id = Utf8Utils
.desacc(id)
114 id = bad_url_chars
.sub('-', id)
115 # If allow_dup is false, an error will be raised if an object
116 # with the given id already exists. If allow_dup is true,
117 # only check that the id string contains no illegal chars;
118 # check_valid_id() will be called again later with allow_dup
119 # set to false before the object is added.
122 if id in ('.', '..'):
124 if id.startswith('_'):
126 if id.startswith('aq_'):
129 while id.endswith('__') :
132 obj
= getattr(self
, id, None)
134 # An object by the given id exists either in this
135 # ObjectManager or in the acquisition path.
136 flags
= getattr(obj
, '__replaceable__', NOT_REPLACEABLE
)
137 if hasattr(aq_base(self
), id):
138 # The object is located in this ObjectManager.
139 if not flags
& REPLACEABLE
:
141 # else the object is replaceable even if the UNIQUE
148 if makeRandomId
is True :
149 id = str(randrange(2,10000)) + id
154 def _checkMemberPermission(userid
, permission
, obj
, StringType
= type('')):
155 user
= obj
.aq_inner
.acl_users
.getUser(userid
)
156 roles
= rolesForPermissionOn(permission
, obj
)
157 if type(roles
) is StringType
:
159 if user
.allowed( obj
, roles
):
163 def getCPInfo(self
) :
164 try: cp
= _cb_decode(self
.REQUEST
['__cp'])
169 def popCP(self
, indexes
=None) :
170 try: cp
= _cb_decode(self
.REQUEST
['__cp'])
174 if indexes
is not None :
175 indexes
= list(indexes
)
178 for index
in indexes
:
184 self
.REQUEST
.RESPONSE
.expireCookie('__cp', path
=self
.REQUEST
['BASEPATH1'] or "/")
187 cp
= _cb_encode( (cp
[0], paths
) )
188 resp
= self
.REQUEST
['RESPONSE']
189 resp
.setCookie('__cp', cp
, path
='%s' % cookie_path(self
.REQUEST
))
191 security
.declarePublic('Message')
192 Message
= MessageFactory('plinn')
194 security
.declarePublic('translate')
195 def translate(message
, context
):
196 """ Translate i18n message.
198 # TODO : localisation.
199 #GTS = getGlobalTranslationService()
200 if isinstance(message
, Exception):
203 except (TypeError, IndexError):
206 return GTS
.translate('plinn', message
, context
=context
)
208 security
.declarePublic('desacc')
209 desacc
= Utf8Utils
.desacc
211 security
.declarePublic('getPreferredLanguages')
212 def getPreferredLanguages(context
):
213 """ returns browser prefered languages"""
214 request
= getattr(context
, 'REQUEST', None)
215 if request
is not None :
216 adapter
= IUserPreferredLanguages(request
, None)
217 if adapter
is not None :
218 return adapter
.getPreferredLanguages()
221 security
.declarePublic('getBestTranslationLanguage')
222 def getBestTranslationLanguage(langs
, context
):
223 """ returns best translation language according
224 availables languages (param langs)
225 and user preferences (retrieves by context)
227 request
= getattr(context
, 'REQUEST', None)
229 negociator
= getUtilityByInterfaceName('zope.i18n.interfaces.INegotiator')
230 return negociator
.getLanguage(langs
, request
) or langs
[0]
234 security
.declarePublic('getAdapterByInterface')
235 def getAdapterByInterface(ob
, dotted_name
, default
=_marker
) :
236 """ Get the adapter which provides the interface on the given object.
239 iface
= resolve_dotted_name(dotted_name
)
241 if default
is _marker
:
242 raise ComponentLookupError
, dotted_name
245 adapter
= queryAdapter(ob
, iface
, default
=default
)
246 if adapter
is _marker
:
247 raise ComponentLookupError
, "no adapter providing %r found on %r" % (dotted_name
, ob
)
249 # the adapter must be wrapped to allow security mahinery to work.
250 if adapter
!= default
:
251 return adapter
.__of
__(ob
)
255 def _sudo(func
, userid
=None) :
257 execute func or any callable object
258 without restriction. Used to switch off
259 security assertions (eg. checkPermission) encountered
260 during the execution.
263 sm
= getSecurityManager()
264 restrictedUser
= sm
.getUser()
267 userid
= restrictedUser
.getId()
269 sm
._context
.user
= UnrestrictedUser(userid
, '', (), ())
274 except Exception, e
:
277 sm
._context
.user
= restrictedUser
279 if deferedEx
is not None :