def getDeviceBrains(self, uid=None, start=0, limit=50, sort='name', dir='ASC', params=None, hashcheck=None): cat = ICatalogTool(self._getObject(uid)) reverse = dir=='DESC' qs = [] query = None globFilters = {} if params is None: params = {} for key, value in params.iteritems(): if key == 'ipAddress': ip = ensureIp(value) try: checkip(ip) except IpAddressError: pass else: if numbip(ip): minip, maxip = getSubnetBounds(ip) qs.append(Between('ipAddress', str(minip), str(maxip))) elif key == 'deviceClass': qs.append(MatchRegexp('uid', '(?i).*%s.*' % value)) elif key == 'productionState': qs.append(Or(*[Eq('productionState', str(state)) for state in value])) else: globFilters[key] = value if qs: query = And(*qs) brains = cat.search('Products.ZenModel.Device.Device', start=start, limit=limit, orderby=sort, reverse=reverse, query=query, globFilters=globFilters, hashcheck=hashcheck) return brains
def _buildRangeQuery(self, index, query): """Transform a complex range query to an Advancedquery version""" if query['range'] == 'min:max': return Between(index, min(query['query']), max(query['query'])) elif query['range'] == 'min': return Ge(index, min(query['query'])) elif query['range'] == 'max': return Le(index, max(query['query']))
def getDeviceBrains(self, uid=None, start=0, limit=50, sort='name', dir='ASC', params=None, hashcheck=None): cat = ICatalogTool(self._getObject(uid)) reverse = bool(dir == 'DESC') qs = [] query = None globFilters = {} if params is None: params = {} for key, value in params.iteritems(): if key == 'ipAddress': ip = ensureIp(value) try: checkip(ip) except IpAddressError: pass else: if numbip(ip): minip, maxip = getSubnetBounds(ip) qs.append(Between('ipAddress', str(minip), str(maxip))) # ZEN-10057 - move filtering on indexed groups/systems/location from post-filter to query elif key in organizersToClass: organizerQuery = self.findMatchingOrganizers(organizersToClass[key], organizersToPath[key], value) if not organizerQuery: return [] qs.append(organizerQuery) elif key == 'productionState': qs.append(Or(*[Eq('productionState', str(state)) for state in value])) else: globFilters[key] = value if qs: query = And(*qs) brains = cat.search( 'Products.ZenModel.Device.Device', start=start, limit=limit, orderby=sort, reverse=reverse, query=query, globFilters=globFilters, hashcheck=hashcheck ) return brains
def _process_request(self): # Use this function from a template that is using bika_listing_table # in such a way that the table_only request var will be used to # in-place-update the table. form_id = self.form_id form = self.request.form workflow = getToolByName(self.context, 'portal_workflow') catalog = getToolByName(self.context, self.catalog) # Some ajax calls duplicate form values? I have not figured out why! if self.request.form: for key, value in self.request.form.items(): if isinstance(value, list): self.request.form[key] = self.request.form[key][0] # If table_only specifies another form_id, then we abort. # this way, a single table among many can request a redraw, # and only it's content will be rendered. if form_id not in self.request.get('table_only', form_id): return '' ## review_state_selector - value can be specified in request selected_state = self.request.get("%s_review_state" % form_id, 'default') # get review_state id=selected_state states = [r for r in self.review_states if r['id'] == selected_state] self.review_state = states and states[0] or self.review_states[0] # set selected review_state ('default'?) to request self.request['review_state'] = self.review_state['id'] # contentFilter is expected in every self.review_state. for k, v in self.review_state['contentFilter'].items(): self.contentFilter[k] = v # sort on self.sort_on = self.request.get(form_id + '_sort_on', None) # manual_sort_on: only sort the current batch of items # this is a compromise for sorting without column indexes self.manual_sort_on = None if self.sort_on \ and self.sort_on in self.columns.keys() \ and self.columns[self.sort_on].get('index', None): idx = self.columns[self.sort_on].get('index', self.sort_on) self.contentFilter['sort_on'] = idx else: if self.sort_on: self.manual_sort_on = self.sort_on if 'sort_on' in self.contentFilter: del self.contentFilter['sort_on'] # sort order self.sort_order = self.request.get(form_id + '_sort_order', '') if self.sort_order: self.contentFilter['sort_order'] = self.sort_order else: if 'sort_order' not in self.contentFilter: self.sort_order = 'ascending' self.contentFilter['sort_order'] = 'ascending' self.request.set(form_id+'_sort_order', 'ascending') else: self.sort_order = self.contentFilter['sort_order'] if self.manual_sort_on: del self.contentFilter['sort_order'] # pagesize pagesize = self.request.get(form_id + '_pagesize', self.pagesize) if type(pagesize) in (list, tuple): pagesize = pagesize[0] try: pagesize = int(pagesize) except: pagesize = self.pagesize = 10 self.pagesize = pagesize # Plone's batching wants this variable: self.request.set('pagesize', self.pagesize) # and we want to make our choice remembered in bika_listing also self.request.set(self.form_id + '_pagesize', self.pagesize) # pagenumber self.pagenumber = int(self.request.get(form_id + '_pagenumber', self.pagenumber)) # Plone's batching wants this variable: self.request.set('pagenumber', self.pagenumber) # index filters. self.And = [] self.Or = [] ##logger.info("contentFilter: %s"%self.contentFilter) for k, v in self.columns.items(): if not v.has_key('index') \ or v['index'] == 'review_state' \ or v['index'] in self.filter_indexes: continue self.filter_indexes.append(v['index']) ##logger.info("Filter indexes: %s"%self.filter_indexes) # any request variable named ${form_id}_{index_name} # will pass it's value to that index in self.contentFilter. # all conditions using ${form_id}_{index_name} are searched with AND for index in self.filter_indexes: idx = catalog.Indexes.get(index, None) if not idx: logger.debug("index named '%s' not found in %s. " "(Perhaps the index is still empty)." % (index, self.catalog)) continue request_key = "%s_%s" % (form_id, index) value = self.request.get(request_key, '') if len(value) > 1: ##logger.info("And: %s=%s"%(index, value)) if idx.meta_type in('ZCTextIndex', 'FieldIndex'): self.And.append(MatchRegexp(index, value)) elif idx.meta_type == 'DateIndex': logger.info("Unhandled DateIndex search on '%s'"%index) continue else: self.Or.append(Generic(index, value)) # if there's a ${form_id}_filter in request, then all indexes # are are searched for it's value. # ${form_id}_filter is searched with OR agains all indexes request_key = "%s_filter" % form_id value = self.request.get(request_key, '') if type(value) in (list, tuple): value = value[0] if len(value) > 1: for index in self.filter_indexes: idx = catalog.Indexes.get(index, None) if not idx: logger.debug("index named '%s' not found in %s. " "(Perhaps the index is still empty)." % (index, self.catalog)) continue ##logger.info("Or: %s=%s"%(index, value)) if idx.meta_type in('ZCTextIndex', 'FieldIndex'): self.Or.append(MatchRegexp(index, value)) # https://github.com/bikalabs/Bika-LIMS/issues/1069 vals = value.split('-') if len(vals) > 2: valroot = vals[0] for i in range(1, len(vals)): valroot = '%s-%s' % (valroot, vals[i]) self.Or.append(MatchRegexp(index, valroot+'-*')) elif idx.meta_type == 'DateIndex': if type(value) in (list, tuple): value = value[0] if value.find(":") > -1: try: lohi = [DateTime(x) for x in value.split(":")] except: logger.info("Error (And, DateIndex='%s', term='%s')"%(index,value)) self.Or.append(Between(index, lohi[0], lohi[1])) else: try: self.Or.append(Eq(index, DateTime(value))) except: logger.info("Error (Or, DateIndex='%s', term='%s')"%(index,value)) else: self.Or.append(Generic(index, value)) self.Or.append(MatchRegexp('review_state', value)) # get toggle_cols cookie value # and modify self.columns[]['toggle'] to match. toggle_cols = self.get_toggle_cols() for col in self.columns.keys(): if col in toggle_cols: self.columns[col]['toggle'] = True else: self.columns[col]['toggle'] = False
def _process_request(self): """Scan request for parameters and configure class attributes accordingly. Setup AdvancedQuery or catalog contentFilter. Request parameters: <form_id>_limit_from: index of the first item to display <form_id>_rows_only: returns only the rows <form_id>_sort_on: list items are sorted on this key <form_id>_manual_sort_on: no index - sort with python <form_id>_pagesize: number of items <form_id>_filter: A string, will be regex matched against indexes in <form_id>_filter_indexes <form_id>_filter_indexes: list of index names which will be searched for the value of <form_id>_filter <form_id>_<index_name>: Any index name can be used after <form_id>_. any request variable named ${form_id}_{index_name} will pass it's value to that index in self.contentFilter. All conditions using ${form_id}_{index_name} are searched with AND. The parameter value will be matched with regexp if a FieldIndex or TextIndex. Else, AdvancedQuery.Generic is used. """ form_id = self.form_id form = self.request.form workflow = getToolByName(self.context, 'portal_workflow') catalog = getToolByName(self.context, self.catalog) # Some ajax calls duplicate form values? I have not figured out why! if self.request.form: for key, value in self.request.form.items(): if isinstance(value, list): self.request.form[key] = self.request.form[key][0] # If table_only specifies another form_id, then we abort. # this way, a single table among many can request a redraw, # and only it's content will be rendered. if form_id not in self.request.get('table_only', form_id) \ or form_id not in self.request.get('rows_only', form_id): return '' self.rows_only = self.request.get('rows_only','') == form_id self.limit_from = int(self.request.get(form_id + '_limit_from',0)) # contentFilter is allowed in every self.review_state. for k, v in self.review_state.get('contentFilter', {}).items(): self.contentFilter[k] = v # sort on self.sort_on = self.sort_on \ if hasattr(self, 'sort_on') and self.sort_on \ else None self.sort_on = self.request.get(form_id + '_sort_on', self.sort_on) self.sort_order = self.request.get(form_id + '_sort_order', 'ascending') self.manual_sort_on = self.request.get(form_id + '_manual_sort_on', None) if self.sort_on: if self.sort_on in self.columns.keys(): if self.columns[self.sort_on].get('index', None): self.request.set(form_id+'_sort_on', self.sort_on) # The column can be sorted directly using an index idx = self.columns[self.sort_on]['index'] self.sort_on = idx # Don't sort manually! self.manual_sort_on = None else: # The column must be manually sorted using python self.manual_sort_on = self.sort_on else: # We cannot sort for a column that doesn't exist! msg = "{}: sort_on is '{}', not a valid column".format( self, self.sort_on) logger.error(msg) self.sort_on = None if self.manual_sort_on: self.manual_sort_on = self.manual_sort_on[0] \ if type(self.manual_sort_on) in (list, tuple) \ else self.manual_sort_on if self.manual_sort_on not in self.columns.keys(): # We cannot sort for a column that doesn't exist! msg = "{}: manual_sort_on is '{}', not a valid column".format( self, self.manual_sort_on) logger.error(msg) self.manual_sort_on = None if self.sort_on or self.manual_sort_on: # By default, if sort_on is set, sort the items ASC # Trick to allow 'descending' keyword instead of 'reverse' self.sort_order = 'reverse' if self.sort_order \ and self.sort_order[0] in ['d','r'] \ else 'ascending' else: # By default, sort on created self.sort_order = 'reverse' self.sort_on = 'created' self.contentFilter['sort_order'] = self.sort_order if self.sort_on: self.contentFilter['sort_on'] = self.sort_on # pagesize pagesize = self.request.get(form_id + '_pagesize', self.pagesize) if type(pagesize) in (list, tuple): pagesize = pagesize[0] try: pagesize = int(pagesize) except: pagesize = self.pagesize = 10 self.pagesize = pagesize # Plone's batching wants this variable: self.request.set('pagesize', self.pagesize) # and we want to make our choice remembered in bika_listing also self.request.set(self.form_id + '_pagesize', self.pagesize) # index filters. self.And = [] self.Or = [] ##logger.info("contentFilter: %s"%self.contentFilter) for k, v in self.columns.items(): if not v.has_key('index') \ or v['index'] == 'review_state' \ or v['index'] in self.filter_indexes: continue self.filter_indexes.append(v['index']) ##logger.info("Filter indexes: %s"%self.filter_indexes) # any request variable named ${form_id}_{index_name} # will pass it's value to that index in self.contentFilter. # all conditions using ${form_id}_{index_name} are searched with AND for index in self.filter_indexes: idx = catalog.Indexes.get(index, None) if not idx: logger.debug("index named '%s' not found in %s. " "(Perhaps the index is still empty)." % (index, self.catalog)) continue request_key = "%s_%s" % (form_id, index) value = self.request.get(request_key, '') if len(value) > 1: ##logger.info("And: %s=%s"%(index, value)) if idx.meta_type in('ZCTextIndex', 'FieldIndex'): self.And.append(MatchRegexp(index, value)) elif idx.meta_type == 'DateIndex': logger.info("Unhandled DateIndex search on '%s'"%index) continue else: self.Or.append(Generic(index, value)) # if there's a ${form_id}_filter in request, then all indexes # are are searched for it's value. # ${form_id}_filter is searched with OR agains all indexes request_key = "%s_filter" % form_id value = self.request.get(request_key, '') if type(value) in (list, tuple): value = value[0] if len(value) > 1: for index in self.filter_indexes: idx = catalog.Indexes.get(index, None) if not idx: logger.debug("index named '%s' not found in %s. " "(Perhaps the index is still empty)." % (index, self.catalog)) continue ##logger.info("Or: %s=%s"%(index, value)) if idx.meta_type in('ZCTextIndex', 'FieldIndex'): self.Or.append(MatchRegexp(index, value)) self.expand_all_categories = True # https://github.com/bikalabs/Bika-LIMS/issues/1069 vals = value.split('-') if len(vals) > 2: valroot = vals[0] for i in range(1, len(vals)): valroot = '%s-%s' % (valroot, vals[i]) self.Or.append(MatchRegexp(index, valroot+'-*')) self.expand_all_categories = True elif idx.meta_type == 'DateIndex': if type(value) in (list, tuple): value = value[0] if value.find(":") > -1: try: lohi = [DateTime(x) for x in value.split(":")] except: logger.info("Error (And, DateIndex='%s', term='%s')"%(index,value)) self.Or.append(Between(index, lohi[0], lohi[1])) self.expand_all_categories = True else: try: self.Or.append(Eq(index, DateTime(value))) self.expand_all_categories = True except: logger.info("Error (Or, DateIndex='%s', term='%s')"%(index,value)) else: self.Or.append(Generic(index, value)) self.expand_all_categories = True self.Or.append(MatchRegexp('review_state', value)) # get toggle_cols cookie value # and modify self.columns[]['toggle'] to match. toggle_cols = self.get_toggle_cols() for col in self.columns.keys(): if col in toggle_cols: self.columns[col]['toggle'] = True else: self.columns[col]['toggle'] = False
#if flag is 1, then set q_xsub for the Adv Query if q_xsub == 1: q_xsub = In('Subject', xsub) #BUILD QUERY """ Build the query for evalAdvancedQuery based on the tests above No query is needed for xmy: it just sets xcrt and xpub appropriately some old tests: query = Between('start', start, end) & Generic(generic_qdict) this works: query = Between('start', start, end) & Generic('review_state','published') this works: query = Between('start', start, end) &~ q_xpub query = Between('start', start, end) &~ q_xpub """ query = Between('start', start, end) if q_xtypes: query = query & q_xtypes if q_xpaths: query = query & q_xpaths if q_xpub: query = query & q_xpub if q_xsub: query = query & q_xsub if q_xcrt: query = query & q_xcrt #RETURN QUERY RESULTS #sort the query by start date return context.portal_catalog.evalAdvancedQuery(query, (('start', 'asc'), ))
def _process_request(self): # Use this function from a template that is using bika_listing_table # in such a way that the table_only request var will be used to # in-place-update the table. form_id = self.form_id form = self.request.form workflow = getToolByName(self.context, 'portal_workflow') catalog = getToolByName(self.context, self.catalog) # If table_only specifies another form_id, then we abort. # this way, a single table among many can request a redraw, # and only it's content will be rendered. if form_id not in self.request.get('table_only', form_id): return '' ## review_state_selector cookie = json.loads(self.request.get("review_state", '{}')) cookie_key = "%s%s" % (self.context.portal_type, form_id) # first check POST selected_state = self.request.get("%s_review_state" % form_id, '') if not selected_state: # then check cookie selected_state = cookie.get(cookie_key, 'default') # get review_state id=selected_state states = [r for r in self.review_states if r['id'] == selected_state] review_state = states and states[0] or self.review_states[0] # set request and cookie to currently selected state id if not selected_state: selected_state = self.review_states[0]['id'] self.review_state = cookie[cookie_key] = selected_state cookie = json.dumps(cookie) self.request['review_state'] = cookie self.request.response.setCookie('review_state', cookie, path="/") # contentFilter is expected in every review_state. for k, v in review_state['contentFilter'].items(): self.contentFilter[k] = v # sort on sort_on = self.request.get(form_id + '_sort_on', '') # manual_sort_on: only sort the current batch of items # this is a compromise for sorting without column indexes self.manual_sort_on = None if sort_on \ and sort_on in self.columns.keys() \ and self.columns[sort_on].get('index', None): idx = self.columns[sort_on].get('index', sort_on) self.contentFilter['sort_on'] = idx else: if sort_on: self.manual_sort_on = sort_on if 'sort_on' in self.contentFilter: del self.contentFilter['sort_on'] # sort order self.sort_order = self.request.get(form_id + '_sort_order', '') if self.sort_order: self.contentFilter['sort_order'] = self.sort_order else: if 'sort_order' not in self.contentFilter: self.sort_order = 'ascending' self.contentFilter['sort_order'] = 'ascending' self.request.set(form_id + '_sort_order', 'ascending') else: self.sort_order = self.contentFilter['sort_order'] if self.manual_sort_on: del self.contentFilter['sort_order'] # pagesize pagesize = self.request.get(form_id + '_pagesize', self.pagesize) if type(pagesize) in (list, tuple): pagesize = pagesize[0] try: pagesize = int(pagesize) except: pagesize = self.pagesize self.pagesize = pagesize # Plone's batching wants this variable: self.request.set('pagesize', self.pagesize) # pagenumber self.pagenumber = int( self.request.get(form_id + '_pagenumber', self.pagenumber)) # Plone's batching wants this variable: self.request.set('pagenumber', self.pagenumber) # index filters. self.And = [] self.Or = [] ##logger.info("contentFilter: %s"%self.contentFilter) for k, v in self.columns.items(): if not v.has_key('index') \ or v['index'] == 'review_state' \ or v['index'] in self.filter_indexes: continue self.filter_indexes.append(v['index']) ##logger.info("Filter indexes: %s"%self.filter_indexes) # any request variable named ${form_id}_{index_name} # will pass it's value to that index in self.contentFilter. # all conditions using ${form_id}_{index_name} are searched with AND for index in self.filter_indexes: idx = catalog.Indexes.get(index, None) if not idx: logger.debug("index named '%s' not found in %s. " "(Perhaps the index is still empty)." % (index, self.catalog)) continue request_key = "%s_%s" % (form_id, index) value = self.request.get(request_key, '') if len(value) > 1: ##logger.info("And: %s=%s"%(index, value)) if idx.meta_type in ('ZCTextIndex', 'FieldIndex'): self.And.append(MatchRegexp(index, value)) elif idx.meta_type == 'DateIndex': logger.info("Unhandled DateIndex search on '%s'" % index) continue else: self.Or.append(Generic(index, value)) # if there's a ${form_id}_filter in request, then all indexes # are are searched for it's value. # ${form_id}_filter is searched with OR agains all indexes request_key = "%s_filter" % form_id value = self.request.get(request_key, '') if len(value) > 1: for index in self.filter_indexes: idx = catalog.Indexes.get(index, None) if not idx: logger.debug("index named '%s' not found in %s. " "(Perhaps the index is still empty)." % (index, self.catalog)) continue ##logger.info("Or: %s=%s"%(index, value)) if idx.meta_type in ('ZCTextIndex', 'FieldIndex'): self.Or.append(MatchRegexp(index, value)) elif idx.meta_type == 'DateIndex': if value.find(":") > -1: try: lohi = [DateTime(x) for x in value.split(":")] except: logger.info( "Error (And, DateIndex='%s', term='%s')" % (index, value)) self.Or.append(Between(index, lohi[0], lohi[1])) else: try: self.Or.append(Eq(index, DateTime(value))) except: logger.info( "Error (Or, DateIndex='%s', term='%s')" % (index, value)) else: self.Or.append(Generic(index, value)) self.Or.append(MatchRegexp('review_state', value)) # get toggle_cols cookie value # and modify self.columns[]['toggle'] to match. toggle_cols = self.get_toggle_cols() for col in self.columns.keys(): if col in toggle_cols: self.columns[col]['toggle'] = True else: self.columns[col]['toggle'] = False