1 #######################################################################################
2 # Plinn - http://plinn.org #
3 # Copyright (C) 2005-2007 Benoît PIN <benoit.pin@ensmp.fr> #
5 # This program is free software; you can redistribute it and/or #
6 # modify it under the terms of the GNU General Public License #
7 # as published by the Free Software Foundation; either version 2 #
8 # of the License, or (at your option) any later version. #
10 # This program is distributed in the hope that it will be useful, #
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
13 # GNU General Public License for more details. #
15 # You should have received a copy of the GNU General Public License #
16 # along with this program; if not, write to the Free Software #
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #
18 #######################################################################################
19 """ Plinn public utilities
20 $Id: utils.py 1534 2009-09-07 11:05:57Z pin $
21 $URL: http://svn.cri.ensmp.fr/svn/Plinn/branches/CMF-2.1/utils.py $
26 from types
import StringType
27 from random
import randrange
28 from Acquisition
import aq_base
29 from AccessControl
.PermissionRole
import rolesForPermissionOn
30 from AccessControl
import ModuleSecurityInfo
31 from AccessControl
import getSecurityManager
32 from AccessControl
.User
import UnrestrictedUser
33 from OFS
.CopySupport
import _cb_decode
, _cb_encode
, cookie_path
34 from Products
.CMFCore
.utils
import getToolByName
, getUtilityByInterfaceName
35 from Products
.CMFCore
.exceptions
import BadRequest
36 from Products
.Utf8Splitter
.Utf8Splitter
import Utf8Utils
37 from Globals
import REPLACEABLE
, NOT_REPLACEABLE
, UNIQUE
38 from Products
.PageTemplates
.GlobalTranslationService
import getGlobalTranslationService
39 from zope
.i18n
.interfaces
import IUserPreferredLanguages
40 from zope
.i18nmessageid
import MessageFactory
41 from zope
.component
.interfaces
import ComponentLookupError
42 from zope
.dottedname
.resolve
import resolve
as resolve_dotted_name
43 from zope
.component
import queryAdapter
47 security
= ModuleSecurityInfo( 'Products.Plinn.utils' )
49 security
.declarePublic('thisObjectComeFromPortalSkin')
50 def thisObjectComeFromPortalSkin(ob
, portal
=None):
51 """ check if ob comes from portal_skins """
53 portal
= getToolByName(ob
, 'portal_url')
54 portal
= portal
.getPortalObject()
56 if ob
.aq_self
== portal
.aq_self
:
63 sob
= getattr(portal
, obId
, None)
67 elif not(sob
.aq_inner
.aq_self
is ob
.aq_inner
.aq_self
) :
76 security
.declarePublic('listActionProviders_')
77 def listActionProviders_(context
) :
78 atool
= getToolByName(context
, 'portal_actions')
79 return atool
.listActionProviders()
81 def capitalizeCompoundGivenName(givenName
) :
82 givenName
= givenName
.strip()
83 givenNames
= ' '.join(givenName
.split('-')).split()
84 givenNameCapitalized
= '-'.join(map(string
.capitalize
, givenNames
))
85 return givenNameCapitalized
88 def formatFullName(memberName
, memberGivenName
, memberId
, nameBefore
=1) :
90 if memberName
and memberGivenName
:
92 memberFullName
= memberName
.capitalize() + ' ' + capitalizeCompoundGivenName(memberGivenName
)
94 memberFullName
= capitalizeCompoundGivenName(memberGivenName
) + ' ' + memberName
.capitalize()
96 elif memberName
and not memberGivenName
:
97 memberFullName
= memberName
.capitalize()
99 elif not memberName
and memberGivenName
:
100 memberFullName
= capitalizeCompoundGivenName(memberGivenName
)
103 memberFullName
= memberId
105 return memberFullName
107 # from OFS.ObjectManager #63
108 bad_url_chars
= re
.compile(r
'[^a-zA-Z0-9-_~,.$\(\)@]')
110 security
.declarePublic('makeValidId')
111 def makeValidId(self
, id, allow_dup
=0):
112 id = Utf8Utils
.desacc(id)
113 id = bad_url_chars
.sub('-', id)
114 # If allow_dup is false, an error will be raised if an object
115 # with the given id already exists. If allow_dup is true,
116 # only check that the id string contains no illegal chars;
117 # check_valid_id() will be called again later with allow_dup
118 # set to false before the object is added.
121 if id in ('.', '..'):
123 if id.startswith('_'):
125 if id.startswith('aq_'):
128 while id.endswith('__') :
131 obj
= getattr(self
, id, None)
133 # An object by the given id exists either in this
134 # ObjectManager or in the acquisition path.
135 flags
= getattr(obj
, '__replaceable__', NOT_REPLACEABLE
)
136 if hasattr(aq_base(self
), id):
137 # The object is located in this ObjectManager.
138 if not flags
& REPLACEABLE
:
140 # else the object is replaceable even if the UNIQUE
147 if makeRandomId
is True :
148 id = str(randrange(2,10000)) + id
153 def _checkMemberPermission(userid
, permission
, obj
, StringType
= type('')):
154 user
= obj
.aq_inner
.acl_users
.getUser(userid
)
155 roles
= rolesForPermissionOn(permission
, obj
)
156 if type(roles
) is StringType
:
158 if user
.allowed( obj
, roles
):
162 def getCPInfo(self
) :
163 try: cp
= _cb_decode(self
.REQUEST
['__cp'])
168 def popCP(self
, indexes
=None) :
169 try: cp
= _cb_decode(self
.REQUEST
['__cp'])
173 if indexes
is not None :
174 indexes
= list(indexes
)
177 for index
in indexes
:
183 self
.REQUEST
.RESPONSE
.expireCookie('__cp', path
=self
.REQUEST
['BASEPATH1'] or "/")
186 cp
= _cb_encode( (cp
[0], paths
) )
187 resp
= self
.REQUEST
['RESPONSE']
188 resp
.setCookie('__cp', cp
, path
='%s' % cookie_path(self
.REQUEST
))
190 security
.declarePublic('Message')
191 Message
= MessageFactory('plinn')
193 security
.declarePublic('translate')
194 def translate(message
, context
):
195 """ Translate i18n message.
197 GTS
= getGlobalTranslationService()
198 if isinstance(message
, Exception):
201 except (TypeError, IndexError):
203 return GTS
.translate('plinn', message
, context
=context
)
205 security
.declarePublic('desacc')
206 desacc
= Utf8Utils
.desacc
208 security
.declarePublic('getPreferredLanguages')
209 def getPreferredLanguages(context
):
210 """ returns browser prefered languages"""
211 request
= getattr(context
, 'REQUEST', None)
212 if request
is not None :
213 adapter
= IUserPreferredLanguages(request
, None)
214 if adapter
is not None :
215 return adapter
.getPreferredLanguages()
218 security
.declarePublic('getBestTranslationLanguage')
219 def getBestTranslationLanguage(langs
, context
):
220 """ returns best translation language according
221 availables languages (param langs)
222 and user preferences (retrieves by context)
224 request
= getattr(context
, 'REQUEST', None)
226 negociator
= getUtilityByInterfaceName('zope.i18n.interfaces.INegotiator')
227 return negociator
.getLanguage(langs
, request
) or langs
[0]
231 security
.declarePublic('getAdapterByInterface')
232 def getAdapterByInterface(ob
, dotted_name
, default
=_marker
) :
233 """ Get the adapter which provides the interface on the given object.
236 iface
= resolve_dotted_name(dotted_name
)
238 if default
is _marker
:
239 raise ComponentLookupError
, dotted_name
242 adapter
= queryAdapter(ob
, iface
, default
=default
)
243 if adapter
is _marker
:
244 raise ComponentLookupError
, "no adapter providing %r found on %r" % (dotted_name
, ob
)
246 # the adapter must be wrapped to allow security mahinery to work.
247 if adapter
!= default
:
248 return adapter
.__of
__(ob
)
252 def _sudo(func
, userid
=None) :
254 execute func or any callable object
255 without restriction. Used to switch off
256 security assertions (eg. checkPermission) encountered
257 during the execution.
260 sm
= getSecurityManager()
261 restrictedUser
= sm
.getUser()
264 userid
= restrictedUser
.getId()
266 sm
._context
.user
= UnrestrictedUser(userid
, '', (), ())
271 except Exception, e
:
274 sm
._context
.user
= restrictedUser
276 if deferedEx
is not None :