Beispiel #1
0
 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 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
Beispiel #3
0
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
Beispiel #5
0
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)
        )
Beispiel #6
0
    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)
Beispiel #7
0
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 ''
Beispiel #8
0
    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 __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"
Beispiel #10
0
 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
Beispiel #11
0
 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
Beispiel #12
0
 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 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 get_plone_root(ctx):
    obj = aq_inner(ctx)
    while obj is not None:
        if ISiteRoot.providedBy(obj):
            break
        obj = aq_parent(obj)
    return obj
Beispiel #15
0
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 _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)
Beispiel #17
0
 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
Beispiel #18
0
        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
Beispiel #19
0
    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
Beispiel #20
0
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
Beispiel #21
0
    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")
Beispiel #22
0
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
Beispiel #23
0
 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)
Beispiel #24
0
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()
Beispiel #25
0
    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
Beispiel #26
0
    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
Beispiel #27
0
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)
Beispiel #28
0
    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)
Beispiel #29
0
 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 _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
Beispiel #31
0
def has_private_parents(obj):
    if (api.content.get_state(obj) != 'published'):
        return True  # needs to be True for private self as well as parents
    parent = aq_parent(obj)
    while not ISiteRoot.providedBy(parent):
        try:
            parent_brain = get_brain(parent.UID())
            try:
                if parent_brain.has_private_parents:
                    return True
            except AttributeError:
                if api.content.get_state(parent) != 'published':
                    return True
        except Exception:
            pass  # to be extra secure, could return True here. Better to be fault tolerant for now.
        parent = aq_parent(parent)
    return False
Beispiel #32
0
    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="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="Copy"),
                        "url": "%s/@@copy" % context_url
                    })

                elif a['id'] == 'cut' and context.cb_isMoveable():
                    children.append({
                        "title": _("menu_cut", default="Cut"),
                        "url": "%s/@@cut" % context_url
                    })

                elif a['id'] == 'paste' and ICopyContainer.providedBy(context):
                    children.append({
                        "title": _("menu_paste", default="Paste"),
                        "url": "%s/@@paste" % context_url
                    })
                elif a['id'] == 'delete':
                    children.append({
                        "title": _("menu_delete", default="Delete"),
                        "url": "%s/@@delete" % context_url
                    })
        if children:
            return menu
Beispiel #33
0
 def getPortal(self):
     ob = aq_inner(self.object)
     while ob is not None:
         if ISiteRoot.providedBy(ob):
             return ob
         if getattr(ob, '_isPortalRoot', None) is not None:
             # BBB
             warn(
                 "The '_isPortalRoot' marker attribute for site "
                 "roots is deprecated and will be removed in "
                 "CMF 2.3;  please mark the root object with "
                 "'ISiteRoot' instead.",
                 DeprecationWarning,
                 stacklevel=2)
             return ob
         ob = aq_parent(ob)
     return None
Beispiel #34
0
    def import_(self, import_context, subdir):
        """ See IFilesystemImporter.
        """
        context = self.context
        if not ISiteRoot.providedBy(context):
            subdir = '%s/%s' % (subdir, context.getId())

        preserve = import_context.readDataFile('.preserve', subdir)

        prior = context.contentIds()

        if not preserve:
            preserve = []
        else:
            preserve = _globtest(preserve, prior)

        for id in prior:
            if id not in preserve:
                context._delObject(id)

        objects = import_context.readDataFile('.objects', subdir)
        if objects is None:
            return

        dialect = 'excel'
        stream = StringIO(objects)

        rowiter = reader(stream, dialect)

        existing = context.objectIds()

        for object_id, portal_type in rowiter:

            if object_id not in existing:
                object = self._makeInstance(object_id, portal_type,
                                            subdir, import_context)
                if object is None:
                    message = "Couldn't make instance: %s/%s" % (subdir,
                                                                 object_id)
                    import_context.note('SFWA', message)
                    continue

            wrapped = context._getOb(object_id)

            IFilesystemImporter(wrapped).import_(import_context, subdir)
Beispiel #35
0
def fix_permissions(poll, event):
    ''' This subscriber will fix permission on poll object if
        allow_anonymous is enabled
    '''
    if event.action in [
            'open',
    ]:
        parent = aq_parent(poll)
        parent_view_roles = parent.rolesOfPermission('View')
        parent_view_roles = [
            r['name'] for r in parent_view_roles if r['selected']
        ]
        # Poll has been opened
        allow_anonymous = poll.allow_anonymous
        parent_is_root = ISiteRoot.providedBy(parent)
        parent_allow_anon = 'Anonymous' in parent_view_roles
        if (parent_allow_anon or parent_is_root) and allow_anonymous:
            poll.manage_permission(PERMISSION_VOTE, ALL_ROLES, acquire=0)
    def __call__(self):
        value = self._getFormValue()
        if value is None or value == self.context.missing_value:
            value = ''

        # Evil acquisition majik to find the site root. This is made tricky
        # by the fact that the widget doesn't have a direct path to its
        # context (you can go self.context.context, but this may be an
        # adapter on the context, not the context itself.). We can find
        # the root using getUtility(ISiteRoot), but this isn't wrapped
        # in the request container. We can use getSite(), but there may be
        # other sites in-between, not at least the KSS site-in-a-view. Sigh.

        site = getSite()
        while site is not None and not ISiteRoot.providedBy(site):
            site = aq_parent(site)

        return self.template(form_context=site, value=value)
Beispiel #37
0
    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("{}/authomatic-handler/{}".format(
                root.absolute_url(), getattr(self, "provider", "")))
            return "redirecting"
        if not getattr(self, "provider", None):
            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:
                logger.warn(
                    "Provider %s is already connected to current "
                    "user.", self.provider)
                return self._redirect()
            # TODO: some sort of CSRF check might be needed, so that
            #       not an account got connected by CSRF. Research needed.
            pass
        secret = authomatic_settings().secret
        auth = Authomatic(cfg, secret=secret)
        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)
        else:
            # now we delegate to PAS plugin in order to login
            self._remember_identity(result, provider_name)

        return self._redirect()
Beispiel #38
0
    def export(self, export_context, subdir):
        """ See IFilesystemExporter.
        """
        # Enumerate exportable children
        exportable = self.context.contentItems()
        exportable = [x + (IFilesystemExporter(x, None), ) for x in exportable]
        exportable = [x for x in exportable if x[1] is not None]

        stream = StringIO()
        csv_writer = writer(stream)

        for object_id, object, ignored in exportable:
            csv_writer.writerow((object_id, object.getPortalTypeName()))

        if not ISiteRoot.providedBy(self.context):
            subdir = '%s/%s' % (subdir, self.context.getId())

        export_context.writeDataFile(
            '.objects',
            text=stream.getvalue(),
            content_type='text/comma-separated-values',
            subdir=subdir,
        )

        parser = ConfigParser()

        parser.set('DEFAULT', 'Title', self.context.Title())
        parser.set('DEFAULT', 'Description', self.context.Description())
        stream = StringIO()
        parser.write(stream)

        export_context.writeDataFile(
            '.properties',
            text=stream.getvalue(),
            content_type='text/plain',
            subdir=subdir,
        )

        for id, object in self.context.objectItems():

            adapter = IFilesystemExporter(object, None)

            if adapter is not None:
                adapter.export(export_context, subdir)
Beispiel #39
0
def acquire_field_value(field, container):
    """Acquire a value for a particular field from an object's container or
    its closest ancestor.

    This works similar to Zope's Acquisition, but also supports fields in
    behaviors with AnnotationStorage.

    The strategy for acquiring a field value can be described as follows:

    - Find the closest ancestor that:
        - Supports the field in question (intermediate ancestors that
          don't support the field are skipped)
        - Has a value for the field that validates
    - If no such ancestor can be found, return the NO_VALUE_FOUND sentinel
    """
    if isinstance(container, MetadataBase) or container is None:
        # These are odd cases where we get passed a weird context and can't
        # (or don't want to) acquire an actual value.
        return NO_VALUE_FOUND

    obj = container
    while not ISiteRoot.providedBy(obj):
        try:
            interface_ = field.interface
        except AttributeError:
            pass
        else:
            try:
                adpt = interface_(obj)
            except TypeError:
                # could not adapt
                pass
            else:
                # XXX: Potential for infinite recursion here (Issue #2033)
                value = field.get(adpt)
                try:
                    field.validate(value)
                    return value
                except ValidationError:
                    pass

        obj = obj.aq_inner.aq_parent
    return NO_VALUE_FOUND
Beispiel #40
0
def write_export(obj, data):
    objpath = '/'.join(obj.getPhysicalPath())
    if IFolder.providedBy(obj):
        objpath = os.path.join(objpath, '__folder__')
    else:
        fobj = aq_parent(obj)
        while not ISiteRoot.providedBy(fobj):
            if not os.path.exists(
                    os.path.join('/'.join(fobj.getPhysicalPath()), '__folder__')):  # noqa
                for eobj, edata in export_obj(fobj):
                    write_export(eobj, edata)
            fobj = aq_parent(fobj)
    path = create_path(objpath)
    try:
        fi = open(path, 'w')
        fi.write(dumps(data))
        fi.close()
    except UnicodeDecodeError:
        print('Error exporting {}'.format(objpath))
Beispiel #41
0
    def current_style(self, site_default_style):
        """Returns current stylesheet selection or site default."""

        context = self.context
        while True:

            if ISiteRoot.providedBy(context):
                return site_default_style

            annotations = IAnnotations(context)
            curr_style = annotations.get(STYLESHEET_SELECTED_KEY)

            if curr_style:
                return curr_style

            if curr_style == '':
                return site_default_style

            context = aq_parent(context)
def check_traversal_to_acquired_content(context, request, name, result):
    if is_suspect_acquisition(context, request, name, result):
        logmsg = (
            "when traversing '%s', (%s) is acquired from (%s)" %
            (request.get('ACTUAL_URL'), '/'.join(result.getPhysicalPath()),
             '/'.join(context.getPhysicalPath())))
        referer = request.get('HTTP_REFERER', "none")
        if referer:
            logmsg += ", referred from %s" % referer
        logger.info(logmsg)
        if request['REQUEST_METHOD'] != 'GET':
            logger.info("no redirect because METHOD is '%s'",
                        request.get('REQUEST_METHOD'))
            return
        if ISiteRoot.providedBy(result):
            request.set('IS_SITE_ACQUIRED', True)
        canonical_url = get_canonical_url(request, result.absolute_url())
        # store CANONICAL_URL in order to be able to redirect later in traversal
        request.set('CANONICAL_URL', canonical_url)
 def __call__(self):
     """
     """
     parents_type_list = []
     for item in self.context.aq_chain:
         if item == self.context:
             # skip current context
             continue
         if ISiteRoot.providedBy(item):
             break
         parents_type_list.append(item.portal_type)
     try:
         parent_uid = self.context.aq_parent.UID()
     except AttributeError:
         parent_uid = ""
     return {
         "parents_type_list": parents_type_list,
         "parent_uid": parent_uid,
     }
Beispiel #44
0
    def get_options(self):
        site_url = success_url = self.context.absolute_url()
        if ISiteRoot.providedBy(self.context):
            success_url += '/@@dashboard'
        if 'came_from' in self.request.form:
            came_from = self.request.form['came_from']
            try:
                url_tool = api.portal.get_tool('portal_url')
            except api.exc.CannotGetPortalError:
                url_tool = None
            if (came_from.startswith(site_url)
                    and (not url_tool or url_tool.isURLInPortal(came_from))):
                success_url = came_from

        data = {
            'supportedAuthSchemes': self.get_supported_auth_schemes(),
            'twoFactorEnabled': self.two_factor_enabled,
            'apiEndpoint': '{}/@@secure-login'.format(site_url),
            'successUrl': success_url,
            'additionalProviders': []
        }
        try:
            data['authenticator'] = createToken()
        except ConnectionStateError:
            # zope root related issue here...
            pass

        username = None
        pwreset = self.request.form.get('pwreset') == 'true'
        if pwreset:
            try:
                user = api.user.get(self.request.form.get('userid'))
                username = user.getUserName()
                data.update({
                    'passwordReset': pwreset,
                    'username': username,
                    'code': self.request.form.get('code'),
                    'userid': self.request.form.get('userid')
                })
            except Exception:
                pass
        return data
Beispiel #45
0
 def save(self):
     adapted = ILayoutAware(self.context)
     data = self.request.form.get('data')
     if not data:
         return
     data = json.loads(data)
     adapted.pageSiteLayout = data['page_layout']
     adapted.sectionSiteLayout = data['section_layout']
     parent = aq_parent(self.context)
     if ISiteRoot.providedBy(parent):
         # check if default page...
         if getDefaultPage(parent) == self.context.id:
             # also set site wide global layout setting...
             registry = getUtility(IRegistry)
             field = registry_field.TextLine(title=u'Default layout',
                                             required=False)
             new_record = Record(field)
             registry.records['castle.cms.default_layout'] = new_record
             registry['castle.cms.default_layout'] = data['section_layout']
     return {'success': True}
    def _checkId(self, id, allow_dup=0):
        PortalFolderBase.inheritedAttribute('_checkId')(self, id, allow_dup)

        if allow_dup:
            return

        # FIXME: needed to allow index_html for join code
        if id == 'index_html':
            return

        # Another exception: Must allow "syndication_information" to enable
        # Syndication...
        if id == 'syndication_information':
            return

        # IDs starting with '@@' are reserved for views.
        if id[:2] == '@@':
            raise BadRequest('The id "%s" is invalid because it begins with '
                             '"@@".' % id)

        # This code prevents people other than the portal manager from
        # overriding skinned names and tools.
        if not getSecurityManager().checkPermission(ManagePortal, self):
            ob = aq_inner(self)
            while ob is not None:
                if ISiteRoot.providedBy(ob):
                    break
                ob = aq_parent(ob)

            if ob is not None:
                # If the portal root has a non-contentish object by this name,
                # don't allow an override.
                if (hasattr(ob, id) and
                    id not in ob.contentIds() and
                    # Allow root doted prefixed object name overrides
                    not id.startswith('.')):
                    raise BadRequest('The id "%s" is reserved.' % id)
            # Don't allow ids used by Method Aliases.
            ti = self.getTypeInfo()
            if ti and ti.queryMethodID(id, context=self):
                raise BadRequest('The id "%s" is reserved.' % id)
    def get_results(self, portal_type):
        """Returns results depending on request and the following logic

        Case 1: a folder with a Scheda set as  default view ->
                return scheda contents filtered by content_types

        Case 2: the context is a Scheda ->
                return the contents of Moduli or Riferimenti according
                to the requeste portal type

        Case 3: as a fallback return an empty list
        """
        if ISiteRoot.providedBy(self.context):
            return []
        if self.has_default_view(self.context):
            return self.find_nephews(
                portal_type, self.get_default_view_object(self.context))

        if self.is_scheda(self.context):
            return self.find_nephews(portal_type)
        return []
Beispiel #48
0
    def update(self):
        super(View, self).update()
        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()
        # 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:
                msg = _(
                    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')
                api.portal.show_message(msg, self.request, type='warn')

        if 'poll.submit' in form:
            self._updateForm(form)
        # Update status messages
        for error in self.errors:
            api.portal.show_message(error, self.request, type='warn')
        for msg in self.messages:
            api.portal.show_message(msg, self.request, type='info')
Beispiel #49
0
    def breadcrumbs(self):
        """ Breadcrumbs
        """
        if ISiteRoot.providedBy(self.context):
            return ()

        context = aq_inner(self.context)
        request = self.request
        container = utils.parent(context)

        try:
            name, item_url = get_view_url(context)
        except AttributeError:
            print context
            raise

        if container is None:
            return ({
                'absolute_url': item_url,
                'Title': utils.pretty_title_or_id(context, context),
            }, )

        view = getMultiAdapter((container, request), name='breadcrumbs_view')
        base = tuple(view.breadcrumbs())

        # Some things want to be hidden from the breadcrumbs
        if IHideFromBreadcrumbs.providedBy(context):
            return base

        if base:
            item_url = '%s/%s' % (base[-1]['absolute_url'], name)

        # don't show default pages in breadcrumbs
        if not utils.isDefaultPage(context, request):
            base += ({
                'absolute_url': item_url,
                'Title': utils.pretty_title_or_id(context, context),
            }, )

        return base
Beispiel #50
0
    def get_basic_tags(self):
        try:
            context = self.context
            if ISiteRoot.providedBy(context):
                try:
                    context = context[get_default_page(context)]
                except AttributeError:
                    pass
            tags = {
                'modificationDate': _date(context, 'modified'),
                'publicationDate': _date(context, 'effective'),
                'expirationDate': _date(context, 'expires'),
                'generator': CASTLE_VERSION_STRING,
                "distribution": "Global",
            }
            ldata = ILocation(context, None)
            if ldata is not None:
                if ldata.locations:
                    location = ldata.locations
                    if type(location) in (list, tuple, set):
                        location = location[0]
                    tags['location'] = location

            search = ISearch(context, None)
            if search is not None:
                robot_configuration = self._get_robot_config(search)
                config = robot_configuration[:]
                if 'index' not in config:
                    config.append('noindex')
                if 'follow' not in config:
                    config.append('nofollow')
                tags['robots'] = ','.join(config)

            return ''.join([
                u'<meta name="{}" content="{}">'.format(name, value)
                for name, value in tags.items()
            ])
        except Exception:
            return u''
Beispiel #51
0
    def breadcrumbs(self):
        context = aq_inner(self.context)

        view_utils = Utils(self.context, self.request)

        crumbs = []
        while context is not None:
            if ISiteRoot.providedBy(context):
                break

            try:
                if utils.isDefaultPage(context, self.request):
                    context = utils.parent(context)
                    continue
            except AttributeError:
                break

            # Some things want to be hidden from the breadcrumbs
            if IHideFromBreadcrumbs.providedBy(context):
                context = utils.parent(context)
                continue

            item_url = view_utils.get_object_url(context)
            try:
                state = api.content.get_state(obj=context)
            except WorkflowException:
                state = None
            label = getattr(context, 'navigation_label', None)
            if not label:
                label = utils.pretty_title_or_id(context, context)
            crumbs.append({
                'absolute_url': item_url,
                'Title': label,
                'state': state
            })
            context = utils.parent(context)

        return list(reversed(crumbs))
Beispiel #52
0
    def validate(self, value):
        super(IntGreaterEqualThanParentValidator, self).validate(value)

        # should not be negative
        if int(value) < 0:
            raise schema.interfaces.TooSmall()

        # get parent value
        #XXX CHANGED FROM PATH_TRANSLATED TO PATH_INFO because the test
        # don't work
        if '++add++' in self.request.get('PATH_INFO', object()):
            obj = self.context
        else:
            obj = self.context.aq_inner.aq_parent

        parent_value = -1
        while parent_value < 0 and not ISiteRoot.providedBy(obj):
            cf_obj = queryAdapter(obj, ILifeCycle)

            if cf_obj:
                try:
                    parent_value = int(self.field.get(cf_obj))
                except AttributeError:
                    pass
                except TypeError:
                    parent_value = 0

            try:
                obj = obj.aq_inner.aq_parent

            except AttributeError:
                return

        # should not be smaller than parent
        if parent_value > -1 and int(value) < parent_value:
            raise schema.interfaces.TooBig()
Beispiel #53
0
        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

            """

            assert context is not None

            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')
                if parent:
                    log.info('Parent is not translatable: %s' %
                             parent.absolute_url())
                else:
                    log.error(
                        'Cannot translate language: %s, no parent for %s' %
                        (language, context.absolute_url()))

                return False

            translation = translatable.getTranslation(language)

            return translation is not None
Beispiel #54
0
def add_leadimage_from_file(container,
                            file_name,
                            folder_name='data',
                            image_field='image'):
    """Add leadimage from a file from a folder"""
    if not container:
        container = api.portal.get()
    data_path = os.path.join(os.path.dirname(__file__), folder_name)
    file_path = os.path.join(data_path, file_name)
    if not getattr(aq_base(container), file_name, False):
        namedblobimage = NamedBlobImage(data=open(file_path, 'r').read(),
                                        filename=unicode(file_name))
        image_container = container
        if not INavigationRoot.providedBy(container) and \
                not ISiteRoot.providedBy(container):
            image_container = container.aq_parent

        image = api.content.create(type='Image',
                                   title=file_name,
                                   image=namedblobimage,
                                   container=image_container)
        image.setTitle(file_name)
        image.reindexObject()
        setattr(container, image_field, namedblobimage)
Beispiel #55
0
def log_deleted(context, event):
    if ISiteRoot.providedBy(event.object):
        return
    ModificationLogger().deleted(context)
Beispiel #56
0
 def buildAjaxViewName(self):
     "根据当前上下文,构建ajax view 名称"
     context = aq_inner(self.context)
     if ISiteRoot.providedBy(context): return "oajaxsearch"
     else: return "xiangtanshisearch"
Beispiel #57
0
 def sliderobject(self):
     for item in self.context.aq_chain:
         if ISliderPage.providedBy(item):
             return item
         if ISiteRoot.providedBy(item):
             return None
Beispiel #58
0
    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')
        plone_livesearch = props.site_properties.getProperty(
            'enable_livesearch', False)
        livesearch = props.site_properties.getProperty(
            'enable_tinymce_livesearch', plone_livesearch)
        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"
        plone_view = context.restrictedTraverse('@@plone')
        template = None
        if IBrowserDefault.providedBy(context):
            template = context.unrestrictedTraverse(context.getLayout())
        results['body_class'] += ' ' + plone_view.bodyClass(template, template)

        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
Beispiel #59
0
    def import_ala_data(self):
        if self.request.get('REQUEST_METHOD', 'GET').upper() != 'POST':
            self.record_error('Request must be POST', 400)
            raise BadRequest('Request must be POST')

        context = None
        # get import context
        if ISiteRoot.providedBy(self.context):
            # we have been called at site root... let's traverse to default
            # import location
            context = self.context.restrictedTraverse("/".join(
                (defaults.DATASETS_FOLDER_ID,
                 defaults.DATASETS_SPECIES_FOLDER_ID, 'ala')))
        else:
            # custom context.... let's use in
            context = self.context
        # do user check first
        member = ploneapi.user.get_current()
        if member.getId():
            user = {
                'id': member.getUserName(),
                'email': member.getProperty('email'),
                'fullname': member.getProperty('fullname')
            }
        else:
            # We need at least a valid user
            raise Unauthorized("Invalid user")
        # check permission
        if not checkPermission('org.bccvl.AddDataset', context):
            raise Unauthorized("User not allowed in this context")

        params = self.request.form.get('data')

        if not params:
            raise BadRequest("At least on of traits or environ has to be set")

        if params is None:
            self.record_error('Bad Request', 400, 'Missing parameter data',
                              {'parameter': 'data'})
        if not params:
            self.record_error('Bad Request', 400, 'Empty parameter data',
                              {'parameter': 'data'})
        # TODO: should validate objects inside as well? (or use json schema
        # validation?)

        # all good so far
        # pull dataset from aekos
        # TODO: get better name here
        title = params[0].get('name', 'ALA import')
        # determine dataset type
        # 1. test if it is a multi species import
        species = set()
        for query in params:
            biocache_url = '{}/occurrences/search'.format(query['url'])
            query = {
                'q': query['query'],
                'pageSize': 0,
                'limit': 2,
                'facets': 'species_guid',
                'fq': 'species_guid:*'  # skip results without species guid
            }
            res = requests.get(biocache_url, params=query)
            res = res.json()
            # FIXME: do we need to treat sandbox downloads differently?
            if res.get('facetResults'):  # do we have some results at all?
                for guid in res['facetResults'][0]['fieldResult']:
                    species.add(guid['label'])
        if len(species) > 1:
            portal_type = 'org.bccvl.content.multispeciesdataset'

        else:
            portal_type = 'org.bccvl.content.dataset'
            swiftsettings = getUtility(IRegistry).forInterface(ISwiftSettings)
            if swiftsettings.storage_url:
                portal_type = 'org.bccvl.content.remotedataset'
        # create content
        ds = createContent(portal_type, title=title)
        ds.dataSource = 'ala'
        ds.description = u' '.join([title, u' imported from ALA'])
        ds.import_params = params
        ds = addContentToContainer(context, ds)
        md = IBCCVLMetadata(ds)
        if IMultiSpeciesDataset.providedBy(ds):
            md['genre'] = 'DataGenreSpeciesCollection'
            md['categories'] = ['multispecies']
        else:
            # species dataset
            md['genre'] = 'DataGenreSpeciesOccurrence'
            md['categories'] = ['occurrence']
        # TODO: populate this correctly as well
        md['species'] = [{'scientificName': 'qid', 'taxonID': 'qid'}]
        # FIXME: IStatusMessage should not be in API call
        from Products.statusmessages.interfaces import IStatusMessage
        IStatusMessage(self.request).add('New Dataset created', type='info')
        # start import job
        jt = IExperimentJobTracker(ds)
        status, message = jt.start_job()
        # reindex ojebct to make sure everything is up to date
        ds.reindexObject()
        # FIXME: IStatutsMessage should not be in API call
        IStatusMessage(self.request).add(message, type=status)

        # FIXME: API should not return a redirect
        #        201: new resource created ... location may point to resource
        from Products.CMFCore.utils import getToolByName
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        nexturl = portal[defaults.DATASETS_FOLDER_ID].absolute_url()
        self.request.response.setStatus(201)
        self.request.response.setHeader('Location', nexturl)
        # FIXME: should return a nice json representation of success or error
        return {
            'status': status,
            'message': message,
            'jobid': IJobTracker(ds).get_job().id
        }
Beispiel #60
0
    def import_trait_data(self):
        if self.request.get('REQUEST_METHOD', 'GET').upper() != 'POST':
            self.record_error('Request must be POST', 400)
            raise BadRequest('Request must be POST')

        source = self.request.form.get('source', None)
        species = self.request.form.get('species', None)
        traits = self.request.form.get('traits', None)
        environ = self.request.form.get('environ', None)
        dataurl = self.request.form.get('url', None)
        context = None

        if not source or source not in ('aekos', 'zoatrack'):
            raise BadRequest("source parameter must be 'aekos' or 'zoatrack'")

        # get import context
        if ISiteRoot.providedBy(self.context):
            # we have been called at site root... let's traverse to default
            # import location
            context = self.context.restrictedTraverse("/".join(
                (defaults.DATASETS_FOLDER_ID,
                 defaults.DATASETS_SPECIES_FOLDER_ID, str(source))))
        else:
            # custom context.... let's use in
            context = self.context
        # do user check first
        member = ploneapi.user.get_current()
        if member.getId():
            user = {
                'id': member.getUserName(),
                'email': member.getProperty('email'),
                'fullname': member.getProperty('fullname')
            }
        else:
            # We need at least a valid user
            raise Unauthorized("Invalid user")
        # check permission
        if not checkPermission('org.bccvl.AddDataset', context):
            raise Unauthorized("User not allowed in this context")

        # check parameters
        if not species or not isinstance(species, (basestring, list)):
            raise BadRequest("Missing or invalid species parameter")
        elif isinstance(species, basestring):
            species = [species]

        # for zoatrack, url needs to be set
        if source == 'zoatrack' and not dataurl:
            raise BadRequest("url has to be set")
        # for aekos, at least a trait or environment variable must be specified.
        if source == 'aekos' and not traits and not environ:
            raise BadRequest(
                "At least a trait or environent variable has to be set")
        if not traits:
            traits = []
        elif isinstance(traits, basestring):
            traits = [traits]
        if not environ:
            environ = []
        elif isinstance(environ, basestring):
            environ = [environ]

        # all good so far
        # pull dataset from aekos
        title = ' '.join(species)
        # determine dataset type
        portal_type = 'org.bccvl.content.dataset'
        swiftsettings = getUtility(IRegistry).forInterface(ISwiftSettings)
        if swiftsettings.storage_url:
            portal_type = 'org.bccvl.content.remotedataset'
        # create content
        ds = createContent(portal_type, title=title)
        ds.dataSource = source
        ds.description = u' '.join([
            title, ','.join(traits), ','.join(environ),
            u' imported from {}'.format(source.upper())
        ])
        ds = addContentToContainer(context, ds)
        md = IBCCVLMetadata(ds)
        md['genre'] = 'DataGenreTraits'
        md['categories'] = ['traits']
        md['species'] = [{
            'scientificName': spec,
            'taxonID': spec
        } for spec in species]
        md['traits'] = traits
        md['environ'] = environ
        md['dataurl'] = dataurl
        # FIXME: IStatusMessage should not be in API call
        from Products.statusmessages.interfaces import IStatusMessage
        IStatusMessage(self.request).add('New Dataset created', type='info')
        # start import job
        jt = IExperimentJobTracker(ds)
        status, message = jt.start_job()
        # reindex ojebct to make sure everything is up to date
        ds.reindexObject()
        # FIXME: IStatutsMessage should not be in API call
        IStatusMessage(self.request).add(message, type=status)

        # FIXME: API should not return a redirect
        #        201: new resource created ... location may point to resource
        from Products.CMFCore.utils import getToolByName
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        nexturl = portal[defaults.DATASETS_FOLDER_ID].absolute_url()
        self.request.response.setStatus(201)
        self.request.response.setHeader('Location', nexturl)
        # FIXME: should return a nice json representation of success or error
        return {
            'status': status,
            'message': message,
            'jobid': IJobTracker(ds).get_job().id
        }