def get_rule_matches(id):
    """ This route can operate in 3 ways. With no parameters, it looks at yesterday (from the
        second most recent midnight till the most recent midnight). With a `since` parameter, it uses
        the range from `since` until now. With `start_time` and `end_time`, it uses that range.

        It also checks if there are any values at all since the start time, and if there are none,
        this likely means that there's some problem with the Value Pipeline, and today's values
        haven't been imported yet. To just report 0 would be a false negative, so we throw a 404
        instead, so the client knows that there was a failure.
    """
    since = trycast_int(request.values.get("since"))
    start_time = trycast_int(request.values.get("start_time"))
    end_time = trycast_int(request.values.get("end_time"))
    if since is not None:
        start = since
        end = int(dt.datetime.now().timestamp())
    elif None not in (start_time, end_time):
        start = start_time
        end = end_time
    else:
        end = int(dt.datetime.combine(dt.date.today(), dt.time()).timestamp())
        start = end - 60 * 60 * 24

    if not Values.has_any_since(start):
        abort(404, "No values since start time %s" % start)

    (point_search, value_search) = Rules.searches(id)
    point_ids = Points.ids_where(Search.points(point_search))

    return Values.get(point_ids, start, end, Search.values(value_search))
def get_values():
    # Some clients put `[]` at the end of array parameters. We can handle either case.
    point_ids = request.values.getlist('point_ids') or request.values.getlist(
        'point_ids[]')
    start_time = request.values.get('start_time')
    end_time = request.values.get('end_time')
    search = request.values.get('search')

    if None in (point_ids, start_time, end_time):
        abort(400, "Missing required parameter")

    search_sql = Search.values(search)

    return Values.get(tuple(point_ids), start_time, end_time,
                      search_sql) or "[]"
def values_verify():
    try:
        point_ids = request.values.getlist(
            'point_ids') or request.values.getlist('point_ids[]')
        start_time = request.values.get('start_time')
        end_time = request.values.get('end_time')
        search = request.values.get('search')

        if search is None:
            abort(400, "Request must include a `search` argument")
        search_sql = Search.values(search)

        return "%s values found" % Values.get_count(
            tuple(point_ids), start_time, end_time, search_sql)
    except InvalidSearchException:
        return "Invalid Value Search Syntax"
    except psycopg2.Error as e:  # Any InvalidSearchException will be thrown and result in a 500.
        return "Invalid Value Search: " + str(e.pgerror)