コード例 #1
0
ファイル: app.py プロジェクト: amielsinue/metrics-test
def request_device_readings_quartiles(device_uuid):
    """
    This endpoint allows clients to GET the 1st and 3rd quartile
    sensor reading value for a device.

    Mandatory Query Parameters:
    * type -> The type of sensor value a client is looking for
    * start -> The epoch start time for a sensor being created
    * end -> The epoch end time for a sensor being created
    # TODO: implement a better database to be able to calculate quartiles properly
    #
    """
    where_statement = get_where_statement(device_uuid, request.args)
    where_statement = where_statement if where_statement else 'where 1'

    cur, conn = get_db_cursor(app)
    query = '''
    select value, NTILE(4) OVER(ORDER BY value) as quartile from readings where {}
    '''.format(where_statement)
    cur.execute(query)
    rows = cur.fetchall()
    data = {}
    for row in rows:
        if row['quartile'] == 1:
            data['quartile_1'] = row['value']
        if row['quartile'] == 3:
            data['quartile_3'] = row['value']
    conn.close()
    return jsonify(data), 200
コード例 #2
0
 def create_test_ticket(self):
     with get_db_cursor(commit=True) as cursor:
         cursor.execute("""INSERT INTO tickets (theme, text, email, status)
                     VALUES('test_theme', 'test_text', '*****@*****.**',
                     'open') RETURNING id;""")
         ticket = cursor.fetchone()
         return ticket["id"]
コード例 #3
0
def answer():
    if 'username' not in session:
        return redirect(url_for("login", next="answer"))

    if session['role'] != 'expert' and session['role'] != 'admin':
        abort(403)

    cursor = get_db_cursor()
    if request.method == 'POST':
        db = get_db()
        cursor.execute(
            "INSERT INTO answers (body, question_id, answer_owner) VALUES (%s, %s, %s)",
            (request.form.get("answer"), request.args.get("id"),
             session["username"]))
        cursor.execute("UPDATE questions SET status='answered' WHERE id=%s",
                       (request.args.get("id"), ))
        db.commit()
        flash("Your answer was submitted successfully!", "success")
        return redirect(url_for('answer'))

    cursor.execute(
        "SELECT * FROM questions WHERE status='not answered' and asked_username=%s",
        (session["username"], ))
    questions = cursor.fetchall()

    return render_template("answer.html",
                           title="Answer Questions",
                           questions=questions)
コード例 #4
0
def question(id):
    if 'username' not in session:
        return redirect(url_for("login", next="question", id=id))

    cursor = get_db_cursor()
    cursor.execute(
        "SELECT questions.body as question, answers.body as answer,\
                    questions.asker_username as asker, questions.asked_username as asked,\
                    questions.status as status, questions.ask_time as time FROM questions JOIN answers\
                    ON questions.id = answers.question_id WHERE questions.id = %s and answers.answer_owner = questions.asked_username",
        (id, ))
    question = cursor.fetchone()
    if question:
        cursor.execute(
            "SELECT answer_owner, body as answer FROM answers WHERE question_id = %s and answer_owner != %s",
            (id, question["asked"]))
        answers = cursor.fetchall()

        return render_template("question.html",
                               title="Question",
                               question=question,
                               answers=enumerate(answers) if answers else None)

    flash("There is no question in here!!", "info")
    return redirect(url_for("home"))
コード例 #5
0
def questions_asked_user(username):
    cursor = get_db_cursor(False)
    cursor.execute(
        "SELECT * FROM questions WHERE asked_username = %s and status = 'answered'",
        (username, ))

    return jsonify(
        {"questions": dictionarizeData(cursor.fetchall(), cursor.description)})
コード例 #6
0
 def get_ticket(self, ticket_id):
     ticket = self.get_from_cache("ticket_{0}".format(ticket_id))
     if ticket:
         return json.dumps(ticket, default=self.datetime_converter), 200
     with get_db_cursor() as cursor:
         ticket = self.get_ticket_with_comments(ticket_id, cursor)
         self.set_to_cache("ticket_{0}".format(ticket_id), ticket)
     return json.dumps(ticket, default=self.datetime_converter), 200
コード例 #7
0
 def post_ticket(self, request):
     data = self.prepare_request_data(request)
     data = self.validator.validate_ticket_post_schema(data)
     with get_db_cursor(commit=True) as cursor:
         cursor.execute(self.queries.create_ticket, data)
         ticket = cursor.fetchone()
         ticket.update({"comments": []})
         self.set_to_cache("ticket_{0}".format(ticket["id"]), ticket)
     return json.dumps(ticket, default=self.datetime_converter), 201
コード例 #8
0
 def create_test_comment(self):
     with get_db_cursor(commit=True) as cursor:
         cursor.execute(
             """INSERT INTO comments (text, email, ticket_id)
                     VALUES('test_text', '*****@*****.**',
                      %s) RETURNING id;""",
             (self.ticket, ),
         )
         comment = cursor.fetchone()
         return comment["id"]
コード例 #9
0
def questions():
    cursor = get_db_cursor(False)
    cursor.execute("SELECT questions.body as question, answers.body as answer,\
                    questions.asker_username as asker, questions.asked_username as asked,\
                    questions.status as status, questions.ask_time as time FROM questions JOIN answers\
                    ON questions.id = answers.question_id WHERE answers.answer_owner = questions.asked_username"
                   )

    return jsonify(
        {"questions": dictionarizeData(cursor.fetchall(), cursor.description)})
コード例 #10
0
def home():
    if 'username' not in session:
        return redirect(url_for("login", next="home"))

    cursor = get_db_cursor()
    cursor.execute(
        "SELECT * FROM questions Where status='answered' ORDER BY ask_time DESC, id DESC"
    )
    questions = cursor.fetchall()
    return render_template("home.html", title="Home", questions=questions)
コード例 #11
0
def unanswered():
    if 'username' not in session:
        return redirect(url_for("login", next="unanswered"))

    cursor = get_db_cursor()
    cursor.execute("SELECT * FROM questions Where status='not answered'")
    questions = cursor.fetchall()

    return render_template("unanswered.html",
                           title="Unanswered",
                           questions=questions)
コード例 #12
0
    def wrapper(*args, **kwargs):
        if not request.authorization:
            return jsonify({"error": "Authentication Error"}), 403

        cursor = get_db_cursor()
        cursor.execute("SELECT * FROM users WHERE username = %s",
                       (request.authorization.username, ))
        user = cursor.fetchone()
        if not user or not check_password_hash(user["password"],
                                               request.authorization.password):
            return jsonify({"error": "Authentication Error"}), 403
        return func(*args, **kwargs)
コード例 #13
0
 def patch_ticket(self, ticket_id, request):
     data = self.validator.validate_ticket_patch_schema(
         self.prepare_request_data(request))
     status = data["status"]
     with get_db_cursor(commit=True) as cursor:
         self.check_ticket_patch_logic(ticket_id, status, cursor)
         cursor.execute(self.queries.update_ticket_status,
                        (status, ticket_id))
         ticket = cursor.fetchone()
         cursor.execute(self.queries.get_comments_by_ticket, (ticket_id, ))
         comments = cursor.fetchall() or []
         ticket.update({"comments": comments})
         self.set_to_cache("ticket_{0}".format(ticket_id), ticket)
     return json.dumps(ticket, default=self.datetime_converter), 200
コード例 #14
0
 def post_comment(self, request):
     data = self.validator.validate_comment_post_schema(
         self.prepare_request_data(request))
     with get_db_cursor(commit=True) as cursor:
         try:
             cursor.execute(self.queries.create_comment, data)
         except IntegrityError:
             raise ValidationException(
                 "You are not allowed create comments for closed tickets")
         comment = cursor.fetchone()
         self.set_to_cache(
             "ticket_{0}".format(comment["ticket_id"]),
             self.get_ticket_with_comments(comment["ticket_id"], cursor),
         )
     return json.dumps(comment, default=self.datetime_converter), 201
コード例 #15
0
ファイル: app.py プロジェクト: amielsinue/metrics-test
def request_device_readings_min(device_uuid, metric):
    """
    This endpoint allows clients to GET the max sensor reading for a device.

    Mandatory Query Parameters:
    * type -> The type of sensor value a client is looking for

    Optional Query Parameters
    * start -> The epoch start time for a sensor being created
    * end -> The epoch end time for a sensor being created
    """
    if metric not in ['min', 'max', 'mean', 'median', 'mode']:
        return 'Invalid value for metric', 404

    where_statement = get_where_statement(device_uuid, request.args)

    cur, conn = get_db_cursor(app)
    if metric == 'median':
        query = '''
        SELECT AVG(value) as total
            FROM (
            SELECT value
                  FROM readings where {}
                  ORDER BY value
                  LIMIT 2 - (SELECT COUNT(*) FROM readings where {}) % 2    -- odd 1, even 2
                  OFFSET (SELECT (COUNT(*) - 1) / 2 FROM readings where {}))
        '''.format(where_statement, where_statement, where_statement)
        cur.execute(query)
        row = cur.fetchone()
        total = row['total']
        response = jsonify(dict(value=total)), 200
    elif metric == 'mode':
        cur.execute('select `value`, count(*) as n from readings where {} group by value order by 2 DESC limit 1'.format(where_statement))
        row = cur.fetchone()
        total = row['value']
        response = jsonify(dict(value=total)), 200
    else:
        if metric == 'mean':
            metric = 'avg'
        cur.execute('select {}(value) as value from readings where {}'.format(metric, where_statement))
        row = cur.fetchone()
        # Return the JSON
        response = jsonify(dict(zip(['value'], row))), 200

    conn.close()
    return response
コード例 #16
0
def users():
    if session['role'] != 'admin':
        abort(403)

    cursor = get_db_cursor()
    if request.method == 'POST':
        db = get_db()
        username = request.json["username"]
        role = request.json["role"]
        cursor.execute("UPDATE users SET role=%s WHERE username=%s",
                       (role, username))
        db.commit()

        return jsonify({'success': 'true'})

    cursor.execute("SELECT * FROM users")
    users = cursor.fetchall()

    return render_template("users.html", title="User Setup", users=users)
コード例 #17
0
ファイル: app.py プロジェクト: amielsinue/metrics-test
def request_device_readings_post(device_uuid):
    # Grab the post parameters
    create_device_reading_schema = CreateDeviceReading()
    unmarshal_result = create_device_reading_schema.load(request.data)
    if unmarshal_result.errors:
        abort(BAD_REQUEST, message=str(unmarshal_result.errors))
    post_data = unmarshal_result.data
    sensor_type = post_data.get('type')
    value = post_data.get('value')
    date_created = post_data.get('date_created', int(time.time()))
    # Insert data into db
    cur, conn = get_db_cursor(app)
    cur.execute('insert into readings (device_uuid,type,value,date_created) VALUES (?,?,?,?)',
                (device_uuid, sensor_type, value, date_created))

    conn.commit()
    conn.close()
    # Return success
    return 'success', 201
コード例 #18
0
def answer_unanswered(id):
    if 'username' not in session:
        return redirect(url_for("login", next="answer_unanswered", id=id))

    cursor = get_db_cursor()
    cursor.execute(
        "SELECT * FROM questions WHERE id=%s and status='not answered'",
        (id, ))
    question = cursor.fetchone()

    if not question:
        flash("There is no an unanswered question with this id!", "info")
        return redirect(url_for('unanswered'))

    if request.method == 'POST':
        db = get_db()
        cursor.execute(
            "INSERT INTO answers (body, question_id, answer_owner) VALUES (%s, %s, %s)",
            (request.form.get("answer"), id, session["username"]))
        # if the one who answered the question was the one who the question was led to its
        # status will be changed to 'answered'
        if question["asked_username"] == session["username"]:
            cursor.execute(
                "UPDATE questions SET status='answered' WHERE id=%s", (id, ))
            db.commit()
            flash("Your answer was submitted successfully!", "success")
            return redirect(url_for("unanswered"))
        db.commit()
        flash("Your answer has been submitted", "success")
        return redirect(url_for('answer_unanswered', id=id))
    else:
        cursor.execute(
            "SELECT answer_owner, body as answer FROM answers WHERE question_id = %s",
            (id, ))
        answers = cursor.fetchall()

        return render_template("answer_unanswered.html",
                               question=question,
                               answers=enumerate(answers) if answers else None)
コード例 #19
0
def ask():
    if 'username' not in session:
        return redirect(url_for("login", next="ask"))

    cursor = get_db_cursor()
    if request.method == 'POST':
        db = get_db()
        cursor.execute(
            "INSERT INTO questions (ask_time, body, asker_username, asked_username) VALUES (%s, %s, %s, %s)",
            (datetime.strftime(datetime.now(),
                               DATE_FORMAT), request.form.get("question"),
             session["username"], request.form.get("expert")))
        db.commit()
        flash(
            "Your question has been submitted successfully, and soon you will be able to get the answer to it.",
            "success")
        return redirect(url_for("ask"))

    cursor.execute("SELECT * FROM users Where role='expert' and username!=%s",
                   (session["username"], ))
    experts = cursor.fetchall()

    return render_template("ask.html", title="Ask Question", experts=experts)
コード例 #20
0
ファイル: app.py プロジェクト: amielsinue/metrics-test
def request_device_readings_get(device_uuid):
    """
    This endpoint allows clients to POST or GET data specific sensor types.

    POST Parameters:
    * type -> The type of sensor (temperature or humidity)
    * value -> The integer value of the sensor reading
    * date_created -> The epoch date of the sensor reading.
        If none provided, we set to now.

    Optional Query Parameters:
    * start -> The epoch start time for a sensor being created
    * end -> The epoch end time for a sensor being created
    * type -> The type of sensor value a client is looking for
    """
    # Execute the query
    where_statement = get_where_statement(device_uuid, request.args)
    cur, conn = get_db_cursor(app)
    cur.execute('select * from readings where {}'.format(where_statement))
    rows = cur.fetchall()
    # Return the JSON
    conn.close()
    return jsonify([dict(zip(['device_uuid', 'type', 'value', 'date_created'], row)) for row in rows]), 200
コード例 #21
0
def login():
    if 'username' in session:
        return redirect(url_for("home"))

    if request.method == 'POST':
        cursor = get_db_cursor()
        cursor.execute("SELECT * FROM users WHERE username=%s",
                       (request.form.get("username"), ))
        user = cursor.fetchone()
        if user:
            if check_password_hash(user["password"],
                                   request.form.get("password")):
                flash("You have logged in successfully!", "success")
                session["username"] = user["username"]
                session["role"] = user["role"]
                if request.args:
                    if request.args.get("id"):
                        return redirect(
                            url_for(request.args.get("next"),
                                    id=request.args.get("id")))
                    else:
                        return redirect(url_for(request.args.get("next")))
                else:
                    return redirect(url_for("home"))
            else:
                flash("You should check your input!!", "danger")
                # in here I redirected the user to the same page to make the request method
                # GET again instead of POST
                return redirect(url_for("login"))
        else:
            flash(
                "There is no user with this username, maybe you should register first!",
                "danger")
            return redirect(url_for("login"))

    return render_template("login.html", title="Login")
コード例 #22
0
def add_question():
    question = request.get_json()
    question_body = question.get("question")
    question_asker_username = question.get("asker_username")
    question_asked_username = question.get("asked_username")

    db = get_db()
    cursor = get_db_cursor()
    cursor.execute("SELECT * FROM users WHERE username = %s",
                   (question_asked_username, ))
    asked_user = cursor.fetchone()
    if not asked_user:
        return jsonify({
            "error":
            f"there is no expert with the username {request.authorization.username}"
        })

    cursor.execute(
        "INSERT INTO questions (ask_time, body, asker_username, asked_username) VALUES (%s, %s, %s, %s)",
        (datetime.strftime(datetime.now(), DATE_FORMAT), question_body,
         request.authorization.username, asked_user["username"]))
    db.commit()

    return jsonify({"status": "success"}), 201
コード例 #23
0
def register():
    if 'username' in session:
        return redirect(url_for("home"))

    if request.method == 'POST':
        db = get_db()
        cursor = get_db_cursor()
        cursor.execute("SELECT * FROM users WHERE username=%s",
                       (request.form.get("username"), ))
        user = cursor.fetchone()
        if user:
            flash("This username isn't available, Try choosing another one!",
                  "danger")
        else:
            hashed_password = generate_password_hash(
                request.form.get("password"))
            cursor.execute(
                "INSERT INTO users (username, password) values (%s, %s)",
                (request.form.get("username"), hashed_password))
            db.commit()
            flash("You signed up successfully, You can login now", "success")
            return redirect(url_for("login"))

    return render_template("register.html", title="Register")
コード例 #24
0
ファイル: app.py プロジェクト: amielsinue/metrics-test
def request_readings_summary():
    """
    This endpoint allows clients to GET a full summary
    of all sensor data in the database per device.

    Optional Query Parameters
    * type -> The type of sensor value a client is looking for
    * start -> The epoch start time for a sensor being created
    * end -> The epoch end time for a sensor being created
    """
    where_statement = get_where_statement(args=request.args)
    where_statement = where_statement if where_statement else '1=1'
    cur, conn = get_db_cursor(app)
    query = '''
    select 
        device_uuid,
        min(value) as `min`,
        max(value) as `max`,
        avg(value) as `mean`,
        (
        select value from (select value, ntile(4) over (order by value) as q from readings where {} and device_uuid=main_readings.device_uuid) as q1 where q = 1
        ) as quartile_1,
        (
        select value from (select value, ntile(4) over (order by value) as q from readings where {} and device_uuid=main_readings.device_uuid) as q1 where q = 3
        ) as quartile_3,  
        (
        SELECT AVG(value) 
        FROM (
        SELECT value
              FROM readings where {} and device_uuid=main_readings.device_uuid
              ORDER BY value
              LIMIT 2 - (SELECT COUNT(*) FROM readings where {}) % 2    -- odd 1, even 2
              OFFSET (SELECT (COUNT(*) - 1) / 2 FROM readings where {}))
        ) as median,
        (
            select value from (select `value`, count(*) as n from readings where {} and device_uuid=main_readings.device_uuid group by value order by 2 DESC limit 1)
        ) as `mode`       
    from readings as main_readings where {} group by device_uuid
    '''.format(
        where_statement,
        where_statement,
        where_statement,
        where_statement,
        where_statement,
        where_statement,
        where_statement
    )
    cur.execute(query)
    rows = cur.fetchall()
    data = []
    for row in rows:
        min = row['min']
        max = row['max']
        mean = row['mean']
        quartile_1 = row['quartile_1']
        quartile_3 = row['quartile_3']
        median = row['median']
        mode = row['mode']
        data.append(dict(
            device_uuid=row['device_uuid'],
            min=min,
            max=max,
            mean=mean,
            quartile_1=quartile_1,
            quartile_3=quartile_3,
            median=median,
            mode=mode
        ))


    conn.close()

    return jsonify(data), 200
コード例 #25
0
 def tearDown(self):
     with get_db_cursor(commit=True) as cursor:
         cursor.execute("TRUNCATE tickets CASCADE;")
         cursor.execute("TRUNCATE comments;")