Esempio n. 1
0
def terminate_manager():
    database.get_conn().close()
    if constants.IS_REMOTE:
        clean_all_workers()
        ec2 = aws_helper.session.client("ec2")
        ec2.stop_instances(InstanceIds=['i-0d92ec486e6faeb22'])
        sys.exit(4)
    else:
        shutdown = request.environ.get("werkzeug.server.shutdown")
        if not shutdown:
            flash("Failed to terminate manager app", constants.ERROR)
            return
        clean_all_workers()
        shutdown()
    return redirect(url_for("manager.display_main_page"))
Esempio n. 2
0
def show_image(image_id):
    try:
        # query image data from the database
        sql_stmt = '''
        SELECT processed_image_path, unprocessed_image_path, thumbnail_image_path, category, num_faces, 
        num_masked, num_unmasked, username FROM image WHERE image_id="{}"
        '''.format(image_id)
        db_conn = get_conn()
        cursor = db_conn.cursor()
        cursor.execute(sql_stmt)
        image_record = cursor.fetchone()
        db_conn.commit()

        # if not found the image record
        if not image_record:
            flash("Couldn't find the image", constants.ERROR)
            return redirect(url_for("detection.detect"))

        # prevent unwanted access from other user
        if image_record[-1] != g.user[constants.USERNAME]:
            flash("Not allowed to access the image uploaded by other user",
                  constants.ERROR)
            return redirect(url_for("detection.detect"))

    # error handling
    except Exception as e:
        flash("Unexpected exception {}".format(e), constants.ERROR)
        return redirect(url_for("detection.detect"))

    return render_template("detection/show.html",
                           image_record=image_record,
                           category_map=constants.CATEGORY_MAP,
                           is_remote=constants.IS_REMOTE)
Esempio n. 3
0
def auto_scaler_policy():
    policy = get_auto_scaler_policy()
    if request.method == "POST":
        with manager.lock:
            try:
                expand_ratio = request.form.get("expand_ratio")
                shrink_ratio = request.form.get("shrink_ratio")
                grow_threshold = request.form.get("grow_threshold")
                shrink_threshold = request.form.get("shrink_threshold")
                is_valid, error = validate_input_policy(policy, expand_ratio, shrink_ratio, grow_threshold, shrink_threshold)
                if not is_valid:
                    flash(error, constants.ERROR)
                    return redirect(url_for("auto_scaler.auto_scaler_policy"))
                policy[constants.EXPAND_RATIO] = float(expand_ratio) if expand_ratio else policy[constants.EXPAND_RATIO]
                policy[constants.SHRINK_RATIO] = float(shrink_ratio) if shrink_ratio else policy[constants.SHRINK_RATIO]
                policy[constants.CPU_UTIL_GROW_THRESHOLD] = int(grow_threshold) if grow_threshold else policy[constants.CPU_UTIL_GROW_THRESHOLD]
                policy[constants.CPU_UTIL_SHRINK_THRESHOLD] = int(shrink_threshold) if shrink_threshold else policy[constants.CPU_UTIL_SHRINK_THRESHOLD]
                db_conn = database.get_conn()
                cursor = db_conn.cursor()
                sql_stmt = '''UPDATE policy SET expand_ratio={}, shrink_ratio={}, cpu_util_grow_threshold={}, 
                            cpu_util_shrink_threshold={} WHERE policy_id=1'''.format(
                    policy[constants.EXPAND_RATIO], policy[constants.SHRINK_RATIO],
                    policy[constants.CPU_UTIL_GROW_THRESHOLD], policy[constants.CPU_UTIL_SHRINK_THRESHOLD]
                )
                cursor.execute(sql_stmt)
                db_conn.commit()
                flash("Successfully updated Auto-Scaler policy", constants.INFO)
            except Exception as e:
                flash("Unexpected error, failed to update Auto-Scaler policy, please try again", constants.ERROR)
            return redirect(url_for("auto_scaler.auto_scaler_policy"))

    return render_template("auto_scaler.html", policy=policy)
Esempio n. 4
0
def get_sensor_time_series_data(sensor_id):
    """Get the time series data in a Pandas DataFrame, for the sensor chosen in the dropdown"""

    sql = f"""
        SELECT 
            --Get the 3-hour average instead of every single data point
            time_bucket('03:00:00'::interval, time) as time,
            sensor_id,
            avg(temperature) as temperature,
            avg(cpu) as cpu
        FROM sensor_data
        WHERE sensor_id = {sensor_id}
        GROUP BY 
            time_bucket('03:00:00'::interval, time), 
            sensor_id
        ORDER BY 
            time_bucket('03:00:00'::interval, time), 
            sensor_id;
    """

    conn = get_conn()
    with conn.cursor(cursor_factory=RealDictCursor) as cursor:
        cursor.execute(sql)
        rows = cursor.fetchall()
        columns = [str.lower(x[0]) for x in cursor.description]

    df = pd.DataFrame(rows, columns=columns)

    return df
Esempio n. 5
0
def user_management():
    # show a list of user for selection to delete
    db_conn = get_conn()
    cursor = db_conn.cursor()
    sql_stmt = "SELECT username FROM user WHERE role='{}'".format(
        constants.USER)
    cursor.execute(sql_stmt)
    user = [i[0] for i in cursor.fetchall()]
    db_conn.commit()
    return render_template("user/user_management.html", users=user)
Esempio n. 6
0
def get_auto_scaler_policy():
    try:
        db_conn = database.get_conn()
        cursor = db_conn.cursor()
        cursor.execute("SELECT expand_ratio, shrink_ratio, cpu_util_grow_threshold, cpu_util_shrink_threshold FROM policy")
        policy = cursor.fetchone()
        policy = policy if policy else constants.DEFAULT_POLICY
        db_conn.commit()
        return list(policy)
    except Exception as e:
        return constants.DEFAULT_POLICY
Esempio n. 7
0
def password_recovery():
    if request.method == "POST":
        username = request.form.get("username")
        security_answer = request.form.get("securityanswer")
        password = request.form.get("password")
        if not username or not password or not security_answer:
            flash(
                "Please provide all the required fields to recover your passwords",
                constants.ERROR)
            return redirect(request.url)

        # make queries to the SQL DB to modify the user record
        try:
            db_conn = get_conn()
            cursor = db_conn.cursor()
            sql_stmt = "SELECT * FROM user WHERE username='******'".format(
                username)
            cursor.execute(sql_stmt)
            user = cursor.fetchone()
            if not user:
                db_conn.commit()
                flash("No user with username {} exists".format(username),
                      constants.ERROR)
                return redirect(request.url)

            # verify the answer if not default
            if user[constants.MODIFIED_ANSWER] != 0:
                if not verify_password(user[constants.SECURITY_ANSWER],
                                       security_answer):
                    db_conn.commit()
                    flash("Incorrect security answer", constants.ERROR)
                    return redirect(request.url)

            # change password to one provided
            new_pwd = encrypt_credentials(password)
            sql_stmt = "UPDATE user SET password='******' WHERE username='******'".format(
                new_pwd, username)
            cursor.execute(sql_stmt)
            db_conn.commit()

        except Exception as e:
            flash("Unexpected error {}".format(e), constants.ERROR)
            return redirect(request.url)
        else:
            flash("Password is reset successfully", constants.INFO)
            return redirect(url_for("login.login"))

    return render_template("login/password_recovery.html")
Esempio n. 8
0
def get_sensor_types():
    """Get a list of different types of sensors"""
    sql = """
        --Get the labels and underlying values for the dropdown menu "children"
        SELECT 
            distinct 
            type as label, 
            type as value
        FROM sensors;
    """
    conn = get_conn()
    with conn.cursor(cursor_factory=RealDictCursor) as cursor:
        cursor.execute(sql)
        # types is a list of dictionaries that looks like this, for example:
        # [{'label': 'a', 'value': 'a'}]
        types = cursor.fetchall()
    
    return types
Esempio n. 9
0
def history(username):
    try:
        # query the images for user
        db_conn = get_conn()
        cursor = db_conn.cursor()
        query = '''SELECT user.username, image.category, image.thumbnail_image_path, image.image_id , image.created_at 
        FROM user JOIN image  ON user.username = image.username WHERE user.username = "******" Order by image.created_at DESC
        '''.format(username)
        cursor.execute(query)
        images = cursor.fetchall()
        db_conn.commit()

        # separate the user images based on the category
        no_faces_detected = []
        all_faces_wear_masks = []
        no_faces_wear_masks = []
        partial_faces_wear_masks = []
        for image in images:
            if image[1] == constants.NO_FACES_DETECTED:
                no_faces_detected.append(image)
            elif image[1] == constants.ALL_FACES_WEAR_MASKS:
                all_faces_wear_masks.append(image)
            elif image[1] == constants.NO_FACES_WEAR_MASKS:
                no_faces_wear_masks.append(image)
            elif image[1] == constants.PARTIAL_FACES_WEAR_MASKS:
                partial_faces_wear_masks.append(image)
        category_map = {
            "No face detected in image":
            no_faces_detected,
            "All faces from image are wearing masks":
            all_faces_wear_masks,
            "No faces from image are wearing masks":
            no_faces_wear_masks,
            "Only some faces from image are wearing masks":
            partial_faces_wear_masks
        }

        # pass in the image lists to the view
        return render_template("history/history.html",
                               category_map=category_map,
                               is_remote=constants.IS_REMOTE)
    except Exception as e:
        flash("Unexpected error {}".format(e), constants.ERROR)
        return redirect(request.url)
Esempio n. 10
0
def get_sensor_locations(type_):
    """Get a list of different locations of sensors"""
    sql = f"""
        --Get the labels and underlying values for the dropdown menu "children"
        SELECT 
            distinct 
            location as label, 
            location as value
        FROM sensors
        WHERE type = '{type_}';
    """
    conn = get_conn()
    with conn.cursor(cursor_factory=RealDictCursor) as cursor:
        cursor.execute(sql)
        # locations is a list of dictionaries that looks like this, for example:
        # [{'label': 'floor', 'value': 'floor'}]
        locations = cursor.fetchall()

    return locations
Esempio n. 11
0
def change_password(username):
    old_password = request.form.get("old_password")
    new_password = request.form.get("new_password")
    new_password_confirm = request.form.get("new_password_confirm")
    if not old_password or not new_password or not new_password_confirm:
        flash(
            "Please provide old password, new password and confirm new password",
            constants.ERROR)
        return redirect(request.url)

    if new_password != new_password_confirm:
        flash(
            "Please make sure the new password and confirm new password are the same",
            constants.ERROR)
        return redirect(request.url)
    elif new_password == old_password:
        flash("New password is the same as old password, please change",
              constants.ERROR)
        return redirect(request.url)

    # make queries to the SQL DB to modify the user record
    try:
        db_conn = get_conn()
        cursor = db_conn.cursor()
        # hash_pwd = generate_hashed_password(old_password)
        sql_stmt = "SELECT * FROM user WHERE username='******'".format(username)
        cursor.execute(sql_stmt)
        user = cursor.fetchone()
        if not verify_password(user[constants.PASSWORD], old_password):
            db_conn.commit()
            flash("Incorrect password", constants.ERROR)
            return redirect(request.url)
        new_hash_pwd = encrypt_credentials(new_password)
        sql_stmt = "UPDATE user SET password='******' WHERE username='******'".format(
            new_hash_pwd, username)
        cursor.execute(sql_stmt)
        db_conn.commit()
    except Exception as e:
        flash("Unexpected error {}".format(e), constants.ERROR)
        return redirect(request.url)
    else:
        flash("Password is updated successfully", constants.INFO)
        return render_template("user/profile.html", username=username)
Esempio n. 12
0
def remove_app_data():
    try:
        s3 = aws_helper.session.resource('s3')
        bucket = s3.Bucket(constants.BUCKET_NAME)
        bucket.objects.all().delete()
        db_conn = database.get_conn()
        cursor = db_conn.cursor()
        sql_script = open("app/static/schema.sql")
        sql_commands = sql_script.read().split(";")
        for command in sql_commands:
            command = command.replace("\n", "")
            if command:
                cursor.execute(command)
        db_conn.commit()
    except Exception as e:
        flash("Failed to remove application data, please try again",
              constants.ERROR)
    else:
        flash("Successfully removed application data", constants.INFO)
    return redirect(url_for("manager.display_main_page"))
Esempio n. 13
0
def change_security_answer(username):
    # confirm the input are the same
    new_securityanswer = request.form.get("new_securityAnswer")
    new_securityanswer_confirm = request.form.get("new_securityAnswer_confirm")
    if not new_securityanswer or not new_securityanswer_confirm:
        flash(
            "Please provide new security answer and confirm new security answer when making changes",
            constants.ERROR)
        return redirect(request.url)
    if new_securityanswer != new_securityanswer_confirm:
        flash(
            "Please make sure the new security answer and confirm new security answer are the same",
            constants.ERROR)
        return redirect(request.url)

    try:
        new_hash_pwd = encrypt_credentials(new_securityanswer)
        db_conn = get_conn()
        cursor = db_conn.cursor()
        if g.user[constants.MODIFIED_ANSWER]:
            old_securityanswer = request.form.get("old_securityAnswer")
            if not old_securityanswer:
                flash("Please provide old security answer", constants.ERROR)
            if not verify_password(g.user[constants.SECURITY_ANSWER],
                                   old_securityanswer):
                db_conn.commit()
                flash("Incorrect security answer", constants.ERROR)
                return redirect(request.url)
        sql_stmt = "UPDATE user SET security_answer='{}' WHERE username='******'".format(
            new_hash_pwd, username)
        cursor.execute(sql_stmt)
        sql_stmt = "UPDATE user SET modified_answer='1' WHERE username='******'".format(
            username)
        cursor.execute(sql_stmt)
        db_conn.commit()
    except Exception as e:
        flash("Unexpected error {}".format(e), constants.ERROR)
        return redirect(request.url)
    else:
        flash("Security answer is updated successfully", constants.INFO)
        return redirect(url_for("user.user_profile", username=username))
Esempio n. 14
0
def load_logged_in_user():
    # keep track of requests on CloudWatch
    with aws_helper.lock:
        aws_helper.requests_count += 1

    # for the image request, we just skip the user info retrieval to avoid overloading DB
    if request.path.startswith("/static"):
        return

    # for normal request, we need to ensure that we have proper user credentials
    # store username only as we want to hide user credentials from client
    username = session.get("username")
    if username is None:
        g.user = None
    else:
        db_conn = get_conn()
        cursor = db_conn.cursor()
        cursor.execute(
            "SELECT * FROM user WHERE username='******'".format(username))
        user = cursor.fetchone()
        g.user = user
        db_conn.commit()
Esempio n. 15
0
def delete_user():
    db_conn = get_conn()
    cursor = db_conn.cursor()
    username = request.form.get("username")
    try:
        sql_stmt = "SELECT * FROM user WHERE username='******'".format(username)
        cursor.execute(sql_stmt)
        if not cursor.fetchone():
            db_conn.commit()
            flash("No user exist in the database", constants.ERROR)
            return redirect(url_for("user.user_management"))
        sql_stmt = "DELETE FROM user WHERE username='******'".format(username)
        cursor.execute(sql_stmt)
        # remove all user uploaded images
        if constants.IS_REMOTE:
            # remove the images stored in S3 as well
            s3_client = session.client("s3")
            response = delete_user_images_s3(s3_client, username)
            # if there's still something to delete
            while response.get("IsTruncated"):
                response = delete_user_images_s3(s3_client, username)
        else:
            user_image_folder = constants.USER_FOLDER.format(username)
            if os.path.exists(user_image_folder):
                shutil.rmtree(user_image_folder)
    except ClientError as ce:
        db_conn.rollback()
        flash("Failed to delete images in S3", constants.ERROR)
        return redirect(url_for("user.user_management"))
    except Exception as e:
        db_conn.rollback()
        flash("Unexpected error {}".format(e), constants.ERROR)
        return redirect(url_for("user.user_management"))
    else:
        db_conn.commit()
        flash("Successfully deleted user with username {}".format(username),
              constants.INFO)
        return redirect(url_for("user.user_management"))
Esempio n. 16
0
def get_sensors(type_, location):
    """
    Get a list of sensor dictionaries from our TimescaleDB database, 
    along with lists of distinct sensor types and locations
    """
    sql = f"""
        --Get the labels and underlying values for the dropdown menu "children"
        SELECT 
            location || ' - ' || type as label,
            id as value
        FROM sensors
        WHERE 
            type = '{type_}'
            and location = '{location}';
    """
    conn = get_conn()
    with conn.cursor(cursor_factory=RealDictCursor) as cursor:
        cursor.execute(sql)
        # sensors is a list of dictionaries that looks like this, for example:
        # [{'label': 'floor - a', 'value': 1}]
        sensors = cursor.fetchall()

    return sensors
Esempio n. 17
0
def authenticate(username, password):
    try:
        db_conn = get_conn()
        cursor = db_conn.cursor()
        # hash_pwd = generate_hashed_password(password)
        sql_stmt = "SELECT * FROM user WHERE username='******'".format(username)
        cursor.execute(sql_stmt)
        user = cursor.fetchone()
        db_conn.commit()
    except Exception as e:
        error = "Unexpected error {}".format(e)
    else:
        if user:
            verified = verify_password(user[constants.PASSWORD], password)
            error = None if verified else "Incorrect username or password"
            if not error and verified:
                session.clear()
                session["username"] = user[constants.USERNAME]
                # load logged in user for api case, normally this will be loaded before every request
                load_logged_in_user()
        else:
            error = "User doesn't exist"
    return error
Esempio n. 18
0
def work():
    response = {"success": False}
    status_code = HTTPStatus.BAD_REQUEST
    username = request.form.get("username")
    password = request.form.get("password")

    # request validation before doing actual work
    if not username:
        response["error"] = {
            "code": "MissingParameter",
            "message": "Please provide username in request"
        }
        return response, status_code
    elif not password:
        response["error"] = {
            "code": "MissingParameter",
            "message": "Please provide password in request"
        }
        return response, status_code
    elif username in constants.RESERVED_NAMES:
        response["error"] = {
            "code": "ReservedUsername",
            "message": "The username provided is reserved"
        }
        return response, status_code

    try:
        # check if the user is registered or not
        db_conn = get_conn()
        cursor = db_conn.cursor()
        sql_stmt = "SELECT * FROM user WHERE username='******' ".format(username)
        cursor.execute(sql_stmt)

        if cursor.fetchone() is not None:
            response["error"] = {
                "code": "UserAlreadyExists",
                "message": "Username is already registered"
            }
            db_conn.commit()
            return response, status_code

        # create new user and insert into DB
        hashed_pwd = encrypt_credentials(password)
        hashed_ans = encrypt_credentials("default")
        insert_stmt = "INSERT INTO user (username, password,role,security_answer) VALUES ('{}', '{}', '{}','{}')".format(
            username, hashed_pwd, constants.USER, hashed_ans)
        cursor.execute(insert_stmt)
        db_conn.commit()

    # in case of error, report error
    except Exception as e:
        status_code = HTTPStatus.INTERNAL_SERVER_ERROR
        response["error"] = {
            "code": "ServerError",
            "message": "Unexpected Server Error {}".format(e)
        }
    # otherwise return success message
    else:
        status_code = HTTPStatus.OK
        response["success"] = True

    # returns response body with the corresponding HTTP status code
    return response, status_code
Esempio n. 19
0
def upload_file(file_data):
    # file directory processing
    output_info = None
    output_file_name, image_id = generate_file_name()
    username = g.user[constants.USERNAME]
    processed_path = os.path.join(constants.PROCESSED_FOLDER.format(username),
                                  output_file_name)
    original_path = os.path.join(constants.UNPROCESSED_FOLDER.format(username),
                                 output_file_name)
    thumbnail_path = os.path.join(constants.THUMBNAIL_FOLDER.format(username),
                                  output_file_name)

    # make directory if not exist to prevent issue
    if not os.path.exists(constants.PROCESSED_FOLDER.format(username)):
        os.makedirs(constants.PROCESSED_FOLDER.format(username))
    if not os.path.exists(constants.UNPROCESSED_FOLDER.format(username)):
        os.makedirs(constants.UNPROCESSED_FOLDER.format(username))
    if not os.path.exists(constants.THUMBNAIL_FOLDER.format(username)):
        os.makedirs(constants.THUMBNAIL_FOLDER.format(username))

    try:
        # store the original file and do the detection
        open(original_path, "wb").write(file_data)
        output_info = pytorch_infer.main(original_path, processed_path)
        image = Image.open(processed_path)
        image.thumbnail((80, 80))
        image.save(thumbnail_path)

        # for easier switch between local dev and prod usage
        if constants.IS_REMOTE:
            paths = {
                "processed": processed_path,
                "original": original_path,
                "thumbnail": thumbnail_path
            }
            paths = store_image_s3(paths)
            processed_path = paths["processed"]
            original_path = paths["original"]
            thumbnail_path = paths["thumbnail"]
        else:
            processed_path = processed_path[len(constants.STATIC_PREFIX):]
            original_path = original_path[len(constants.STATIC_PREFIX):]
            thumbnail_path = thumbnail_path[len(constants.STATIC_PREFIX):]

        # insert the record into the SQL DB
        mask_info = extract_mask_info(output_info)
        sql_stmt = '''
        INSERT INTO image (image_id, processed_image_path, unprocessed_image_path, thumbnail_image_path, category, 
        num_faces, num_masked, num_unmasked, username) VALUES ("{}", "{}", "{}", "{}", {}, {}, {}, {}, "{}")
        '''.format(image_id, processed_path, original_path, thumbnail_path,
                   classify_image_category(mask_info),
                   mask_info.get("num_faces",
                                 0), mask_info.get("num_masked", 0),
                   mask_info.get("num_unmasked", 0),
                   g.user[constants.USERNAME])
        db_conn = get_conn()
        cursor = db_conn.cursor()
        cursor.execute(sql_stmt)
        db_conn.commit()

    except ClientError as ce:
        error = "Failed to upload file to S3"
        return error, output_info, None
    except Exception as e:
        error = "Unexpected error {}".format(e)
        return error, output_info, None
    else:
        return None, output_info, image_id