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)
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)))
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
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)
_("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
" '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
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
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)))