Пример #1
0
    def testMigrateStaticTextPortlets(self):
        class HiddenAssignment(static.Assignment):
            hide = True

        self.setRoles(["Manager"])
        self.portal.invokeFactory('Folder', id="statictest")
        folder = self.portal['statictest']

        manager = getUtility(
                IPortletManager, name='plone.rightcolumn',
                context=folder)
        assignments = getMultiAdapter(
                (folder, manager), IPortletAssignmentMapping)
        hidden_portlet = HiddenAssignment()
        visible_portlet = static.Assignment()
        assignments['hidden'] = hidden_portlet
        assignments['visible'] = visible_portlet

        migrateStaticTextPortlets(self.portal)

        self.assertFalse(
                IPortletAssignmentSettings(hidden_portlet).get(
                        'visible', True))
        self.assertTrue(
                IPortletAssignmentSettings(visible_portlet).get(
                        'visible', True))
    def test_portlet_visibility_settings(self):
        assignment = self.layer['right_portlets'].get('title2', False)
        settings = PersistentMapping({'visible': False})
        IPortletAssignmentSettings(assignment).data = settings

        # get the data
        adapter = getAdapter(self.layer['folder1'],
                             IDataCollector,
                             name="portlet_data_adapter")

        data = adapter.getData()
        jsondata = json.dumps(utils.decode_for_json(data))
        data = utils.encode_after_json(json.loads(jsondata))

        self.assertEqual(settings,
                         data['plone.rightcolumn']['title2']['settings'])

        # set the data
        adapter2 = getAdapter(self.layer['folder2'],
                              IDataCollector,
                              name="portlet_data_adapter")
        adapter2.setData(data, metadata=None)

        new_assignment = self.layer['right_portlets'].get('title2', False)
        self.assertEqual(settings,
                         IPortletAssignmentSettings(new_assignment).data)
Пример #3
0
    def testAssignmentSettings(self):
        mapping = assignment_mapping_from_key(self.portal,
            manager_name=u"test.testcolumn", category=CONTEXT_CATEGORY, key="/")
        assignment = mapping['test.portlet1']
        settings = IPortletAssignmentSettings(assignment)
        self.assertTrue(settings.get('visible', True))

        assignment = mapping['test.portlet2']
        settings = IPortletAssignmentSettings(assignment)
        self.assertFalse(settings.get('visible', True))
Пример #4
0
def extract_mapping(manager_name, category, key, mapping):
    portlets_schemata = dict([
        (iface, name) for name, iface in getUtilitiesFor(IPortletTypeInterface)
    ])

    for name, assignment in mapping.items():
        type_ = None
        schema = None
        for schema in providedBy(assignment).flattened():
            type_ = portlets_schemata.get(schema, None)
            if type_ is not None:
                break

        if type_ is not None:
            child = PrettyDocument().createElement('assignment')
            child.setAttribute('manager', manager_name)
            child.setAttribute('category', category)
            child.setAttribute('key', key)
            child.setAttribute('type', type_)
            child.setAttribute('name', name)

            assignment = assignment.__of__(mapping)

            settings = IPortletAssignmentSettings(assignment)
            visible = settings.get('visible', True)
            child.setAttribute('visible', repr(visible))

            handler = IPortletAssignmentExportImportHandler(assignment)
            handler.export_assignment(schema, PrettyDocument(), child)

            yield child
Пример #5
0
        def extractMapping(manager_name, category, key, mapping):
            for name, assignment in mapping.items():
                type_ = None
                for schema in providedBy(assignment).flattened():
                    type_ = portletSchemata.get(schema, None)
                    if type_ is not None:
                        break

                if type_ is not None:
                    child = self._doc.createElement('assignment')
                    child.setAttribute('manager', manager_name)
                    child.setAttribute('category', category)
                    child.setAttribute('key', key)
                    child.setAttribute('type', type_)
                    child.setAttribute('name', name)

                    assignment = assignment.__of__(mapping)

                    settings = IPortletAssignmentSettings(assignment)
                    visible = settings.get('visible', True)
                    child.setAttribute('visible', repr(visible))

                    handler = IPortletAssignmentExportImportHandler(assignment)
                    handler.export_assignment(schema, self._doc, child)
                    fragment.appendChild(child)
Пример #6
0
    def getPortlets(self):
        if IPortletContext.providedBy(self.context):
            pcontext = self.context
        else:
            pcontext = queryAdapter(self.context, IPortletContext)

        if pcontext is None:
            return []

        assignments = []
        for category, key in pcontext.globalPortletCategories(True):
            mapping = self.storage.get(category, None)
            if mapping is not None:
                for assignment in mapping.get(key, {}).values():
                    try:
                        settings = IPortletAssignmentSettings(assignment)
                    except TypeError:
                        # Portlet does not exist any longer
                        continue
                    else:
                        if not settings.get('visible', True):
                            continue

                    assignments.append({'category': category,
                                        'key': key,
                                        'name': assignment.__name__,
                                        'assignment': assignment
                                        })

        return assignments
Пример #7
0
 def toggle_visibility(self, name):
     self.authorize()
     assignments = aq_inner(self.context)
     settings = IPortletAssignmentSettings(assignments[name])
     visible = settings.get('visible', True)
     settings['visible'] = not visible
     return self.finish_portlet_change()
Пример #8
0
    def global_portlets(self, category, prefix):
        """ Return the list of global portlets from a given category for the current context.

        Invisible (hidden) portlets are excluded.

        """
        context = aq_inner(self.context)

        # get the portlet context
        pcontext = IPortletContext(self.context)

        portal_state = getMultiAdapter((context, self.request),
                                       name=u'plone_portal_state')  # noqa
        base_url = portal_state.portal_url()

        portlets = []
        for cat, key in pcontext.globalPortletCategories(False):
            if cat == category:
                mapping = self.manager.get(category, None)
                assignments = []
                if mapping is not None:
                    is_visible = lambda a: IPortletAssignmentSettings(a).get(
                        'visible', True)  # noqa
                    assignments.extend([
                        a for a in mapping.get(key, {}).values()
                        if is_visible(a)
                    ])
                if assignments:
                    edit_url = '%s/++%s++%s+%s' % (base_url, prefix,
                                                   self.manager.__name__, key)
                    portlets.extend(
                        self.portlets_for_assignments(assignments,
                                                      self.manager, edit_url))

        return portlets
Пример #9
0
def _lazyLoadPortlets(self, manager):
    retriever = getMultiAdapter((self.context, manager), IPortletRetriever)
    items = []
    for p in self.filter(retriever.getPortlets()):
        renderer = self._dataToPortlet(p['assignment'].data)
        info = p.copy()
        info['manager'] = self.manager.__name__
        info['renderer'] = renderer
        hashPortletInfo(info)
        # Record metadata on the renderer
        renderer.__portlet_metadata__ = info.copy()
        del renderer.__portlet_metadata__['renderer']
        try:
            isAvailable = renderer.available
        except ConflictError:
            raise
        except Exception, e:
            isAvailable = False
            logger.exception(
                "Error while determining renderer availability of portlet "
                "(%r %r %r): %s" %
                (p['category'], p['key'], p['name'], str(e)))

        info['available'] = isAvailable

        assignments = info['assignment'].__parent__
        settings = IPortletAssignmentSettings(assignments[info['name']])
        info['settings'] = settings

        items.append(info)
Пример #10
0
    def test_invoke_edit_form(self):
        mapping = PortletAssignmentMapping()
        request = self.folder.REQUEST

        mapping['foo'] = news.Assignment(count=5)
        editview = getMultiAdapter((mapping['foo'], request), name='edit')
        editview.update()
        editview.applyChanges(data={
            'count': 6,
            EXTENDER_PREFIX + '.css_class': 'my-class'
        })
        portlet_assignment = mapping.values()[0]
        settings = IPortletAssignmentSettings(portlet_assignment)

        self.assertEqual(portlet_assignment.count, 6)
        # We have not extended our storage adapter, so nothing gets saved:
        self.assertIsNone(settings.get('css_class', None))

        # Register our schemaextender
        gsm = getGlobalSiteManager()
        gsm.registerAdapter(PortletCssClassAdapter, (IPortletAssignment, ))
        gsm.registerAdapter(
            PortletCssClassFormExtender,
            (Interface, IDefaultBrowserLayer, IPortletEditForm), IFormExtender,
            'portletcssclass.extender')
        mapping = PortletAssignmentMapping()
        request = self.folder.REQUEST

        mapping['foo'] = news.Assignment(count=5)
        editview = getMultiAdapter((mapping['foo'], request), name='edit')
        editview.update()
        editview.applyChanges(data={
            'count': 6,
            EXTENDER_PREFIX + '.css_class': 'my-class'
        })
        portlet_assignment = mapping.values()[0]
        settings = IPortletAssignmentSettings(portlet_assignment)

        gsm.unregisterAdapter(
            PortletCssClassFormExtender,
            (Interface, IDefaultBrowserLayer, IPortletEditForm), IFormExtender,
            'portletcssclass.extender')
        gsm.unregisterAdapter(PortletCssClassAdapter, (IPortletAssignment, ))

        self.assertEqual(portlet_assignment.count, 6)
        # The prefix is used for the form field, not for the stored data:
        self.assertEqual(settings.get('css_class'), 'my-class')
Пример #11
0
    def test_invoke_add_form(self):
        portlet = getUtility(IPortletType, name='portlets.News')
        mapping = self.portal.restrictedTraverse(
            '++contextportlets++plone.leftcolumn')
        for m in mapping.keys():
            del mapping[m]
        addview = mapping.restrictedTraverse('+/' + portlet.addview)
        addview.update()
        addview.createAndAdd(data={
            'count': 5,
            EXTENDER_PREFIX + '.css_class': 'my-class'
        })
        portlet_assignment = mapping.values()[0]
        settings = IPortletAssignmentSettings(portlet_assignment)

        self.assertEqual(portlet_assignment.count, 5)
        # We have not extended our storage adapter, so nothing gets saved:
        self.assertIsNone(settings.get('css_class', None))

        # Register our schemaextender
        gsm = getGlobalSiteManager()
        gsm.registerAdapter(PortletCssClassAdapter, (IPortletAssignment, ))
        gsm.registerAdapter(PortletCssClassFormExtender,
                            (Interface, IDefaultBrowserLayer, IPortletAddForm),
                            IFormExtender, 'portletcssclass.extender')
        for m in mapping.keys():
            del mapping[m]
        addview = mapping.restrictedTraverse('+/' + portlet.addview)
        addview.update()
        addview.createAndAdd(data={
            'count': 5,
            EXTENDER_PREFIX + '.css_class': 'my-class'
        })
        portlet_assignment = mapping.values()[0]
        settings = IPortletAssignmentSettings(portlet_assignment)

        gsm.unregisterAdapter(
            PortletCssClassFormExtender,
            (Interface, IDefaultBrowserLayer, IPortletAddForm), IFormExtender,
            'portletcssclass.extender')
        gsm.unregisterAdapter(PortletCssClassAdapter, (IPortletAssignment, ))

        self.assertEqual(portlet_assignment.count, 5)
        # The prefix is used for the form field, not for the stored data:
        self.assertEqual(settings.get('css_class'), 'my-class')
Пример #12
0
    def panels_for_assignments(self, assignments, manager, base_url):
        # todo: do we use a special cat for panels?
        category = self.__parent__.category
        key = self.__parent__.key

        data = []
        for idx in range(len(assignments)):
            name = assignments[idx].__name__
            if hasattr(assignments[idx], '__Broken_state__'):
                name = assignments[idx].__Broken_state__['__name__']

            # Todo: we can define an edit view for panels - for overlay etc. - IF needed...
            editview = queryMultiAdapter((assignments[idx], self.request),
                                         name='edit',
                                         default=None)

            if editview is None:
                editviewName = ''
            else:
                editviewName = '%s/%s/edit' % (base_url, name)

            panel_hash = hashPortletInfo(
                dict(
                    manager=manager.__name__,
                    category=category,
                    key=key,
                    name=name,
                ))

            try:
                settings = IPortletAssignmentSettings(assignments[idx])
                visible = settings.get('visible', True)
            except TypeError:
                visible = False

            data.append({
                'title': assignments[idx].title,
                'editview': editviewName,
                'hash': panel_hash,
                'name': name,
                'up_url': '%s/@@move-panel-up' % (base_url),
                'down_url': '%s/@@move-panel-down' % (base_url),
                'delete_url': '%s/@@delete-panel' % (base_url),
                'duplicate_url': '%s/@@duplicate-panel' % (base_url),
                'hide_url': '%s/@@toggle-visibility' % (base_url),
                'show_url': '%s/@@toggle-visibility' % (base_url),
                'visible': visible,
                'has_assignments': len(assignments[idx]),
            })
        if len(data) > 0:
            data[0]['up_url'] = data[-1]['down_url'] = None

        return data
Пример #13
0
def portlets_for_assignments(self, assignments, manager, base_url):
    category = self.__parent__.category
    key = self.__parent__.key

    data = []
    for idx in range(len(assignments)):
        name = assignments[idx].__name__
        if hasattr(assignments[idx], '__Broken_state__'):
            name = assignments[idx].__Broken_state__['__name__']

        editview = queryMultiAdapter((assignments[idx], self.request),
                                     name='edit',
                                     default=None)

        if editview is None:
            editviewName = ''
        else:
            editviewName = '%s/%s/edit' % (base_url, name)

        settingsviewName = '%s/%s/edit-portlet-metadata' % (base_url, name)

        portlet_hash = hashPortletInfo(
            dict(
                manager=manager.__name__,
                category=category,
                key=key,
                name=name,
            ))

        try:
            settings = IPortletAssignmentSettings(assignments[idx])
            visible = settings.get('visible', True)
        except TypeError:
            visible = False

        data.append({
            'title': assignments[idx].title,
            'editview': editviewName,
            'hash': portlet_hash,
            'name': name,
            'up_url': '%s/@@move-portlet-up' % base_url,
            'down_url': '%s/@@move-portlet-down' % base_url,
            'delete_url': '%s/@@delete-portlet' % base_url,
            'metadata_url': settingsviewName,
            'hide_url': '%s/@@toggle-visibility' % base_url,
            'show_url': '%s/@@toggle-visibility' % base_url,
            'visible': visible,
        })
    if len(data) > 0:
        data[0]['up_url'] = data[-1]['down_url'] = None

    return data
Пример #14
0
    def __call__(self):
        # The parent object is the Plone content object here; we get
        # it from the acquisition chain.
        parent = self.context.aq_inner.aq_parent.aq_parent
        panel = self.context

        portlets = []
        for assignment in panel:
            settings = IPortletAssignmentSettings(assignment)
            if not settings.get('visible', True):
                continue

            try:
                portlet = getMultiAdapter(
                    (parent, self.request, self, panel, assignment),
                    IPortletRenderer)
            except ComponentLookupError:
                logging.getLogger("panels").info(
                    "unable to look up renderer for '%s.%s'." %
                    (assignment.__class__.__module__,
                     assignment.__class__.__name__))
                continue

            info = {
                'manager': "panels",
                'category': CONTEXT_CATEGORY,
                'key': '/'.join(panel.getPhysicalPath()),
                'name': assignment.__name__,
                'renderer': portlet,
                'settings': settings,
                'assignment': assignment
            }

            hashPortletInfo(info)

            portlet.update()

            try:
                available = portlet.available
            except Exception as e:
                logging.getLogger('panels').info(
                    "available threw an exception for %s (%s %s)" %
                    (assignment.__name__, type(e), str(e)))
                continue

            if available:
                result = self.portlet(**info)
                portlets.append(result)

        return render(portlets, self.context.layout, self.request)
Пример #15
0
 def migrate_portlets_for_object(obj, path):
     portlet_managers = getUtilitiesFor(IPortletManager, context=obj)
     for portlet_manager_name, portlet_manager in portlet_managers:
         assignments = queryMultiAdapter(
             (obj, portlet_manager), IPortletAssignmentMapping, context=obj)
         if assignments is None:
             continue
         for portlet_id, portlet in assignments.items():
             if IStaticPortlet.providedBy(portlet) and \
                     getattr(portlet, 'hide', False):
                 logger.info(
                     'Found hidden static text portlet %s at %s' %
                     (portlet_id, path))
                 settings = IPortletAssignmentSettings(portlet)
                 settings['visible'] = False
def export_local_portlets(obj):
    """Serialize portlets for one content object
    Code mostly taken from https://github.com/plone/plone.restapi/pull/669
    """
    portlets_schemata = {
        iface: name
        for name, iface in getUtilitiesFor(IPortletTypeInterface)
    }
    items = {}
    for manager_name, manager in getUtilitiesFor(IPortletManager):
        mapping = queryMultiAdapter((obj, manager), IPortletAssignmentMapping)
        if mapping is None:
            continue
        mapping = mapping.__of__(obj)
        for name, assignment in mapping.items():
            portlet_type = None
            schema = None
            for schema in providedBy(assignment).flattened():
                portlet_type = portlets_schemata.get(schema, None)
                if portlet_type is not None:
                    break
            if portlet_type is None:
                continue
            assignment = assignment.__of__(mapping)
            settings = IPortletAssignmentSettings(assignment)
            if manager_name not in items:
                items[manager_name] = []
            values = {}
            for name in schema.names():
                value = getattr(assignment, name, None)
                if RelationValue is not None and isinstance(
                        value, RelationValue):
                    value = value.to_object.UID()
                elif isinstance(value, RichTextValue):
                    value = {
                        "data": json_compatible(value.raw),
                        "content-type": json_compatible(value.mimeType),
                        "encoding": json_compatible(value.encoding),
                    }
                value = json_compatible(value)
                values[name] = value
            items[manager_name].append({
                "type": portlet_type,
                "visible": settings.get("visible", True),
                "assignment": values,
            })
    return items
Пример #17
0
    def getPortlets(self):
        """Work out which portlets to display, returning a list of dicts
        describing assignments to render.
        """
        manager = self.storage.__name__

        pcontext = IPortletContext(self.context, None)
        if pcontext is None:
            return []

        assignable = ILocalPortletAssignable(self.context, None)
        if assignable is None:
            return []

        annotations = IAnnotations(assignable, None)
        if annotations is None:
            return []

        local = annotations.get(CONTEXT_ASSIGNMENT_KEY, None)
        if local is None:
            return []

        localManager = local.get(manager, None)
        if localManager is None:
            return []

        assignments = []
        for assignment in localManager.values():
            try:
                settings = IPortletAssignmentSettings(assignment)
            except TypeError:
                # Portlet does not exist any longer
                continue
            if not settings.get('visible', True):
                continue
            assignments.append(assignment)

        return [{
            'category': CONTEXT_CATEGORY,
            'key': pcontext.uid,
            'name': a.__name__,
            'assignment': a
        } for a in assignments]
Пример #18
0
 def get_portlets(self):
     portlets_schemata = {
         iface: name
         for name, iface in getUtilitiesFor(IPortletTypeInterface)
     }
     portlets = {}
     for manager_name, manager in getUtilitiesFor(IPortletManager):
         mapping = queryMultiAdapter(
             (self.context, manager), IPortletAssignmentMapping
         )
         if mapping is None:
             continue
         mapping = mapping.__of__(self.context)
         for name, assignment in mapping.items():
             type_ = None
             schema = None
             for schema in providedBy(assignment).flattened():
                 type_ = portlets_schemata.get(schema, None)
                 if type_ is not None:
                     break
             if type_ is None:
                 continue
             assignment = assignment.__of__(mapping)
             settings = IPortletAssignmentSettings(assignment)
             if manager_name not in portlets:
                 portlets[manager_name] = []
             title = getattr(assignment, "title", "") or getattr(
                 assignment, "header", ""
             )
             portlets[manager_name].append(
                 {
                     "type": type_,
                     "title": title,
                     "visible": settings.get("visible", True),
                     "assignment": {
                         name: getattr(assignment, name, None)
                         for name in schema.names()
                     },
                 }
             )
     self["portlets"] = portlets
Пример #19
0
    def exportAssignments(self, obj):
        assignments = []
        for manager_name, manager in self.portlet_managers:
            mapping = queryMultiAdapter((obj, manager),
                                        IPortletAssignmentMapping)
            if mapping is None:
                continue

            mapping = mapping.__of__(obj)
            if len(mapping.items()) > 0:
                for name, assignment in mapping.items():
                    type_ = None
                    for schema in providedBy(assignment).flattened():
                        type_ = self.portlet_schemata.get(schema, None)
                        if type_ is not None:
                            break

                    if type_ is not None:
                        child = self.doc.createElement('assignment')
                        child.setAttribute('manager', manager_name)
                        child.setAttribute('category', CONTEXT_CATEGORY)
                        child.setAttribute('key',
                                           '/'.join(obj.getPhysicalPath()))
                        child.setAttribute('type', type_)
                        child.setAttribute('name', name)
                        settings = IPortletAssignmentSettings(assignment)
                        if not settings.get('visible', True):
                            child.setAttribute('visible', 'False')

                        assignment = assignment.__of__(mapping)
                        # use existing adapter for exporting a portlet assignment  # noqa
                        handler = IPortletAssignmentExportImportHandler(
                            assignment)  # noqa
                        handler.export_assignment(schema, self.doc, child)

                        assignments.append(child)

        return assignments
Пример #20
0
    def _initAssignmentNode(self, node):
        """Create an assignment from a node
        """
        site = self.environ.getSite()

        # 1. Determine the assignment mapping and the name
        manager = node.getAttribute('manager')
        category = node.getAttribute('category')
        key = node.getAttribute('key')
        # convert unicode to str as unicode paths are not allowed in
        # restrictedTraverse called in assignment_mapping_from_key
        if six.PY2:
            key = key.encode()

        purge = False
        if node.hasAttribute('purge'):
            purge = self._convertToBoolean(node.getAttribute('purge'))

        mapping = assignment_mapping_from_key(site,
                                              manager,
                                              category,
                                              key,
                                              create=True)

        # 2. Either find or create the assignment

        assignment = None
        name = node.getAttribute('name')
        if name:
            name = str(name)
            assignment = mapping.get(name, None)

        __traceback_info__ = "Assignment name: " + name

        if node.hasAttribute('remove'):
            if assignment is not None:
                del mapping[name]
            return

        if purge:
            for portlet in mapping.keys():
                del mapping[portlet]
            return

        type_ = str(node.getAttribute('type'))

        if assignment is None:
            portlet_factory = getUtility(IFactory, name=type_)
            assignment = portlet_factory()

            if not name:
                chooser = INameChooser(mapping)
                name = chooser.chooseName(None, assignment)

            mapping[name] = assignment

        # aq-wrap it so that complex fields will work
        assignment = assignment.__of__(site)

        # set visibility setting
        visible = node.getAttribute('visible')
        if visible:
            settings = IPortletAssignmentSettings(assignment)
            settings['visible'] = self._convertToBoolean(visible)

        # 3. Use an adapter to update the portlet settings

        portlet_interface = getUtility(IPortletTypeInterface, name=type_)
        assignment_handler = IPortletAssignmentExportImportHandler(assignment)
        assignment_handler.import_assignment(portlet_interface, node)

        # 4. Handle ordering

        insert_before = node.getAttribute('insert-before')
        if insert_before:
            position = None
            keys = list(mapping.keys())

            if insert_before == "*":
                position = 0
            elif insert_before in keys:
                position = keys.index(insert_before)

            if position is not None:
                keys.remove(name)
                keys.insert(position, name)
                mapping.updateOrder(keys)
Пример #21
0
def register_portlets(obj, item):
    """Register portlets fror one object
    Code adapted from plone.app.portlets.exportimport.portlets.PortletsXMLAdapter
    Work in progress...
    """
    site = api.portal.get()
    request = getRequest()
    results = 0
    for manager_name, portlets in item.get("portlets", {}).items():
        manager = getUtility(IPortletManager, manager_name)
        mapping = queryMultiAdapter((obj, manager), IPortletAssignmentMapping)
        namechooser = INameChooser(mapping)

        for portlet_data in portlets:
            # 1. Create the assignment
            assignment_data = portlet_data["assignment"]
            portlet_type = portlet_data["type"]
            portlet_factory = getUtility(IFactory, name=portlet_type)
            assignment = portlet_factory()

            name = namechooser.chooseName(None, assignment)
            mapping[name] = assignment
            logger.info("Added portlet {} to {}".format(
                name, obj.absolute_url()))

            # aq-wrap it so that complex fields will work
            assignment = assignment.__of__(site)

            # set visibility setting
            visible = portlet_data.get("visible")
            if visible:
                settings = IPortletAssignmentSettings(assignment)
                settings["visible"] = visible

            # 2. Apply portlet settings
            portlet_interface = getUtility(IPortletTypeInterface,
                                           name=portlet_type)
            for property_name, value in assignment_data.items():
                field = portlet_interface.get(property_name, None)
                if field is None:
                    continue
                field = field.bind(assignment)
                # deserialize data (e.g. for RichText)
                deserializer = queryMultiAdapter((field, obj, request),
                                                 IFieldDeserializer)
                if deserializer is not None:
                    try:
                        value = deserializer(value)
                    except Exception as e:
                        logger.info(
                            u"Could not import portlet data {} for field {} on {}: {}"
                            .format(value, field, obj.absolute_url(), str(e)))
                        continue
                field.set(assignment, value)

            results += 1

    for blacklist_status in item.get("blacklist_status", []):
        status = blacklist_status["status"]
        manager_name = blacklist_status["manager"]
        category = blacklist_status["category"]
        manager = getUtility(IPortletManager, manager_name)
        assignable = queryMultiAdapter((obj, manager),
                                       ILocalPortletAssignmentManager)
        if status.lower() == "block":
            assignable.setBlacklistStatus(category, True)
        elif status.lower() == "show":
            assignable.setBlacklistStatus(category, False)

    return results
Пример #22
0
    def setData(self, portletsdata, metadata):
        """create or updates portlet informations
        """

        for manager_name in portletsdata.keys():
            column = queryUtility(IPortletManager,
                                  name=manager_name,
                                  context=self.object)
            if column is None:
                continue
            # ok we have a portlet manager
            # get all current assigned portlets
            portlets = getMultiAdapter((
                self.object,
                column,
            ),
                                       IPortletAssignmentMapping,
                                       context=self.object)
            p_ids = [p for p in portlets._data.keys()]
            # get new order
            order = portletsdata[manager_name]['order'] and \
                portletsdata[manager_name]['order'].split(',') or []

            # set blackliststatus
            blacklist = getMultiAdapter((self.object, column),
                                        ILocalPortletAssignmentManager)
            blacklistdata = portletsdata[manager_name]['blackliststatus']
            blacklist.setBlacklistStatus(GROUP_CATEGORY,
                                         blacklistdata[GROUP_CATEGORY])
            blacklist.setBlacklistStatus(USER_CATEGORY,
                                         blacklistdata[USER_CATEGORY])
            blacklist.setBlacklistStatus(CONTENT_TYPE_CATEGORY,
                                         blacklistdata[CONTENT_TYPE_CATEGORY])

            blacklist.setBlacklistStatus(CONTEXT_CATEGORY,
                                         blacklistdata[CONTEXT_CATEGORY])

            # bit clean up
            del portletsdata[manager_name]['blackliststatus']
            del portletsdata[manager_name]['order']

            # remove all currenlty assigned portlets from manager
            for p_id in p_ids:
                del portlets._data[p_id]

            for portlet_id in portletsdata[manager_name].keys():
                portletfielddata = portletsdata[manager_name][portlet_id]
                # get Assignment
                portlet_module = modules[portletfielddata['module']]
                portlet_class = getattr(
                    portlet_module, portletfielddata['assignment_class_name'])
                settings = portletfielddata.get('settings', None)
                # prepare data to pass as arguments
                del portletfielddata['module']
                del portletfielddata['assignment_class_name']
                del portletfielddata['settings']

                annotations = portletfielddata.get('__annotations__', None)
                if '__annotations__' in portletfielddata:
                    del portletfielddata['__annotations__']

                # check for dicts
                for k, v in portletfielddata.items():

                    if isinstance(v, dict):
                        # so we have one, now we have to turn the
                        # serialized data into an object
                        # this is generic, but currently only in use
                        # by the image portlet
                        klass = modules[v['module']].__dict__[v['klass_name']]

                        for argname in ('file', 'data'):
                            if argname in v['kwargs']:
                                v['kwargs'][argname] = base64.decodestring(
                                    v['kwargs'][argname])

                        imgobj = klass(**v['kwargs'])
                        portletfielddata[k] = imgobj

                portlets[portlet_id] = portlet_class(**portletfielddata)

                # XXX boolean value fix
                # for some reason boolean types cannpt be passed with **...
                # use setattr
                for k, v in portletfielddata.items():
                    if isinstance(v, bool):
                        setattr(portlets[portlet_id], k, v)

                if annotations:
                    portlets[portlet_id].__annotations__ = annotations

                # portlet settings (visibility)
                portlet_assignment = portlets[portlet_id]
                IPortletAssignmentSettings(portlet_assignment).data = settings

            # set new order afterwards
            portlets._order = PersistentList(order)
Пример #23
0
def hidePortlet(context, portletName, columnName='plone.leftcolumn'):
    manager = getUtility(IPortletManager, columnName)
    assignmentMapping = getMultiAdapter((context, manager),
                                        IPortletAssignmentMapping)
    settings = IPortletAssignmentSettings(assignmentMapping[portletName])
    settings['visible'] = False
Пример #24
0
 def __setattr__(self, attr, value):
     settings = IPortletAssignmentSettings(self.context)
     settings[attr] = value
Пример #25
0
 def __getattr__(self, attr):
     settings = IPortletAssignmentSettings(self.context)
     return settings.get(attr, None)
Пример #26
0
 def is_visible(a):
     try:
         return IPortletAssignmentSettings(a).get('visible', True)
     except TypeError:
         # Assignment is broken
         return False
Пример #27
0
    def getData(self):
        """returns all important data
        data form
        {'column':
        {portlet:
        {key:value}
        }
        .
        .
        .
        .
        {'blackliststatus':
        {category:True},

        {'order':
        ['portlet 1', 'portlet 2']}
        }
        }
        """

        data = {}
        plone_portlet_manager = []
        # gets all portlet managers used on this object
        annotations = getattr(self.object, '__annotations__', None)
        if not annotations:
            return data

        has_portlets = 'plone.portlets.contextassignments' in annotations
        has_blacklist = 'plone.portlets.categoryblackliststatus' in annotations
        if not has_portlets and not has_blacklist:
            return data

        if has_portlets:
            plone_portlet_manager += self.object.__annotations__[
                'plone.portlets.contextassignments'].keys()
        if has_blacklist:
            plone_portlet_manager += self.object.__annotations__[
                'plone.portlets.categoryblackliststatus'].keys()

        EXCLUDED_FIELDS = ['__name__', '__parent__']
        # XXX this is a static list, replace by a configlet option
        # the list contains all not serializable portlets (__module__)
        blacklisted_portlets = [
            'collective.dancing.browser.portlets.channelsubscribe'
        ]

        for manager_name in plone_portlet_manager:
            column = queryUtility(IPortletManager,
                                  name=manager_name,
                                  context=self.object)
            if column is None:
                continue

            # ok we have a portlet manager
            data[manager_name] = {}

            # get blackliststatus
            blacklist = getMultiAdapter((self.object, column),
                                        ILocalPortletAssignmentManager)
            data[manager_name]['blackliststatus'] = {}
            blacklistdata = data[manager_name]['blackliststatus']
            blacklistdata[GROUP_CATEGORY] = blacklist.getBlacklistStatus(
                GROUP_CATEGORY)
            blacklistdata[USER_CATEGORY] = blacklist.getBlacklistStatus(
                USER_CATEGORY)

            blacklistdata[CONTENT_TYPE_CATEGORY] = \
                blacklist.getBlacklistStatus(CONTENT_TYPE_CATEGORY)

            blacklistdata[CONTEXT_CATEGORY] = \
                blacklist.getBlacklistStatus(CONTEXT_CATEGORY)

            portlets = getMultiAdapter((
                self.object,
                column,
            ),
                                       IPortletAssignmentMapping,
                                       context=self.object)

            # portlets order - dicts are unsorted
            data[manager_name]['order'] = ','.join(portlets._order)

            for portlet_id in portlets.keys():
                portlet_assignment = portlets[portlet_id]
                # continue if portlet is blacklisted
                if portlet_assignment.__module__ in blacklisted_portlets:
                    continue

                # we habe a portlet
                data[manager_name][portlet_assignment.__name__] = {}
                data[manager_name][portlet_assignment.__name__]['module'] = \
                    portlet_assignment.__class__.__module__
                data[manager_name][portlet_assignment.__name__]['assignment_class_name'] = \
                    portlet_assignment.__class__.__name__

                # portlet settings (visibility)
                settings = IPortletAssignmentSettings(portlet_assignment).data
                data[manager_name][
                    portlet_assignment.__name__]['settings'] = settings

                # get all data
                for field in portlet_assignment.__dict__.keys():
                    if field not in EXCLUDED_FIELDS:
                        field_value = getattr(portlet_assignment, field, '')
                        # image field - image.portlet integration
                        if isinstance(field_value, OFSImage):
                            # same way as in AT field serializer

                            field_value = {
                                'module': OFSImage.__module__,
                                'klass_name': OFSImage.__name__,
                                'kwargs': {
                                    'file':
                                    base64.encodestring(field_value.data),
                                    'id': field_value.id(),
                                    'title': field_value.title
                                }
                            }

                        elif (HAS_NAMEDFILE
                              and INamedFile.providedBy(field_value)):
                            klass = type(field_value)
                            field_value = {
                                'module': klass.__module__,
                                'klass_name': klass.__name__,
                                'kwargs': {
                                    'data':
                                    base64.encodestring(field_value.data),
                                    'filename': field_value.filename,
                                    'contentType': field_value.contentType
                                }
                            }

                        data[manager_name][
                            portlet_assignment.__name__][field] = field_value

        return data
Пример #28
0
    def __init__(self, context, request):
        super(DisplayPanelView, self).__init__(context, request)

        # todo: move away from init

        # The parent object is the Plone content object here; we get
        # it from the acquisition chain.

        # The panel can be rendered in different contexts, where the length of
        # the chain to the Plone content object is not obvious;
        # on portlet edit forms for instance, where we have a panel of
        # portlets below the edit form.
        # So to get the content object we go up in the aq chain, until we are
        # out of the chain of portlet assignments, panels etc.
        parent = self.context.aq_inner
        while True:
            parent = parent.aq_parent
            if not (IPanel.providedBy(parent)
                    or IPortletAssignment.providedBy(parent)
                    or IPortletAssignmentMapping.providedBy(parent)):
                break

        panel = self.context

        portlets = []
        for assignment in panel:
            settings = IPortletAssignmentSettings(assignment)
            if not settings.get('visible', True):
                continue

            try:
                portlet = getMultiAdapter((parent, self.request, self, panel,
                                           assignment.__of__(panel)),
                                          IPortletRenderer)
            except ComponentLookupError:
                logging.getLogger("panels").info(
                    "unable to look up renderer for '%s.%s'." %
                    (assignment.__class__.__module__,
                     assignment.__class__.__name__))
                continue

            info = {
                'manager': "panels",
                'category': CONTEXT_CATEGORY,
                'key': str('/'.join(parent.getPhysicalPath())),
                'name': assignment.__name__,
                'renderer': portlet,
                'settings': settings,
                'assignment': assignment
            }

            # todo: check new impl. of portlet rendering
            hashPortletInfo(info)

            portlet.__portlet_metadata__ = info.copy()
            del portlet.__portlet_metadata__['renderer']

            portlet.update()

            try:
                available = portlet.available
            except ConflictError:
                raise
            except Exception as err:
                logging.getLogger('panels').info(
                    "available threw an exception for %s (%s %s)" %
                    (assignment.__name__, type(err), str(err)))
                continue

            info['available'] = available
            portlets.append(info)

        self.portlets = portlets
Пример #29
0
    def getPortlets(self):
        """Work out which portlets to display, returning a list of dicts
        describing assignments to render.
        """

        if IPortletContext.providedBy(self.context):
            pcontext = self.context
        else:
            pcontext = queryAdapter(self.context, IPortletContext)

        if pcontext is None:
            return []

        # Holds a list of (category, key, assignment).
        categories = []

        # Keeps track of the blacklisting status for global categores
        # (user, group, content type). The status is either True (blocked)
        # or False (not blocked).
        blacklisted = {}

        # This is the name of the manager (column) we're rendering
        manager = self.storage.__name__

        # 1. Fetch blacklisting status for each global category

        # First, find out which categories we will need to determine
        # blacklist status for

        for category, key in pcontext.globalPortletCategories(False):
            blacklisted[category] = None

        # Then walk the content hierarchy to find out what blacklist status
        # was assigned. Note that the blacklist is tri-state; if it's None it
        # means no assertion has been made (i.e. the category has neither been
        # whitelisted or blacklisted by this object or any parent). The first
        # item to give either a blacklisted (True) or whitelisted (False)
        # value for a given item will set the appropriate value. Parents of
        # this item that also set a black- or white-list value will then be
        # ignored.

        # Whilst walking the hierarchy, we also collect parent portlets,
        # until we hit the first block.

        current = self.context
        currentpc = pcontext
        blacklistFetched = set()
        parentsBlocked = False

        while current is not None and currentpc is not None:
            if ILocalPortletAssignable.providedBy(current):
                assignable = current
            else:
                assignable = queryAdapter(current, ILocalPortletAssignable)

            if assignable is not None:
                if IAnnotations.providedBy(assignable):
                    annotations = assignable
                else:
                    annotations = queryAdapter(assignable, IAnnotations)

                if not parentsBlocked:
                    local = annotations.get(CONTEXT_ASSIGNMENT_KEY, None)
                    if local is not None:
                        localManager = local.get(manager, None)
                        if localManager is not None:
                            categories.extend([(CONTEXT_CATEGORY, currentpc.uid, a) for a in localManager.values()])

                lpam = getMultiAdapter((assignable, self.storage), ILocalPortletAssignmentManager)
                if lpam.getBlacklistStatus(CONTEXT_CATEGORY):
                    parentsBlocked = True
                for cat, cat_status in blacklisted.items():
                    local_status = lpam.getBlacklistStatus(cat)
                    if local_status is not None:
                        blacklistFetched.add(cat)
                        if cat_status is None:
                            blacklisted[cat] = local_status

            # We can abort if parents are blocked and we've fetched all
            # blacklist statuses

            if parentsBlocked and len(blacklistFetched) == len(blacklisted):
                break

            # Check the parent - if there is no parent, we will stop
            current = currentpc.getParent()
            if current is not None:
                if IPortletContext.providedBy(current):
                    currentpc = current
                else:
                    currentpc = queryAdapter(current, IPortletContext)

        # Get all global mappings for non-blacklisted categories

        for category, key in pcontext.globalPortletCategories(False):
            if not blacklisted[category]:
                mapping = self.storage.get(category, None)
                if mapping is not None:
                    for a in mapping.get(key, {}).values():
                        categories.append((category, key, a, ))

        assignments = []
        for category, key, assignment in categories:
            try:
                settings = IPortletAssignmentSettings(assignment)
                if not settings.get('visible', True):
                    continue
            except TypeError:
                # Portlet does not exist any longer
                continue
            assignments.append({'category': category,
                                'key': key,
                                'name': str(assignment.__name__),
                                'assignment': assignment
                                })
        return assignments
Пример #30
0
    def create_portlet(self, data):
        errors = []
        portlet_type = data.get('@type', None)
        iface = self.portlettypes.get(portlet_type)
        fields = getFields(iface)
        portlet_data = dict()
        for field_name, field in fields.items():
            # Deserialize to field value
            deserializer = queryMultiAdapter((field, self.request),
                                             IFieldDeserializer)
            if deserializer is None or field_name not in data:
                continue

            try:
                value = deserializer(data[field_name])
            except ValueError as e:
                errors.append({
                    "message": str(e),
                    "field": field_name,
                    "error": e
                })
                continue
            except ValidationError as e:
                errors.append({
                    "message": e.doc(),
                    "field": field_name,
                    "error": e
                })
                continue

            portlet_data[field_name] = value

        manager = queryMultiAdapter((self.context, self.manager),
                                    IPortletAssignmentMapping)
        factory = queryUtility(IFactory, name=portlet_type)
        if not factory:
            self.request.response.setStatus(501)
            return dict(error=dict(
                message="Could not get factory for portlet type {}".format(
                    portlet_type)))
        assignment = factory(**portlet_data)

        portlet_id = data.get('portlet_id', None)
        if portlet_id:
            # If portlet id is specified, check if there is a portlet with that id, and if so, remove it
            if portlet_id in manager:
                # set fixing_up to True to let zope.container.contained
                # know that our object doesn't have __name__ and __parent__
                fixing_up = contained.fixing_up
                contained.fixing_up = True
                del manager[portlet_id]
                # revert our fixing_up customization
                contained.fixing_up = fixing_up
        else:
            chooser = INameChooser(manager)
            portlet_id = chooser.chooseName(None, assignment)

        manager[portlet_id] = assignment

        visible = data.get('visible', True)
        settings = IPortletAssignmentSettings(assignment)
        settings['visible'] = visible