Ejemplo n.º 1
0
def searchMetadata():
    # Get request data
    querystr = request.args.get("query")
    fieldname = request.args.get('fieldName', default=None)

    # Error out if query or field not provided
    if not querystr:
        return api_error(400, "Query string not specified.")
    if not fieldname:
        return api_error(400, "Field name to search not specified.")

    # Search by table
    matches = search_db(fieldname, querystr)

    # Log query
    current_app.logger.info(
        "{}\t{}\tsearchMetadata\tquery: {}\tfieldname: {}".format(
            epochalypse_now(), request.cookies.get("user_id"), querystr,
            fieldname))

    # Yield a list of variable names
    if not matches:
        rv = jsonify({"matches": []})
    else:
        rv = jsonify({"matches": matches})

    resp = make_response(rv)

    # Set cookie data if not found
    if not request.cookies.get("user_id"):
        expire_date = datetime.datetime.now() + datetime.timedelta(days=90)
        g_uuid = str(uuid.uuid4())
        resp.set_cookie("user_id", g_uuid, expires=expire_date)

    return resp
Ejemplo n.º 2
0
def selectMetadata():
    # Get request data
    varname = request.args.get("varName")
    fieldname = request.args.get('fieldName', default=None)

    # Error out if varname not provided
    if not varname:
        return api_error(400, "Variable name not provided.")

    # Get variable data (abort if not valid)
    var = session.query(Variable).filter(Variable.name == varname).first()
    if not var:
        return api_error(400, "Invalid variable name.")
    var_data = var.serialize

    # Append topics
    topics = session.query(Topic).filter(Topic.name == varname).group_by(
        Topic.topic).all()
    umbrellas = session.query(Umbrella).filter(
        Umbrella.topic.in_([str(t.topic) for t in topics])).all()
    var_data["topics"] = [{
        "umbrella": str(u.umbrella),
        "topic": str(u.topic)
    } for u in umbrellas]

    # Append responses
    responses = session.query(Response).filter(
        Response.name == varname).group_by(Response.label).all()
    var_data["responses"] = {
        value: label
        for (value, label) in [(r.value, r.label) for r in responses]
    }

    # Error out if field name not valid
    if fieldname and fieldname not in var_data.keys():
        return api_error(400, "Invalid field name.")

    # Log query
    current_app.logger.info(
        "{}\t{}\tselectMetadata\tname: {}\tfield: {}".format(
            epochalypse_now(), request.cookies.get("user_id"), varname,
            str(fieldname)))

    # Return only a single field if specified
    if not fieldname:
        rv = jsonify(var_data)
    else:
        result = {fieldname: var_data[fieldname]}
        rv = jsonify(result)

    resp = make_response(rv)

    # Set cookie data if not found
    if not request.cookies.get("user_id"):
        expire_date = datetime.datetime.now() + datetime.timedelta(days=90)
        g_uuid = str(uuid.uuid4())
        resp.set_cookie("user_id", g_uuid, expires=expire_date)

    return resp
Ejemplo n.º 3
0
def _pred(filter):
    """
    Create a SqlAlchemy Binary Expression given a single search criteria.

    :param filter: A dictionary with keys 'name', 'op' and 'val', indicating the attribute name, comparison operation
        and the comparison value we wish to use.
        'name' can be any supported attribute name of a variable (e.g. 'name'/'data_source'),
            or one of 'response'/'topic'/'umbrella'.
        'op' can be one of 'like','eq','neq','gt','gte','lt','lte' (where the op name corresponds to the usual
            semantics of these binary comparison operators.
            Note that specifying 'like' performs a fuzzy (LIKE) query in the database. Corresponding wildcards ('%')
            must be provided in the 'val' attribute for this to take effect.
        'val' is the value we wish to compare against. This is either a string or a numeric, corresponding to the
            type of the attribute specified by 'name'. Comparison against values work as expected, but
            comparison against another attribute is not supported.

    :return: A SqlAlchemy BinaryExpression object corresponding to given search criteria.
    """
    # Note: We may not have a 'val' key (for is_null/is_not_null)
    name, op, val = filter['name'], filter['op'], filter.get('val')
    op = op.lower().strip()

    if name in variable_attrs:
        column = getattr(Variable, name)
    elif name == 'response':
        column = Response.label
    else:
        return api_error(400, "Invalid name for search.")

    if op == 'like':
        pred = column.like(val)
    elif op in ('eq', '=='):
        pred = operator.eq(column, val)
    elif op in ('neq', 'ne', '!='):
        pred = operator.ne(column, val)
    elif op in ('gt', '>'):
        pred = operator.gt(column, val)
    elif op in ('gte', 'ge', '>='):
        pred = operator.ge(column, val)
    elif op in ('lt', '<'):
        pred = operator.lt(column, val)
    elif op in ('lte', 'le', '<='):
        pred = operator.le(column, val)
    elif op in ('in', ):
        pred = column.in_(val)
    elif op in ('not_in', ):
        pred = ~column.in_(val)
    elif op in ('is_null', ):
        pred = operator.eq(column, None)
    elif op in ('is_not_null', ):
        pred = operator.ne(column, None)
    else:
        return api_error(400, "Unrecognized operator")

    return pred
Ejemplo n.º 4
0
def filterMetadata():
    # Get request data
    fields = request.args.keys()

    # Error out if no fields provided
    if not fields:
        return api_error(400, "Fields to search not provided.")

    # Construct filter object
    found = []
    for field in fields:
        for value in request.args.getlist(field):
            found.extend(search_db(field, value))

    # Log query
    current_app.logger.info("{}\t{}\tfilterMetadata\tfilters: {}".format(
        epochalypse_now(), request.cookies.get("user_id"),
        list(request.args.items())))

    # Return list of matches
    if not found:
        rv = jsonify({"matches": []})
    else:
        varlist = dedupe_varlist(found)
        rv = jsonify({"matches": varlist})

    resp = make_response(rv)

    # Set cookie data if not found
    if not request.cookies.get("user_id"):
        expire_date = datetime.datetime.now() + datetime.timedelta(days=90)
        g_uuid = str(uuid.uuid4())
        resp.set_cookie("user_id", g_uuid, expires=expire_date)

    return resp
Ejemplo n.º 5
0
def search():
    name = request.args.get('name').lower().strip()
    val = request.args.get('val')  # May contain embedded '%' as wildcard(s)

    if name in variable_attrs:
        column = getattr(Variable, name)
        results = [
            v.name for v in session.query(Variable).filter(column.like(val))
        ]
    elif name == 'response':
        results = [
            r.name
            for r in session.query(Response).filter(Response.label.like(val))
        ]
    elif name == 'topic':
        results = [
            t.name for t in session.query(Topic).filter(Topic.topic.like(val))
        ]
    elif name == 'umbrella':
        topic_names = [
            u.topic_obj.topic for u in session.query(Umbrella).filter(
                Umbrella.umbrella.like(val))
        ]
        results = [
            t.name
            for t in session.query(Topic).filter(Topic.topic.in_(topic_names))
        ]
    else:
        return api_error(400, "Invalid name for search.")

    return jsonify(list(set(results)))
Ejemplo n.º 6
0
def select(variable_name, attrs=None, as_json=False):
    """
    Return a dictionary of variable attributes, given the variable's name
    :param variable_name: The name of the variable we're interested in
    :param attrs: optional, a list of attributes that we're interested in. If unspecified, all attributes of the
        variable are returned. Unrecognized attributes are ignored.
    :return: A dictionary with attribute names as the keys, and attribute value as the values.

    This function raises an AppException if no variable with the given name is found
    """
    obj = session.query(Variable).filter(
        Variable.name == variable_name).first()
    if obj:
        return variable_details(obj, attrs=attrs, as_json=as_json)
    else:
        return api_error(400, "Invalid variable name.")
Ejemplo n.º 7
0
def select(variable_name):
    obj = session.query(Variable).filter(
        Variable.name == variable_name).first()
    if obj:
        d = dict((attr, getattr(obj, attr, '')) for attr in variable_attrs)

        # TODO: The following structure is used to maintain compatibility with old behavior
        # Probably it makes sense to reverse the keys/values
        d['responses'] = dict((r.value, r.label) for r in obj.responses)

        # TODO: The following structure is used to maintain compatibility with old behavior
        # A better structure to this would be to simply return an <umbrella_name>: [<topic_names>] dictionary here
        d['topics'] = [{
            'umbrella': str(t.umbrella),
            'topic': str(t)
        } for t in obj.topics]

        keys = list(request.args.keys()) or d.keys()
        return jsonify(dict((k, d[k]) for k in keys))
    else:
        return api_error(400, "Invalid variable name.")