def acquired_rules(self): # Short circuit if this is the root of the portal if ISiteRoot.providedBy(self.context): return [] in_use = set([r['id'] for r in self.assigned_rules()]) storage = getUtility(IRuleStorage) events = self._events() assignments = [] context = aq_parent(aq_inner(self.context)) while context is not None: assignable = IRuleAssignmentManager(context, None) if assignable is not None: for key, assignment in assignable.items(): if key not in in_use and assignment.bubbles: rule = storage.get(key, None) if rule is not None: assignments.append(dict(id=key, title=rule.title, description=rule.description, trigger=events.get(rule.event, "Unknown"), url=context.absolute_url() + '/@@manage-content-rules', enabled=(assignment.enabled and rule.enabled), )) if ISiteRoot.providedBy(context): context = None else: context = aq_parent(context) return assignments
def _items(self, **query): adapter = IAdapter(self.context) sort_limit = adapter.get_feed_number(self.interface) if sort_limit: query['sort_limit'] = sort_limit if isinstance(self, BaseNewsEventFeedViewlet): query['sort_limit'] += adapter.get_feed_number(ITopPageMainFeed) base = IBaseAdapter(self.context) res = [] for item in base.get_content_listing(**query): obj = item.getObject() if not isinstance(self, BaseNewsEventFeedViewlet) or ( ISiteRoot.providedBy(self.context) and not ITopPageFeed.providedBy(obj)) or ( not ISiteRoot.providedBy(self.context) and INavigationRoot.providedBy(self.context) and not IMicroSiteFeed.providedBy(obj)): parent = aq_parent(aq_inner(obj)) res.append({ 'title': item.Title(), 'url': item.getURL(), 'parent_title': parent.Title(), 'parent_url': parent.absolute_url(), 'date': self._date(item), 'image': self._image(item), 'description': self._description(item), }) if sort_limit: return res[:sort_limit] return res
def execute(context, event): """Execute all rules relative to the context, and bubble as appropriate. """ # Do nothing if there is no rule storage or it is not active storage = queryUtility(IRuleStorage) if storage is None or not storage.active: return init() rule_filter = _status.rule_filter # Stop if someone else is already executing. This could happen if, # for example, a rule triggered here caused another event to be fired. # We continue if we are in the context of a 'cascading' rule. if rule_filter.in_progress and not rule_filter.cascade: return # Tell other event handlers to be equally kind rule_filter.in_progress = True # Prepare to break hard if a rule demanded execution be stopped try: # Try to execute rules in the context. It may not work if the context # is not a rule executor, but we may still want to bubble events executor = IRuleExecutor(context, None) if executor is not None: executor(event, bubbled=False, rule_filter=rule_filter) # Do not bubble beyond the site root if not ISiteRoot.providedBy(context): parent = aq_parent(aq_inner(context)) while parent is not None: executor = IRuleExecutor(parent, None) if executor is not None: executor(event, bubbled=True, rule_filter=rule_filter) if ISiteRoot.providedBy(parent): parent = None else: parent = aq_parent(aq_inner(parent)) except StopRule: pass # We are done - other events that occur after this one will be allowed to # execute rules again rule_filter.in_progress = False
def isSiteRoot(self, ob): """ Returns a boolean value indicating if the object is an ISiteRoot or the default page of an ISiteRoot. """ siteroot = ISiteRoot.providedBy(ob) if siteroot: return True parent = aq_parent(ob) if ISiteRoot.providedBy(parent): if getattr(ob, "isPrincipiaFolderish", False) and ob.isPrincipiaFolderish: # We are looking at a folder in the root return False # We are at a non-folderish item in the root return True return False
def _get_translations_by_dialog(self, supported_langs): """ """ context = aq_inner(self.context) default_view_for = getMultiAdapter((context, self.request), name='plone_context_state').canonical_object() _checkPermission = getSecurityManager().checkPermission translations = {} if ISiteRoot.providedBy(context): # We have a site root, which works as a fallback for code in supported_langs: has_view_permission = bool(_checkPermission('View', context)) translations[code] = (context, True, has_view_permission) elif INavigationRoot.providedBy(default_view_for): for code, content in ITranslationManager(default_view_for).get_translations().items(): code = str(code) has_view_permission = bool(_checkPermission('View', content)) translations[code] = (content, True, has_view_permission) else: for code, content in ITranslationManager(context).get_translations().items(): code = str(code) has_view_permission = bool(_checkPermission('View', content)) translations[code] = (content, True, has_view_permission) return translations
def _acquire_value(self, context): if isinstance(context, MetadataBase) or context is None: # we do not test the factory, it is not acquisition wrapped and # we cant get the request... return None request = context.REQUEST if IDuringContentCreation.providedBy(request): # object does not yet exist, context is container (add) container = context elif ISiteRoot.providedBy(context): # The context is the siteroot when using the /@types endpoint # from the plone rest-api. # See https://github.com/4teamwork/opengever.core/issues/5283 container = context else: # object already exists, container is parent of context (edit) container = context.aq_inner.aq_parent acquired_value = acquire_field_value(self.field, container) # Use acquired value if one was found if acquired_value is not NO_VALUE_FOUND: return acquired_value # Otherwise fall back to static field default # # NOTE: We deliberately avoid accessing field.default, because doing # so would invoke a defaultFactory if present return self.field.__dict__.get('default', None)
def getInitialTree(self): '''Returns the initial tree for the dynatree.''' context = self.getFolderishParent(self.context) child_tree = None child_uid = None while True: is_root = ISiteRoot.providedBy(context) if is_root: uid = None else: uid = IUUID(context) tree = self.get_tree(uid) if child_tree is not None: self._insert_child_tree(tree, child_tree, child_uid) if is_root: break context = aq_parent(context) child_tree = tree child_uid = uid root_node = self.getRootNode() root_node['children'] = tree return simplejson.dumps(root_node)
def heading_link_target(self): """ Get the href target where clicking the portlet header will take you. If this is a customized portlet with a custom root item set, we probably want to take the user to the custom root item instead of the sitemap of the navigation root. Plone does not have subsection sitemaps so there is no point of displaying /sitemap links for anything besides nav root. """ if not self.data.root: # No particular root item assigned -> should get link to the # navigation root sitemap of the current context acquisition chain portal_state = getMultiAdapter((self.context, self.request), name="plone_portal_state") return portal_state.navigation_root_url() + "/sitemap" nav_root = self.getNavRoot() # Root content item gone away or similar issue if not nav_root: return None if INavigationRoot.providedBy(nav_root) or ISiteRoot.providedBy(nav_root): # For top level folders go to the sitemap return nav_root.absolute_url() + "/sitemap" else: # Go to the item /view we have chosen as root item return nav_root.absolute_url()
def containing_subdossier(obj): """Returns the title of the subdossier the object is contained in, unless it's contained directly in the root of a dossier, in which case an empty string is returned. """ if obj.portal_type not in TYPES_WITH_CONTAINING_SUBDOSSIER_INDEX: return '' context = aq_inner(obj) parent = context parent_dossier = None parent_dossier_found = False while not parent_dossier_found: parent = aq_parent(parent) if ISiteRoot.providedBy(parent): # Shouldn't happen, just to be safe break if IDossierMarker.providedBy(parent): parent_dossier_found = True parent_dossier = parent if IDossierMarker.providedBy(aq_parent(parent_dossier)): # parent dossier is a subdossier return parent_dossier.Title() return ''
def getPortal(self): ob = aq_inner(self.object) while ob is not None: if ISiteRoot.providedBy(ob): return ob ob = aq_parent(ob) return None
def create( container=None, type=None, id=None, title=None, safe_id=False, **kwargs ): """Create a new content item. :param container: [required] Container object in which to create the new object. :type container: Folderish content object :param type: [required] Type of the object. :type type: string :param id: Id of the object. If the id conflicts with another object in the container, a suffix will be added to the new object's id. If no id is provided, automatically generate one from the title. If there is no id or title provided, raise a ValueError. :type id: string :param title: Title of the object. If no title is provided, use id as the title. :type title: string :param safe_id: When False, the given id will be enforced. If the id is conflicting with another object in the target container, raise an InvalidParameterError. When True, choose a new, non-conflicting id. :type safe_id: boolean :returns: Content object :raises: KeyError, :class:`~plone.api.exc.MissingParameterError`, :class:`~plone.api.exc.InvalidParameterError` :Example: :ref:`content_create_example` """ # Create a temporary id if the id is not given content_id = not safe_id and id or str(random.randint(0, 99999999)) if title: kwargs['title'] = title try: container.invokeFactory(type, content_id, **kwargs) except ValueError, e: if ISiteRoot.providedBy(container): allowed_types = container.allowedContentTypes() types = [allowed_type.id for allowed_type in allowed_types] else: try: types = container.getLocallyAllowedTypes() except AttributeError: raise InvalidParameterError( "Cannot add a '%s' object to the container." % type ) raise InvalidParameterError( "Cannot add a '{0}' object to the container.\n" "Allowed types are:\n" "{1}\n" "{2}".format(type, '\n'.join(sorted(types)), e.message) )
def organise(self): """Helper method to generate the menu items for organising content (copy/paste/etc.). If no organising actions are available None is returned. """ context = aq_inner(self.context) context_url = context.absolute_url() is_root = ISiteRoot.providedBy(context) pa = getToolByName(context, "portal_actions") actions = pa.listActions(object=context, categories=("folder_buttons",), ignore_categories=None) ec = pa._getExprContext(context) actions = [ActionInfo(action, ec) for action in actions] menu = {"title": _("menu_organise", default=u"Organise")} children = menu["children"] = [] for a in actions: if a["visible"] and a["allowed"] and a["available"] and not is_root: if a["id"] == "copy" and context.cb_isCopyable(): children.append({"title": _("menu_copy", default=u"Copy"), "url": "%s/@@copy" % context_url}) elif a["id"] == "cut" and context.cb_isMoveable(): children.append({"title": _("menu_cut", default=u"Cut"), "url": "%s/@@cut" % context_url}) elif a["id"] == "paste" and ICopyContainer.providedBy(context): children.append({"title": _("menu_paste", default=u"Paste"), "url": "%s/@@paste" % context_url}) elif a["id"] == "delete": children.append({"title": _("menu_delete", default=u"Delete"), "url": "%s/@@delete" % context_url}) if children: return menu
def default_value_generator(data): obj = data.context # try to get it from context or a parent while not ISiteRoot.providedBy(obj): try: interface_ = data.field.interface except AttributeError: pass else: try: adpt = interface_(obj) except TypeError: # could not adapt pass else: value = data.field.get(adpt) if value is not None: return value obj = aq_parent(aq_inner(obj)) # otherwise use default value if field._acquisition_default: return field._acquisition_default else: # use first value try: return tuple(data.widget.terms)[0].value except AttributeError: return None
def _get_acquisiton_value(self): context = self.context if isinstance(context, MetadataBase) or context is None: # we do not test the factory, it is not acquisition wrapped and # we cant get the request... return None request = self.context.REQUEST # XXX CHANGED FROM PATH_TRANSLATED TO PATH_INFO # because the test don't work if '++add++' in request.get('PATH_INFO', ''): # object is not yet existing, context is container obj = context else: # object is existing, container is parent of context obj = context.aq_inner.aq_parent while not ISiteRoot.providedBy(obj): try: return self.field.get(obj) except AttributeError: try: interface_ = self.field.interface except AttributeError: pass else: try: adpt = interface_(obj) except TypeError: # could not adapt pass else: return self.field.get(adpt) obj = obj.aq_inner.aq_parent return self.field.default
def can_translate(context, language): """ Check if required parent translations are in place so that we can translate this item :return: True if the item can be translated """ parent = aq_parent(context) if ISiteRoot.providedBy(parent): return True # Parent is a language base folder at plone site root if INavigationRoot.providedBy(parent): return True if ITranslatable.providedBy(parent): translatable = ITranslatable(parent) else: from logging import getLogger log = getLogger("silvuple.views.can_translate") log.info("Parent is not translatable: %s" % parent.absolute_url()) return False translation = translatable.getTranslation(language) return translation is not None
def containing_subdossier(obj): """Returns the title of the subdossier the object is contained in, unless it's contained directly in the root of a dossier, in which case an empty string is returned. """ context = aq_inner(obj) # Only compute for types that actually can be contained in a dossier if not context.portal_type in ['opengever.document.document', 'opengever.task.task', 'ftw.mail.mail']: return '' parent = context parent_dossier = None parent_dossier_found = False while not parent_dossier_found: parent = aq_parent(parent) if ISiteRoot.providedBy(parent): # Shouldn't happen, just to be safe break if IDossierMarker.providedBy(parent): parent_dossier_found = True parent_dossier = parent if IDossierMarker.providedBy(aq_parent(parent_dossier)): # parent dossier is a subdossier return parent_dossier.Title() return ''
def get_plone_root(ctx): obj = aq_inner(ctx) while obj is not None: if ISiteRoot.providedBy(obj): break obj = aq_parent(obj) return obj
def __call__(self): cfg = authomatic_cfg() if cfg is None: return "Authomatic is not configured" if not ( ISiteRoot.providedBy(self.context) or INavigationRoot.providedBy(self.context) ): # callback url is expected on either navigationroot or site root # so bevor going on redirect root = api.portal.get_navigation_root(self.context) self.request.response.redirect( "{0}/authomatic-handler/{1}".format( root.absolute_url(), getattr(self, 'provider', '') ) ) return "redirecting" if not hasattr(self, 'provider'): return self.template() if self.provider not in cfg: return "Provider not supported" if not self.is_anon: if self.provider in self._provider_names: raise ValueError( 'Provider {0} is already connected to current ' 'user.'.format(self.provider) ) # TODO: some sort of CSRF check might be needed, so that # not an account got connected by CSRF. Research needed. pass auth = Authomatic( cfg, secret=authomatic_settings().secret.encode('utf8') ) result = auth.login( ZopeRequestAdapter(self), self.provider ) if not result: logger.info('return from view') # let authomatic do its work return if result.error: return result.error.message display = cfg[self.provider].get('display', {}) provider_name = display.get('title', self.provider) if not self.is_anon: # now we delegate to PAS plugin to add the identity self._add_identity(result, provider_name) self.request.response.redirect( "{0}".format(self.context.absolute_url()) ) else: # now we delegate to PAS plugin in order to login self._remember_identity(result, provider_name) self.request.response.redirect( "{0}/login_success".format(self.context.absolute_url()) ) return "redirecting"
def details(self, context=None): # fetch details about dataset, if attributes are unpopulated # get data from associated collection if context is None: context = self.context coll = context while not (ISiteRoot.providedBy(coll) or ICollection.providedBy(coll)): coll = coll.__parent__ # we have either hit siteroot or found a collection ret = { 'title': context.title, 'description': context.description or coll.description, 'attribution': context.attribution or getattr(coll, 'attribution'), 'rights': context.rights or coll.rights, 'external_description': context.external_description or getattr(coll, 'external_description'), } md = IBCCVLMetadata(context) if 'layers' in md: layers = [] for layer in sorted(md.get('layers', ())): try: layers.append(self.layer_vocab.getTerm(layer)) except: layers.append(SimpleTerm(layer, layer, layer)) if layers: ret['layers'] = layers return ret
def disallow_anonymous_views_on_site_root(event): """Do not allow access for anonymous to views on the portal root except those explicitly allowed here. We do it this way because we cannot revoke the view permissions for anonymous on the portal root. The same applies for tabbed_view attributes of a tabbed_view that is displayed for the portal root. """ if getSecurityManager().getUser() != nobody: return # Find the first physical / persistent object in the PARENTS # by filtering all non-persist parents (views, widgets, ...). context = filter(IItem.providedBy, event.request['PARENTS'])[0] if not ISiteRoot.providedBy(context): return endpoint_name = event.request['PUBLISHED'].__name__ if endpoint_name in ALLOWED_ENDPOINTS: return views = filter(IBrowserView.providedBy, event.request['PARENTS']) if len(views) > 0 and views[0].__name__ in ALLOWED_ENDPOINTS: return raise Unauthorized
def update(self): super(View, self).update() messages = IStatusMessage(self.request) context = aq_inner(self.context) self.context = context self.state = getMultiAdapter( (context, self.request), name=u'plone_context_state') self.wf_state = self.state.workflow_state() self.utility = context.utility # Handle vote form = self.request.form self.errors = [] self.messages = [] #if the poll is open and anonymous should vote but the parent folder #is private.. inform the user. # When the poll's container is the site's root, we do not need to # check the permissions. container = aq_parent(aq_inner(self.context)) if 'open' == self.wf_state and not ISiteRoot.providedBy(container): roles = [ r['name'] for r in self.context.rolesOfPermission('collective.polls: Vote') if r['selected']] if 'Anonymous' not in roles and self.context.allow_anonymous: messages.addStatusMessage(_( u"Anonymous user won't be able to vote, you forgot to " u"publish the parent folder, you must sent back the poll " u"to private state, publish the parent folder and open " u"the poll again"), type="info") INVALID_OPTION = _(u'Invalid option') if 'poll.submit' in form: options = form.get('options', '') if isinstance(options, list): self.errors.append(INVALID_OPTION) elif isinstance(options, str): if not options.isdigit(): self.errors.append(INVALID_OPTION) else: options = int(options) if not self.errors: # Let's vote try: self.context.setVote(options, self.request) self.messages.append(_(u'Thanks for your vote')) # We do this to avoid redirecting anonymous user as # we just sent them the cookie self._has_voted = True except Unauthorized: self.errors.append(_(u'You are not authorized to vote')) # Update status messages for error in self.errors: messages.addStatusMessage(error, type="warn") for msg in self.messages: messages.addStatusMessage(msg, type="info")
def reload_template(root): counter = 0 for obj in root.objectValues(): if ISiteRoot.providedBy(obj): tool = getToolByName(obj, 'portal_skins', None) if tool is not None: counter = reload_skins(tool) return counter
def payment_properties(self): context = aq_inner(self.context) if ISiteRoot.providedBy(context): properties = getToolByName(context, 'portal_properties') prop = getattr(properties, 'collective_pfg_payment_properties') if IPloneFormGenForm.providedBy(context): prop = IAnnotations(context)['collective.pfg.payment'] return IProperties(prop)
def get_uid(obj): """ get the UID of the brain/object """ if ICatalogBrain.providedBy(obj): return obj.UID if ISiteRoot.providedBy(obj): return "siteroot" return obj.UID()
def _translations(self, missing): # Figure out the "closest" translation in the parent chain of the # context. We stop at both an INavigationRoot or an ISiteRoot to look # for translations. # Exceptions: 1) If the object does not implement ITranslatable (= not # LP-aware) or # 2) if the object is set to be neutral # then return this object and don't look for a translation. context = aq_inner(self.context) translations = {} chain = aq_chain(context) first_pass = True _checkPermission = getSecurityManager().checkPermission for item in chain: if ISiteRoot.providedBy(item) \ or not ITranslatable.providedBy(item) \ or not item.Language(): # We have a site root, which works as a fallback has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, first_pass, has_view_permission) break translatable = ITranslatable(item, None) if translatable is None: continue item_trans = item.getTranslations(review_state=False) for code, trans in item_trans.items(): code = str(code) if code not in translations: # make a link to a translation only if the user # has view permission has_view_permission = bool(_checkPermission('View', trans)) if (not INavigationRoot.providedBy(item) and not has_view_permission): continue # If we don't yet have a translation for this language # add it and mark it as found translations[code] = (trans, first_pass, has_view_permission) missing = missing - set((code, )) if len(missing) <= 0: # We have translations for all break if INavigationRoot.providedBy(item): # Don't break out of the navigation root jail has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, False, has_view_permission) break first_pass = False # return a dict of language code to tuple. the first tuple element is # the translated object, the second argument indicates wether the # translation is a direct translation of the context or something from # higher up the translation chain return translations
def searchContent(context): # getSide() returns INavigationRoot Object siteroot = getSite() # if INavigationRoot != ISideRoot if not ISiteRoot.providedBy(context): for item in getSite().aq_chain: if ISiteRoot.providedBy(item): siteroot = item path = '/'.join(siteroot.getPhysicalPath()) # all Languages query = {"path": {'query': path}, "Language": 'all' } return ObjPathSourceBinder(navigation_tree_query=query)(context)
def current_section(self, context=None): """Return the current section, used to determine headers etc.""" if not context: context = aq_inner(self.context) if ISection.providedBy(context): return context if ISiteRoot.providedBy(context): return None return self.current_section(context=context.__parent__)
def is_portal(brain_or_object): """Checks if the passed in object is the portal root object :param brain_or_object: A single catalog brain or content object :type brain_or_object: ATContentType/DexterityContentType/CatalogBrain :returns: True if the object is the portal root object :rtype: bool """ return ISiteRoot.providedBy(brain_or_object)
def get_parent_book(self): context = self.context while context and not ISiteRoot.providedBy(context): if IBook.providedBy(context): return context context = aq_parent(aq_inner(context)) return None
def _translations(self, missing): # Figure out the "closest" translation in the parent chain of the # context. We stop at both an INavigationRoot or an ISiteRoot to look # for translations. We do want to find something that is definitely # in the language the user asked for. context = aq_inner(self.context) translations = {} chain = aq_chain(context) first_pass = True _checkPermission = getSecurityManager().checkPermission for item in chain: if ISiteRoot.providedBy(item): # We have a site root, which works as a fallback has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, first_pass, has_view_permission) break elif IFactoryTempFolder.providedBy(item) or \ IFactoryTool.providedBy(item): # TempFolder or portal_factory, can't have a translation continue canonical = ITranslationManager(item, None) item_trans = canonical.get_translations() for code, trans in item_trans.items(): code = str(code) if code not in translations: # make a link to a translation only if the user # has view permission has_view_permission = bool(_checkPermission('View', trans)) if (not INavigationRoot.providedBy(item) and not has_view_permission): continue # If we don't yet have a translation for this language # add it and mark it as found translations[code] = (trans, first_pass, has_view_permission) missing = missing - set((code, )) if len(missing) <= 0: # We have translations for all break if INavigationRoot.providedBy(item): # Don't break out of the navigation root jail has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, False, has_view_permission) break first_pass = False # return a dict of language code to tuple. the first tuple element is # the translated object, the second argument indicates wether the # translation is a direct translation of the context or something from # higher up the translation chain return translations
def __call__(self): # callback url is expected on site root if not ISiteRoot.providedBy(self.context): root = api.portal.get() self.request.response.redirect("{0}/authomatic-handler/{1}".format( root.absolute_url(), getattr(self, 'provider', ''))) return "redirecting" self.authopas = authomatic_plugin() self.cfgs = authomatic_cfg() if self.cfgs is None: return "Authomatic is not configured" self.is_anon = api.user.is_anonymous() if not self.is_anon: self.user = api.user.get_current() self.user_providers = self.authopas._useridentities_by_userid.get( self.user.id).providers() # Validate provider if not hasattr(self, 'provider'): return self.template() if self.provider not in self.cfgs: return "Provider not supported" if not self.is_anon and self.provider in self.user_providers: action = self.request.form.get('action', None) if action == 'unlink': alsoProvides(self.request, IDisableCSRFProtection) self.authopas.remove_identity(self.user.id, self.provider) api.portal.show_message( _('Unlink account with {provider} provider', mapping={'provider': self.provider}), self.request) return self.template() #Any other action ? else: api.portal.show_message( _('Provider {provider} is already connected to current user', mapping={'provider': self.provider}), self.request) return self.template() # TODO: some sort of CSRF check might be needed, so that # not an account got connected by CSRF. Research needed. #Authomatic login auth = Authomatic(self.cfgs, secret=authomatic_settings().secret.encode('utf8')) result = auth.login(ZopeRequestAdapter(self), self.provider) if not result: logger.info('return from view') # let authomatic do its work return if result.error: return result.error.message # fetch provider specific user-data result.user.update() display = self.cfgs[self.provider].get('display', {}) provider_name = display.get('title', self.provider) if not self.is_anon: # now we delegate to PAS plugin to add the identity self._add_identity(result, provider_name) self.request.response.redirect("{0}".format( self.context.absolute_url())) else: # now we delegate to PAS plugin in order to login self._remember_identity(result, provider_name) redirect = self.cfgs[self.provider].get( 'redirect_url', "${portal_url}/login_success") redirect = redirect.replace("${portal_url}", api.portal.get().absolute_url()) self.request.response.redirect(redirect) return "redirecting"
def _get_translations_by_closest(self, supported_langs): """ Return the translations information by figuring out the 'closest' translation in the parent chain of the context. We stop at both an INavigationRoot or an ISiteRoot to look for translations. We do want to find something that is definitely in the language the user asked for regardless anything else. """ context = aq_inner(self.context) missing = set([str(c) for c in supported_langs]) translations = {} chain = aq_chain(context) first_pass = True _checkPermission = getSecurityManager().checkPermission for item in chain: if ISiteRoot.providedBy(item): # We have a site root, which works as a fallback has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, first_pass, has_view_permission) break elif IFactoryTempFolder.providedBy(item) or \ IFactoryTool.providedBy(item): # TempFolder or portal_factory, can't have a translation continue try: canonical = ITranslationManager(item) except TypeError: if not ITranslatable.providedBy(item): # In case there it's not translatable go to parent # This solves the problem when a parent is not ITranslatable continue else: raise item_trans = canonical.get_translations() for code, trans in item_trans.items(): code = str(code) if code not in translations: # make a link to a translation only if the user # has view permission has_view_permission = bool(_checkPermission('View', trans)) if (not INavigationRoot.providedBy(item) and not has_view_permission): continue # If we don't yet have a translation for this language # add it and mark it as found translations[code] = (trans, first_pass, has_view_permission) missing = missing - set((code, )) if len(missing) <= 0: # We have translations for all break if INavigationRoot.providedBy(item): # Don't break out of the navigation root jail has_view_permission = bool(_checkPermission('View', item)) for c in missing: translations[c] = (item, False, has_view_permission) break first_pass = False # return a dict of language code to tuple. the first tuple element is # the translated object, the second argument indicates wether the # translation is a direct translation of the context or something from # higher up the translation chain return translations
def submitcc(self): # TODO: catch UNAuthorized correctly and return json error if self.request.get('REQUEST_METHOD', 'GET').upper() != 'POST': self.record_error('Request must be POST', 400) raise BadRequest('Request must be POST') # make sure we have the right context if ISiteRoot.providedBy(self.context): # we have been called at site root... let's traverse to default # experiments location context = self.context.restrictedTraverse( defaults.EXPERIMENTS_FOLDER_ID) else: # custom context.... let's use in context = self.context # parse request body params = self.request.form # validate input # TODO: should validate type as well..... (e.g. string has to be # string) # TODO: validate dataset and layer id's existence if possible props = {} if not params.get('title', None): self.record_error('Bad Request', 400, 'Missing parameter title', {'parameter': 'title'}) else: props['title'] = params['title'] props['description'] = params.get('description', '') if not params.get('species_distribution_models', None): self.record_error('Bad Request', 400, 'Missing parameter species_distribution_models', {'parameter': 'species_distribution_models'}) else: props['species_distribution_models'] = params[ 'species_distribution_models'] if not params.get('future_climate_datasets', None): self.record_error('Bad Request', 400, 'Missing parameter future_climate_datasets', {'parameter': 'future_climate_datasets'}) else: props['future_climate_datasets'] = params[ 'future_climate_datasets'] if params.get('projection_region', ''): props['projection_region'] = NamedBlobFile( data=json.dumps(params['projection_region'])) else: props['projection_region'] = None if self.errors: raise BadRequest("Validation Failed") # create experiment with data as form would do # TODO: make sure self.context is 'experiments' folder? from plone.dexterity.utils import createContent, addContentToContainer experiment = createContent("org.bccvl.content.projectionexperiment", **props) experiment = addContentToContainer(context, experiment) # FIXME: need to get resolution from somewhere IBCCVLMetadata(experiment)['resolution'] = 'Resolution30m' # submit newly created experiment # TODO: handle background job submit .... at this stage we wouldn't # know the model run job ids # TODO: handle submit errors and other errors that may happen above? # generic exceptions could behandled in returnwrapper retval = { 'experiment': { 'url': experiment.absolute_url(), 'uuid': IUUID(experiment) }, 'jobs': [], } jt = IExperimentJobTracker(experiment) msgtype, msg = jt.start_job(self.request) if msgtype is not None: retval['message'] = { 'type': msgtype, 'message': msg } for result in experiment.values(): jt = IJobTracker(result) retval['jobs'].append(jt.get_job().id) return retval
def submittraits(self): # TODO: catch UNAuthorized correctly and return json error if self.request.get('REQUEST_METHOD', 'GET').upper() != 'POST': self.record_error('Request must be POST', 400) raise BadRequest('Request must be POST') # make sure we have the right context if ISiteRoot.providedBy(self.context): # we have been called at site root... let's traverse to default # experiments location context = self.context.restrictedTraverse( defaults.EXPERIMENTS_FOLDER_ID) else: # custom context.... let's use in context = self.context # parse request body params = self.request.form # validate input # TODO: should validate type as well..... (e.g. string has to be # string) # TODO: validate dataset and layer id's existence if possible props = {} if params.get('species_list', None): props['species_list'] = params['species_list'] else: self.record_error('Bad Request', 400, 'Missing parameter speciesList', {'parameter': 'speciesList'}) if not params.get('title', None): self.record_error('Bad Request', 400, 'Missing parameter title', {'parameter': 'title'}) else: props['title'] = params['title'] props['description'] = params.get('description', '') if not params.get('traits_data', None): self.record_error('Bad Request', 400, 'Missing parameter traits_data', {'parameter': 'traits_data'}) else: # FIXME: should properly support source / id # for now only bccvl source is supported props['species_traits_dataset'] = params[ 'traits_data']['id'] props['species_traits_dataset_params'] = {} for col_name, col_val in params.get("columns", {}).items(): if col_val not in ('lat', 'lon', 'species', 'trait_con', 'trait_ord', 'trait_nom', 'env_var_con', 'env_var_cat', 'random_con', 'random_cat'): continue props['species_traits_dataset_params'][col_name] = col_val if not props['species_traits_dataset_params']: self.record_error('Bad Request', 400, 'Invalid values for columns', {'parameter': 'columns'}) # Check for species-level trait data i.e. species is not specified if 'species' not in props['species_traits_dataset_params'].values(): props['species_list'] = [] props['scale_down'] = params.get('scale_down', False) # env data is optional props['environmental_datasets'] = params.get('environmental_data', None) if not (props['environmental_datasets'] or 'env_var_con' not in props['species_traits_dataset_params'].values() or 'env_var_cat' not in props['species_traits_dataset_params'].values()): self.record_error('Bad Request', 400, 'No Environmental data selected', {'parameter': 'environmental_datasets'}) if params.get('modelling_region', ''): props['modelling_region'] = NamedBlobFile( data=json.dumps(params['modelling_region'])) else: props['modelling_region'] = None if not params.get('algorithms', None): self.record_error('Bad Request', 400, 'Missing parameter algorithms', {'parameter': 'algorithms'}) else: props['algorithms_species'] = {} props['algorithms_diff'] = {} funcs_env = getUtility( IVocabularyFactory, 'traits_functions_species_source')(context) funcs_species = getUtility( IVocabularyFactory, 'traits_functions_diff_source')(context) # FIXME: make sure we get the default values from our func object for algo_uuid, algo_params in params['algorithms'].items(): if algo_params is None: algo_params = {} toolkit = uuidToObject(algo_uuid) toolkit_model = loadString(toolkit.schema) toolkit_schema = toolkit_model.schema func_props = {} for field_name in toolkit_schema.names(): field = toolkit_schema.get(field_name) value = algo_params.get(field_name, field.missing_value) if value == field.missing_value: func_props[field_name] = field.default else: func_props[field_name] = value if algo_uuid in funcs_env: props['algorithms_species'][algo_uuid] = func_props elif algo_uuid in funcs_species: props['algorithms_diff'][algo_uuid] = func_props else: LOG.warn( 'Algorithm {} not in allowed list of functions'.format(toolkit.id)) if not (props['algorithms_species'] or props['algorithms_diff']): self.record_error('Bad Request', 400, 'Iinvalid algorithms selected', {'parameter': 'algorithms'}) if self.errors: raise BadRequest("Validation Failed") # create experiment with data as form would do # TODO: make sure self.context is 'experiments' folder? from plone.dexterity.utils import createContent, addContentToContainer experiment = createContent( "org.bccvl.content.speciestraitsexperiment", **props) experiment = addContentToContainer(context, experiment) experiment.parameters = dict(props['algorithms_species']) experiment.parameters.update(dict(props['algorithms_diff'])) # FIXME: need to get resolution from somewhere IBCCVLMetadata(experiment)['resolution'] = 'Resolution30m' # submit newly created experiment # TODO: handle background job submit .... at this stage we wouldn't # know the model run job ids # TODO: handle submit errors and other errors that may happen above? # generic exceptions could behandled in returnwrapper retval = { 'experiment': { 'url': experiment.absolute_url(), 'uuid': IUUID(experiment) }, 'jobs': [], } jt = IExperimentJobTracker(experiment) msgtype, msg = jt.start_job(self.request) if msgtype is not None: retval['message'] = { 'type': msgtype, 'message': msg } for result in experiment.values(): jt = IJobTracker(result) retval['jobs'].append(jt.get_job().id) return retval
def submitsdm(self): # TODO: catch UNAuthorized correctly and return json error if self.request.get('REQUEST_METHOD', 'GET').upper() != 'POST': self.record_error('Request must be POST', 400) raise BadRequest('Request must be POST') # make sure we have the right context if ISiteRoot.providedBy(self.context): # we have been called at site root... let's traverse to default # experiments location context = self.context.restrictedTraverse( defaults.EXPERIMENTS_FOLDER_ID) else: # custom context.... let's use in context = self.context # parse request body params = self.request.form # validate input # TODO: should validate type as well..... (e.g. string has to be # string) # TODO: validate dataset and layer id's existence if possible props = {} if not params.get('title', None): self.record_error('Bad Request', 400, 'Missing parameter title', {'parameter': 'title'}) else: props['title'] = params['title'] props['description'] = params.get('description', '') if not params.get('occurrence_data', None): self.record_error('Bad Request', 400, 'Missing parameter occurrence_data', {'parameter': 'occurrence_data'}) else: # FIXME: should properly support source / id # for now only bccvl source is supported props['species_occurrence_dataset'] = params[ 'occurrence_data']['id'] # FIXME: should properly support source/id for onw only bccvl source is # supported props['species_absence_dataset'] = params.get( 'absence_data', {}).get('id', None) props['scale_down'] = params.get('scale_down', False) if not params.get('environmental_data', None): self.record_error('Bad Request', 400, 'Missing parameter environmental_data', {'parameter': 'environmental_data'}) else: props['environmental_datasets'] = params['environmental_data'] if params.get('modelling_region', ''): props['modelling_region'] = NamedBlobFile( data=json.dumps(params['modelling_region'])) else: props['modelling_region'] = None if not params.get('algorithms', None): self.record_error('Bad Request', 400, 'Missing parameter algorithms', {'parameter': 'algorithms'}) else: portal = ploneapi.portal.get() props['functions'] = {} # FIXME: make sure we get the default values from our func object for algo, algo_params in params['algorithms'].items(): if algo_params is None: algo_params = {} toolkit = portal[defaults.FUNCTIONS_FOLDER_ID][algo] toolkit_model = loadString(toolkit.schema) toolkit_schema = toolkit_model.schema func_props = {} for field_name in toolkit_schema.names(): field = toolkit_schema.get(field_name) value = algo_params.get(field_name, field.missing_value) if value == field.missing_value: func_props[field_name] = field.default else: func_props[field_name] = value props['functions'][IUUID(toolkit)] = func_props if self.errors: raise BadRequest("Validation Failed") # create experiment with data as form would do # TODO: make sure self.context is 'experiments' folder? from plone.dexterity.utils import createContent, addContentToContainer experiment = createContent("org.bccvl.content.sdmexperiment", **props) experiment = addContentToContainer(context, experiment) # TODO: check if props and algo params have been applied properly experiment.parameters = dict(props['functions']) # FIXME: need to get resolution from somewhere IBCCVLMetadata(experiment)['resolution'] = 'Resolution30m' # submit newly created experiment # TODO: handle background job submit .... at this stage we wouldn't # know the model run job ids # TODO: handle submit errors and other errors that may happen above? # generic exceptions could behandled in returnwrapper retval = { 'experiment': { 'url': experiment.absolute_url(), 'uuid': IUUID(experiment) }, 'jobs': [], } jt = IExperimentJobTracker(experiment) msgtype, msg = jt.start_job(self.request) if msgtype is not None: retval['message'] = { 'type': msgtype, 'message': msg } for result in experiment.values(): jt = IJobTracker(result) retval['jobs'].append(jt.get_job().id) return retval
def _get_language_root_folder_path(self): for item in aq_chain(self.context): if ILanguageRootFolder.providedBy(item) or ISiteRoot.providedBy( item): return '/'.join(item.getPhysicalPath()) return '/'
def __call__(self, request, result, context=None): if '++plone++' in request.ACTUAL_URL: return portal = api.portal.get() original_context = context if context is None or IResourceDirectory.providedBy(context): original_context = context = portal try: context_url = context.absolute_url() except AttributeError: # could be a form/browser class try: context = context.context except Exception: context = aq_parent(context) context_url = context.absolute_url() if (not ISiteRoot.providedBy(context) and not IDexterityContent.providedBy(context)): context = aq_parent(context) portal_url = portal.absolute_url() raw = False if isinstance(result, basestring): raw = True else: self.rewrite(result, context.absolute_url() + '/') result = result.tree theme_base_url = '%s/++%s++%s/index.html' % ( portal_url, THEME_RESOURCE_NAME, self.name) content = self.get_fill_content(result, raw) utils = getMultiAdapter((context, request), name='castle-utils') layout = self.get_layout(context, request=request) layout = layout(portal_url=portal_url, site_url=portal_url, context_url=context_url, request=request, context=context, portal=portal, site=portal, theme_base_url=theme_base_url, content=content, anonymous=api.user.is_anonymous(), debug=api.env.debug_mode(), utils=utils) dom = getHTMLSerializer([layout]) self.rewrite(dom, theme_base_url) if not raw: # old style things... self.bbb(dom.tree, result) dom.tree = tiles.renderTiles(request, dom.tree) self.add_body_classes(original_context, context, request, dom.tree, result, raw) self.add_included_resources(dom.tree, portal, request) self.dynamic_grid(dom.tree) return dom
def getClosestDestination(self): """Get the "closest translated object" URL. """ # We should travel the parent chain using the catalog here, # but I think using the acquisition chain is faster # (or well, __parent__ pointers) because the catalog # would require a lot of queries, while technically, # having done traversal up to this point you should # have the objects in memory already # As we don't have any content object we are going to look # for the best option site = getSite() root = getToolByName(site, 'portal_url') ltool = getToolByName(site, 'portal_languages') # We are using TranslationManager to get the translations of a # string tg manager = TranslationManager(self.tg) context = None languages = manager.get_translations() if len(languages) == 0: # If there is no results there are no translations # we move to portal root return self.wrapDestination(root(), postpath=False) # We are going to see if there is the preferred language translation # Otherwise we get the first as context to look for translation prefered = ltool.getPreferredLanguage(self.request) if prefered in languages: context = languages[prefered] else: context = languages[languages.keys()[0]] checkPermission = getSecurityManager().checkPermission chain = self.getParentChain(context) for item in chain: if ISiteRoot.providedBy(item) \ and not ILanguageRootFolder.providedBy(item): # We do not care to get a permission error # if the whole of the portal cannot be viewed. # Having a permission issue on the root is fine; # not so much for everything else so that is checked there return self.wrapDestination(item.absolute_url()) elif IFactoryTempFolder.providedBy(item) or \ IFactoryTool.providedBy(item): # TempFolder or portal_factory, can't have a translation continue try: canonical = ITranslationManager(item) except TypeError: if not ITranslatable.providedBy(item): # In case there it's not translatable go to parent # This solves the problem when a parent is not # ITranslatable continue else: raise translation = canonical.get_translation(self.lang) if translation and (INavigationRoot.providedBy(translation) or bool(checkPermission('View', translation))): # Not a direct translation, therefore no postpath # (the view might not exist on a different context) return self.wrapDestination(translation.absolute_url(), postpath=False) # Site root's the fallback return self.wrapDestination(root(), postpath=False)
def buildAjaxViewName(self): "根据当前上下文,构建ajax view 名称" context = aq_inner(self.context) if ISiteRoot.providedBy(context): return "oajaxsearch" else: return "xiangtanshisearch"
def create(container=None, type=None, id=None, title=None, safe_id=False, **kwargs): """Create a new content item. :param container: [required] Container object in which to create the new object. :type container: Folderish content object :param type: [required] Type of the object. :type type: string :param id: Id of the object. If the id conflicts with another object in the container, a suffix will be added to the new object's id. If no id is provided, automatically generate one from the title. If there is no id or title provided, raise a ValueError. :type id: string :param title: Title of the object. If no title is provided, use id as the title. :type title: string :param safe_id: When False, the given id will be enforced. If the id is conflicting with another object in the target container, raise an InvalidParameterError. When True, choose a new, non-conflicting id. :type safe_id: boolean :returns: Content object :raises: KeyError, :class:`~plone.api.exc.MissingParameterError`, :class:`~plone.api.exc.InvalidParameterError` :Example: :ref:`content_create_example` """ # Create a temporary id if the id is not given content_id = not safe_id and id or str(random.randint(0, 99999999)) if title: kwargs['title'] = title try: container.invokeFactory(type, content_id, **kwargs) except ValueError: if ISiteRoot.providedBy(container): allowed_types = container.allowedContentTypes() types = [allowed_type.id for allowed_type in allowed_types] else: types = container.getLocallyAllowedTypes() raise InvalidParameterError( "Cannot add a '{0}' object to the container.\n" "Allowed types are:\n" "{1}".format(type, '\n'.join(sorted(types)))) content = container[content_id] # Archetypes specific code if IBaseObject.providedBy(content): # Will finish Archetypes content item creation process, # rename-after-creation and such content.processForm() if not id or (safe_id and id): # Create a new id from title chooser = INameChooser(container) derived_id = id or title new_id = chooser.chooseName(derived_id, content) # kacee: we must do a partial commit, else the renaming fails because # the object isn't in the zodb. # Thus if it is not in zodb, there's nothing to move. We should # choose a correct id when # the object is created. # maurits: tests run fine without this though. transaction.savepoint(optimistic=True) content.aq_parent.manage_renameObject(content_id, new_id) return content
def __createExpmetadata(self, job_params): # To do: add other R package versions dynamically # Get experiment title self.md['Model specifications'] = { 'Title': self.context.title, 'Date/time run': self.context.creation_date.__str__(), 'Description': self.context.description or '' } # iterate over all input datasets and add them as entities self.md['Input datasets:'] = {} for key in ('species_occurrence_dataset', 'species_absence_dataset', 'traits_dataset'): spmd = {} if not job_params.has_key(key): continue dsbrain = uuidToCatalogBrain(job_params[key]) if not dsbrain: continue ds = dsbrain.getObject() mdata = IBCCVLMetadata(ds) if mdata and mdata.get('rows', None): spmd = {'Title': "{} ({})".format(ds.title, mdata.get('rows'))} else: spmd = {'Title': ds.title} info = IDownloadInfo(ds) spmd['Download URL'] = info['url'] coll = ds while not (ISiteRoot.providedBy(coll) or ICollection.providedBy(coll)): coll = coll.__parent__ spmd['Description'] = ds.description or coll.description or '' attribution = ds.attribution or getattr(coll, 'attribution') or '' if isinstance(attribution, list): attribution = '\n'.join([att.raw for att in attribution]) spmd['Attribution'] = attribution self.md['Input datasets:'][key] = spmd key = 'traits_dataset_params' if key in job_params: self.md['Input datasets:'][key] = job_params.get(key, {}) # pseudo-absence metadata. key = u"pseudo_absence_dataset" pa_file = self.context.get('pseudo_absences.csv') pa_url = "" pa_title = "" if pa_file: pa_title = pa_file.title pa_url = pa_file.absolute_url() pa_url = '{}/@@download/{}'.format(pa_url, os.path.basename(pa_url)) pamd = { 'Title': pa_title, 'Download URL': pa_url, 'Pseudo-absence Strategy': job_params.get('pa_strategy', ''), 'Pseudo-absence Ratio': str(job_params.get('pa_ratio', '')) } if job_params.get('pa_strategy', '') == 'disc': pamd['Minimum distance'] = str( job_params.get('pa_disk_min', '')) pamd['Maximum distance'] = str( job_params.get('pa_disk_max', '')) if job_params.get('pa_strategy', '') == 'sre': pamd['Quantile'] = str(job_params.get('pa_sre_quant', '')) self.md['Input datasets:'][key] = pamd for key in ['environmental_datasets', 'future_climate_datasets']: if key not in job_params: continue env_list = [] layer_vocab = getUtility(IVocabularyFactory, 'layer_source')(self.context) for uuid, layers in job_params[key].items(): ds = uuidToObject(uuid) coll = ds while not (ISiteRoot.providedBy(coll) or ICollection.providedBy(coll)): coll = coll.__parent__ description = ds.description or coll.description attribution = ds.attribution or getattr(coll, 'attribution') or '' if isinstance(attribution, list): attribution = '\n'.join([att.raw for att in attribution]) layer_titles = [ layer_vocab.getLayerTitle(layer) for layer in layers ] env_list.append({ 'Title': ds.title, 'Layers': u'\n'.join(layer_titles), 'Description': description, 'Attribution': attribution }) self.md['Input datasets:'][key] = env_list key = "datasets" if key in job_params: dataset_list = [] for uid in job_params[key]: dsbrain = uuidToCatalogBrain(uid) if dsbrain: ds = dsbrain.getObject() # get the source experiment source_exp = ds.__parent__ while not IExperiment.providedBy(source_exp): source_exp = source_exp.__parent__ dataset_list.append({ 'Source experiment': source_exp.title, 'Title': ds.title, 'Description': ds.description, 'Download URL': '{}/@@download/file/{}'.format( ds.absolute_url(), os.path.basename(ds.absolute_url())), 'Algorithm': ds.__parent__.job_params.get('function', ''), 'Species': IBCCVLMetadata(ds).get('species', {}).get('scientificName', ''), 'Resolution': IBCCVLMetadata(ds).get('resolution', '') }) self.md['Input datasets:'][key] = dataset_list key = 'species_distribution_models' if key in job_params: dsbrain = uuidToCatalogBrain(job_params[key]) if dsbrain: ds = dsbrain.getObject() # get the source experiment source_exp = ds.__parent__ while not IExperiment.providedBy(source_exp): source_exp = source_exp.__parent__ # get the threshold threshold = self.context.species_distribution_models.get( source_exp.UID(), {}).get(ds.UID()) self.md['Input datasets:'][key] = { 'Source experiment': source_exp.title, 'Title': ds.title, 'Description': ds.description, 'Download URL': '{}/@@download/file/{}'.format( ds.absolute_url(), os.path.basename(ds.absolute_url())), 'Algorithm': ds.__parent__.job_params.get('function', ''), 'Species': IBCCVLMetadata(ds).get('species', {}).get('scientificName', ''), 'Threshold': "{}({})".format(threshold.get('label', ''), str(threshold.get('value', ''))) } key = 'projections' if key in job_params: for pds in job_params[key]: threshold = pds.get('threshold', {}) dsbrain = uuidToCatalogBrain(pds.get('dataset')) if dsbrain: ds = dsbrain.getObject() # get the source experiment source_exp = ds.__parent__ while not IExperiment.providedBy(source_exp): source_exp = source_exp.__parent__ self.md['Input datasets:'][key] = { 'Source experiment': source_exp.title, 'Title': ds.title, 'Description': ds.description, 'Download URL': '{}/@@download/file/{}'.format( ds.absolute_url(), os.path.basename(ds.absolute_url())), 'Algorithm': ds.__parent__.job_params.get('function', ''), 'Species': IBCCVLMetadata(ds).get('species', {}).get('scientificName', ''), 'Threshold': "{}({})".format(threshold.get('label', ''), str(threshold.get('value', ''))), 'Biodiverse Cell size (m)': str(job_params.get('cluster_size', '')) } # Projection experiment does not have algorithm as input if not IProjectionExperiment.providedBy(self.context.__parent__): for key in ['function', 'algorithm']: if key in job_params: self.md['Algorithm settings:'] = { 'Algorithm Name': job_params[key], 'Configuration options': self.__algoConfigOption(job_params[key], job_params) } # Construct the text mdtext = StringIO.StringIO() for heading in [ 'BCCVL model outputs guide', 'System specifications', 'Model specifications', 'Input datasets:', 'Algorithm settings:', 'Model outputs:' ]: mdtext.write(self.__getMetadataText(heading, self.md)) return mdtext.getvalue()
def tilesobject(self): for item in self.context.aq_chain: if ITilesPage.providedBy(item): return item if ISiteRoot.providedBy(item): return None
def index_positions(obj, ids): hook = getHook() if ISiteRoot.providedBy(obj): hook.positions['/'] = ids else: hook.positions[getUID(obj)] = ids
def __call__(self): cfg = authomatic_cfg() if cfg is None: return "Authomatic is not configured" if not (ISiteRoot.providedBy(self.context) or INavigationRoot.providedBy(self.context)): # callback url is expected on either navigationroot or site root # so bevor going on redirect root = api.portal.get_navigation_root(self.context) self.request.response.redirect( "{0}/authomatic-handler/{1}{2}".format( root.absolute_url(), getattr(self, 'provider', ''), ('?' + self.request.QUERY_STRING if self.request.QUERY_STRING else ''))) return "redirecting" if not hasattr(self, 'provider'): return self.template() if self.provider not in cfg: return "Provider not supported" if not self.is_anon: if self.provider in self._provider_names: raise ValueError( 'Provider {0} is already connected to current ' 'user.'.format(self.provider)) # TODO: some sort of CSRF check might be needed, so that # not an account got connected by CSRF. Research needed. pass auth = Authomatic(cfg, secret=authomatic_settings().secret.encode('utf8')) additional_params = {} for key in ('came_from', 'next'): if key in self.request.form: additional_params[key] = self.request.form[key] # TODO: expire after 1800s (30m) # TODO: single cookie for next and came_from ? self.request.response.setCookie( 'authomatic_{0}'.format(key), self.request.form[key], http_only=True, path=api.portal.get().absolute_url_path()) del (self.request.form[key]) # TODO: expire cookie(s) after successful login, not here. elif self.request.cookies.get('authomatic_{0}'.format(key)): additional_params[key] = self.request.cookies.get( 'authomatic_{0}'.format(key)) self.request.response.expireCookie( 'authomatic_{0}'.format(key), path=api.portal.get().absolute_url_path()) result = auth.login(ZopeRequestAdapter(self), self.provider) if not result: logger.info('return from view') return if result.error: return result.error.message display = cfg[self.provider].get('display', {}) provider_name = display.get('title', self.provider) if not self.is_anon: # now we delegate to PAS plugin to add the identity logger.info('add_identity %s', additional_params) self._add_identity(result, provider_name) self.request.response.redirect( additional_params.get('came_from', self.context.absolute_url())) else: # now we delegate to PAS plugin in order to login logger.info('remember_identity %s', additional_params) self._remember_identity(result, provider_name) if additional_params: self.request.response.redirect("{0}/logged_in?{1}".format( self.context.absolute_url(), urlencode(additional_params))) else: self.request.response.redirect("{0}/login_success".format( self.context.absolute_url())) return "redirecting"
def _isPortalDefaultView(self): context = self.context if ISiteRoot.providedBy(aq_parent(aq_inner(context))): putils = getToolByName(context, 'plone_utils') return putils.isDefaultPage(context) return False
def _isPortal(self): context = self.context if ISiteRoot.providedBy(aq_inner(context)): return True return self._isPortalDefaultView()
def getConfiguration(self, context=None, field=None, request=None): """Return configuration as a dictionary :param field: Dexterity or Archetypes Field instance :param context: The TinyMCE editor content items :return: JSON string of the TinyMCE configuration for this field """ results = {} # Get widget attributes widget = getattr(field, 'widget', None) filter_buttons = getattr(widget, 'filter_buttons', None) allow_buttons = getattr(widget, 'allow_buttons', None) redefine_parastyles = getattr(widget, 'redefine_parastyles', None) parastyles = getattr(widget, 'parastyles', None) rooted = getattr(widget, 'rooted', False) toolbar_width = getattr(widget, 'toolbar_width', self.toolbar_width) # Get safe html transform safe_html = getattr(getToolByName(self, 'portal_transforms'), 'safe_html') # Get kupu library tool filter # Settings are stored on safe_html transform in Plone 4 and # on kupu tool in Plone 3. kupu_library_tool = getToolByName(self, 'kupu_library_tool', None) # Remove to be stripped attributes try: style_whitelist = safe_html.get_parameter_value('style_whitelist') except (KeyError, AttributeError): if kupu_library_tool is not None: style_whitelist = kupu_library_tool.getStyleWhitelist() else: style_whitelist = [] results['valid_inline_styles'] = ','.join( style_whitelist) # tinymce format # Replacing some hardcoded translations labels = {} labels['label_browseimage'] = translate(_('Image Browser'), context=request) labels['label_browselink'] = translate(_('Link Browser'), context=request) labels['label_addnewimage'] = translate(_('Add new Image'), context=request) labels['label_addnewfile'] = translate(_('Add new File'), context=request) labels['label_styles'] = translate(_('(remove style)'), context=request) labels['label_paragraph'] = translate(_('Normal paragraph'), context=request) labels['label_plain_cell'] = translate(_('Plain cell'), context=request) labels['label_style_ldots'] = translate(_('Style...'), context=request) labels['label_text'] = translate(_('Text'), context=request) labels['label_tables'] = translate(_('Tables'), context=request) labels['label_selection'] = translate(_('Selection'), context=request) labels['label_lists'] = translate(_('Lists'), context=request) labels['label_print'] = translate(_('Print'), context=request) labels['label_no_items'] = translate(_('No items in this folder'), context=request) labels['label_no_anchors'] = translate(_('No anchors in this page'), context=request) labels['label_browser'] = translate(_('Browser'), context=request) labels['label_shortcuts'] = translate(_('Shortcuts'), context=request) labels['label_search_results'] = translate(_('Search results:'), context=request) labels['label_internal_path'] = translate(PMF("you_are_here", default="You are here:"), context=request) results['labels'] = labels # Add styles to results results['styles'] = [] table_styles = [] if not redefine_parastyles: if isinstance(self.tablestyles, StringTypes): for tablestyle in self.tablestyles.split('\n'): if not tablestyle: # empty line continue tablestylefields = tablestyle.split('|') tablestyletitle = tablestylefields[0] tablestyleid = tablestylefields[1] if tablestyleid == 'plain': # Do not duplicate the default style hardcoded in the # table.htm.pt continue if request is not None: tablestyletitle = translate(_(tablestylefields[0]), context=request) results['styles'].append(tablestyletitle + '|table|' + tablestyleid) table_styles.append(tablestyletitle + '=' + tablestyleid) if isinstance(self.styles, StringTypes): styles = [] for style in self.styles.split('\n'): if not style: # empty line continue stylefields = style.split('|') styletitle = stylefields[0] if request is not None: styletitle = translate(_(stylefields[0]), context=request) merge = styletitle + '|' + '|'.join(stylefields[1:]) styles.append(merge) results['styles'].extend(styles) results['table_styles'] = ';'.join(table_styles) # tinymce config if parastyles is not None: results['styles'].extend(parastyles) styles = results.pop('styles') # Get buttons from control panel results['buttons'] = self.getEnabledButtons(context=context) # Filter buttons if allow_buttons is not None: allow_buttons = self.translateButtonsFromKupu( context=context, buttons=allow_buttons) results['buttons'] = filter(lambda x: x in results['buttons'], allow_buttons) if filter_buttons is not None: filter_buttons = self.translateButtonsFromKupu( context=context, buttons=filter_buttons) results['buttons'] = filter(lambda x: x not in filter_buttons, results['buttons']) # Get valid html elements valid_elements = self.getValidElements() results['valid_elements'] = ','.join([ "%s[%s]" % (key, '|'.join(value)) for key, value in valid_elements.iteritems() ]) # self.customplugins can be None on old migrated sites results['customplugins'] = (self.customplugins or "").splitlines() # Set toolbar_location if self.toolbar_external: results['theme_advanced_toolbar_location'] = 'external' else: results['theme_advanced_toolbar_location'] = 'top' if self.autoresize: results['theme_advanced_path_location'] = 'none' results['theme_advanced_resizing_use_cookie'] = False results['theme_advanced_resizing'] = False results['autoresize'] = True else: results['theme_advanced_path_location'] = 'bottom' results['theme_advanced_resizing_use_cookie'] = True results['theme_advanced_resizing'] = self.resizing results['autoresize'] = False if '%' in self.editor_width: results['theme_advanced_resize_horizontal'] = False else: results['theme_advanced_resize_horizontal'] = True try: results['theme_advanced_source_editor_width'] = int( self.editor_width) except (TypeError, ValueError): results['theme_advanced_source_editor_width'] = 600 try: results['theme_advanced_source_editor_height'] = int( self.editor_height) except (TypeError, ValueError): results['theme_advanced_source_editor_height'] = 400 try: results['toolbar_width'] = int(toolbar_width) except (TypeError, ValueError): results['toolbar_width'] = 440 portal_state = context.restrictedTraverse('@@plone_portal_state') # is_rtl handles every possible setting as far as RTL/LTR is concerned # pass that to tinmyce results['directionality'] = portal_state.is_rtl() and 'rtl' or 'ltr' portal = portal_state.portal() portal_url = portal_state.portal_url() results['portal_url'] = portal_url results['navigation_root_url'] = portal_state.navigation_root_url() if self.content_css and self.content_css.strip() != "": results['content_css'] = self.content_css else: results['content_css'] = '/'.join( [results['portal_url'], self.getId(), "@@tinymce-getstyle"]) results['link_using_uids'] = self.link_using_uids results['contextmenu'] = self.contextmenu results['entity_encoding'] = self.entity_encoding results['script_url'] = portal_url + '/tiny_mce_gzip.js' results['allow_captioned_images'] = bool(self.allow_captioned_images) results['rooted'] = bool(self.rooted or rooted) props = getToolByName(portal, 'portal_properties') livesearch = props.site_properties.getProperty('enable_livesearch', False) results['livesearch'] = bool(livesearch) AVAILABLE_LANGUAGES = set( 'sq ar hy az eu be bn nb bs br bg ca ch zh hr cs da dv nl en et fi fr gl ' 'ka de el gu he hi hu is id ia it ja ko lv lt lb mk ms ml mn se no nn fa ' 'pl pt ps ro ru sc sr ii si sk sl es sv ta tt te th tr zh-cn zh-tw uk ur cy vi zu' .split()) if 'LANGUAGE' in context.REQUEST: if context.REQUEST.LANGUAGE in AVAILABLE_LANGUAGES: results['language'] = context.REQUEST.LANGUAGE elif context.REQUEST.LANGUAGE[:2] in AVAILABLE_LANGUAGES: results['language'] = context.REQUEST.LANGUAGE[:2] else: results['language'] = "en" else: results['language'] = "en" try: results['document_url'] = context.absolute_url() obj = context while obj is not None: if IFolderish.providedBy(obj): if obj.portal_type != 'TempFolder': # do not use portal_factory generated # temporary object for base url. results['document_base_url'] = obj.absolute_url() + "/" break # We should never reach this. if ISiteRoot.providedBy(obj): results['document_base_url'] = portal_url + "/" results['document_url'] = portal_url break obj = aq_parent(aq_inner(obj)) except AttributeError: results['document_base_url'] = portal_url + "/" results['document_url'] = portal_url # Get Library options results[ 'gecko_spellcheck'] = self.libraries_spellchecker_choice == 'browser' # Content Browser shortcuts_dict = dict(getUtilitiesFor(ITinyMCEShortcut)) results['link_shortcuts_html'] = [] results['image_shortcuts_html'] = [] results['num_of_thumb_columns'] = self.num_of_thumb_columns results['thumbnail_size'] = self.thumbnail_size results['anchor_selector'] = self.anchor_selector for name in self.link_shortcuts: results['link_shortcuts_html'].extend( shortcuts_dict.get(name).render(context)) for name in self.image_shortcuts: results['image_shortcuts_html'].extend( shortcuts_dict.get(name).render(context)) # init vars specific for "After the Deadline" spellchecker mtool = getToolByName(portal, 'portal_membership') member = mtool.getAuthenticatedMember() results['atd_rpc_id'] = 'Products.TinyMCE-' + ( member.getId() or '') # None when Anonymous User results['atd_rpc_url'] = "%s/@@" % portal_url results['atd_show_types'] = self.libraries_atd_show_types.strip( ).replace('\n', ',') results[ 'atd_ignore_strings'] = self.libraries_atd_ignore_strings.strip( ).replace('\n', ',') # generic configuration results['mode'] = "exact" results['theme'] = "advanced" results['skin'] = "plone" results['inlinepopups_skin'] = "plonepopup" results['body_class'] = "documentContent" results['body_id'] = "content" results['table_firstline_th'] = True results['fix_list_elements'] = False # allow embed tag if user removes it from # list of nasty tags - see #10681 results['media_strict'] = False results['theme_advanced_path'] = False results['theme_advanced_toolbar_align'] = "left" results['plugins'] = self.getPlugins() results['theme_advanced_styles'] = self.getStyles(styles, labels) results['theme_advanced_buttons1'], results['theme_advanced_buttons2'], \ results['theme_advanced_buttons3'], results['theme_advanced_buttons4'] = self.getToolbars(results) if self.formats and self.formats.strip(): results['formats'] = json.loads(self.formats) return results
def sliderobject(self): for item in self.context.aq_chain: if ISliderPage.providedBy(item): return item if ISiteRoot.providedBy(item): return None