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
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 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 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=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 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=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 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 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 __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('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
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
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 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)