def test_batch_lazy_map(self): def get(key): return key sequence = LazyMap(get, range(80, 90), actual_result_count=95) batch = Batch(sequence, size=10, start=80) self.assertEqual([b for b in batch], [80, 81, 82, 83, 84, 85, 86, 87, 88, 89]) self.assertEqual(batch.numpages, 10) self.assertEqual(batch.pagenumber, 9) self.assertEqual(batch.navlist, [6, 7, 8, 9, 10]) self.assertEqual(batch.leapback, []) self.assertEqual(batch.prevlist, [6, 7, 8]) self.assertEqual(batch.previous.length, 10) self.assertEqual(batch.next.length, 5) self.assertEqual(batch.pageurl({}), "b_start:int=80") self.assertEqual(batch.prevurls({}), [(6, "b_start:int=50"), (7, "b_start:int=60"), (8, "b_start:int=70")]) self.assertEqual(batch.nexturls({}), [(10, "b_start:int=90")])
def getUsers(self): """ Returns list of users """ b_start = self.request.get('b_start', 0) show_all = self.request.get('show_all', '').lower() == 'true' group_id = self.request.get('group_id', None) checked = self.request.get('users', []) self.selectcurrentbatch = not self.show_select_all_items self.selectorphan = not self.show_select_orphan_items if isinstance(checked, basestring): checked = [checked] if not isinstance(checked, (list, tuple)): raise(TypeError('checked must be list or tuple')) self.selectedusers = checked contents = map(self._getMemberInfo, self._getContents(group_id)) if show_all: pagesize = len(contents) else: pagesize = self.pagesize batch = Batch(contents, pagesize, b_start, orphan=1) map(self._setChecked, batch) batch.orphans = self._countOrphan(contents) return batch
def getTopics(self): """Returns a list of dicts containing information about the initial messages in threads. """ batch = self.request.get('batch', True) batch_size = int(self.request.get('b_size', 25)) batch_start = int(self.request.get('b_start', 0)) context = self.context topic_list = [] search = self.search getToplevelMessages = search.getToplevelMessages getMessageReferrers = search.getMessageReferrers messages = getToplevelMessages(recent_first=True) mem_list = IMembershipList(self.getMailingList()) if batch: messages = Batch(messages, batch_size, batch_start) for message in messages: msg_dict = messageStructure(message, sub_mgr=mem_list) msg_dict['responses'] = message.responses or 0 msg_dict['last_post'] = format_date(message.modification_date, context) msg_dict['url'] = msg_dict['url'] +'/forum_view' topic_list.append(msg_dict) messages.topic_list = topic_list return messages
def search(self, query=None, page=1, b_size=ITEMS_BY_REQUEST, uuids=None): # XXX uuids parameter not used anywhere catalog = api.portal.get_tool('portal_catalog') registry = getUtility(IRegistry) settings = registry.forInterface(ICoverSettings) searchable_types = settings.searchable_content_types # temporary we'll only list published elements catalog_query = {'sort_on': 'effective', 'sort_order': 'descending'} catalog_query['portal_type'] = searchable_types if query: catalog_query['Title'] = u'{0}*'.format(safe_unicode(query)) results = catalog(**catalog_query) self.total_results = len(results) start = (page - 1) * b_size results = Batch(results, size=b_size, start=start, orphan=0) return results
def solr_results(self, query=None, batch=True, b_size=10, b_start=0): searchable_text = self.request.form.get('SearchableText', '') if searchable_text: query = make_query(searchable_text) else: query = u'*:*' filters = self.solr_filters() if 'trashed' not in self.request.form: filters.append(u'trashed:false') params = { 'fl': [ 'UID', 'Title', 'getIcon', 'portal_type', 'path', 'containing_dossier', 'id', 'created', 'modified', 'review_state', 'bumblebee_checksum', ], 'hl': 'on', 'hl.fl': 'SearchableText', 'hl.snippets': 3, } solr = getUtility(ISolrSearch) resp = solr.search(query=query, filters=filters, start=b_start, rows=b_size, sort=self.solr_sort(), **params) results = OGSolrContentListing(resp) if batch: results = Batch(results, b_size, b_start) return results
def getFolderContents(self, contentFilter=None, batch=False, b_size=100, full_objects=False): #logging.getLogger('foo').error('cont hitted') context = self.context mtool = context.portal_membership cur_path = '/'.join(context.getPhysicalPath()) path = {} if not contentFilter: contentFilter = {} else: contentFilter = dict(contentFilter) if not contentFilter.get('sort_on', None): contentFilter['sort_on'] = 'getObjPositionInParent' if contentFilter.get('path', None) is None: path['query'] = cur_path path['depth'] = 1 contentFilter['path'] = path show_inactive = mtool.checkPermission('Access inactive portal content', context) # Provide batching hints to the catalog b_start = int(context.REQUEST.get('b_start', 0)) # Evaluate in catalog context because # some containers override queryCatalog # with their own unrelated method (Topics) method = context.portal_catalog.queryCatalog if IATTopic.providedBy(self.context): method = self.context.queryCatalog contents = list( method( contentFilter, show_all=1, show_inactive=show_inactive, )) if full_objects: contents = [b.getObject() for b in contents] contents.sort(key=comparecustom) if not b_size: b_size = len(contents) if batch: batch = Batch(contents, b_size, b_start, orphan=0) return batch return contents
def redirects(self): """ Get existing redirects from the redirection storage. Return dict with the strings redirect, path and redirect-to. Strip the id of the instance from path and redirect-to if it is present. (Seems to be always true) If id of instance is not present in path the var 'path' and 'redirect' are equal. """ return Batch( RedirectionSet( query=self.request.form.get('q', ''), created=self.request.form.get('datetime', ''), manual=self.request.form.get('manual', ''), ), 15, int(self.request.form.get('b_start', '0')), orphan=1, )
def get_all_events(self, batch=True): # Fall back to default language for local events kw = {} default_lang = api.portal.get_tool( "portal_languages").getDefaultLanguage() if ITranslatable.providedBy(self.context): if default_lang != self.context.Language(): portal = getSite() trans = ITranslationManager( self.context).get_translation(default_lang) root = getNavigationRootObject(trans, portal) kw['path'] = '/'.join(root.getPhysicalPath()) kw['Language'] = [default_lang, ''] start, end = self._start_end sort = 'start' sort_reverse = False if self.mode in ('past', 'all'): sort_reverse = True expand = True local_events = get_events(self.context, start=start, end=end, sort=sort, review_state='published', sort_reverse=sort_reverse, ret_mode=RET_MODE_ACCESSORS, expand=expand, **kw) remote_events = self._remote_events() reverse = self.mode == 'past' all_events = sorted(local_events + remote_events, key=lambda x: x.start, reverse=reverse) if batch: b_start = self.b_start b_size = self.b_size res = Batch(all_events, size=b_size, start=b_start, orphan=self.orphan) else: res = all_events return res
def results(self, query=None, batch=True, b_size=10, b_start=0): """ Get properly wrapped search results from the catalog. Everything in Plone that performs searches should go through this view. 'query' should be a dictionary of catalog parameters. """ if query is None: query = {} if batch: query['b_start'] = b_start = int(b_start) query['b_size'] = b_size # 79924 patch str values in order to avoid bad values # in case it contains non alphabetic characters p = re.compile(r"[^A-Za-z0-9-_]+") query = self.filter_query(query) if query is None: query = {} for k, v in query.items(): if k != 'sort_on': continue if not isinstance(v, basestring): continue if p.search(v): query[k] = re.sub(p, "", v) # 79924 # you should only be allowed to search by date or sortable_title # by removing the sort_on key if we have other values passed in # we avoid a CatalogError if v and v not in ['Date', 'sortable_title']: del query[k] if not query: res = [] else: catalog = getToolByName(self.context, 'portal_catalog') try: res = catalog(**query) except ParseError: return [] res = IContentListing(res) if batch: res = Batch(res, b_size, b_start) return res
def __call__(self): form = self.request.form if self.request.REQUEST_METHOD == 'POST': if form.get('button.exportregistry'): return self.export_registry() if form.get('button.importregistry'): return self.import_registry() search = form.get('q') searchp = form.get('qp') compare = _is_in if searchp not in (None, ''): search = searchp if search is not None and search.startswith('prefix:'): search = search[len('prefix:'):] compare = _starts_with if not search: compare = _true self.prefixes = {} self.records = [] for record in self.context.records.values(): ifaceName = record.interfaceName if ifaceName is not None: recordPrefix = ifaceName.split('.')[-1] prefixValue = record.interfaceName else: prefixValue = record.__name__ for prefix in _okay_prefixes: name = record.__name__ if name.startswith(prefix): recordPrefix = '.'.join( name.split('.')[:len(prefix.split('.')) + 1]) prefixValue = recordPrefix break if recordPrefix not in self.prefixes: self.prefixes[recordPrefix] = prefixValue if (compare(search, prefixValue) or compare(search, record.__name__)): self.records.append(record) self.records = Batch(self.records, 15, int(form.get('b_start', '0')), orphan=1) return super(RecordsControlPanel, self).__call__()
def _makequery(self, query=None, batch=False, b_start=0, b_size=30, sort_on=None, sort_order=None, limit=0, brains=False): """Parse the (form)query and return using multi-adapter""" parsedquery = queryparser.parseFormquery( self.context, query, sort_on, sort_order, catalog_name=self.catalog_name, kwargs=self.contentFilter) if not parsedquery: if brains: return [] else: return IContentListing([]) catalog = getToolByName(self.context, self.catalog_name) if batch: parsedquery['b_start'] = b_start parsedquery['b_size'] = b_size elif limit: parsedquery['sort_limit'] = limit if 'path' not in parsedquery: parsedquery['path'] = {'query': ''} parsedquery['path']['query'] = getNavigationRoot(self.context) + \ parsedquery['path']['query'] results = catalog(parsedquery) if not brains: results = IContentListing(results) if batch: results = Batch(results, b_size, b_start) return results
def events(self, ret_mode=RET_MODE_ACCESSORS, expand=False, batch=True): res = [] if self.is_collection: ctx = self.default_context # Whatever sorting is defined, we're overriding it. sort_on = 'start' sort_order = None if self.mode in ('past', 'all'): sort_order = 'reverse' query = queryparser.parseFormquery(ctx, ctx.query, sort_on=sort_on, sort_order=sort_order) custom_query = self.request.get('contentFilter', {}) if 'start' not in query or 'end' not in query: # ... else don't show the navigation bar start, end = self._start_end start, end = _prepare_range(ctx, start, end) custom_query.update(start_end_query(start, end)) res = ctx.results(batch=False, brains=True, custom_query=custom_query) if expand: # get start and end values from the query to ensure limited # listing for occurrences start, end = self._expand_events_start_end( query.get('start') or custom_query.get('start'), query.get('end') or custom_query.get('end')) # import pdb; pdb.set_trace() res = expand_events(res, ret_mode, start=start, end=end, sort=sort_on, sort_reverse=True if sort_order else False) else: res = self._get_events(ret_mode, expand=expand) if batch: b_start = self.b_start b_size = self.b_size res = Batch(res, size=b_size, start=b_start, orphan=self.orphan) return res
def cloudQueryCatalog(self, use_types_blacklist=False, use_navigation_root=False,\ batch=True, b_size=10, b_start=0): results = [] portlet_assignments = self.findPortlet() base_query = self.request.form.copy() del base_query['path'] base_query['use_types_blacklist'] = use_types_blacklist base_query['use_navigation_root'] = use_navigation_root if portlet_assignments: base_query['portal_type'] = portlet_assignments.type site_id = self.context.getId() base_query['path'] = '/' + site_id + (portlet_assignments.startpath or '') if batch: base_query['b_start'] = b_start = int(b_start) base_query['b_size'] = b_size tags = base_query.get('tags', None) if not tags: results = self.context.queryCatalog(base_query) else: for tag in tags: indexes = base_query.get(tag, []) result = [] for index in indexes: spec_query = base_query.copy() spec_query[index] = {'query': tag, 'operator': 'and'} result.extend(self.context.queryCatalog(spec_query)) if results: results_uid = [brain.UID for brain in results] results = [brain for brain in result if brain.UID in results_uid] else: results = result results = self.clearResults(results) results.sort(key=lambda x: x.modified, reverse=True) results = IContentListing(results) if batch: results = Batch(results, b_size, b_start) return results
def __call__(self, *args, **kwargs): redirect = False if ('button.cleanup' in self.request or 'button.delete.olderthan' in self.request or 'requeue.job' in self.request): redirect = self.button_action() if redirect: url = './@@publisher-config-listExecutedJobs' return self.request.RESPONSE.redirect(url) # BATCH # create a fake iterable object with the length of all objects, # but we dont want to load them all.. fake_data = xrange(self.queue.get_executed_jobs_length()) b_start = int(self.request.get('b_start', 0)) self.batch = Batch(fake_data, EXECUTED_JOBS_BATCH_SIZE, b_start) return super(ListExecutedJobs, self).__call__(*args, **kwargs)
def query(self, batch=True, sort=True, **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) catalog = getUtility(IFacetedCatalog) try: brains = catalog(self.context, **query) except Exception, err: logger.exception(err) return Batch([], 20, 0)
def search(self, query=None, page=0, b_size=10, uids=None): catalog = getToolByName(self.context, 'portal_catalog') registry = getUtility(IRegistry) settings = registry.forInterface(ICoverSettings) searchable_types = settings.searchable_content_types #temporary we'll only list published elements catalog_query = {'sort_on': 'effective', 'sort_order': 'descending'} catalog_query['portal_type'] = searchable_types if query: catalog_query = {'SearchableText': u'{0}*'.format(query)} # XXX: not implemented, this is needed? # if uids: # catalog_query['UID'] = uids results = catalog(**catalog_query) results = Batch(results, size=b_size, start=(page * b_size), orphan=0) return results
def __call__(self): items = [] try: per_page = int(self.request.form.get('perPage')) except: per_page = 10 try: page = int(self.request.form.get('page')) except: page = 1 results = self.results(batch=False, use_content_listing=False) batch = Batch(results, per_page, start=(page - 1) * per_page) registry = queryUtility(IRegistry) length = registry.get('plone.search_results_description_length') plone_view = getMultiAdapter((self.context, self.request), name='plone') registry = getUtility(IRegistry) view_action_types = registry.get( 'plone.types_use_view_action_in_listings', []) for item in batch: url = item.getURL() if item.portal_type in view_action_types: url = '%s/view' % url items.append({ 'id': item.UID, 'title': item.Title, 'description': plone_view.cropText(item.Description, length), 'url': url, 'state': item.review_state if item.review_state else None, }) return json.dumps({'total': len(results), 'items': items})
def results(self, query=None, batch=True, b_size=10, b_start=0): """ Get properly wrapped search results from the catalog. Everything in Plone that performs searches should go through this view. 'query' should be a dictionary of catalog parameters. """ if query is None: query = {} if batch: query['b_start'] = b_start = int(b_start) query['b_size'] = b_size config = queryUtility(ISolrConnectionConfig) if config: query['facet'] = 'true' query['facet.field'] = config.facets query = self.filter_query(query) if query is None: results = [] else: catalog = getToolByName(self.context, 'portal_catalog') try: results = catalog(**query) except ParseError: return [] qtime = timedelta(0) if isinstance( results, SolrResponse ) and results.responseHeader and 'QTime' in results.responseHeader: qtime = timedelta(milliseconds=results.responseHeader.get('QTime')) log.debug("Raw Results: %s", getattr(results, '__dict__', {})) results = IContentListing(results) if batch: results = Batch(results, b_size, b_start) results.qtime = qtime log.debug("Processed Results: %s", getattr(results, '__dict__', {})) return results
def __call__(self): items = [] try: per_page = int(self.request.form.get("perPage")) except: per_page = 10 try: page = int(self.request.form.get("page")) except: page = 1 results = self.results(batch=False, use_content_listing=False) batch = Batch(results, per_page, start=(page - 1) * per_page) registry = queryUtility(IRegistry) length = registry.get("plone.search_results_description_length") plone_view = getMultiAdapter((self.context, self.request), name="plone") registry = getUtility(IRegistry) view_action_types = registry.get( "plone.types_use_view_action_in_listings", []) for item in batch: url = item.getURL() if item.portal_type in view_action_types: url = "%s/view" % url items.append({ "id": item.UID, "title": item.Title, "description": plone_view.cropText(item.Description, length), "url": url, "state": item.review_state if item.review_state else None, }) return json.dumps({"total": len(results), "items": items})
def events(self, ret_mode=3, batch=True): res = [] is_col = self.is_collection is_top = self.is_topic if is_col or is_top: ctx = self.default_context if is_col: res = ctx.results(batch=False, sort_on='start', brains=False) else: res = ctx.queryCatalog( REQUEST=self.request, batch=False, full_objects=True ) # TODO: uff, we have to walk through all results... if ret_mode == 3: res = [IEventAccessor(obj) for obj in res if IEvent.providedBy(obj)] else: res = self._get_events(ret_mode) if batch: b_start = self.b_start b_size = self.b_size res = Batch(res, size=b_size, start=b_start, orphan=self.orphan) return res
def get_batched_press_releases(self): b_size = int(self.request.get('b_size', 20)) b_start = int(self.request.get('b_start', 0)) items = self.get_all_press_releases() for i in range(b_start, b_size): if i >= len(items): break if ICatalogBrain.providedBy(items[i]): item = items[i] obj = item.getObject() blob = getattr(obj.image, '_blob', None) plain_text = obj.restrictedTraverse('@@text-transform/text/text/plain') items[i] = { 'Title': item.Title, 'Date': DateTime(item.Date).utcdatetime(), 'getURL': item.getURL(), 'Description': item.Description, 'image': blob and base64.encodestring(blob.open().read()) or None, 'obj': obj, 'text': self.make_intro(plain_text), } else: items[i]['Date'] = DateTime(items[i]['Date']).utcdatetime() return Batch(items, b_size, b_start, orphan=1)
def __call__(self): form = self.request.form search = form.get('q') searchp = form.get('qp') compare = _is_in if searchp not in (None, ''): search = searchp if search is not None and search.startswith('prefix:'): search = search[len('prefix:'):] compare = _starts_with if not search: compare = _true self.prefixes = {} self.records = [] for record in self.context.records.values(): ifaceName = record.interfaceName if ifaceName is not None: recordPrefix = ifaceName.split('.')[-1] prefixValue = record.interfaceName else: prefixValue = record.__name__ for prefix in _okay_prefixes: name = record.__name__ if name.startswith(prefix): recordPrefix = '.'.join( name.split('.')[:len(prefix.split('.')) + 1]) prefixValue = recordPrefix break if recordPrefix not in self.prefixes: self.prefixes[recordPrefix] = prefixValue if compare(search, prefixValue) or compare(search, record.__name__): self.records.append(record) self.records = Batch(self.records, 15, int(form.get('b_start', '0')), orphan=1) return self.index()
def make_batch(sequence, size=25, start=0): """Make a batch of the given size from the sequence """ # we call an adapter here to allow backwards compatibility hooks return IBatch(Batch(sequence, size, start))
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)
def test_batch_no_lazy(self): batch = Batch(range(100), size=10, start=10) self.assertEqual([b for b in batch], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
def batch(self): b_size = 5 b_start = self.request.form.get('b_start', 0) return Batch(self.blogitems(), b_size, b_start, orphan=1)
def batch_results(self): """Wrap all results in a batch""" results = self._list_results() batch = Batch(results, BATCH_SIZE, int(self.batch_start), orphan=1) return batch
def solrResults(self, query, batch=True, b_size=20, b_start=0): """ Do the search with solr. Add to the query some solr parameters. """ # registry = getUtility(IRegistry) # required_solr_fields = registry['collective.solr.required'] # # if required_solr_fields: # # for field in required_solr_fields: # # query[field] = True query['facet'] = 'true' indexes_list = self.available_indexes.keys() indexes_list.append('portal_type') query['facet_field'] = indexes_list if batch: query['b_size'] = b_size query['b_start'] = b_start results = self.doSearch(query) res_dict = {'tabs': ['all']} if results.actual_result_count is None: res_dict['tot_results_len'] = 0 return res_dict res_dict['tot_results_len'] = results.actual_result_count filtered_results = [] global_facet_counts = getattr(results, 'facet_counts', None) if global_facet_counts: if getattr(global_facet_counts, 'facet_fields', None): # new c.solr with scorched lib facet_fields = global_facet_counts.facet_fields.items() facets = dict((k, dict(v)) for k, v in facet_fields) else: # old c.solr facets = global_facet_counts.get('facet_fields', {}) res_dict['tabs'] = self.solrAvailableTabs(facets) active_tab = self.context.REQUEST.form.get('filter_tab') if active_tab: filtered_results = self.doFilteredSearch(active_tab, query) else: if self.tabs_order[0] != 'all': for tab_id in self.tabs_order: filtered_results = self.doFilteredSearch(tab_id, query) if filtered_results: break if filtered_results: facet_counts = getattr(filtered_results, 'facet_counts', None) results = IContentListing(filtered_results) else: facet_counts = getattr(results, 'facet_counts', None) results = IContentListing(results) if batch: results = Batch(results, b_size, b_start) res_dict['results'] = results if facet_counts: if getattr(facet_counts, 'facet_fields', None): # new c.solr with scorched lib facets = dict( (k, dict(v)) for k, v in facet_counts.facet_fields.items()) else: # old c.solr facets = facet_counts.get('facet_fields', {}) res_dict['indexes_dict'] = self.solrFacetsFormatter(facets) return res_dict
class ArchiveSearchView(ArchiveBaseView): messages = None def __call__(self, *args, **kw): # Do the search before rendering the template, # to be sure PSMs are set. self.messages = self._searchArchive() return self.index(*args, **kw) def Title(self): title = _('label_archive_search', u'Search messages in ${title}') title = Message(title, mapping={ u'title': self.listTitle(), }) return title def _searchArchive(self, text=None): messages = [] batch = self.request.get('batch', True) batch_size = int(self.request.get('b_size', 25)) batch_start = int(self.request.get('b_start', 0)) text = text or decode(self.request.get('search_text'), '') context = self.context subscription = IMembershipList(self.getMailingList()) if text: text = text.strip() try: messages = self.search.search(text) except ParseTree.ParseError, inst: if "Token 'ATOM' required, 'EOF' found" in str( inst) or "Token 'EOF' required" in str(inst): self.request.set( 'portal_status_message', _(u'Invalid Search: Search phrase cannot end with \'and\', \'or\', or \'not\'' )) elif "Token 'ATOM' required" in str(inst): self.request.set( 'portal_status_message', _(u'Invalid Search: Search phrase cannot begin with \'and\', \'or\', or \'not\'' )) elif "a term must have at least one positive word" in str( inst): self.request.set( 'portal_status_message', _(u'Invalid Search: Search phrase cannot begin with \'not\'' )) elif "Query contains only common words" in str(inst): self.request.set( 'portal_status_message', _(u'Invalid Search: Search phrase must contain words other than \'and\', \'or\', and \'not\'' )) else: messages = catalogMessageIterator(messages, sub_mgr=subscription) if len(messages) == 0: self.request.set('portal_status_message', _(u'There were no messages found')) if batch: messages = Batch(messages, batch_size, batch_start) return messages
class FacetedQueryHandler(FolderView): """ Faceted Query """ def __init__(self, context, request): super(FacetedQueryHandler, self).__init__(context, request) if request.get('HTTP_X_REQUESTED_WITH', '') == 'XMLHttpRequest': registry = getUtility(IRegistry) settings = registry.forInterface(IEEASettings, check=False) if settings.disable_diazo_rules_ajax: request.response.setHeader('X-Theme-Disabled', '1') def macros(self, name='content-core'): """ Return macro from default layout """ return IFacetedLayout(self.context).get_macro(macro=name) @property def language(self): """ Get context language """ lang = getattr(self.context, 'getLanguage', None) if lang: return lang() return self.request.get('LANGUAGE', '') @property def default_criteria(self): """ Return default criteria """ query = {} criteria = queryAdapter(self.context, ICriteria) for cid, criterion in criteria.items(): widget = criteria.widget(cid=cid) widget = widget(self.context, self.request, criterion) default = widget.default if not default: continue query[cid.encode('utf-8')] = default return query def get_context(self, content=None): """ Return context """ wrapper = queryAdapter(self.context, IFacetedWrapper) if not wrapper: return self.context return wrapper(content) 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 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) if not brains: return Batch([], 20, 0) # Apply after query (filter) on brains 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] return Batch(brains, num_per_page, b_start, orphan=orphans)
def jsonByType(self, rooted, document_base_url, searchtext, page='1'): """ Returns the actual listing """ catalog_results = [] results = {} obj = self.obj catalog = api.portal.get_tool('portal_catalog') normalizer = getUtility(IIDNormalizer) if 'filter_portal_types' in self.request.keys(): self.filter_portal_types = self.request['filter_portal_types'] else: self.filter_portal_types = [i[0] for i in self._getCurrentValues()] if INavigationRoot.providedBy(obj) or (rooted == 'True' and document_base_url[:-1] == obj.absolute_url()): results['parent_url'] = '' else: results['parent_url'] = aq_parent(obj).absolute_url() if rooted == 'True': results['path'] = self.getBreadcrumbs(results['parent_url']) else: # get all items from siteroot to context (title and url) results['path'] = self.getBreadcrumbs() # get all portal types and get information from brains path = '/'.join(obj.getPhysicalPath()) catalog_query = {'sort_on': 'getObjPositionInParent'} catalog_query['portal_type'] = self.filter_portal_types catalog_query['path'] = {'query': path, 'depth': 1} if searchtext: catalog_query['Title'] = '{0}*'.format(searchtext) brains = catalog(**catalog_query) page = int(page, 10) start = (page - 1) * ITEMS_BY_REQUEST brains = Batch(brains, size=ITEMS_BY_REQUEST, start=start, orphan=0) results['has_next'] = brains.next is not None results['nextpage'] = brains.pagenumber + 1 results['total_results'] = len(brains) for brain in brains: catalog_results.append({ 'id': brain.getId, 'uuid': brain.UID or None, # Maybe Missing.Value 'url': brain.getURL(), 'portal_type': brain.portal_type, 'normalized_type': normalizer.normalize(brain.portal_type), 'classicon': 'contenttype-{0}'.format( normalizer.normalize(brain.portal_type)), 'r_state': 'state-{0}'.format( normalizer.normalize(brain.review_state or '')), 'title': brain.Title == '' and brain.id or brain.Title, 'icon': self.getIcon(brain).url or '', 'is_folderish': brain.is_folderish, 'description': brain.Description or '', }) # add catalog_results results['items'] = catalog_results # return results in JSON format return json.dumps(results)
def batch(self): batch = Batch(self.results(), size=self.b_size, start=self.b_start, orphan=1) return batch
def __call__(self): """ Get all the Blogentries and return the listingview template. It check if the request has some filtering parameters: -archiv -searchable_text -getCategoryUids -tag """ # TODO: Refactor me. This method is too long! context = aq_inner(self.context) query = {} self.filters = [] catalog = getToolByName(context, 'portal_catalog') if self.request.form.get('archiv'): datestr = self.request.form.get('archiv') try: start = DateTime(datestr) except DateTime.SyntaxError: start = DateTime(DateTime().strftime("%Y/%m/01")) end = DateTime('%s/%s/%s' % (start.year() + start.month() / 12, start.month() % 12 + 1, 1)) end = end - 1 query['created'] = {'query': (start.earliestTime(), end.latestTime()), 'range': 'minmax'} month_msgid = 'month_%s' % start.strftime("%b").lower() month = translate(month_msgid, domain='plonelocales', context=self.request) self.filters.append("%s %s" % (month, start.strftime('%Y'))) if self.request.form.get('getCategoryUids'): uid = self.request.form.get('getCategoryUids') category = catalog(UID=uid)[0] category_title = category.Title if category: category_obj = category.getObject() if base_hasattr(category_obj, 'getTranslations'): uid = [c.UID() for c in category_obj.getTranslations( review_state=False).values()] translated = category_obj.getTranslation() # If there are no translations getTranslation returns None if translated: category_title = translated.Title() query['getCategoryUids'] = uid category = catalog(UID=uid)[0] self.filters.append(category_title) if self.request.form.get('searchable_text'): query['SearchableText'] = self.request.get('searchable_text') self.filters.append(query['SearchableText']) if self.request.form.get('tag'): query['tags'] = self.request.form.get('tag').decode('utf-8') self.filters.append(query['tags']) if context.portal_type != 'Blog': querystring = self.query_string() if querystring: querystring = '?%s' % querystring return self.request.response.redirect( aq_parent(context).absolute_url() + querystring) query['sort_on'] = 'created' query['sort_order'] = 'reverse' query['portal_type'] = 'BlogEntry' # show all entries from all languages # XXX make this configurable if not base_hasattr(context, 'getTranslations'): self.entries = context.getFolderContents(contentFilter=query) else: translations = context.getTranslations().values() paths = ['/'.join(tr[0].getPhysicalPath()) for tr in translations] query['path'] = paths query['Language'] = 'all' self.entries = catalog(query) b_start = self.request.form.get('b_start', 0) self.batch = Batch(self.entries, 5, b_start) return self.template()