Пример #1
0
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}
Пример #2
0
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}
Пример #3
0
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}
Пример #4
0
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
Пример #5
0
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()
Пример #6
0
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
Пример #7
0
Файл: get.py Проект: slmnhq/ckan
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
Пример #8
0
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()
Пример #9
0
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
Пример #10
0
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}