def sendInvitationMail(site, member, vars): request = aq_get(site, 'REQUEST') fullname = member.getProperty('fullname') or member.getId() hostname = request.other['SERVER_URL'] invite_to_address = vars['invite_to_address'] invitecode = vars['invitecode'] message = vars['message'] tool = getToolByName(site, 'portal_invitations') expires = DateTime() + tool.getProperty('days', 7) accept_url = '%s/accept/%s?email=%s' % ( site.absolute_url(), quote(invitecode), quote(invite_to_address)) mail_text = InvitationMail(site, request)(member=member, email=invite_to_address, sender_fullname=fullname, hostname=hostname, message=message, expires=expires, accept_url=accept_url) if isinstance(mail_text, unicode): mail_text = mail_text.encode('utf-8') message_obj = message_from_string(mail_text.strip()) subject = message_obj['Subject'] m_to = message_obj['To'] m_from = message_obj['From'] host = getToolByName(site, 'MailHost') host.send(mail_text, m_to, m_from, subject=subject, charset='utf-8', immediate=True)
def assignTitles(self, portal, out): titles={'portal_actions':'Contains custom tabs and buttons', 'portal_membership':'Handles membership policies', 'portal_memberdata':'Handles the available properties on members', 'portal_undo':'Defines actions and functionality related to undo', 'portal_types':'Controls the available content types in your portal', 'plone_utils':'Various utility methods', 'portal_metadata':'Controls metadata like keywords, copyrights, etc', 'portal_migration':'Upgrades to newer Plone versions', 'portal_registration':'Handles registration of new users', 'portal_skins':'Controls skin behaviour (search order etc)', 'portal_syndication':'Generates RSS for folders', 'portal_workflow':'Contains workflow definitions for your portal', 'portal_url':'Methods to anchor you to the root of your Plone site', 'portal_discussion':'Controls how discussions are stored', 'portal_catalog':'Indexes all content in the site', 'portal_factory':'Responsible for the creation of content objects', 'portal_calendar':'Controls how events are shown', 'portal_quickinstaller':'Allows to install/uninstall products', 'portal_interface':'Allows to query object interfaces', 'portal_actionicons':'Associates actions with icons', 'portal_groupdata':'Handles properties on groups', 'portal_groups':'Handles group related functionality', 'translation_service': 'Provides access to the translation machinery', 'mimetypes_registry': 'MIME types recognized by Plone', 'portal_transforms': 'Handles data conversion between MIME types', } for oid in portal.objectIds(): title=titles.get(oid, None) if title: setattr(aq_get(portal, oid), 'title', title) out.append('Assigned titles to portal tools.')
def __call__(self, context): site = getSite() wtool = getToolByName(site, "portal_workflow", None) if wtool is None: return SimpleVocabulary([]) transitions = {} for wf in wtool.values(): transition_folder = getattr(wf, "transitions", None) wf_name = wf.title or wf.id if transition_folder is not None: for transition in transition_folder.values(): # zope.i18nmessageid will choke # if undecoded UTF-8 bytestrings slip through # which we may encounter on international sites # where transition names are in local language. # This may break overlying functionality even # if the terms themselves are never used name = safe_unicode(transition.actbox_name) transition_title = translate(_(name), context=aq_get(wtool, "REQUEST", None)) transitions.setdefault(transition.id, []).append(dict(title=transition_title, wf_name=wf_name)) items = [] transition_items = transitions.items() transition_items.sort(key=lambda transition: transition[0]) for transition_id, info in transition_items: titles = set([i["title"] for i in info]) item_title = " // ".join(sorted(titles)) item_title = "%s [%s]" % (item_title, transition_id) items.append(SimpleTerm(transition_id, transition_id, item_title)) return SimpleVocabulary(items)
def ignore_link_integrity_exceptions(site): error_log = aq_get(site, 'error_log') props = error_log.getProperties() exceptions = props['ignored_exceptions'] exceptions = exceptions + ('LinkIntegrityNotificationException', ) error_log.setProperties(props['keep_entries'], ignored_exceptions=tuple(sorted(set(exceptions))))
def setPassword(self, password, domains=None, REQUEST=None): '''Allows the authenticated member to set his/her own password. ''' registration = getToolByName(self, 'portal_registration', None) if not self.isAnonymousUser(): member = self.getAuthenticatedMember() acl_users = self._findUsersAclHome(member.getUserId())#self.acl_users if not acl_users: # should not possibly ever happen raise BadRequest, 'did not find current user in any user folder' if registration: failMessage = registration.testPasswordValidity(password) if failMessage is not None: raise BadRequest, failMessage if domains is None: domains = [] user = acl_users.getUserById(member.getUserId(), None) # we must change the users password trough grufs changepassword # to keep her group settings if hasattr(user, 'changePassword'): user.changePassword(password) else: acl_users._doChangeUser(member.getUserId(), password, member.getRoles(), domains) if REQUEST is None: REQUEST = aq_get(self, 'REQUEST', None) self.credentialsChanged(password, REQUEST=REQUEST) else: raise BadRequest, 'Not logged in.'
def getObject(self, REQUEST=None): """Return the object for this record Will return None if the object cannot be found via its cataloged path (i.e., it was deleted or moved without recataloging), or if the user is not authorized to access the object. This method mimicks a subset of what publisher's traversal does, so it allows access if the final object can be accessed even if intermediate objects cannot. """ path = self.getPath().split('/') if not path: return None parent = aq_parent(self) if (aq_get(parent, 'REQUEST', None) is None and _GLOBALREQUEST_INSTALLED and _REQUESTCONTAINER_EXISTS): request = getRequest() if request is not None: # path should be absolute, starting at the physical root parent = self.getPhysicalRoot() request_container = RequestContainer(REQUEST=request) parent = aq_base(parent).__of__(request_container) if len(path) > 1: parent = parent.unrestrictedTraverse(path[:-1]) return parent.restrictedTraverse(path[-1])
def referenceRemoved(obj, event, toInterface=IContactContent): """Store information about the removed link integrity reference. """ # inspired from z3c/relationfield/event.py:breakRelations # and plone/app/linkintegrity/handlers.py:referenceRemoved # if the object the event was fired on doesn't have a `REQUEST` attribute # we can safely assume no direct user action was involved and therefore # never raise a link integrity exception... request = aq_get(obj, 'REQUEST', None) if not request: return storage = ILinkIntegrityInfo(request) catalog = component.queryUtility(ICatalog) intids = component.queryUtility(IIntIds) if catalog is None or intids is None: return # find all relations that point to us obj_id = intids.queryId(obj) if obj_id is None: return rels = list(catalog.findRelations({'to_id': obj_id})) for rel in rels: if toInterface.providedBy(rel.to_object): storage.addBreach(rel.from_object, rel.to_object)
def getExprContext(context, object=None): request = getRequest() if request: cache = request.get('_ec_cache', None) if cache is None: request['_ec_cache'] = cache = {} ec = cache.get(id(object), None) else: ec = None if ec is None: try: utool = getUtility(IURLTool) except ComponentLookupError: # BBB: fallback for CMF 2.2 instances utool = aq_get(context, 'portal_url') portal = utool.getPortalObject() if object is None or not hasattr(object, 'aq_base'): folder = portal else: folder = object # Search up the containment hierarchy until we find an # object that claims it's a folder. while folder is not None: if getattr(aq_base(folder), 'isPrincipiaFolderish', 0): # found it. break else: folder = aq_parent(aq_inner(folder)) ec = createExprContext(folder, portal, object) if request: cache[id(object)] = ec return ec
def createExprContext(folder, portal, object): """ An expression context provides names for TALES expressions. """ try: mtool = getUtility(IMembershipTool) except ComponentLookupError: # BBB: fallback for CMF 2.2 instances mtool = aq_get(portal, 'portal_membership') if object is None: object_url = '' else: object_url = object.absolute_url() if mtool.isAnonymousUser(): member = None else: member = mtool.getAuthenticatedMember() data = { 'object_url': object_url, 'folder_url': folder.absolute_url(), 'portal_url': portal.absolute_url(), 'object': object, 'folder': folder, 'portal': portal, 'nothing': None, 'request': getattr(portal, 'REQUEST', None), 'modules': SecureModuleImporter, 'member': member, 'here': object, } return getEngine().getContext(data)
def __call__(self, context): site = getSite() wtool = getToolByName(site, 'portal_workflow', None) if wtool is None: return SimpleVocabulary([]) # XXX This is evil. A vocabulary shouldn't be request specific. # The sorting should go into a separate widget. # we get REQUEST from wtool because context may be an adapter request = aq_get(wtool, 'REQUEST', None) items = wtool.listWFStatesByTitle(filter_similar=True) items = [(safe_unicode(i[0]), i[1]) for i in items] items_dict = dict( # no dict comprehension in py 2.6 [ (i[1], translate(_(i[0]), context=request)) for i in items ] ) items_list = [(k, v) for k, v in items_dict.items()] items_list.sort(lambda x, y: cmp(x[1], y[1])) terms = [ SimpleTerm(k, title=u'%s [%s]' % (v, k)) for k, v in items_list ] return SimpleVocabulary(terms)
def pt_getContext(self, instance, request=None, **kw): namespace = super(ViewAwareZopePageTemplate, self).pt_getContext(**kw) namespace["request"] = request namespace["view"] = instance namespace["context"] = context = instance.context namespace["views"] = ViewMapper(context, request) # get the root obj = context root = None meth = aq_get(obj, "getPhysicalRoot", None) if meth is not None: root = meth() namespace.update( here=obj, # philiKON thinks container should be the view, # but BBB is more important than aesthetics. container=obj, root=root, modules=SecureModuleImporter, traverse_subpath=[], # BBB, never really worked user=getSecurityManager().getUser(), ) return namespace
def getRolesForPrincipal(self, principal, request=None): """ See IRolesPlugin. """ roles = set([]) principal_ids = set([]) # Some services need to determine the roles obtained from groups # while excluding the directly assigned roles. In this case # '__ignore_direct_roles__' = True should be pushed in the request. request = aq_get(self, 'REQUEST', None) if request is None \ or not request.get('__ignore_direct_roles__', False): principal_ids.add(principal.getId()) # Some services may need the real roles of an user but **not** # the ones he got through his groups. In this case, the # '__ignore_group_roles__'= True should be previously pushed # in the request. plugins = self._getPAS()['plugins'] if request is None \ or not request.get('__ignore_group_roles__', False): principal_ids.update( getGroupsForPrincipal(principal, plugins, request) ) for pid in principal_ids: roles.update(self._principal_roles.get(pid, ())) return tuple(roles)
def getToolByName(obj, name, default=_marker): """ Get the tool, 'toolname', by acquiring it. o Application code should use this method, rather than simply acquiring the tool by name, to ease forward migration (e.g., to Zope3). """ tool_interface = _tool_interface_registry.get(name) if tool_interface is not None: warn('getToolByName is deprecated and will be removed in ' 'CMF 2.3, please use "getUtility(%s)"' % ( tool_interface.__name__), DeprecationWarning, stacklevel=2) try: return getUtility(tool_interface) except ComponentLookupError: # behave in backwards-compatible way # fall through to old implementation pass try: tool = aq_get(obj, name, default, 1) except AttributeError: if default is _marker: raise return default else: if tool is _marker: raise AttributeError, name return tool
def formatException(context, editing): """Returns an HTML-ified error message. If not editing, the message includes no details. """ exc_info = sys.exc_info() try: if editing: # Show editors the real error t, v = exc_info[:2] t = getattr(t, '__name__', t) msg = "An error occurred. %s" % ( escape(('%s: %s' % (t, v))[:80])) else: # Show viewers a simplified error. msg = ("An error occurred while generating " "this part of the page.") try: log = aq_get(context, '__error_log__', None, 1) except AttributeError: LOG("Composite", ERROR, "Error in a page element", error=exc_info) return msg else: error_log_url = log.raising(exc_info) return error_tag % (msg, error_log_url) finally: del exc_info
def findObject(base, path): """ traverse to given path and find the upmost object """ if path.startswith('/'): obj = getToolByName(base, 'portal_url').getPortalObject() portal_path = '/'.join(obj.getPhysicalPath()) components = path.lstrip(portal_path + '/').split('/') else: obj = aq_parent(base) # relative urls start at the parent... components = path.split('/') while components: child_id = unquote(components[0]) try: try: child = obj.unrestrictedTraverse(child_id) except AttributeError: request = aq_get(obj, 'REQUEST') child = request.traverseName(obj, child_id) except ConflictError: raise except (AttributeError, KeyError, NotFound, ztkNotFound): return None, None if not IItem.providedBy(child): break obj = child components.pop(0) return obj, '/'.join(components)
def _edit( self, remote_url ): """ Edit the Favorite. Unlike Links, Favorites have URLs that are relative to the root of the site. """ # strip off scheme and machine from URL if present tokens = urlparse.urlparse( remote_url, 'http' ) if tokens[1]: # There is a nethost, remove it t=('', '') + tokens[2:] remote_url=urlparse.urlunparse(t) # if URL begins with site URL, remove site URL utool = queryUtility(IURLTool) if utool is None: # fallback for bootstrap utool = aq_get(self, 'portal_url', None) portal_url = utool.getPortalPath() i = remote_url.find(portal_url) if i==0: remote_url=remote_url[len(portal_url):] # if site is still absolute, make it relative if remote_url[:1]=='/': remote_url=remote_url[1:] self.remote_url=remote_url # save unique id of favorite self.remote_uid = self._getUidByUrl()
def getObject(self, REQUEST=None): path = self.getPath().split('/') if not path: return None parent = aq_parent(self) if (aq_get(parent, 'REQUEST', None) is None and _GLOBALREQUEST_INSTALLED and _REQUESTCONTAINER_EXISTS): request = getRequest() if request is not None: # path should be absolute, starting at the physical root parent = self.getPhysicalRoot() request_container = RequestContainer(REQUEST=request) parent = aq_base(parent).__of__(request_container) if len(path) > 1: try: parent = parent.unrestrictedTraverse(path[:-1]) except: if path[:-2] == 'data-'+self.portal_type: parent = queryMultiAdapter((None, ICollectiveBehaviorSQLLayer), IBrowserView, name='data-'+name, default=None) try: return parent.restrictedTraverse(path[-1]) except: connection = queryUtility(ISQLConnectionsUtility, name=self.portal_type, default=None) if connection == None and self.portal_type: fti = queryUtility(IDexterityFTI, name=self.portal_type, default=None) if not fti: return None updateConnectionsForFti(fti) connection = queryUtility(ISQLConnectionsUtility, name=self.portal_type, default=None) return connection.getVirtualItem(self.sql_id, context=parent)
def __call__(self, context): request = aq_get(context, "REQUEST", None) terms = [ SimpleTerm(value, token, translate(title, domain="plone", context=request, default=default)) for value, token, title, default in self.terms ] return SimpleVocabulary(terms)
def __call__(self, id, instance, *args, **kwargs): try: # try to use the check_id script of CMFPlone check_id = aq_get(instance, 'check_id', None, 1) if check_id is None: raise AttributeError('check_id script not found') return check_id(id, required=kwargs.get('required', 0)) or 1 except AttributeError: # space test if ' ' in id: msg = _(u'Spaces are not allowed in ids') return recursiveTranslate(msg, **kwargs) # in parent test parent = aq_parent(aq_inner(instance)) # If the id is given to a different object already if id in parent.objectIds() and getattr(aq_base(parent), id) is not aq_base(instance): msg = _(u'Id $id is already in use', mapping = {'id': safe_unicode(id)}) return recursiveTranslate(msg, **kwargs) # objet manager test # XXX: This is f***ed try: ObjectManager.checkValidId(self, id, allow_dup=1) except BadRequest, m: return str(m) return 1
def getOwner(self, info=0, aq_get=aq_get, UnownableOwner=UnownableOwner, getSecurityManager=getSecurityManager, ): """Get the owner If a true argument is provided, then only the owner path and id are returned. Otherwise, the owner object is returned. """ if info: import warnings warnings.warn('Owned.getOwner(1) is deprecated; ' 'please use getOwnerTuple() instead.', DeprecationWarning, stacklevel=2) owner=aq_get(self, '_owner', None, 1) if info or (owner is None): return owner if owner is UnownableOwner: return None udb, oid = owner root=self.getPhysicalRoot() udb=root.unrestrictedTraverse(udb, None) if udb is None: user = SpecialUsers.nobody else: user = udb.getUserById(oid, None) if user is None: user = SpecialUsers.nobody return user
def __call__(self, context): site = getSite() wtool = getToolByName(site, 'portal_workflow', None) if wtool is None: return SimpleVocabulary([]) transitions = {} for wf in wtool.values(): transition_folder = getattr(wf, 'transitions', None) wf_name = wf.title or wf.id if transition_folder is not None: for transition in transition_folder.values(): transition_title = translate( _(transition.actbox_name), context=aq_get(wtool, 'REQUEST', None)) transitions.setdefault(transition.id, []).append( dict(title=transition_title, wf_name=wf_name)) items = [] transition_items = transitions.items() transition_items.sort(key=lambda transition: transition[0]) for transition_id, info in transition_items: titles = set([i['title'] for i in info]) item_title = ' // '.join(sorted(titles)) item_title = "%s [%s]" % (item_title, transition_id) items.append(SimpleTerm(transition_id, transition_id, item_title)) return SimpleVocabulary(items)
def getOwnerTuple(self): """Return a tuple, (userdb_path, user_id) for the owner. o Ownership can be acquired, but only from the containment path. o If unowned, return None. """ return aq_get(self, '_owner', None, 1)
def pt_getContext(self, *args, **kw): root = None meth = aq_get(self, 'getPhysicalRoot', None) if meth is not None: root = meth() context = self._getContext() c = {'template': self, 'here': context, 'context': context, 'container': self._getContainer(), 'nothing': None, 'options': {}, 'root': root, 'request': aq_get(root, 'REQUEST', None), 'modules': SecureModuleImporter, } return c
def getUI(self, ui=None): """Returns a UI object. """ if not ui: ui = self.default_ui tool = aq_get(self, "composite_tool", None, 1) if tool is None: raise CompositeError("No composite_tool found") return guarded_getattr(tool.uis, ui)
def test_mail_setup(self): portal = self.layer['portal'] name = portal.getProperty('email_from_name') self.assertNotEquals(name, '') address = portal.getProperty('email_from_address') self.assertNotEquals(address, '') mailhost = aq_get(portal, 'MailHost') self.assertNotEquals(mailhost.smtp_host, '') self.assertNotEquals(mailhost.smtp_port, '')
def getEmptyTitle(context, translated=True): """Returns string to be used for objects with no title or id""" # The default is an extra fancy unicode elipsis empty = unicode("\x5b\xc2\xb7\xc2\xb7\xc2\xb7\x5d", "utf-8") if translated: if context is not None: if not IBrowserRequest.providedBy(context): context = aq_get(context, "REQUEST", None) empty = translate("title_unset", domain="plone", context=context, default=empty) return empty
def translate(self, msgid, domain=None, mapping=None, context=None, target_language=None, default=None): # Translate method for resticted code like skins. if context is not None: if not IBrowserRequest.providedBy(context): context = aq_get(context, 'REQUEST', None) return translate(msgid, domain=domain, mapping=mapping, context=context, target_language=target_language, default=default)
def getGroups(self): gf = aq_get(self.context, "__allow_groups__", None, 1) if gf is None: return () try: groups = gf.searchGroups() except AttributeError: return () else: return groups
def manage_changeOwnershipType(self, explicit=1, RESPONSE=None, REQUEST=None): """Change the type (implicit or explicit) of ownership. """ old=getattr(self, '_owner', None) if explicit: if old is not None: return owner=aq_get(self, '_owner', None, 1) if owner is not None and owner is not UnownableOwner: self._owner=owner else: if old is None: return new=aq_get(aq_parent(self), '_owner', None, 1) if old is new and ( self.__dict__.get('_owner', _mark) is not _mark ): del self._owner if RESPONSE is not None: RESPONSE.redirect(REQUEST['HTTP_REFERER'])
def translate(self, domain, msgid, context=None, **kw): translate = self.getTranslateMethod(context, domain) # For zope.i18n, the 'context' of a translation request is actually the # an IBrowserRequest, for languate negotiation (see, for instance, # Products.CMFPlone.TranslationServiceTool). The new localizer # MessageCatalog abides by the zope.i18n.interface definitions. # (Actually, it ignores the context). request = aq_get(context, 'REQUEST', None) return translate(msgid=msgid, context=request, **kw)