Пример #1
0
    def search(self, ver=None, register=None):

        log.debug('search %s params: %r', register, request.params)
        if register == 'revision':
            since_time = None
            if 'since_id' in request.params:
                id = request.params['since_id']
                if not id:
                    return self._finish_bad_request(
                        _(u'No revision specified'))
                rev = model.Session.query(model.Revision).get(id)
                if rev is None:
                    return self._finish_not_found(
                        _(u'There is no revision with id: %s') % id)
                since_time = rev.timestamp
            elif 'since_time' in request.params:
                since_time_str = request.params['since_time']
                try:
                    since_time = h.date_str_to_datetime(since_time_str)
                except ValueError as inst:
                    return self._finish_bad_request('ValueError: %s' % inst)
            else:
                return self._finish_bad_request(
                    _("Missing search term ('since_id=UUID' or " +
                      " 'since_time=TIMESTAMP')"))
            revs = model.Session.query(model.Revision) \
                .filter(model.Revision.timestamp > since_time) \
                .order_by(model.Revision.timestamp) \
                .limit(50)  # reasonable enough for a page
            return self._finish_ok([rev.id for rev in revs])
        elif register in ['dataset', 'package', 'resource']:
            try:
                params = MultiDict(self._get_search_params(request.params))
            except ValueError as e:
                return self._finish_bad_request(
                    _('Could not read parameters: %r' % e))

            # if using API v2, default to returning the package ID if
            # no field list is specified
            if register in ['dataset', 'package'] and not params.get('fl'):
                params['fl'] = 'id' if ver == 2 else 'name'

            try:
                if register == 'resource':
                    query = search.query_for(model.Resource)

                    # resource search still uses ckan query parser
                    options = search.QueryOptions()
                    for k, v in params.items():
                        if (k in search.DEFAULT_OPTIONS.keys()):
                            options[k] = v
                    options.update(params)
                    options.username = c.user
                    options.search_tags = False
                    options.return_objects = False
                    query_fields = MultiDict()
                    for field, value in params.items():
                        field = field.strip()
                        if field in search.DEFAULT_OPTIONS.keys() or \
                                field in IGNORE_FIELDS:
                            continue
                        values = [value]
                        if isinstance(value, list):
                            values = value
                        for v in values:
                            query_fields.add(field, v)

                    results = query.run(
                        query=params.get('q'),
                        fields=query_fields,
                        options=options
                    )
                else:
                    # For package searches in API v3 and higher, we can pass
                    # parameters straight to Solr.
                    if ver in [1, 2]:
                        # Otherwise, put all unrecognised ones into the q
                        # parameter
                        params = search.\
                            convert_legacy_parameters_to_solr(params)
                    query = search.query_for(model.Package)

                    # Remove any existing fq param and set the capacity to
                    # public
                    if 'fq' in params:
                        del params['fq']
                    params['fq'] = '+capacity:public'
                    # if callback is specified we do not want to send that to
                    # the search
                    if 'callback' in params:
                        del params['callback']
                    results = query.run(params)
                return self._finish_ok(results)
            except search.SearchError as e:
                log.exception(e)
                return self._finish_bad_request(
                    _('Bad search option: %s') % e)
        else:
            return self._finish_not_found(
                _('Unknown register: %s') % register)
Пример #2
0
class MimeHeaders(object):
    """Dictionary-like object that preserves the order and
    supports multiple values for the same key, knows
    whether it has been changed after the creation
    """

    def __init__(self, items=()):
        self._v = MultiDict([(normalize(key), remove_newlines(val))
                             for (key, val) in items])
        self.changed = False

    def __getitem__(self, key):
        return self._v.get(normalize(key), None)

    def __len__(self):
        return len(self._v)

    def __iter__(self):
        return iter(self._v)

    def __contains__(self, key):
        return normalize(key) in self._v

    def __setitem__(self, key, value):
        self._v[normalize(key)] = remove_newlines(value)
        self.changed = True

    def __delitem__(self, key):
        del self._v[normalize(key)]
        self.changed = True

    def __nonzero__(self):
        return len(self._v) > 0

    def prepend(self, key, value):
        self._v._items.insert(0, (normalize(key), remove_newlines(value)))
        self.changed = True

    def add(self, key, value):
        """Adds header without changing the
        existing headers with same name"""

        self._v.add(normalize(key), remove_newlines(value))
        self.changed = True

    def keys(self):
        """
        Returns the keys. (message header names)
        It remembers the order in which they were added, what
        is really important
        """
        return self._v.keys()

    def transform(self, fn):
        """Accepts a function, getting a key, val and returning
        a new pair of key, val and applies the function to all
        header, value pairs in the message.
        """

        changed = [False]

        def tracking_fn(key, val):
            new_key, new_val = fn(key, val)
            if new_val != val or new_key != key:
                changed[0] = True
            return new_key, new_val

        v = MultiDict(tracking_fn(key, val) for key, val in self._v.iteritems())
        if changed[0]:
            self._v = v
            self.changed = True

    def items(self):
        """
        Returns header,val pairs in the preserved order.
        """
        return list(self.iteritems())

    def iteritems(self):
        """
        Returns iterator header,val pairs in the preserved order.
        """
        return self._v.iteritems()

    def get(self, key, default=None):
        """
        Returns header value (case-insensitive).
        """
        return self._v.get(normalize(key), default)

    def getall(self, key):
        """
        Returns all header values by the given header name
        (case-insensitive)
        """
        return self._v.getall(normalize(key))

    def have_changed(self):
        """Tells whether someone has altered the headers
        after creation"""
        return self.changed

    def __str__(self):
        return str(self._v)

    @classmethod
    def from_stream(cls, stream):
        """Takes a stream and reads the headers,
        decodes headers to unicode dict like object"""
        return cls(parse_stream(stream))

    def to_stream(self, stream):
        """Takes a stream and serializes headers
        in a mime format"""

        for h, v in self._v.iteritems():
            try:
                h = h.encode('ascii')
            except UnicodeDecodeError:
                raise EncodingError("Non-ascii header name")
            stream.write("{0}: {1}\r\n".format(h, to_mime(h, v)))
Пример #3
0
                    return self._finish_bad_request("ValueError: %s" % inst)
            else:
                return self._finish_bad_request(
                    _("Missing search term ('since_id=UUID' or " + " 'since_time=TIMESTAMP')")
                )
            revs = model.Session.query(model.Revision).filter(model.Revision.timestamp > since_time)
            return self._finish_ok([rev.id for rev in revs])
        elif register in ["dataset", "package", "resource"]:
            try:
                params = MultiDict(self._get_search_params(request.params))
            except ValueError, e:
                return self._finish_bad_request(_("Could not read parameters: %r" % e))

            # if using API v2, default to returning the package ID if
            # no field list is specified
            if register in ["dataset", "package"] and not params.get("fl"):
                params["fl"] = "id" if ver == 2 else "name"

            try:
                if register == "resource":
                    query = search.query_for(model.Resource)

                    # resource search still uses ckan query parser
                    options = search.QueryOptions()
                    for k, v in params.items():
                        if k in search.DEFAULT_OPTIONS.keys():
                            options[k] = v
                    options.update(params)
                    options.username = c.user
                    options.search_tags = False
                    options.return_objects = False
Пример #4
0
    def search(self, ver=None, register=None):

        log.debug('search %s params: %r', register, request.params)
        if register == 'revision':
            since_time = None
            if 'since_id' in request.params:
                id = request.params['since_id']
                if not id:
                    return self._finish_bad_request(
                        _(u'No revision specified'))
                rev = model.Session.query(model.Revision).get(id)
                if rev is None:
                    return self._finish_not_found(
                        _(u'There is no revision with id: %s') % id)
                since_time = rev.timestamp
            elif 'since_time' in request.params:
                since_time_str = request.params['since_time']
                try:
                    since_time = h.date_str_to_datetime(since_time_str)
                except ValueError as inst:
                    return self._finish_bad_request('ValueError: %s' % inst)
            else:
                return self._finish_bad_request(
                    _("Missing search term ('since_id=UUID' or " +
                      " 'since_time=TIMESTAMP')"))
            revs = model.Session.query(model.Revision) \
                .filter(model.Revision.timestamp > since_time) \
                .order_by(model.Revision.timestamp) \
                .limit(50)  # reasonable enough for a page
            return self._finish_ok([rev.id for rev in revs])
        elif register in ['dataset', 'package', 'resource']:
            try:
                params = MultiDict(self._get_search_params(request.params))
            except ValueError as e:
                return self._finish_bad_request(
                    _('Could not read parameters: %r' % e))

            # if using API v2, default to returning the package ID if
            # no field list is specified
            if register in ['dataset', 'package'] and not params.get('fl'):
                params['fl'] = 'id' if ver == 2 else 'name'

            try:
                if register == 'resource':
                    query = search.query_for(model.Resource)

                    # resource search still uses ckan query parser
                    options = search.QueryOptions()
                    for k, v in params.items():
                        if (k in search.DEFAULT_OPTIONS.keys()):
                            options[k] = v
                    options.update(params)
                    options.username = c.user
                    options.search_tags = False
                    options.return_objects = False
                    query_fields = MultiDict()
                    for field, value in params.items():
                        field = field.strip()
                        if field in search.DEFAULT_OPTIONS.keys() or \
                                field in IGNORE_FIELDS:
                            continue
                        values = [value]
                        if isinstance(value, list):
                            values = value
                        for v in values:
                            query_fields.add(field, v)

                    results = query.run(query=params.get('q'),
                                        fields=query_fields,
                                        options=options)
                else:
                    # For package searches in API v3 and higher, we can pass
                    # parameters straight to Solr.
                    if ver in [1, 2]:
                        # Otherwise, put all unrecognised ones into the q
                        # parameter
                        params = search.\
                            convert_legacy_parameters_to_solr(params)
                    query = search.query_for(model.Package)

                    # Remove any existing fq param and set the capacity to
                    # public
                    if 'fq' in params:
                        del params['fq']
                    params['fq'] = '+capacity:public'
                    # if callback is specified we do not want to send that to
                    # the search
                    if 'callback' in params:
                        del params['callback']
                    results = query.run(params)
                return self._finish_ok(results)
            except search.SearchError as e:
                log.exception(e)
                return self._finish_bad_request(_('Bad search option: %s') % e)
        else:
            return self._finish_not_found(_('Unknown register: %s') % register)
Пример #5
0
                    _("Missing search term ('since_id=UUID' or " +
                            " 'since_time=TIMESTAMP')"))
            revs = model.Session.query(model.Revision).\
                filter(model.Revision.timestamp > since_time).\
                limit(50) # reasonable enough for a page
            return self._finish_ok([rev.id for rev in revs])
        elif register in ['dataset', 'package', 'resource']:
            try:
                params = MultiDict(self._get_search_params(request.params))
            except ValueError, e:
                return self._finish_bad_request(
                    _('Could not read parameters: %r' % e))

            # if using API v2, default to returning the package ID if
            # no field list is specified
            if register in ['dataset', 'package'] and not params.get('fl'):
                params['fl'] = 'id' if ver == 2 else 'name'

            try:
                if register == 'resource':
                    query = search.query_for(model.Resource)

                    # resource search still uses ckan query parser
                    options = search.QueryOptions()
                    for k, v in params.items():
                        if (k in search.DEFAULT_OPTIONS.keys()):
                            options[k] = v
                    options.update(params)
                    options.username = c.user
                    options.search_tags = False
                    options.return_objects = False
Пример #6
0
                      " 'since_time=TIMESTAMP')"))
            revs = model.Session.query(model.Revision) \
                .filter(model.Revision.timestamp > since_time) \
                .order_by(model.Revision.timestamp) \
                .limit(50)  # reasonable enough for a page
            return self._finish_ok([rev.id for rev in revs])
        elif register in ['dataset', 'package', 'resource']:
            try:
                params = MultiDict(self._get_search_params(request.params))
            except ValueError, e:
                return self._finish_bad_request(
                    _('Could not read parameters: %r' % e))

            # if using API v2, default to returning the package ID if
            # no field list is specified
            if register in ['dataset', 'package'] and not params.get('fl'):
                params['fl'] = 'id' if ver == 2 else 'name'

            try:
                if register == 'resource':
                    query = search.query_for(model.Resource)

                    # resource search still uses ckan query parser
                    options = search.QueryOptions()
                    for k, v in params.items():
                        if (k in search.DEFAULT_OPTIONS.keys()):
                            options[k] = v
                    options.update(params)
                    options.username = c.user
                    options.search_tags = False
                    options.return_objects = False
Пример #7
0
                    return self._finish_bad_request('ValueError: %s' % inst)
            else:
                return self._finish_bad_request(
                    gettext("Missing search term ('since_id=UUID' or 'since_time=TIMESTAMP')"))
            revs = model.Session.query(model.Revision).filter(model.Revision.timestamp>since_time)
            return self._finish_ok([rev.id for rev in revs])
        elif register in ['dataset', 'package', 'resource']:
            try:
                params = MultiDict(self._get_search_params(request.params))
            except ValueError, e:
                return self._finish_bad_request(
                    gettext('Could not read parameters: %r' % e))

            # if using API v2, default to returning the package ID if
            # no field list is specified
            if register in ['dataset', 'package'] and not params.get('fl'):
                params['fl'] = 'id' if ver == 2 else 'name'

            try:
                if register == 'resource':
                    query = search.query_for(model.Resource)

                    # resource search still uses ckan query parser
                    options = search.QueryOptions()
                    for k, v in params.items():
                        if (k in search.DEFAULT_OPTIONS.keys()):
                            options[k] = v
                    options.update(params)
                    options.username = c.user
                    options.search_tags = False
                    options.return_objects = False
Пример #8
0
                      " 'since_time=TIMESTAMP')"))
            revs = model.Session.query(model.Revision) \
                .filter(model.Revision.timestamp > since_time) \
                .order_by(model.Revision.timestamp) \
                .limit(50)  # reasonable enough for a page
            return self._finish_ok([rev.id for rev in revs])
        elif register in ['dataset', 'package', 'resource']:
            try:
                params = MultiDict(self._get_search_params(request.params))
            except ValueError, e:
                return self._finish_bad_request(
                    _('Could not read parameters: %r' % e))

            # if using API v2, default to returning the package ID if
            # no field list is specified
            if register in ['dataset', 'package'] and not params.get('fl'):
                params['fl'] = 'id' if ver == 2 else 'name'

            try:
                if register == 'resource':
                    query = search.query_for(model.Resource)

                    # resource search still uses ckan query parser
                    options = search.QueryOptions()
                    for k, v in params.items():
                        if (k in search.DEFAULT_OPTIONS.keys()):
                            options[k] = v
                    options.update(params)
                    options.username = c.user
                    options.search_tags = False
                    options.return_objects = False
Пример #9
0
                    return self._finish_bad_request('ValueError: %s' % inst)
            else:
                return self._finish_bad_request(
                    gettext("Missing search term ('since_id=UUID' or 'since_time=TIMESTAMP')"))
            revs = model.Session.query(model.Revision).filter(model.Revision.timestamp>since_time)
            return self._finish_ok([rev.id for rev in revs])
        elif register in ['dataset', 'package', 'resource']:
            try:
                params = MultiDict(self._get_search_params(request.params))
            except ValueError, e:
                return self._finish_bad_request(
                    gettext('Could not read parameters: %r' % e))

            # if using API v2, default to returning the package ID if
            # no field list is specified
            if register in ['dataset', 'package'] and not params.get('fl'):
                params['fl'] = 'id' if ver == 2 else 'name'

            try:
                if register == 'resource':
                    query = search.query_for(model.Resource)

                    # resource search still uses ckan query parser
                    options = search.QueryOptions()
                    for k, v in params.items():
                        if (k in search.DEFAULT_OPTIONS.keys()):
                            options[k] = v
                    options.update(params)
                    options.username = c.user
                    options.search_tags = False
                    options.return_objects = False
Пример #10
0
class MimeHeaders(object):
    """Dictionary-like object that preserves the order and
    supports multiple values for the same key, knows
    whether it has been changed after the creation
    """
    def __init__(self, items=()):
        self.v = MultiDict([(normalize(key), val) for (key, val) in items])
        self.changed = False

    def __getitem__(self, key):
        return self.v.get(normalize(key), None)

    def __len__(self):
        return len(self.v)

    def __iter__(self):
        return iter(self.v)

    def __contains__(self, key):
        return normalize(key) in self.v

    def __setitem__(self, key, value):
        self.v[normalize(key)] = _remove_newlines(value)
        self.changed = True

    def __delitem__(self, key):
        del self.v[normalize(key)]
        self.changed = True

    def __nonzero__(self):
        return len(self.v) > 0

    def prepend(self, key, val):
        self.v._items.insert(0, (key, _remove_newlines(val)))
        self.changed = True

    def add(self, key, value):
        """Adds header without changing the
        existing headers with same name"""

        self.v.add(normalize(key), _remove_newlines(value))
        self.changed = True

    def keys(self):
        """
        Returns the keys. (message header names)
        It remembers the order in which they were added, what
        is really important
        """
        return self.v.keys()

    def transform(self, fn):
        """Accepts a function, getting a key, val and returning
        a new pair of key, val and applies the function to all
        header, value pairs in the message.
        """

        changed = [False]

        def tracking_fn(key, val):
            new_key, new_val = fn(key, val)
            if new_val != val or new_key != key:
                changed[0] = True
            return new_key, new_val

        v = MultiDict(tracking_fn(key, val) for key, val in self.v.iteritems())
        if changed[0]:
            self.v = v
            self.changed = True

    def items(self):
        """
        Returns header,val pairs in the preserved order.
        """
        return list(self.iteritems())

    def iteritems(self):
        """
        Returns iterator header,val pairs in the preserved order.
        """
        return self.v.iteritems()

    def get(self, key, default=None):
        """
        Returns header value (case-insensitive).
        """
        return self.v.get(normalize(key), default)

    def getall(self, key):
        """
        Returns all header values by the given header name
        (case-insensitive)
        """
        return self.v.getall(normalize(key))

    def have_changed(self):
        """Tells whether someone has altered the headers
        after creation"""
        return self.changed

    def __str__(self):
        return str(self.v)

    @classmethod
    def from_stream(cls, stream):
        """Takes a stream and reads the headers,
        decodes headers to unicode dict like object"""
        return cls(parse_stream(stream))

    def to_stream(self, stream):
        """Takes a stream and serializes headers
        in a mime format"""

        for h, v in self.v.iteritems():
            try:
                h = h.encode('ascii')
            except UnicodeDecodeError:
                raise EncodingError("Non-ascii header name")
            stream.write("{0}: {1}\r\n".format(h, to_mime(h, v)))