예제 #1
0
파일: dao.py 프로젝트: CottageLabs/oarr
 def query(self):
     q = None
     
     # full_query overrides query_string, and if neither are set, then match all
     if self.full_query is not None:
         q = self.full_query
     elif self.query_string is not None:
         q = {"query" : {"query_string" : {"query" : Query.escape(self.query_string)}}}
     else:
         if self.from_date is not None or self.until_date is not None:
             rq = {"range" : {"last_updated" : {}}}
             if self.from_date:
                 rq["range"]["last_updated"]["gte"] = self.from_date
             if self.until_date:
                 rq["range"]["last_updated"]["lte"] = self.until_date
             q = {"query" : rq}
         else:
             q = {"query" : {"match_all" : {}}}
     
     if self.fields is not None:
         q["fields"] = self.fields
     
     if self.from_number is not None:
         q["from"] = self.from_number
     
     if self.size is not None:
         q["size"] = self.size
     
     if self.order is not None:
         sort_by, direction = self.order
         q["sort"] = {sort_by : {"order" : direction}}
     
     return q
예제 #2
0
def query(path=None):
    # get the bits out of the path, and ensure that we have at least some parts to work with
    pathparts = path.strip('/').split('/')
    if len(pathparts) == 0:
        abort(400)

    # load the query route config and the path we are being requested for
    qrs = app.config.get("QUERY_ROUTE", {})
    frag = request.path

    # get the configuration for this url route
    route_cfg = None
    for key in qrs:
        if frag.startswith("/" + key):
            route_cfg = qrs.get(key)
            break

    # if no route cfg is found this is not authorised
    if route_cfg is None:
        abort(401)

    # get the configuration for the specific index being queried
    index = pathparts[0]
    cfg = route_cfg.get(index)
    if cfg is None:
        abort(401)

    # does the user have to be authenticated
    if cfg.get("auth"):
        if current_user is None or current_user.is_anonymous():
            abort(401)

        # if so, does the user require a role
        role = cfg.get("roles")
        if role is not None and not current_user.has_role(role):
            abort(401)

    # get the name of the model that will handle this query, and then look up
    # the class that will handle it
    dao_name = cfg.get("dao")
    dao_klass = plugin.load_class(dao_name)
    if dao_klass is None:
        abort(404)

    # now work out what kind of operation is being asked for
    # if _search is specified, then this is a normal query
    search = False
    by_id = None
    if len(pathparts) == 1 or (len(pathparts) == 2 and pathparts[1] == "_search"):
        search = True
    elif len(pathparts) == 2:
        if request.method == "POST":
            abort(401)
        by_id = pathparts[1]
    else:
        abort(400)

    resp = None
    if by_id is not None:
        rec = dao_klass.pull(by_id, wrap=False)
        resp = make_response(rec)
    elif search:
        q = Query()

        # if this is a POST, read the contents out of the body
        if request.method == "POST":
            q = Query(request.json) if request.json else Query(dict(request.form).keys()[-1]) # FIXME: does this actually work?

        # if there is a q param, make it into a query string query
        elif 'q' in request.values:
            s = request.values['q']
            op = request.values.get('default_operator')
            q.query_string(s, op)

        # if there is a source param, load the json from it
        elif 'source' in request.values:
            q = Query(json.loads(urllib2.unquote(request.values['source'])))

        # now run the query through the filters
        filters = app.config.get("QUERY_FILTERS", {})
        filter_names = cfg.get("filters", [])
        for filter_name in filter_names:
            # because of back-compat, we have to do a few tricky things here...
            # filter may be the name of a filter in the list of query filters
            fn = filters.get(filter_name)
            if fn is None:
                # filter may be the path to a function
                fn = plugin.load_function(filter_name)
            if fn is None:
                app.logger.info("Unable to load query filter for {x}".format(x=filter_name))
                abort(500)
            fn(q)

        # finally send the query and return the response
        res = dao_klass.query(q=q.as_dict())
        resp = make_response(json.dumps(res))
    else:
        abort(400)

    resp.mimetype = "application/json"
    return resp