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
Beispiel #2
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
Beispiel #3
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 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
Beispiel #5
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 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 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)
Beispiel #9
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
Beispiel #10
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
Beispiel #11
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)

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

    if 'Language' in query:
        query.pop('Language')
    logger.debug('QUERY: %s', query)
    return query
Beispiel #12
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())

        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))
        # make sure orphans is an integer, // is used so in Python3 we have an
        # integer division as by default, a division result is a float
        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 as err:
            logger.exception(err)
            return Batch([], 20, 0)
        if not brains:
            return Batch([], 20, 0)

        # Apply after query (filter) on brains
        start = time.time()
        for brains_filter in brains_filters:
            brains = brains_filter(brains, kwargs)

        if not batch:
            return brains

        if isinstance(brains, GeneratorType):
            brains = [brain for brain in brains]

        delta = time.time() - start
        if delta > 30:
            logger.warn("Very slow IWidgetFilterBrains adapters: %s at %s",
                brains_filters, self.context.absolute_url())
        return Batch(brains, num_per_page, b_start, orphan=orphans)
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