def tag_search(context, data_dict): model = context['model'] session = context['session'] query = data_dict.get('query') terms = [query] if query else [] fields = data_dict.get('fields', {}) offset = data_dict.get('offset') limit = data_dict.get('limit') # TODO: should we check for user authentication first? q = model.Session.query(model.Tag) q = q.distinct().join(model.Tag.package_tags) for field, value in fields.items(): if field in ('tag', 'tags'): terms.append(value) if not len(terms): return for term in terms: escaped_term = misc.escape_sql_like_special_characters(term, escape='\\') q = q.filter(model.Tag.name.ilike('%' + escaped_term + '%')) count = q.count() q = q.offset(offset) q = q.limit(limit) results = [r for r in q] return {'count': count, 'results': results}
def tag_search(context, data_dict): model = context["model"] session = context["session"] query = data_dict.get("query") terms = [query] if query else [] fields = data_dict.get("fields", {}) offset = data_dict.get("offset") limit = data_dict.get("limit") # TODO: should we check for user authentication first? q = model.Session.query(model.Tag) q = q.distinct().join(model.Tag.package_tags) for field, value in fields.items(): if field in ("tag", "tags"): terms.append(value) if not len(terms): return for term in terms: escaped_term = misc.escape_sql_like_special_characters(term, escape="\\") q = q.filter(model.Tag.name.ilike("%" + escaped_term + "%")) count = q.count() q = q.offset(offset) q = q.limit(limit) results = [r for r in q] return {"count": count, "results": results}
def get_discipline(context, data_dict): model = context['model'] terms = data_dict.get('query') or data_dict.get('q') or [] if isinstance(terms, basestring): terms = [terms] terms = [t.strip() for t in terms if t.strip()] if 'fields' in data_dict: log.warning('"fields" parameter is deprecated. ' 'Use the "query" parameter instead') offset = data_dict.get('offset') limit = data_dict.get('limit') # TODO: should we check for user authentication first? q = model.Session.query(model.Group) if not len(terms): return [], 0 katagrp = Group.get('KATA') res = [] for term in terms: escaped_term = misc.escape_sql_like_special_characters(term, escape='\\') for child in katagrp.get_children_groups(): if escaped_term in child['name']: res.append(child) return res
def get_extra_contact(context, data_dict, key="contact_name"): model = context['model'] terms = data_dict.get('query') or data_dict.get('q') or [] if isinstance(terms, basestring): terms = [terms] terms = [t.strip() for t in terms if t.strip()] if 'fields' in data_dict: log.warning('"fields" parameter is deprecated. ' 'Use the "query" parameter instead') offset = data_dict.get('offset') limit = data_dict.get('limit') # TODO: should we check for user authentication first? q = model.Session.query(model.PackageExtra) if not len(terms): return [], 0 for term in terms: escaped_term = misc.escape_sql_like_special_characters(term, escape='\\') q = q.filter(model.PackageExtra.key.contains(key)) q = q.filter(model.PackageExtra.value.ilike("%" + escaped_term + "%")) q = q.offset(offset) q = q.limit(limit) return q.all()
def _tag_search(context, data_dict): """ Searches tags for autocomplete, but makes sure only return active tags """ model = context['model'] terms = data_dict.get('query') or data_dict.get('q') or [] if isinstance(terms, basestring): terms = [terms] terms = [t.strip() for t in terms if t.strip()] if 'fields' in data_dict: log.warning('"fields" parameter is deprecated. ' 'Use the "query" parameter instead') fields = data_dict.get('fields', {}) offset = data_dict.get('offset') limit = data_dict.get('limit') # TODO: should we check for user authentication first? q = model.Session.query(model.Tag) if 'vocabulary_id' in data_dict: # Filter by vocabulary. vocab = model.Vocabulary.get(_get_or_bust(data_dict, 'vocabulary_id')) if not vocab: raise NotFound q = q.filter(model.Tag.vocabulary_id == vocab.id) # CHANGES to initial version # else: # If no vocabulary_name in data dict then show free tags only. # q = q.filter(model.Tag.vocabulary_id == None) # If we're searching free tags, limit results to tags that are # currently applied to a package. # q = q.distinct().join(model.Tag.package_tags) for field, value in fields.items(): if field in ('tag', 'tags'): terms.append(value) if not len(terms): return [], 0 for term in terms: escaped_term = misc.escape_sql_like_special_characters(term, escape='\\') q = q.filter(model.Tag.name.ilike('%' + escaped_term + '%')) # q = q.join('package_tags').filter(model.PackageTag.state == 'active') count = q.count() q = q.offset(offset) q = q.limit(limit) tags = q.all() return tags, count
def _tag_search(context, data_dict): '''Return a list of tag objects that contain the given string and the full count (for paging). The query string should be provided in the data_dict with key 'query' or 'q'. By default only free tags (tags that don't belong to a vocabulary) are searched. If a 'vocabulary_id' is provided in the data_dict then tags belonging to the given vocabulary (id or name) will be searched instead. Use 'offset' and 'limit' parameters to page through results. ''' model = context['model'] query = data_dict.get('query') or data_dict.get('q') if query: query = query.strip() terms = [query] if query else [] fields = data_dict.get('fields', {}) offset = data_dict.get('offset') limit = data_dict.get('limit') # TODO: should we check for user authentication first? q = model.Session.query(model.Tag) if data_dict.has_key('vocabulary_id'): # Filter by vocabulary. vocab = model.Vocabulary.get(data_dict['vocabulary_id']) if not vocab: raise NotFound q = q.filter(model.Tag.vocabulary_id == vocab.id) else: # If no vocabulary_name in data dict then show free tags only. q = q.filter(model.Tag.vocabulary_id == None) # If we're searching free tags, limit results to tags that are # currently applied to a package. q = q.distinct().join(model.Tag.package_tags) for field, value in fields.items(): if field in ('tag', 'tags'): terms.append(value) if not len(terms): return [], 0 for term in terms: escaped_term = misc.escape_sql_like_special_characters(term, escape='\\') q = q.filter(model.Tag.name.ilike('%' + escaped_term + '%')) count = q.count() q = q.offset(offset) q = q.limit(limit) return q.all(), count
def _tag_search(context, data_dict): '''Return a list of tag objects that contain the given string. The query string should be provided in the data_dict with key 'query' or 'q'. By default only free tags (tags that don't belong to a vocabulary) are searched. If a 'vocabulary_id' is provided in the data_dict then tags belonging to the given vocabulary (id or name) will be searched instead. ''' model = context['model'] query = data_dict.get('query') or data_dict.get('q') if query: query = query.strip() terms = [query] if query else [] fields = data_dict.get('fields', {}) offset = data_dict.get('offset') limit = data_dict.get('limit') # TODO: should we check for user authentication first? q = model.Session.query(model.Tag) if data_dict.has_key('vocabulary_id'): # Filter by vocabulary. vocab = model.Vocabulary.get(data_dict['vocabulary_id']) if not vocab: raise NotFound q = q.filter(model.Tag.vocabulary_id == vocab.id) else: # If no vocabulary_name in data dict then show free tags only. q = q.filter(model.Tag.vocabulary_id == None) # If we're searching free tags, limit results to tags that are # currently applied to a package. q = q.distinct().join(model.Tag.package_tags) for field, value in fields.items(): if field in ('tag', 'tags'): terms.append(value) if not len(terms): return [] for term in terms: escaped_term = misc.escape_sql_like_special_characters(term, escape='\\') q = q.filter(model.Tag.name.ilike('%' + escaped_term + '%')) q = q.offset(offset) q = q.limit(limit) return q.all()
def _tag_search(context, data_dict): model = context["model"] terms = data_dict.get("query") or data_dict.get("q") or [] if isinstance(terms, basestring): terms = [terms] terms = [t.strip() for t in terms if t.strip()] if "fields" in data_dict: log.warning('"fields" parameter is deprecated. ' 'Use the "query" parameter instead') fields = data_dict.get("fields", {}) offset = data_dict.get("offset") limit = data_dict.get("limit") # TODO: should we check for user authentication first? q = model.Session.query(model.Tag) if "vocabulary_id" in data_dict: # Filter by vocabulary. vocab = model.Vocabulary.get(_get_or_bust(data_dict, "vocabulary_id")) if not vocab: raise NotFound q = q.filter(model.Tag.vocabulary_id == vocab.id) # CHANGES to initial version # else: # If no vocabulary_name in data dict then show free tags only. # q = q.filter(model.Tag.vocabulary_id == None) # If we're searching free tags, limit results to tags that are # currently applied to a package. # q = q.distinct().join(model.Tag.package_tags) for field, value in fields.items(): if field in ("tag", "tags"): terms.append(value) if not len(terms): return [], 0 for term in terms: escaped_term = misc.escape_sql_like_special_characters(term, escape="\\") q = q.filter(model.Tag.name.ilike("%" + escaped_term + "%")) count = q.count() q = q.offset(offset) q = q.limit(limit) tags = q.all() return tags, count
def resource_search(context, data_dict): model = context['model'] query = data_dict.get('query') fields = data_dict.get('fields') if query is None and fields is None: raise ValidationError({'query': _('Missing value')}) elif query is not None and fields is not None: raise ValidationError( {'fields': _('Do not specify if using "query" parameter')}) elif query is not None: if isinstance(query, basestring): query = [query] try: fields = dict(pair.split(":", 1) for pair in query) except ValueError: raise ValidationError( {'query': _('Must be <field>:<value> pair(s)')}) else: log.warning('Use of the "fields" parameter in resource_search is ' 'deprecated. Use the "query" parameter instead') # The legacy fields paramter splits string terms. # So maintain that behaviour split_terms = {} for field, terms in fields.items(): if isinstance(terms, basestring): terms = terms.split() split_terms[field] = terms fields = split_terms order_by = data_dict.get('order_by') offset = data_dict.get('offset') limit = data_dict.get('limit') q = model.Session.query(model.Resource) \ .join(model.Package) \ .filter(model.Package.state == 'active') \ .filter(model.Package.private == False) \ .filter(model.Resource.state == 'active') \ resource_fields = model.Resource.get_columns() for field, terms in fields.items(): if isinstance(terms, basestring): terms = [terms] if field not in resource_fields: msg = _('Field "{field}" not recognised in resource_search.')\ .format(field=field) # Running in the context of the internal search api. if context.get('search_query', False): raise search.SearchError(msg) # Otherwise, assume we're in the context of an external api # and need to provide meaningful external error messages. raise ValidationError({'query': msg}) for term in terms: # prevent pattern injection term = misc.escape_sql_like_special_characters(term) model_attr = getattr(model.Resource, field) # Treat the has field separately, see docstring. if field == 'hash': q = q.filter(model_attr.ilike(unicode(term) + '%')) # Resource extras are stored in a json blob. So searching for # matching fields is a bit trickier. See the docstring. elif field in model.Resource.get_extra_columns(): model_attr = getattr(model.Resource, 'extras') like = _or_( model_attr.ilike( u'''%%"%s": "%%%s%%",%%''' % (field, term)), model_attr.ilike( u'''%%"%s": "%%%s%%"}''' % (field, term)) ) q = q.filter(like) # Just a regular field else: q = q.filter(model_attr.ilike('%' + unicode(term) + '%')) if order_by is not None: if hasattr(model.Resource, order_by): q = q.order_by(getattr(model.Resource, order_by)) count = q.count() q = q.offset(offset) q = q.limit(limit) results = [] for result in q: if isinstance(result, tuple) \ and isinstance(result[0], model.DomainObject): # This is the case for order_by rank due to the add_column. if result[0].package.extras.get("restricted", 0) == "1" and not context.get("user", None): continue results.append(result[0]) else: if result.package.extras.get("restricted", 0) == "1" and not context.get("user", None): continue results.append(result) # If run in the context of a search query, then don't dictize the results. if not context.get('search_query', False): results = model_dictize.resource_list_dictize(results, context) return {'count': count, 'results': results}