Beispiel #1
0
def upgrade_to_1004_daterange_widget(context):
    from eea.facetednavigation.subtypes.interfaces import IFacetedNavigable
    from eea.facetednavigation.layout.interfaces import IFacetedLayout
    from eea.facetednavigation.interfaces import ICriteria
    from eea.facetednavigation.widgets.storage import Criterion

    brains = api.content.find(object_provides=IFacetedNavigable.__identifier__)
    layouts = ("faceted-agenda-ungrouped-view-items",
               "faceted-agenda-view-items")
    for brain in brains:
        obj = brain.getObject()
        if IFacetedLayout(obj).layout not in layouts:
            continue
        criterion = ICriteria(obj)
        for key, criteria in criterion.items():
            if criteria.get("widget") != "daterange":
                continue
            if criteria.get("usePloneDateFormat") is True:
                continue
            logger.info("Upgrade daterange widget for faceted {0}".format(obj))
            position = criterion.criteria.index(criteria)
            values = criteria.__dict__
            values["usePloneDateFormat"] = True
            criterion.criteria[position] = Criterion(**values)
            criterion.criteria._p_changed = 1
def migrate_autocomplete_widget(context):
    """
    As in version 8.4 we added selection of the autocomplete suggestion
    view. To maintain backward compatibility we will set the value of
    this 'autocomplete_view' field to solr suggestions view.
    """
    ctool = getToolByName(context, 'portal_catalog')
    iface = interfaceToName(context, IFacetedNavigable)
    brains = ctool.unrestrictedSearchResults(object_provides=iface)

    count = 0
    for brain in brains:
        doc = brain.getObject()
        settings = ICriteria(doc)

        for criterion in settings.values():
            if criterion.widget == 'autocomplete':
                criterion.autocomplete_view = u'solr-autocomplete-suggest'
                logger.info(
                    'Set defaut autocomplete view of widget: %s',
                    criterion.title
                )
                count += 1

    logger.info('Migrated %s autocomplete widgets', count)
def add_sorting_widget(context):
    """
    As in version 7.1 we removed default sorting by effective date, in order
    to maintain backward compatibility we will add a sorting widget, hidden
    for all faceted navigable items where this widget is not present
    """
    ctool = getToolByName(context, 'portal_catalog')
    iface = interfaceToName(context, IFacetedNavigable)
    brains = ctool.unrestrictedSearchResults(object_provides=iface)

    count = 0
    for brain in brains:
        try:
            doc = brain.getObject()
            settings = ICriteria(doc)
            sorting = [criterion for criterion in settings.values()
                       if criterion.widget == 'sorting']
            if sorting:
                continue

            settings.add(
                'sorting', 'right',
                 title='Sort on', default='effective(reverse)',
                 hidden=True
            )
        except Exception, err:
            logger.exception(err)
        else:
            logger.info('Added sorting widget for: %s', doc.absolute_url())
            count += 1
    def edit(self, cid, **kwargs):
        """ See IFacetedCriterionHandler
        """
        criteria = ICriteria(self.context)
        widget = criteria.widget(cid=cid)
        criterion = criteria.get(cid)
        if kwargs.pop('__new__', False):
            criterion = criterion.__class__(cid='c0')
        widget = widget(self.context, self.request, criterion)

        wid = kwargs.pop('widget', None)
        properties = self.extractData(widget, **kwargs)
        if wid:
            properties['widget'] = wid

        update = {}
        for prop, value in properties.items():
            form_key =  'faceted.%s.%s' % (cid, prop)
            if form_key not in kwargs and value is None:
                continue
            update[prop] = value

        if update:
            criteria.edit(cid, **update)
            if widget.hidden:
                notify(FacetedGlobalSettingsChangedEvent(self.context))
            elif set(['hidden', 'operator']).intersection(update.keys()):
                notify(FacetedGlobalSettingsChangedEvent(self.context))

        return self._redirect('Changes saved')
    def query(self, cid, **kwargs):
        """ Count catalog items
        """
        # Cleanup query
        kwargs.pop('sort_on', None)
        kwargs.pop('sort_order', None)

        kwargs.pop(cid, None)
        self.request.form.pop(cid, None)
        # jQuery >= 1.4 adds type to params keys
        # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4"
        # Let's fix this
        kwargs.pop(cid + '[]', None)
        self.request.form.pop(cid + '[]', None)

        criteria = ICriteria(self.context)
        criterion = criteria.get(cid)

        start = time.time()
        # Query catalog
        handler = getMultiAdapter((self.context, self.request),
                                  name=u'faceted_query')

        if criterion.get('index', '') == 'Language':
            kwargs['_language_count_'] = True
        brains = handler.query(batch=False, sort=False, **kwargs)

        # Get index
        widget = criteria.widget(cid=cid)(self.context, self.request, criterion)
        res = widget.count(brains)
        logger.debug('Benchmark %s: %s', cid, time.time() - start)
        return res
Beispiel #6
0
def add_sorting_widget(context):
    """
    As in version 7.1 we removed default sorting by effective date, in order
    to maintain backward compatibility we will add a sorting widget, hidden
    for all faceted navigable items where this widget is not present
    """
    ctool = getToolByName(context, 'portal_catalog')
    iface = interfaceToName(context, IFacetedNavigable)
    brains = ctool.unrestrictedSearchResults(object_provides=iface)

    count = 0
    for brain in brains:
        try:
            doc = brain.getObject()
            settings = ICriteria(doc)
            sorting = [
                criterion for criterion in settings.values()
                if criterion.widget == 'sorting'
            ]
            if sorting:
                continue

            settings.add('sorting',
                         'right',
                         title='Sort on',
                         default='effective(reverse)',
                         hidden=True)
        except Exception, err:
            logger.exception(err)
        else:
            logger.info('Added sorting widget for: %s', doc.absolute_url())
            count += 1
Beispiel #7
0
    def language_present(self):
        """ Is there any widget for Language index?
        """

        criteria = ICriteria(self.context)
        for criterion in criteria.values():
            if criterion.get('index', None) == 'Language':
                if not criterion.hidden:
                    return True
        return False
    def language_present(self):
        """ Is there any widget for Language index?
        """

        criteria = ICriteria(self.context)
        for criterion in criteria.values():
            if criterion.get('index', None) == 'Language':
                if not criterion.hidden:
                    return True
        return False
Beispiel #9
0
    def _updateFacetedFilters(self):
        """Update vocabulary used for "Taken over by".
           Make sure the default for contacts 'c5' widget is not a list."""
        logger.info(
            "Updating faceted filter \"Taken over by\" for every MeetingConfigs..."
        )
        for cfg in self.tool.objectValues('MeetingConfig'):
            obj = cfg.searches.searches_items
            # update vocabulary for relevant filters
            criteria = ICriteria(obj)
            criteria.edit(
                'c12', **{
                    'vocabulary':
                    'Products.PloneMeeting.vocabularies.creatorswithnobodyforfacetedfiltervocabulary'
                })
            criteria.edit(
                'c27', **{
                    'vocabulary':
                    'Products.PloneMeeting.vocabularies.associatedgroupsvocabulary'
                })
        logger.info('Done.')

        logger.info("Updating faceted filter \"Defined in\" for 'c5' "
                    "criterion of contacts/orgs-searches...")
        obj = self.portal.contacts.get('orgs-searches')
        # as default is not correct (a string instead a list, we can not use edit or it fails to validate)
        criteria = ICriteria(obj)
        criterion = criteria.get('c5')
        criterion.default = u'collective.contact.plonegroup.interfaces.IPloneGroupContact'
        logger.info('Done.')
 def get_widgets(self, position='', section=''):
     """ Get all widgets
     """
     criteria = ICriteria(self.context)
     for criterion in criteria.values():
         if position and criterion.get('position', 'right') != position:
             continue
         if section and criterion.get('section', 'default') != section:
             continue
         widget = criteria.widget(wid=criterion.get('widget'))
         yield widget(self.context, self.request, criterion)
Beispiel #11
0
 def perPage(self):
     num_per_page = 20
     criteria = ICriteria(self.context)
     for cid, criterion in criteria.items():
         widgetclass = criteria.widget(cid=cid)
         widget = widgetclass(self.context, self.request, criterion)
         if widget.widget_type == 'resultsperpage':
             kwargs = dict((key.replace('[]', ''), val)
                           for key, val in self.request.form.items())
             num_per_page = widget.results_per_page(kwargs)
     return num_per_page
 def get_widgets(self, position='', section=''):
     """ Get all widgets
     """
     criteria = ICriteria(self.context)
     for criterion in criteria.values():
         if position and criterion.get('position', 'right') != position:
             continue
         if section and criterion.get('section', 'default') != section:
             continue
         widget = criteria.widget(wid=criterion.get('widget'))
         yield widget(self.context, self.request, criterion)
 def get_widgets(self, position="", section=""):
     """ Get all widgets
     """
     criteria = ICriteria(self.context)
     for criterion in criteria.values():
         if position and criterion.get("position", "right") != position:
             continue
         if section and criterion.get("section", "default") != section:
             continue
         widget = criteria.widget(wid=criterion.get("widget"))
         yield widget(self.context, self.request, criterion)
    def add(self, **kwargs):
        """ See IFacetedCriterionHandler
        """
        kwargs = self._request_form(kwargs)

        wid = kwargs.pop('wtype', None)
        position = kwargs.pop('wposition', 'right')
        section = kwargs.pop('wsection', 'default')

        criteria = ICriteria(self.context)
        cid = criteria.add(wid, position, section)
        return self.edit(cid, **kwargs)
Beispiel #15
0
    def query(self, batch=True, sort=False, **kwargs):
        """ Search using given criteria
        """
        if self.request:
            kwargs.update(self.request.form)
            kwargs.pop('sort[]', None)
            kwargs.pop('sort', None)

        # jQuery >= 1.4 adds type to params keys
        # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4"
        # Let's fix this
        kwargs = dict(
            (key.replace('[]', ''), val) for key, val in kwargs.items())

        #fix for unicode error in indexes
        for key, val in kwargs.items():
            if isinstance(val, str):
                kwargs[key] = val.decode('utf-8')

        query = self.criteria(sort=sort, **kwargs)
        # We don't want to do an unnecessary sort for a counter query
        counter_query = kwargs.pop('counter_query', False)
        if counter_query:
            query.pop('sort_on', None)
            query.pop('sort_order', None)

        catalog = getUtility(IFacetedCatalog)
        num_per_page = 20
        criteria = ICriteria(self.context)
        brains_filters = []
        for cid, criterion in criteria.items():
            widgetclass = criteria.widget(cid=cid)
            widget = widgetclass(self.context, self.request, criterion)

            if widget.widget_type == 'resultsperpage':
                num_per_page = widget.results_per_page(kwargs)

            brains_filter = queryAdapter(widget, IWidgetFilterBrains)
            if brains_filter:
                brains_filters.append(brains_filter)

        b_start = safeToInt(kwargs.get('b_start', 0))
        orphans = num_per_page * 20 / 100  # orphans = 20% of items per page
        if batch and not brains_filters:
            # add b_start and b_size to query to use better sort algorithm
            query['b_start'] = b_start
            query['b_size'] = num_per_page + orphans

        try:
            brains = catalog(self.context, **query)
        except Exception, err:
            logger.exception(err)
            return Batch([], 20, 0)
    def add(self, **kwargs):
        """ See IFacetedCriterionHandler
        """
        wid = kwargs.pop('wtype', self.request.get('wtype', None))
        position = kwargs.pop('wposition',
                              self.request.get('wposition', 'right'))
        section = kwargs.pop('wsection',
                             self.request.get('wsection', 'default'))

        criteria = ICriteria(self.context)
        cid = criteria.add(wid, position, section)
        return self.edit(cid, __new__=True, **kwargs)
    def criteria(self, sort=False, **kwargs):
        """ Process catalog query
        """
        if self.request:
            kwargs.update(self.request.form)

        # jQuery >= 1.4 adds type to params keys
        # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4"
        # Let's fix this
        kwargs = dict((key.replace('[]', ''), val)
                      for key, val in kwargs.items())

        logger.debug("REQUEST: %r", kwargs)

        # Generate the catalog query
        criteria = ICriteria(self.context)
        query = {}
        for cid, criterion in criteria.items():
            widget = criteria.widget(cid=cid)
            widget = widget(self.context, self.request, criterion)

            widget_query = widget.query(kwargs)
            if getattr(widget, 'faceted_field', False):
                widget_index = widget.data.get('index', '')
                if ('facet.field' in query and
                            widget_index not in query['facet.field']):
                    query['facet.field'].append(widget_index)
                else:
                    query['facet.field'] = [widget_index]
            query.update(widget_query)

            # Handle language widgets
            if criterion.get('index', '') == 'Language':
                language_widget = queryMultiAdapter((widget, self.context),
                                                    ILanguageWidgetAdapter)
                if not language_widget:
                    continue
                query.update(language_widget(kwargs))

        # Add default sorting criteria
        if sort and not query.has_key('sort_on'):
            query['sort_on'] = 'effective'
            query['sort_order'] = 'reverse'

        # Add default language.
        # Also make sure to return language-independent content.
        lang = self.language
        if lang:
            lang = [lang, '']
        query.setdefault('Language', lang)

        logger.debug('QUERY: %s', query)
        return query
    def add(self, **kwargs):
        """ See IFacetedCriterionHandler
        """
        kwargs = self._request_form(kwargs)

        wid = kwargs.pop('wtype', None)
        position = kwargs.pop('wposition', 'right')
        section = kwargs.pop('wsection', 'default')

        criteria = ICriteria(self.context)
        cid = criteria.add(wid, position, section)
        return self.edit(cid, **kwargs)
Beispiel #19
0
    def criteria(self, sort=False, **kwargs):
        """ Process catalog query
        """
        if self.request:
            kwargs.update(self.request.form)

        # jQuery >= 1.4 adds type to params keys
        # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4"
        # Let's fix this
        kwargs = dict((key.replace('[]', ''), val)
                      for key, val in kwargs.items())

        logger.debug("REQUEST: %r", kwargs)

        # Generate the catalog query
        criteria = ICriteria(self.context)
        query = {}
        for cid, criterion in criteria.items():
            widget = criteria.widget(cid=cid)
            widget = widget(self.context, self.request, criterion)

            widget_query = widget.query(kwargs)
            if getattr(widget, 'faceted_field', False):
                widget_index = widget.data.get('index', '')
                if ('facet.field' in query and
                            widget_index not in query['facet.field']):
                    query['facet.field'].append(widget_index)
                else:
                    query['facet.field'] = [widget_index]
            query.update(widget_query)

            # Handle language widgets
            if criterion.get('index', '') == 'Language':
                language_widget = queryMultiAdapter((widget, self.context),
                                                    ILanguageWidgetAdapter)
                if not language_widget:
                    continue
                query.update(language_widget(kwargs))

        # Add default sorting criteria
        if sort and 'sort_on' not in query:
            query['sort_on'] = 'effective'
            query['sort_order'] = 'reverse'

        # Add default language.
        # Also make sure to return language-independent content.
        lang = self.language
        if lang:
            lang = [lang, '']
        query.setdefault('Language', lang)

        logger.debug('QUERY: %s', query)
        return query
    def add(self, **kwargs):
        """ See IFacetedCriterionHandler
        """
        wid = kwargs.pop('wtype',
                         self.request.get('wtype', None))
        position = kwargs.pop('wposition',
                              self.request.get('wposition', 'right'))
        section = kwargs.pop('wsection',
                             self.request.get('wsection', 'default'))

        criteria = ICriteria(self.context)
        cid = criteria.add(wid, position, section)
        return self.edit(cid, __new__=True, **kwargs)
Beispiel #21
0
 def _updateFacetedFilters(self):
     """Update vocabulary used for "Taken over by"."""
     logger.info(
         "Updating faceted filter \"Taken over by\" for every MeetingConfigs..."
     )
     for cfg in self.tool.objectValues('MeetingConfig'):
         criteria = ICriteria(cfg.searches.searches_items)
         criteria.edit(
             'c12', **{
                 'vocabulary':
                 'Products.PloneMeeting.vocabularies.creatorswithnobodyforfacetedfiltervocabulary'
             })
     logger.info('Done.')
    def criteria(self, sort=True, **kwargs):
        """ Process catalog query
        """
        if self.request:
            kwargs.update(self.request.form)

        # jQuery >= 1.4 adds type to params keys
        # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4"
        # Let's fix this
        kwargs = dict((key.replace('[]', ''), val)
                      for key, val in kwargs.items())

        logger.debug("REQUEST: %r", kwargs)

        # Generate the catalog query
        mtool = getToolByName(self.context, 'portal_membership', None)
        criteria = ICriteria(self.context)

        query = {}
        if mtool.isAnonymousUser():
            query['review_state'] = 'published'

        for cid, criterion in criteria.items():
            widget = criteria.widget(cid=cid)
            widget = widget(self.context, self.request, criterion)

            query.update(widget.query(kwargs))

            # Handle language widgets
            if criterion.get('index', '') == 'Language':
                language_widget = queryMultiAdapter((widget, self.context),
                                                    ILanguageWidgetAdapter)
                if not language_widget:
                    continue
                query.update(language_widget(kwargs))

        # Add default sorting criteria
        if sort and not query.has_key('sort_on'):
            query['sort_on'] = 'effective'
            query['sort_order'] = 'reverse'

        # Add default language.
        # Also make sure to return language-independent content.
        lang = self.language
        if lang:
            lang = [lang, '']
        query.setdefault('Language', lang)

        logger.debug('QUERY: %s', query)
        return query
 def edit(self, **kwargs):
     """ See IFacetedCriteriaHandler
     """
     criteria = ICriteria(self.context)
     handler = getMultiAdapter((self.context, self.request),
                               name=u'faceted_update_criterion')
     for cid in criteria.keys():
         properties = {}
         for key, value in kwargs.items():
             if not key.startswith(cid):
                 continue
             key = key[len(cid) + 1:]
             properties[key] = value
         handler.edit(cid, **properties)
     return self._redirect('Changes saved', to=self.redirect)
 def edit(self, **kwargs):
     """ See IFacetedCriteriaHandler
     """
     criteria = ICriteria(self.context)
     handler = getMultiAdapter((self.context, self.request),
                               name=u'faceted_update_criterion')
     for cid in criteria.keys():
         properties = {}
         for key, value in kwargs.items():
             if not key.startswith(cid):
                 continue
             key = key[len(cid) + 1:]
             properties[key] = value
         handler.edit(cid, **properties)
     return self._redirect('Changes saved', to=self.redirect)
def upgrade_to_3(context):
    catalog = api.portal.get_tool('portal_catalog')
    brains = catalog(object_provides=IFacetedNavigable.__identifier__)
    for brain in brains:
        obj = brain.getObject()
        criterias = ICriteria(obj)
        changes = False
        for cid, crit in criterias.items():
            if crit.get('vocabulary', u'') in (u'imio.dashboard.conditionawarecollectionvocabulary',
                                               u'imio.dashboard.cachedcollectionvocabulary'):
                crit.vocabulary = u'collective.eeafaceted.collectionwidget.cachedcollectionvocabulary'
                changes = True
                logger.info('Criterion {} updated on object {}'.format(cid, brain.getPath()))
        if changes:
            criterias.criteria._p_changed = 1
    def query(self, batch=True, sort=False, **kwargs):
        """ Search using given criteria
        """
        if self.request:
            kwargs.update(self.request.form)
            kwargs.pop('sort[]', None)
            kwargs.pop('sort', None)

        # jQuery >= 1.4 adds type to params keys
        # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4"
        # Let's fix this
        kwargs = dict((key.replace('[]', ''), val)
                      for key, val in kwargs.items())

        query = self.criteria(sort=sort, **kwargs)
        # We don't want to do an unnecessary sort for a counter query
        counter_query = kwargs.pop('counter_query', False)
        if counter_query:
            query.pop('sort_on', None)
            query.pop('sort_order', None)

        catalog = getUtility(IFacetedCatalog)
        num_per_page = 20
        criteria = ICriteria(self.context)
        brains_filters = []
        for cid, criterion in criteria.items():
            widgetclass = criteria.widget(cid=cid)
            widget = widgetclass(self.context, self.request, criterion)

            if widget.widget_type == 'resultsperpage':
                num_per_page = widget.results_per_page(kwargs)

            brains_filter = queryAdapter(widget, IWidgetFilterBrains)
            if brains_filter:
                brains_filters.append(brains_filter)

        b_start = safeToInt(kwargs.get('b_start', 0))
        orphans = num_per_page * 20 / 100 # orphans = 20% of items per page
        if batch and not brains_filters:
            # add b_start and b_size to query to use better sort algorithm
            query['b_start'] = b_start
            query['b_size'] = num_per_page + orphans

        try:
            brains = catalog(self.context, **query)
        except Exception, err:
            logger.exception(err)
            return Batch([], 20, 0)
    def test_get_generation_context_filtered_query(self):
        """
        If a filter is used in the facetedQuery, elements displayed
        in the dashboard are correctly given to the template.
        """
        faceted_query = self.folder.restrictedTraverse('@@faceted_query')
        # for now 3 elements
        self.assertEquals(len(faceted_query.query()), 3)
        # filter on text, 'Folder 2'
        self.assertEquals(ICriteria(self.folder).get('c2').index,
                          u'SearchableText')
        self.request.form['c2[]'] = 'Folder 2'
        self.assertEquals(len(faceted_query.query()), 1)
        # generation context respect query
        self.request.form['facetedQuery'] = ''
        gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate)
        self.assertEquals(len(gen_context['uids']), 1)

        # facetedQuery is passed to the generation context as json
        # reset query, back to 3 elements found
        self.request.form = {}
        self.assertEquals(len(faceted_query.query()), 3)
        self.request.form['facetedQuery'] = ''
        gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate)
        self.assertEquals(len(gen_context['uids']), 3)
        # 'facetedQuery' is received as a serialized JSON of query criteria
        self.request.form['facetedQuery'] = '{"c2":"Folder 2"}'
        gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate)
        self.assertEquals(len(gen_context['uids']), 1)
 def delete(self, cid, **kwargs):
     """ See IFacetedCriterionHandler
     """
     try:
         ICriteria(self.context).delete(cid)
     except (TypeError, KeyError), err:
         msg = err
    def query(self, cid, **kwargs):
        """ Count catalog items
        """
        # Cleanup query
        kwargs.pop('sort_on', None)
        kwargs.pop('sort_order', None)
        kwargs.pop(cid, None)
        self.request.form.pop(cid, None)

        criteria = ICriteria(self.context)
        criterion = criteria.get(cid)

        # Query catalog
        handler = getMultiAdapter((self.context, self.request),
                                  name=u'faceted_query')

        if criterion.get('index', '') == 'Language':
            kwargs['_language_count_'] = True
        brains = handler.query(batch=False, sort=False, **kwargs)

        # Get index
        widget = criteria.widget(cid=cid)(self.context, self.request,
                                          criterion)
        vocabulary = dict((key, value)
                          for key, value, count in widget.vocabulary(oll=True)
                          if key not in ("", "all"))

        # Count
        count = getattr(widget, 'count', lambda brains, sequence: {})
        res = count(brains, sequence=vocabulary.keys())
        res.pop("", 0)
        oll = res.pop('all', 0)

        res = res.items()
        res.sort(key=operator.itemgetter(1), reverse=True)

        maxitems = widget.maxitems
        if maxitems:
            res = res[:maxitems]
        res.sort(key=operator.itemgetter(0), cmp=compare)

        # Return a of list of three items tuples (key, label, count)
        res = [(key, vocabulary.get(key, key), value) for key, value in res]

        res.insert(0, ('all', 'All', oll))
        for item in res:
            yield item
    def update(self, **kwargs):
        """ Update position by given slots
        """
        logger.debug(kwargs)
        kwargs = self._request_form(kwargs)

        ICriteria(self.context).position(**kwargs)
        return self._redirect('Position changed')
 def __init__(self, context, request, data=None):
     super(CollectionWidget, self).__init__(context, request, data)
     # real context could not be current context but some distant context
     # look in eea.facetednavigation.criteria.handler.Criteria
     self.criteria = ICriteria(self.context)
     self.context = self.criteria.context
     # display the fieldset around the widget when rendered?
     self.display_fieldset = True
 def _exportNode(self):
     """Export the object as a DOM node.
     """
     node = self._getObjectNode('object')
     criteria = ICriteria(self.context)
     exporter = queryMultiAdapter((criteria, self.environ), IBody)
     node.appendChild(exporter.node)
     return node
    def __call__(self, **kwargs):
        if self.request:
            kwargs.update(self.request.form)

        # Calling self.index() will set cache headers for varnish
        self.index()

        cid = kwargs.pop('cid', None)
        if not cid:
            return {}

        res = self.query(cid, **kwargs)

        criteria = ICriteria(self.context)
        criterion = criteria.get(cid)
        widget = criteria.widget(cid=cid)(self.context, self.request, criterion)
        return widget(vocabulary=res)
    def query(self, cid, **kwargs):
        """ Count catalog items
        """
        # Cleanup query
        kwargs.pop('sort_on', None)
        kwargs.pop('sort_order', None)
        kwargs.pop(cid, None)
        self.request.form.pop(cid, None)

        criteria = ICriteria(self.context)
        criterion = criteria.get(cid)

        # Query catalog
        handler = getMultiAdapter((self.context, self.request),
                                  name=u'faceted_query')

        if criterion.get('index', '') == 'Language':
            kwargs['_language_count_'] = True
        brains = handler.query(batch=False, sort=False, **kwargs)

        # Get index
        widget = criteria.widget(cid=cid)(self.context, self.request, criterion)
        vocabulary = dict((key, value) for key, value, count
                    in widget.vocabulary(oll=True) if key not in ("", "all"))

        # Count
        count = getattr(widget, 'count', lambda brains, sequence: {})
        res = count(brains, sequence=vocabulary.keys())
        res.pop("", 0)
        oll = res.pop('all', 0)

        res = res.items()
        res.sort(key=operator.itemgetter(1), reverse=True)

        maxitems = widget.maxitems
        if maxitems:
            res = res[:maxitems]
        res.sort(key=operator.itemgetter(0), cmp=compare)

        # Return a of list of three items tuples (key, label, count)
        res = [(key, vocabulary.get(key, key), value) for key, value in res]

        res.insert(0, ('all', 'All', oll))
        for item in res:
            yield item
Beispiel #35
0
    def __call__(self, **kwargs):
        if self.request:
            kwargs.update(self.request.form)

        # Calling self.index() will set cache headers for varnish
        self.index()

        cid = kwargs.pop('cid', None)
        if not cid:
            return {}

        res = self.query(cid, **kwargs)

        criteria = ICriteria(self.context)
        criterion = criteria.get(cid)
        widget = criteria.widget(cid=cid)(self.context, self.request,
                                          criterion)
        return widget(vocabulary=res)
 def _importNode(self, node):
     """Import the object from the DOM node.
     """
     criteria = ICriteria(self.context)
     for child in node.childNodes:
         if child.nodeName != 'criteria':
             continue
         importer = queryMultiAdapter((criteria, self.environ), IBody)
         importer.node = child
 def __init__(self, context, request):
     # TODO: update this to new workings of collection facet (now that we have a custom portal_type)
     super(DatasetsCollectionListView, self).__init__(context, request)
     self.datasets_url = self.context.absolute_url()
     self.criteria = ICriteria(self.context, {})
     self.defaults = {}
     self.criterion = None
     for criterion in self.criteria.values():
         if criterion.widget == 'pathselect':
             self.criterion = criterion
         if criterion.widget == 'sorting':
             default = criterion.default
             if not default:
                 continue
             if '(reverse)' in default:
                 default = default.replace('(reverse)', '', 1)
                 self.defaults['reversed'] = True
             self.defaults[criterion.getId()] = default
Beispiel #38
0
 def delete(self, cid, **kwargs):
     """ See IFacetedCriterionHandler
     """
     try:
         ICriteria(self.context).delete(cid)
     except (TypeError, KeyError) as err:
         msg = err
     else:
         msg = _(u'Filter deleted')
     return self._redirect(msg=msg)
 def add(self, **kwargs):
     """ See IFacetedCriteriaHandler
     """
     wid = kwargs.pop('wtype', None)
     position = kwargs.pop('wposition', 'right')
     section = kwargs.pop('wsection', 'default')
     try:
         ICriteria(self.context).add(wid, position, section)
     except NameError, err:
         msg = err
    def test_enableFacetedDashboardFor(self):
        """This method will enable the faceted navigation for a given folder."""
        # faceted can be enabled using the default widgets
        catalog = self.portal.portal_catalog
        folder2_id = self.portal.invokeFactory('Folder', 'folder2', title='Folder2')
        folder2 = getattr(self.portal, folder2_id)
        folder2.reindexObject()
        folder2UID = folder2.UID()
        # not enabled for now
        self.assertFalse(IFacetedNavigable.providedBy(folder2))
        self.assertTrue(catalog(UID=folder2UID))
        self.assertFalse(catalog(UID=folder2UID, object_provides=IFacetedNavigable.__identifier__))
        enableFacetedDashboardFor(folder2)
        # several things are done :
        # faceted is enabled
        self.assertTrue(IFacetedNavigable.providedBy(folder2))
        # used faceted layout is 'faceted-table-items'
        self.assertEquals(IFacetedLayout(folder2).layout, 'faceted-table-items')
        # left portlets are shown
        self.assertFalse(IHidePloneLeftColumn.providedBy(folder2))
        # folder2 was reindexed, especially provided interfaces
        self.assertTrue(catalog(UID=folder2UID, object_provides=IFacetedNavigable.__identifier__))
        # redirect is swallowed, indeed enabling faceted on a folder redirects to it
        self.assertEquals(self.portal.REQUEST.RESPONSE.status, 200)

        # a xmlpath parameter can be passed to use a specific widgets xml file
        # calling this on an already enabled faceted will do nothing
        xmlpath = os.path.dirname(__file__) + '/faceted_conf/testing_widgets.xml'
        enableFacetedDashboardFor(folder2, xmlpath=xmlpath)
        # only one 'c44' widget in testing_widgets.xml, not added here
        self.assertFalse(ICriteria(folder2).get('c44'))
        # create a new folder and apply faceted with xmlpath to it
        folder3_id = self.portal.invokeFactory('Folder', 'folder3', title='Folder3')
        folder3 = getattr(self.portal, folder3_id)
        folder3.reindexObject()
        # an Exception is raised if xmlpath does not exist
        wrong_xmlpath = os.path.dirname(__file__) + '/faceted_conf/wrong_testing_widgets.xml'
        self.assertRaises(Exception, enableFacetedDashboardFor, folder3, wrong_xmlpath)
        # apply correct xmlpath
        enableFacetedDashboardFor(folder3, xmlpath=xmlpath)
        # same things are done except that the widgets are taken from the given xmlpath
        self.assertEquals(len(ICriteria(folder3).criteria), 1)
        self.assertTrue(ICriteria(folder3).get('c44'))
    def defaultForVocabulary(self, vocabulary):
        """
            return the faceted nav default for a particular criteria
        """

        for criterion in ICriteria(self.context).criteria:
            if criterion.vocabulary == vocabulary:
                return criterion.default

        return None
Beispiel #42
0
    def query(self, form):
        """ Get value from form and return a catalog dict query
        """
        query = {}

        # import ipdb; ipdb.set_trace()
        index = self.data.get("index", "")
        moreorless = self.data.get("moreorless", "")
        index = index.encode("utf-8", "replace")
        value = None
        if not index:
            return query

        if self.hidden:
            value = self.default
        else:
            value = form.get(self.data.getId(), "")

        if not value:
            return query
        # check if there are other criteria with same index
        second_value = None
        second_moreorless = None
        criteria = ICriteria(self.context)
        for cid, criterion in criteria.items():
            if cid in form.keys() and cid != self.data.getId():
                if criterion.index == index:
                    second_value = form.get(cid)
                    second_moreorless = criterion.moreorless

        value = int(value)
        # portal_catalog({'price':{'query':[2,1000],'range':'min:max'}})
        if moreorless == u"more" and not second_value:
            range = "min"
        elif moreorless == u"less" and not second_value:
            range = "max"
        else:
            range = "min:max"
            if second_moreorless == u"more":
                value = [int(second_value), value]

        query[index] = {"query": value, "range": range}
        return query
    def test_get_generation_context(self):
        """
        Changes are about 'uids' and 'brains' that are added to the
        pod template generation context if possible
        if nothing particular is done, every elements of the displayed
        dashboard are added to the template generation context.
        """
        # document-generator view is called outside dashboard from base viewlet
        gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate)
        self.assertIn('view', gen_context)
        self.assertNotIn('facetedQuery', gen_context)
        self.assertIn('details', gen_context)

        # document-generator view is called from dashboard viewlet
        self.request.form['facetedQuery'] = ''
        # order is respected so sort_on created
        # Date catalog queries are 1 minute sensitive...
        # make sure self.folder created is really older than self.folder2
        self.folder.creation_date = DateTime('2015/01/01 12:00')
        self.folder.reindexObject()
        self.assertEquals(ICriteria(self.folder).get('c0').widget,
                          u'sorting')
        self.request.form['c0[]'] = 'created'

        self.assertEqual(self.dashboardtemplate.max_objects, 500)
        gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate)
        self.assertTrue('uids' in gen_context)
        self.assertEquals(len(gen_context['uids']), 3)
        self.assertTrue('brains' in gen_context)
        self.assertEquals(len(gen_context['brains']), 3)

        self.dashboardtemplate.max_objects = 2
        gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate)
        self.assertEquals(len(gen_context['uids']), 2)
        self.assertEquals(len(gen_context['brains']), 2)

        self.dashboardtemplate.max_objects = 3
        gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate)
        self.assertEquals(len(gen_context['uids']), 3)
        self.assertEquals(len(gen_context['brains']), 3)

        self.assertEqual(gen_context['details'], '1')
        # brains are sorted according to uids list
        self.assertEquals(gen_context['uids'],
                          [brain.UID for brain in gen_context['brains']])

        # we have 3 elements in the dashboard : self.folder and self.folder2
        self.assertListEqual(['Folder', 'Folder 2', 'Dashboard template'],
                             [brain.Title for brain in gen_context['brains']])

        # order of query is kept in brains
        self.request.form['reversed'] = 'on'
        gen_context = self.view._get_generation_context(self.helper, self.dashboardtemplate)
        self.assertListEqual(['Dashboard template', 'Folder 2', 'Folder'],
                             [brain.Title for brain in gen_context['brains']])
Beispiel #44
0
    def query(self, cid, **kwargs):
        """ Count catalog items
        """
        # Cleanup query
        kwargs.pop('sort_on', None)
        kwargs.pop('sort_order', None)
        kwargs.pop('sort[]', None)
        kwargs.pop('sort', None)
        kwargs.pop('reversed[]', None)
        oid = '%s-operator' % cid
        operator = kwargs.pop(oid, kwargs.pop(oid + '[]', None))

        if not operator or operator != 'and':
            kwargs.pop(cid, None)
            self.request.form.pop(cid, None)
            # jQuery >= 1.4 adds type to params keys
            # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4"
            # Let's fix this
            kwargs.pop(cid + '[]', None)
            self.request.form.pop(cid + '[]', None)

        criteria = ICriteria(self.context)
        criterion = criteria.get(cid)

        start = time.time()
        # Query catalog
        handler = getMultiAdapter((self.context, self.request),
                                  name=u'faceted_query')

        if criterion.get('index', '') == 'Language':
            kwargs['_language_count_'] = True
        kwargs['counter_query'] = True
        brains = handler.query(batch=False, sort=False, **kwargs)

        # Get index
        widget = criteria.widget(cid=cid)(self.context, self.request,
                                          criterion)
        count = getattr(widget, 'count', lambda brains: {})
        res = count(brains)
        logger.debug('Benchmark %s: %s', cid, time.time() - start)
        return res
Beispiel #45
0
    def _removeGroupsOfMatter(self):
        """Remove MeetingCategory.groupsOfMatter field and related."""
        logger.info('Removing MeetingCategory.groupsOfMatter...')
        brains = self.portal.portal_catalog(meta_type='MeetingCategory')
        for brain in brains:
            cat = brain.getObject()
            if hasattr(cat, 'groupsOfMatter'):
                cat.setGroupsInCharge(cat.groupsOfMatter)
                delattr(cat, 'groupsOfMatter')
            else:
                self._already_migrated()
                return
        # remove portal_catalog index 'groupsOfMatter'
        self.removeUnusedIndexes(indexes=['groupsOfMatter'])

        # remove faceted filter
        for cfg in self.tool.objectValues('MeetingConfig'):
            # enable includeGroupsInChargeDefinedOnCategory so indexed groupsInCharge is correct
            cfg.setIncludeGroupsInChargeDefinedOnCategory(True)
            obj = cfg.searches.searches_items
            # update vocabulary for relevant filters
            criteria = ICriteria(obj)
            if criteria.get('c50'):
                criteria.delete('c50')
            # unselect 'c50' from dashboard filters and select 'c23'
            dashboardItemsListingsFilters = list(cfg.getDashboardItemsListingsFilters())
            if 'c50' in dashboardItemsListingsFilters:
                dashboardItemsListingsFilters.remove('c50')
                dashboardItemsListingsFilters.append('c23')
                cfg.setDashboardItemsListingsFilters(dashboardItemsListingsFilters)
            dashboardMeetingAvailableItemsFilters = list(cfg.getDashboardMeetingAvailableItemsFilters())
            if 'c50' in dashboardMeetingAvailableItemsFilters:
                dashboardMeetingAvailableItemsFilters.remove('c50')
                dashboardMeetingAvailableItemsFilters.append('c23')
                cfg.setDashboardMeetingAvailableItemsFilters(dashboardMeetingAvailableItemsFilters)
            dashboardMeetingLinkedItemsFilters = list(cfg.getDashboardMeetingLinkedItemsFilters())
            if 'c50' in dashboardMeetingLinkedItemsFilters:
                dashboardMeetingLinkedItemsFilters.remove('c50')
                dashboardMeetingLinkedItemsFilters.append('c23')
                cfg.setDashboardMeetingLinkedItemsFilters(dashboardMeetingLinkedItemsFilters)
        logger.info('Done.')
Beispiel #46
0
 def update_dashboards(self):
     # update daterange criteria
     brains = api.content.find(
         object_provides=IFacetedNavigable.__identifier__)
     for brain in brains:
         obj = brain.getObject()
         criterion = ICriteria(obj)
         for key, criteria in criterion.items():
             if criteria.get("widget") != "daterange":
                 continue
             if criteria.get("usePloneDateFormat") is True:
                 continue
             logger.info(
                 "Upgrade daterange widget for faceted {0}".format(obj))
             position = criterion.criteria.index(criteria)
             values = criteria.__dict__
             values["usePloneDateFormat"] = True
             values["labelStart"] = u'Start date'
             values["labelEnd"] = u'End date'
             criterion.criteria[position] = Criterion(**values)
             criterion.criteria._p_changed = 1
    def edit(self, cid, **kwargs):
        """ See IFacetedCriterionHandler
        """
        criteria = ICriteria(self.context)
        widget = criteria.widget(cid=cid)
        criterion = criteria.get(cid)
        if kwargs.pop('__new__', False):
            criterion = criterion.__class__(cid='c0')
        widget = widget(self.context, self.request, criterion)

        wid = kwargs.pop('widget', None)
        properties = self.extractData(widget, **kwargs)
        if wid:
            properties['widget'] = wid

        update = {}
        for prop, value in properties.items():
            form_key = 'faceted.%s.%s' % (cid, prop)
            if form_key not in kwargs and value is None:
                continue
            update[prop] = value

        if update:
            criteria.edit(cid, **update)
            if widget.hidden:
                notify(FacetedGlobalSettingsChangedEvent(self.context))
            elif set(['hidden', 'operator']).intersection(update.keys()):
                notify(FacetedGlobalSettingsChangedEvent(self.context))

        return self._redirect('Changes saved')
    def query(self, cid, **kwargs):
        """ Count catalog items
        """
        # Cleanup query
        kwargs.pop("sort_on", None)
        kwargs.pop("sort_order", None)
        kwargs.pop("sort[]", None)
        kwargs.pop("sort", None)
        kwargs.pop("reversed[]", None)
        oid = "%s-operator" % cid
        operator = kwargs.pop(oid, kwargs.pop(oid + "[]", None))

        if not operator or operator != "and":
            kwargs.pop(cid, None)
            self.request.form.pop(cid, None)
            # jQuery >= 1.4 adds type to params keys
            # $.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4"
            # Let's fix this
            kwargs.pop(cid + "[]", None)
            self.request.form.pop(cid + "[]", None)

        criteria = ICriteria(self.context)
        criterion = criteria.get(cid)

        start = time.time()
        # Query catalog
        handler = getMultiAdapter((self.context, self.request), name=u"faceted_query")

        if criterion.get("index", "") == "Language":
            kwargs["_language_count_"] = True
        brains = handler.query(batch=False, sort=False, **kwargs)

        # Get index
        widget = criteria.widget(cid=cid)(self.context, self.request, criterion)
        count = getattr(widget, "count", lambda brains: {})
        res = count(brains)
        logger.debug("Benchmark %s: %s", cid, time.time() - start)
        return res
    def edit(self, cid, **kwargs):
        """ See IFacetedCriterionHandler
        """
        kwargs = self._request_form(kwargs)

        criteria = ICriteria(self.context)
        widget = criteria.widget(cid=cid)
        fields = widget.edit_schema.keys()[:]
        update = {}

        for prop in fields:
            new_value = kwargs.get(prop, None)
            if new_value is None:
                continue
            update[prop] = new_value

        if update:
            criteria.edit(cid, **update)
            if widget.hidden:
                notify(FacetedGlobalSettingsChangedEvent(self.context))
            elif set(['hidden', 'operator']).intersection(update.keys()):
                notify(FacetedGlobalSettingsChangedEvent(self.context))

        return self._redirect('Changes saved')
 def __init__(self, context, request):
     # TODO: update this to new workings of collection facet (now that we have a custom portal_type)
     super(DatasetsCollectionListView, self).__init__(context, request)
     self.datasets_url = self.context.absolute_url()
     self.criteria = ICriteria(self.context, {})
     self.defaults = {}
     self.criterion = None
     for criterion in self.criteria.values():
         if criterion.widget == 'pathselect':
             self.criterion = criterion
         if criterion.widget == 'sorting':
             default = criterion.default
             if not default:
                 continue
             if '(reverse)' in default:
                 default = default.replace('(reverse)', '', 1)
                 self.defaults['reversed'] = True
             self.defaults[criterion.getId()] = default
class DatasetsCollectionListView(BrowserView):

    title = u"Collections"

    def __init__(self, context, request):
        # TODO: update this to new workings of collection facet (now that we have a custom portal_type)
        super(DatasetsCollectionListView, self).__init__(context, request)
        self.datasets_url = self.context.absolute_url()
        self.criteria = ICriteria(self.context, {})
        self.defaults = {}
        self.criterion = None
        for criterion in self.criteria.values():
            if criterion.widget == 'pathselect':
                self.criterion = criterion
            if criterion.widget == 'sorting':
                default = criterion.default
                if not default:
                    continue
                if '(reverse)' in default:
                    default = default.replace('(reverse)', '', 1)
                    self.defaults['reversed'] = True
                self.defaults[criterion.getId()] = default

    def categories(self):
        for term in getUtility(IVocabularyFactory, 'collection_category_source')(self.context):
            yield term

    def get_browse_link(self, uuid):
        # return link into datasets facetedview to filter given collection
        collection = uuidToCatalogBrain(uuid)
        if not collection:
            return self.datasets_url
        params = dict(self.defaults)
        if self.criterion:
            params[self.criterion.getId()] = collection.UID
            return "{}#{}".format(self.datasets_url, urlencode(params))
        # fallback to original datasets_listing_view
        groupid = collection.getObject().__parent__.getId()
        params['datasets.filter.source:list'] = '{}-{}'.format(self.datesets_url, groupid, collection.getId)
        return "{}/?{}" . format(self.datasets_url, urlencode(params))
Beispiel #52
0
def installFacetedNavigation(obj, event):
    if not ISecretomeFolder.providedBy(obj): return
    factory = getToolByName(obj, 'portal_factory')
    if factory.isTemporary(obj): return
    request = obj.REQUEST
    subtyper = getMultiAdapter((obj, request), name=u'faceted_subtyper')
    if subtyper.is_faceted or not subtyper.can_enable: return
    subtyper.enable()
    criteria = ICriteria(obj)
    for cid in criteria.keys():
        criteria.delete(cid)
    criteria.add('resultsperpage', 'bottom', 'default', title='Results per page', hidden=True, start=0, end=50, step=5,
        default=20)
    criteria.add(
        'checkbox', 'bottom', 'default',
        title='Obj provides',
        hidden=True,
        index='object_provides',
        operator='or',
        vocabulary=u'eea.faceted.vocabularies.ObjectProvides',
        default=[IGeneProtein.__identifier__],
        count=False,
        maxitems=0,
        sortreversed=False,
        hidezerocount=False
    )
    criteria.add('debug', 'top', 'default', title='Debug Criteria', user='******')
    criteria.add(
        'checkbox', 'left', 'default',
        title=u'Databases',
        hidden=False,
        index='databaseNames',
        operator='or',
        vocabulary=u'eke.secretome.DatabaseNamesVocabulary',
        count=False,
        maxitems=0,
        sortreversed=False,
        hidezerocount=False
    )
    IFacetedLayout(obj).update_layout(u'faceted_secretome_view')
    noLongerProvides(obj, IHidePloneLeftColumn)
Beispiel #53
0
def setFacetedNavigation(folder, request, force=False):
    subtyper = getMultiAdapter((folder, request), name=u'faceted_subtyper')
    if (subtyper.is_faceted or not subtyper.can_enable) and not force: return
    subtyper.enable()
    urlTool = plone.api.portal.get_tool(name='portal_url')
    path = '/' + '/'.join(urlTool.getRelativeContentPath(folder))
    criteria = ICriteria(folder)
    for cid in criteria.keys():
        criteria.delete(cid)
    criteria.add(
        'checkbox', 'left', 'default',
        title=u'Organ',
        hidden=False,
        index='indicatedBodySystems',
        operator='or',
        vocabulary=u'eke.biomarker.IndicatedOrgansVocabulary',
        count=False,
        maxitems=0,
        sortreversed=False,
        hidezerocount=False,
    )
    criteria.add('resultsperpage', 'bottom', 'default', title='Results per page', hidden=True, start=0, end=50, step=5, default=20)
    criteria.add('sorting', 'bottom', 'default', title='Sort on', hidden=True, default='sortable_title')
    criteria.add(
        'checkbox', 'bottom', 'default',
        title='Obj provides',
        hidden=True,
        index='object_provides',
        operator='or',
        vocabulary=u'eea.faceted.vocabularies.ObjectProvides',
        default=[IBiomarker.__identifier__],
        count=False,
        maxitems=0,
        sortreversed=False,
        hidezerocount=False
    )
    criteria.add('path', 'bottom', 'default', title='Path Search', hidden=True, index='path', default=path)
    criteria.add('text', 'top', 'default', title=u'Search', hidden=False, index='SearchableText', count=False,
        onlyallelements=True)
    IFacetedLayout(folder).update_layout('faceted_biomarkers_view')
    noLongerProvides(folder, IHidePloneLeftColumn)
    noLongerProvides(folder, IHidePloneRightColumn)
Beispiel #54
0
def setFacetedNavigation(folder, request):
    subtyper = getMultiAdapter((folder, request), name=u'faceted_subtyper')
    if subtyper.is_faceted or not subtyper.can_enable: return
    subtyper.enable()
    urlTool = getToolByName(folder, 'portal_url')
    path = '/' + '/'.join(urlTool.getRelativeContentPath(folder))
    criteria = ICriteria(folder)
    for cid in criteria.keys():
        criteria.delete(cid)
    criteria.add('resultsperpage', 'bottom', 'default', title='Results per page', hidden=True, start=0, end=50, step=5, default=20)
    criteria.add('sorting', 'bottom', 'default', title='Sort on', hidden=True, default='sortable_title')
    criteria.add(
        'checkbox', 'left', 'default',
        title='System',
        hidden=False,
        index='getSystemName',
        operator='or',
        vocabulary=u'eke.specimens.vocab.SystemNames',
        count=False,
        maxitems=0,
        sortreversed=False,
        hidezerocount=False,
    )
    criteria.add(
        'checkbox', 'left', 'default',
        title='Diagnosis',
        hidden=False,
        index='diagnosis',
        operator='or',
        vocabulary=u'eke.specimens.vocab.Diagnoses',
        count=False,
        maxitems=0,
        sortreversed=False,
        hidezerocount=False,
    )
    criteria.add(
        'checkbox', 'left', 'default',
        title='Storage',
        hidden=False,
        index='getStorageType',
        operator='or',
        vocabulary=STORAGE_VOCAB_NAME,
        count=False,
        maxitems=5,
        sortreversed=False,
        hidezerocount=False,
    )
    criteria.add(
        'checkbox', 'left', 'default',
        title='Collection Type',
        hidden=False,
        index='collectionType',
        operator='or',
        vocabulary=COLLECTION_VOCAB_NAME,
        count=False,
        maxitems=5,
        sortreversed=False,
        hidezerocount=False,
    )
    criteria.add(
        'checkbox', 'left', 'default',
        title='Site',
        hidden=False,
        index='siteName',
        operator='or',
        vocabulary=u'eke.specimens.vocab.SitesWithSpecimens',
        count=False,
        maxitems=5,
        sortreversed=False,
        hidezerocount=False,
    )
    criteria.add(
        'checkbox', 'bottom', 'default',
        title='Obj provides',
        hidden=True,
        index='object_provides',
        operator='or',
        vocabulary=u'eea.faceted.vocabularies.ObjectProvides',
        default=[ISpecimenSet.__identifier__],
        count=False,
        maxitems=0,
        sortreversed=False,
        hidezerocount=False
    )
    criteria.add(
        'text', 'center', 'default',
        title='Open Search',
        hidden=False,
        index='SearchableText',
    )
    criteria.add('path', 'bottom', 'default', title='Path Search', hidden=True, index='path', default=path)
    IFacetedLayout(folder).update_layout('faceted_specimens_view')
    alsoProvides(folder, IHidePloneRightColumn)
class CollectionWidget(RadioWidget):
    """A widget listing collections used as base query."""

    widget_type = 'collection-link'
    widget_label = 'Collection Link'
    faceted_field = False

    index = ViewPageTemplateFile('widget.pt')

    css_class = 'faceted-tagscloud-collection-widget'

    category_vocabulary = (
        'collective.eeafaceted.collectionwidget.collectioncategoryvocabulary'
    )

    def __init__(self, context, request, data=None):
        super(CollectionWidget, self).__init__(context, request, data)
        # real context could not be current context but some distant context
        # look in eea.facetednavigation.criteria.handler.Criteria
        self.criteria = ICriteria(self.context)
        self.context = self.criteria.context
        # display the fieldset around the widget when rendered?
        self.display_fieldset = True

    def update(self):
        """Remove fields 'index' and 'catalog', unused."""
        super(CollectionWidget, self).update()
        default_group = self.groups[0]
        if 'index' in default_group.fields:
            del default_group.fields['index']
        if 'catalog' in default_group.widgets:
            del default_group.fields['catalog']
        if 'index' in default_group.widgets:
            del default_group.widgets['index']
        if 'catalog' in default_group.widgets:
            del default_group.widgets['catalog']

    def _initialize_widget(self):
        """ """
        self.grouped_vocabulary = self._generate_vocabulary()

    def __call__(self, **kwargs):
        # compute the vocabulary used in the widget
        self._initialize_widget()
        return super(CollectionWidget, self).__call__(**kwargs)

    def query(self, form):
        """ Get value from form and return a catalog dict query """
        # we receive the UID of the selected Collection
        # get the collection, compute the query and return it
        collection_uid = form.get(self.data.__name__, '')
        if collection_uid and not collection_uid == 'all':
            # get the collection and compute the query
            catalog = getToolByName(self.context, 'portal_catalog')
            brains = catalog(UID=collection_uid)
            collection = brains[0].getObject()
            query = queryparser.parseFormquery(collection, collection.query)
            # use sort_on defined on the collection if it is
            # not already in the request.form
            # get the sort_on criterion and look in the request.form if it is used
            sort_on_is_used = False
            for criterion_id, criterion in self.criteria.items():
                if criterion.widget == SortingWidget.widget_type:
                    # criterion id in the request.form is like c0[]
                    if "{0}[]".format(criterion_id) in self.request.form:
                        sort_on_is_used = True
                    break
            if not sort_on_is_used:
                if collection.sort_on:
                    query['sort_on'] = collection.sort_on
                if collection.sort_reversed:
                    query['sort_order'] = collection.sort_reversed and 'descending' or ''
            return query
        return {}

    def count(self, brains, sequence=None):
        """
        """
        res = {}
        if not sequence:
            sequence = [term.token for term in self.vocabulary()]

        catalog = getToolByName(self.context, 'portal_catalog')
        for value in sequence:
            if not value:
                res[value] = len(brains)
                continue
            res[value] = len(
                catalog(self.query(form={self.data.__name__: value})))
        return res

    @property
    @memoize
    def default(self):
        """Return the default value"""
        default = super(CollectionWidget, self).default
        if not default:
            # it is possible to not select a default, it will have
            # same behaviour as selecting option "All"
            return default
        # call an adapter to get the correct value
        return self.adapter_default_value

    @property
    def adapter_default_value(self):
        adapter = queryMultiAdapter((self.context, self.request, self),
                                    IWidgetDefaultValue)
        if adapter:
            return adapter.value

    @property
    def default_term_value(self):
        idx = self.sortreversed and -1 or 0
        terms = self.portal_vocabulary()
        if len(terms) > 0:
            return terms[idx][0]

    def kept_criteria_as_json(self, collection_uid):
        '''Given a p_collectionUID, get indexes managed by the collection.'''
        adapter = queryMultiAdapter((self.context, self),
                                    IKeptCriteria)
        res = adapter.compute(collection_uid)
        # DateTime are not json serializable, we convert them before
        for k, v in res.iteritems():
            if isinstance(v, DateTime):
                res[k] = v.ISO()

        return json.dumps(res)

    @property
    def advanced_criteria(self):
        '''Returns a dict containing advanced criteria, the key is the
           criterion id and the value is the managed index.'''
        faceted_config = queryMultiAdapter((self.context, self.request),
                                           name='configure_faceted.html')
        advanced_criteria = {}
        for criterion in faceted_config.get_criteria():
            if criterion.section == u'advanced':
                advanced_criteria[criterion.getId()] = criterion.index
        return advanced_criteria

    @property
    def advanced_criteria_as_json(self):
        return json.dumps(self.advanced_criteria.keys())

    @property
    def sortreversed(self):
        return bool(int(getattr(self.data, 'sortreversed', u'0') or u'0'))

    @property
    def hidealloption(self):
        return bool(int(getattr(self.data, 'hidealloption', u'0') or u'0'))

    @property
    @memoize
    def categories(self):
        factory = getUtility(IVocabularyFactory, self.category_vocabulary)
        voc = factory(self.context)
        return voc

    def vocabulary(self):
        voc_id = self.data.get('vocabulary', None)
        voc = queryUtility(IVocabularyFactory, voc_id, None)
        if voc is None:
            return []

        return list(voc(self.context))

    def _generate_vocabulary(self):
        voc = OrderedDict()
        # empty category
        voc[''] = {'collections': []}
        for term in self.categories:
            voc[term.token] = {'term': term, 'collections': []}

        categories_token = [term.token for term in self.categories]
        for term in self.vocabulary():
            parent = aq_parent(term.value)
            # collections directly added to context, no intermediate category
            if parent == self.context and parent.UID() not in categories_token:
                category = ''
            elif parent.UID() in categories_token:
                category = parent.UID()
            else:
                # parent is not visible, a subfolder private for current user
                continue

            voc[category]['collections'].append(term)

        # remove empty categories
        res = OrderedDict()
        for k, v in voc.items():
            if v['collections']:
                res[k] = v

        return res
    def test_with_sub_faceted(self):
        """Test behaviour of the vocabulary when we have subfolders
           with activated faceted navigation."""
        # add collection to self.folder
        c1 = api.content.create(
            id='collection1',
            type='DashboardCollection',
            title='Collection 1',
            container=self.folder,
            tal_condition=u'',
            roles_bypassing_talcondition=[],
        )
        c2 = api.content.create(
            id='collection2',
            type='DashboardCollection',
            title='Collection 2',
            container=self.folder,
            tal_condition=u'',
            roles_bypassing_talcondition=[],
        )

        # create a subfolder, add collections into it
        api.content.create(
            id='subfolder',
            type='Folder',
            title='Subfolder',
            container=self.folder
        )
        c3 = api.content.create(
            id='collection3',
            type='DashboardCollection',
            title='Collection 3',
            container=self.folder.subfolder,
            tal_condition=u'',
            roles_bypassing_talcondition=[],
        )
        c4 = api.content.create(
            id='collection4',
            type='DashboardCollection',
            title='Collection 4',
            container=self.folder.subfolder,
            tal_condition=u'',
            roles_bypassing_talcondition=[],
        )

        # for now, faceted navigation is not enabled on subfolder,
        # it behaves like a normal category

        vocabulary = CollectionVocabularyFactory(self.folder)
        folderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder)
        subfolderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder.subfolder)
        self.assertTrue(folderCatVocabulary.by_token.keys() ==
                        subfolderCatVocabulary.by_token.keys())
        # redirect_to is not filled
        self.assertFalse(vocabulary.getTermByToken(c1.UID()).title[1])
        self.assertFalse(vocabulary.getTermByToken(c2.UID()).title[1])
        self.assertFalse(vocabulary.getTermByToken(c3.UID()).title[1])
        self.assertFalse(vocabulary.getTermByToken(c4.UID()).title[1])

        # now enable faceted navigation for subfolder
        subtyper = getMultiAdapter((self.folder.subfolder, self.request),
                                   name=u'faceted_subtyper')
        subtyper.enable()
        # change the CollectionWidget id to "c44" so we are sure that
        # the generated link is the one to this widget
        collection_widget = ICriteria(self.folder.subfolder).get('c1')
        self.assertEquals(collection_widget.widget,
                          CollectionWidget.widget_type)
        collection_widget.__name__ = u'c44'
        vocabulary = CollectionVocabularyFactory(self.folder)
        folderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder)
        subfolderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder.subfolder)
        self.assertTrue(folderCatVocabulary.by_token.keys() ==
                        subfolderCatVocabulary.by_token.keys())
        # as we are getting the vocabulary on self.folder,
        # redirect_to is filled for collections of subfolder
        # while generating links to specific sub faceted, a 'no_redirect' is added
        # so the user is not redirected to the faceted using the default
        self.assertFalse(vocabulary.getTermByToken(c1.UID()).title[1])
        self.assertFalse(vocabulary.getTermByToken(c2.UID()).title[1])
        self.assertEquals(vocabulary.getTermByToken(c3.UID()).title[1],
                          '{0}?no_redirect=1#c44={1}'.format(self.folder.subfolder.absolute_url(),
                                                             c3.UID())
                          )
        self.assertEquals(vocabulary.getTermByToken(c4.UID()).title[1],
                          '{0}?no_redirect=1#c44={1}'.format(self.folder.subfolder.absolute_url(),
                                                             c4.UID())
                          )

        # if we get vocabulary from subfolder, it works the other way round
        # but moreover, we have a no_redirect=1 that avoid to redirect if we
        # are sending the user to the root folder of the faceted navigation
        vocabulary = CollectionVocabularyFactory(self.folder.subfolder)
        folderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder)
        subfolderCatVocabulary = CollectionCategoryVocabularyFactory(self.folder.subfolder)
        self.assertTrue(folderCatVocabulary.by_token.keys() ==
                        subfolderCatVocabulary.by_token.keys())
        self.assertEquals(vocabulary.getTermByToken(c1.UID()).title[1],
                          '{0}?no_redirect=1#c1={1}'.format(self.folder.absolute_url(),
                                                            c1.UID())
                          )
        self.assertEquals(vocabulary.getTermByToken(c2.UID()).title[1],
                          '{0}?no_redirect=1#c1={1}'.format(self.folder.absolute_url(),
                                                            c2.UID())
                          )
        self.assertFalse(vocabulary.getTermByToken(c3.UID()).title[1])
        self.assertFalse(vocabulary.getTermByToken(c4.UID()).title[1])

        # test the generated link when having a faceted using a sorting index reversed or not
        data = {'default': u'effective(reverse)'}
        sortingCriterionId = ICriteria(self.folder).add('sorting', 'bottom', **data)
        vocabulary = CollectionVocabularyFactory(self.folder.subfolder)
        self.assertEquals(vocabulary.getTermByToken(c1.UID()).title[1],
                          '{0}?no_redirect=1#c1={1}&c5=effective&reversed=on'.format(self.folder.absolute_url(),
                                                                                     c1.UID()))
        data = {'default': u'effective'}
        ICriteria(self.folder).edit(sortingCriterionId, **data)
        vocabulary = CollectionVocabularyFactory(self.folder.subfolder)
        self.assertEquals(vocabulary.getTermByToken(c1.UID()).title[1],
                          '{0}?no_redirect=1#c1={1}&c5=effective'.format(self.folder.absolute_url(),
                                                                         c1.UID()))

        # test that other default values are kept also, add a 'resultsperpage' widget
        data = {'default': u'20'}
        ICriteria(self.folder).add('resultsperpage', 'bottom', **data)
        vocabulary = CollectionVocabularyFactory(self.folder.subfolder)
        self.assertEquals(vocabulary.getTermByToken(c1.UID()).title[1],
                          '{0}?no_redirect=1#c1={1}&c5=effective&c6=20'.format(self.folder.absolute_url(),
                                                                               c1.UID()))
Beispiel #57
0
def createMembersListSearchPage(portal):
    '''Create the members list page'''
    # New in profile version 1 (software version 1.0.2):
    request = portal.REQUEST
    if 'members-list' in portal.objectIds():
        portal.manage_delObjects('members-list')
    membersList = portal[portal.invokeFactory('Folder', 'members-list')]
    membersList.setTitle('Members List')
    membersList.setDescription('A directory of the people that comprise EDRN.')
    membersList.setExcludeFromNav(True)
    _doPublish(membersList, getToolByName(portal, 'portal_workflow'))
    subtyper = getMultiAdapter((membersList, request), name=u'faceted_subtyper')
    subtyper.enable()
    layout = IFacetedLayout(membersList)
    layout.update_layout('folder_listing')
    criteria = ICriteria(membersList)
    for cid in criteria.keys():
        criteria.delete(cid)
    criteria.add('resultsperpage', 'bottom', 'default', title='Results per page', hidden=True, start=0, end=50, step=5, default=20)
    criteria.add('sorting', 'bottom', 'default', title='Sort on', hidden=True, default='sortable_title')
    criteria.add(
        'checkbox', 'bottom', 'default',
        title='Obj provides',
        hidden=True,
        index='object_provides',
        operator='or',
        vocabulary=u'eea.faceted.vocabularies.ObjectProvides',
        default=[IPerson.__identifier__],
        count=False,
        maxitems=0,
        sortreversed=False,
        hidezerocount=False
    )
    criteria.add(
        'checkbox', 'left', 'default',
        title='Investigator',
        hidden=False,
        index='piUID',
        operator='or',
        vocabulary=u'eke.site.PrincipalInvestigators',
        count=False,
        maxitems=4,
        sortreversed=False,
        hidezerocount=False
    )
    criteria.add(
        'checkbox', 'left', 'default',
        title='Type',
        index='investigatorStatus',
        operator='or',
        vocabulary=u'eke.site.NotPeons',
        count=True,
        maxitems=0,
        sortreversed=False,
        hidezerocount=False
    )
    criteria.add(
        'checkbox', 'left', 'default',
        title='Institution',
        hidden=False,
        index='siteName',
        operator='or',
        vocabulary=u'eke.site.SitesNames',
        count=True,
        maxitems=4,
        sortreversed=False,
        hidezerocount=False
    )
    criteria.add(
        'checkbox', 'left', 'default',
        title='Member Type',
        hidden=False,
        index='memberType',
        operator='or',
        vocabulary=u'eke.site.MemberType',
        count=True,
        maxitems=20,
        sortreversed=False,
        hidezerocount=False
    )
    criteria.add('criteria', 'top', 'default', title='Current Search')
    membersList.reindexObject()