Esempio n. 1
0
def delete_puzzle_timeline(puzzle_id):
    ""
    cur = db.cursor()
    result = cur.execute(
        fetch_query_string("select-internal-puzzle-details-for-puzzle_id.sql"),
        {
            "puzzle_id": puzzle_id
        },
    ).fetchall()
    if not result:
        err_msg = {"msg": "No puzzle found", "status_code": 400}
        cur.close()
        return err_msg

    (result, col_names) = rowify(result, cur.description)
    puzzle_data = result[0]
    puzzle = puzzle_data["id"]

    result = cur.execute(fetch_query_string("delete_puzzle_timeline.sql"),
                         {"puzzle": puzzle})
    cur.close()
    db.commit()

    redis_connection.delete("timeline:{puzzle}".format(puzzle=puzzle))
    redis_connection.delete("score:{puzzle}".format(puzzle=puzzle))

    msg = {"rowcount": result.rowcount, "msg": "Deleted", "status_code": 200}
    return msg
    def post(self):
        args = {}
        if request.form:
            args.update(request.form.to_dict(flat=True))

        # Verify args
        action = args.get("action")
        if action not in SLOT_ACTIONS:
            abort(400)

        player = args.get("player")
        if not player:
            abort(400)

        cur = db.cursor()

        if action == "add":
            cur.execute(fetch_query_string("add-new-user-puzzle-slot.sql"),
                        {"player": player})
        elif action == "delete":
            cur.execute(fetch_query_string("delete-user-puzzle-slot.sql"),
                        {"player": player})

        cur.close()
        db.commit()

        return redirect(
            "/chill/site/admin/player/details/{player}/".format(player=player))
Esempio n. 3
0
def user_id_from_ip(ip, skip_generate=True):
    cur = db.cursor()

    shareduser = current_app.secure_cookie.get(u"shareduser")
    if shareduser != None:
        # Check if this shareduser is still valid and another user hasn't chosen
        # a bit icon.
        result = cur.execute(
            fetch_query_string("select-user-by-id-and-no-password.sql"),
            {
                "id": shareduser
            },
        ).fetchall()
        if result:
            cur.close()
            return int(shareduser)

    # Handle players that had a cookie in their browser, but then deleted it.
    # Or new players that are from the same ip that existing players are on.
    # These players are shown the new-player page.
    result = cur.execute(
        fetch_query_string("select-user-id-by-ip-and-no-password.sql"), {
            "ip": ip
        }).fetchall()
    user_id = ANONYMOUS_USER_ID

    # No ip in db so create it except if the skip_generate flag is set
    if not result:
        if skip_generate:
            cur.close()
            return None
        login = generate_user_login()
        cur.execute(
            fetch_query_string("add-new-user-for-ip.sql"),
            {
                "ip": ip,
                "login": login,
                "points": current_app.config["NEW_USER_STARTING_POINTS"],
            },
        )
        db.commit()

        result = cur.execute(
            fetch_query_string("select-user-id-by-ip-and-login.sql"),
            {
                "ip": ip,
                "login": login
            },
        ).fetchall()
        (result, col_names) = rowify(result, cur.description)
        user_id = result[0]["id"]
    else:
        (result, col_names) = rowify(result, cur.description)
        user_id = result[0]["id"]

    cur.close()
    return user_id
Esempio n. 4
0
def delete_puzzle_file(puzzle_id, file_name):
    ""

    cur = db.cursor()
    result = cur.execute(
        fetch_query_string("select-internal-puzzle-details-for-puzzle_id.sql"),
        {
            "puzzle_id": puzzle_id
        },
    ).fetchall()
    if not result:
        err_msg = {"msg": "No puzzle found", "status_code": 400}
        cur.close()
        return err_msg

    (result, col_names) = rowify(result, cur.description)
    puzzle_data = result[0]
    puzzle = puzzle_data["id"]

    result = cur.execute(
        fetch_query_string("select_puzzle_file_with_attribution.sql"),
        {
            "puzzle": puzzle,
            "name": file_name
        },
    ).fetchall()
    if result:
        (result, col_names) = rowify(result, cur.description)
        puzzle_file_with_attribution_data = result[0]

        # Delete previous attribution if it exists
        if puzzle_file_with_attribution_data["attribution_id"]:
            result = cur.execute(
                fetch_query_string("delete_attribution_from_puzzle_file.sql"),
                {"id": puzzle_file_with_attribution_data["puzzle_file_id"]},
            )
            result = cur.execute(
                fetch_query_string("delete_attribution.sql"),
                {
                    "attribution":
                    puzzle_file_with_attribution_data["attribution_id"]
                },
            )

    result = cur.execute(
        fetch_query_string("delete_puzzle_file_with_name_for_puzzle.sql"),
        {
            "puzzle": puzzle,
            "name": file_name
        },
    )
    db.commit()
    cur.close()

    msg = {"rowcount": result.rowcount, "msg": "Deleted", "status_code": 200}
    return msg
Esempio n. 5
0
def add_to_timeline(puzzle_id, player, points=0, timestamp=None, message=""):
    ""

    if timestamp is None:
        _timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())
    else:
        # TODO: Should verify timestamp is in ISO format.
        _timestamp = timestamp

    if not isinstance(points, int):
        err_msg = {"msg": "points needs to be an integer", "status_code": 400}
        return err_msg

    cur = db.cursor()
    result = cur.execute(
        fetch_query_string("select-internal-puzzle-details-for-puzzle_id.sql"),
        {
            "puzzle_id": puzzle_id
        },
    ).fetchall()
    if not result:
        err_msg = {"msg": "No puzzle found", "status_code": 400}
        cur.close()
        return err_msg

    (result, col_names) = rowify(result, cur.description)
    puzzle_data = result[0]
    puzzle = puzzle_data["id"]

    # TODO: The message is not added to the Timeline DB table for now since that
    # information is not currently being used.
    try:
        result = cur.execute(
            fetch_query_string("insert_batchpoints_to_timeline.sql"),
            {
                "puzzle": puzzle,
                "player": player,
                "points": points,
                "timestamp": _timestamp,
            },
        )
    except sqlite3.IntegrityError:
        err_msg = {
            "msg":
            "Database integrity error. Does the player ({}) exist?".format(
                player),
            "status_code":
            400,
        }
        cur.close()
        return err_msg

    cur.close()
    db.commit()
    msg = {"rowcount": result.rowcount, "msg": "Inserted", "status_code": 200}
    return msg
Esempio n. 6
0
    def post(self):
        """Update shareduser to user"""

        # Prevent creating a new user if no support for cookies. Player should
        # have 'ot' already set by viewing the page.
        uses_cookies = current_app.secure_cookie.get(u"ot")
        if not uses_cookies:
            abort(400)

        cur = db.cursor()

        response = make_response("", 200)

        user = user_id_from_ip(request.headers.get("X-Real-IP"))
        if user == None:
            abort(400)
        user = int(user)

        # Only set new user if enough dots
        result = cur.execute(
            fetch_query_string("select-minimum-points-for-user.sql"),
            {
                "user":
                user,
                "points":
                current_app.config["NEW_USER_STARTING_POINTS"] +
                current_app.config["POINT_COST_FOR_CHANGING_BIT"],
            },
        ).fetchone()
        if result:
            self.register_new_user(user)
            # Save as a cookie
            current_app.secure_cookie.set(u"user",
                                          str(user),
                                          response,
                                          expires_days=365)
            # Remove shareduser
            expires = datetime.datetime.utcnow() - datetime.timedelta(days=365)
            current_app.secure_cookie.set(u"shareduser",
                                          "",
                                          response,
                                          expires=expires)

            cur.execute(
                fetch_query_string("decrease-user-points.sql"),
                {
                    "user": user,
                    "points":
                    current_app.config["POINT_COST_FOR_CHANGING_BIT"],
                },
            )

        cur.close()
        db.commit()
        return response
Esempio n. 7
0
    def get(self, puzzle_id):
        ""
        ip = request.headers.get("X-Real-IP")
        user = int(
            current_app.secure_cookie.get(u"user") or user_id_from_ip(ip))
        cur = db.cursor()
        result = cur.execute(
            fetch_query_string("select_viewable_puzzle_id.sql"),
            {
                "puzzle_id": puzzle_id
            },
        ).fetchall()
        if not result:
            # 404 if puzzle does not exist
            abort(404)

        (result, col_names) = rowify(result, cur.description)
        puzzle = result[0].get("puzzle")
        status = result[0].get("status")
        now = int(time.time())

        count = (redis_connection.zcount(
            "timeline:{puzzle}".format(puzzle=puzzle), now - 5 * 60, "+inf")
                 or 0)

        player_active_count = {"now": now, "count": count}

        cur.close()
        return json.jsonify(player_active_count)
Esempio n. 8
0
    def get(self):

        url_match = request.args.get("url_match", "/resources/%")

        cur = db.cursor()

        result = cur.execute(
            fetch_query_string(
                "select_rendered_puzzle_files_with_url_like.sql"),
            {
                "url_match": url_match
            },
        ).fetchall()
        if not result:
            puzzle_files = []
        else:
            (result, col_names) = rowify(result, cur.description)
            puzzle_files = result

        response = {
            "puzzle_files": puzzle_files,
        }

        cur.close()

        return make_response(json.jsonify(response), 200)
Esempio n. 9
0
    def get(self, puzzle_id):
        ""
        cur = db.cursor()
        result = cur.execute(
            fetch_query_string("select_viewable_puzzle_id.sql"),
            {
                "puzzle_id": puzzle_id
            },
        ).fetchall()
        if not result:
            # 404 if puzzle does not exist
            abort(404)

        (result, col_names) = rowify(result, cur.description)
        puzzle = result[0].get("puzzle")
        status = result[0].get("status")
        now = int(time.time())

        count = (redis_connection.zcount(
            "timeline:{puzzle}".format(puzzle=puzzle), now - 5 * 60, "+inf")
                 or 0)

        player_active_count = {"now": now, "count": count}

        cur.close()
        return make_response(json.jsonify(player_active_count), 200)
Esempio n. 10
0
def reward_player_for_score_threshold(player):
    cur = db.cursor()
    try:
        result = cur.execute(
            fetch_query_string(
                "reward_player_for_score_threshold--puzzle-instance-slot.sql"),
            {
                "player":
                player,
                "score_threshold":
                int(
                    current_app.config.get(
                        "REWARD_INSTANCE_SLOT_SCORE_THRESHOLD", '0'))
            },
        )

    except sqlite3.IntegrityError:
        err_msg = {
            "msg":
            "Database integrity error. Does the player ({}) exist?".format(
                player),
            "status_code":
            400,
        }
        cur.close()
        return err_msg
    cur.close()
    db.commit()
    msg = {"rowcount": result.rowcount, "msg": "Executed", "status_code": 200}
    return msg
Esempio n. 11
0
def update_user_points_and_m_date(player, points, score):
    cur = db.cursor()
    try:
        result = cur.execute(
            fetch_query_string("update_user_points_and_m_date.sql"),
            {
                "id": player,
                "points": points,
                "score": score,
                "POINTS_CAP": current_app.config["POINTS_CAP"],
            },
        )
    except sqlite3.IntegrityError:
        err_msg = {
            "msg":
            "Database integrity error. Does the player ({}) exist?".format(
                player),
            "status_code":
            400,
        }
        cur.close()
        return err_msg
    cur.close()
    db.commit()
    msg = {"rowcount": result.rowcount, "msg": "Executed", "status_code": 200}
    return msg
Esempio n. 12
0
    def post(self, puzzle_id):
        "Ping and record the time in milliseconds for this player."
        now_ms = int(time.time() * 1000)
        response = {"message": "", "name": ""}

        user = current_app.secure_cookie.get(u"user") or user_id_from_ip(
            request.headers.get("X-Real-IP"), skip_generate=True)

        if user == None:
            response["message"] = "Player not currently logged in."
            response["name"] = "error"
            return make_response(json.jsonify(response), 400)

        user = int(user)

        cur = db.cursor()

        # Validate the puzzle_id
        result = cur.execute(
            fetch_query_string("select_viewable_puzzle_id.sql"),
            {
                "puzzle_id": puzzle_id
            },
        ).fetchall()
        if not result:
            response["message"] = "Invalid puzzle id."
            response["name"] = "error"
            cur.close()
            db.commit()
            return make_response(json.jsonify(response), 400)
        else:
            (result, col_names) = rowify(result, cur.description)
            puzzle = result[0].get("puzzle")
            status = result[0].get("status")
            if status != ACTIVE:
                response["message"] = "Puzzle not active"
                response["name"] = "invalid"
                cur.close()
                db.commit()
                return make_response(json.jsonify(response), 200)

        # publish to the puzzle channel the ping with the user id.  This will
        # allow that player to determine their latency.
        token = uuid.uuid4().hex[:4]
        pingtoken_key = get_pingtoken_key(puzzle, user, token)
        redis_connection.setex(pingtoken_key, 60, now_ms)

        current_app.logger.debug(
            "publish ping {puzzle_id}".format(puzzle_id=puzzle_id))
        sse.publish(
            "{user}:{token}".format(user=user, token=token),
            type="ping",
            channel="puzzle:{puzzle_id}".format(puzzle_id=puzzle_id),
        )
        response["message"] = "ping accepted"
        response["name"] = "accepted"
        response = make_response(json.jsonify(response), 202)
        cur.close()
        db.commit()
        return response
Esempio n. 13
0
    def get(self):
        cur = db.cursor()

        response = make_response(redirect("/chill/site/admin/puzzle/"))

        # Delete the shareduser cookie if it exists
        expires = datetime.datetime.utcnow() - datetime.timedelta(days=365)
        current_app.secure_cookie.set("shareduser",
                                      "",
                                      response,
                                      expires=expires)

        current_app.secure_cookie.set("user",
                                      str(ADMIN_USER_ID),
                                      response,
                                      expires_days=365)
        cur.execute(
            fetch_query_string("extend-cookie_expires-for-user.sql"),
            {"id": ADMIN_USER_ID},
        )
        db.commit()

        cur.close()

        return response
Esempio n. 14
0
    def post(self):
        args = {}
        xhr_data = request.get_json()
        if xhr_data:
            args.update(xhr_data)
        args.update(request.form.to_dict(flat=True))
        args.update(request.args.to_dict(flat=True))

        if len(args.keys()) == 0:
            abort(400)

        # Start db operations
        cur = db.cursor()

        llamas = 0
        result = cur.execute(fetch_query_string("get-llama-count.sql")).fetchall()
        if result:
            (result, col_names) = rowify(result, cur.description)
            llamas = result[0]["llamas"]

        # TODO: Process args for llamaness
        processed = {"llama-check": True, "count": llamas}

        db.commit()
        cur.close()

        return json.jsonify(processed)
    def test_updates_puzzle_details_with_values(self):
        "Should update the puzzle details with the values that were sent"
        with self.app.app_context():
            with self.app.test_client() as c:
                new_data = {"status": 1, "queue": 1, "pieces": 1234}
                rv = c.patch(
                    "/internal/puzzle/{puzzle_id}/details/".format(
                        puzzle_id=self.puzzle_id
                    ),
                    json=new_data,
                )
                self.assertEqual(200, rv.status_code)
                self.assertEqual(
                    {"msg": "Updated", "rowcount": 1, "status_code": 200}, rv.json
                )

                self.puzzle_data.update(new_data)

                cur = self.db.cursor()
                result = cur.execute(
                    fetch_query_string(
                        "select-internal-puzzle-details-for-puzzle_id.sql"
                    ),
                    {"puzzle_id": self.puzzle_id,},
                ).fetchall()
                (result, col_names) = rowify(result, cur.description)
                self.assertEqual(result[0], self.puzzle_data)
Esempio n. 16
0
def build_select_available_puzzle_sql(query_file, status, type):
    """
    The sqlite bind params don't support expanding lists, so doing this
    manually.  Careful here to avoid sql injection attacks.
    """
    recent_status = set()  # include false values for is_recent
    active_status = {
        0,
    }  # include false values for is_active
    status_ids = set()
    for name in status:
        if name == STATUS_RECENT:
            recent_status.add(1)
            status_ids.add(ACTIVE)

        elif name == STATUS_ACTIVE:
            recent_status.add(0)
            recent_status.add(1)
            active_status.add(1)
            status_ids.add(ACTIVE)

        elif name == STATUS_IN_QUEUE:
            recent_status.add(0)
            status_ids.add(IN_QUEUE)

        elif name == STATUS_COMPLETE:
            recent_status.add(0)
            status_ids.add(COMPLETED)

        elif name == STATUS_FROZEN:
            recent_status.add(0)
            status_ids.add(FROZEN)

        elif name == STATUS_UNAVAILABLE:
            recent_status.add(0)
            status_ids.add(REBUILD)
            status_ids.add(IN_RENDER_QUEUE)
            status_ids.add(RENDERING)
            status_ids.add(RENDERING_FAILED)

    original_type = set()
    for name in type:
        if name == TYPE_ORIGINAL:
            original_type.add(1)
        elif name == TYPE_INSTANCE:
            original_type.add(0)

    query = fetch_query_string(query_file)

    query = query.format(
        status="({})".format(", ".join(map(str, status_ids))),
        recent_status="({})".format(", ".join(map(str, recent_status))),
        active_status="({})".format(", ".join(map(str, active_status))),
        original_type="({})".format(", ".join(map(str, original_type))),
    )
    # current_app.logger.debug(query)

    return query
Esempio n. 17
0
    def get(self, puzzle_id):
        """
        deletePenalty: number;
        canFreeze: boolean;
        canDelete: boolean;
        canReset: boolean;
        hasActions: boolean;
        deleteDisabledMessage: string; //Not enough dots to delete this puzzle
        isFrozen: boolean;
        status: number;
        """
        ip = request.headers.get("X-Real-IP")
        user = int(current_app.secure_cookie.get("user") or user_id_from_ip(ip))

        cur = db.cursor()

        # validate the puzzle_id
        result = cur.execute(
            fetch_query_string("select-puzzle-details-for-puzzle_id.sql"),
            {"puzzle_id": puzzle_id},
        ).fetchall()
        if not result:
            # 400 if puzzle does not exist
            err_msg = {
                "msg": "No puzzle found",
            }
            cur.close()
            return make_response(json.jsonify(err_msg), 400)
        (result, col_names) = rowify(result, cur.description)
        puzzleData = result[0]

        (delete_penalty, can_delete, delete_disabled_message) = self.get_delete_prereq(
            puzzleData
        )
        response = {
            "canDelete": can_delete,
            "canFreeze": puzzleData.get("status") in (FROZEN, BUGGY_UNLISTED, ACTIVE),
            "canReset": puzzleData.get("permission") == PRIVATE
            and not puzzleData.get("is_original")
            and puzzleData.get("status") in (FROZEN, BUGGY_UNLISTED, ACTIVE, COMPLETED),
            "hasActions": puzzleData.get("status")
            in (
                FROZEN,
                ACTIVE,
                COMPLETED,
                BUGGY_UNLISTED,
                RENDERING_FAILED,
                REBUILD,
                IN_RENDER_QUEUE,
                MAINTENANCE,
            ),
            "deleteDisabledMessage": delete_disabled_message,
            "deletePenalty": delete_penalty,
            "isFrozen": puzzleData.get("status") == FROZEN,
            "status": puzzleData.get("status", -99),
        }
        cur.close()
        return make_response(json.jsonify(response), 200)
Esempio n. 18
0
    def get(self, anonymous_login):
        "Set the user cookie if correct anon bit link."
        login = anonymous_login[:-13]
        password = anonymous_login[-13:]
        cur = db.cursor()

        response = make_response(redirect("/"))

        result = cur.execute(fetch_query_string("select-user-by-login.sql"), {
            "login": login
        }).fetchall()

        if not result:
            cur.close()
            return make_response("no user", 404)

        (result, col_names) = rowify(result, cur.description)
        user_data = result[0]

        expires = datetime.datetime.utcnow() - datetime.timedelta(days=365)
        if crypt.crypt(password,
                       user_data["password"]) == user_data["password"]:
            current_app.secure_cookie.set("shareduser",
                                          "",
                                          response,
                                          expires=expires)
            current_app.secure_cookie.set("user",
                                          str(user_data["id"]),
                                          response,
                                          expires_days=365)
            cur.execute(
                fetch_query_string("extend-cookie_expires-for-user.sql"),
                {"id": user_data["id"]},
            )
            db.commit()
        else:
            # Invalid anon login; delete cookie just in case it's there
            current_app.secure_cookie.set("user",
                                          "",
                                          response,
                                          expires=expires)

        cur.close()

        return response
Esempio n. 19
0
    def get(self):
        "Return an object to be used by the generateBitLink js call"

        user = current_app.secure_cookie.get("user")
        if user is None:
            return make_response("no user", 403)
        user = int(user)

        (p_string, password) = generate_password()

        # Store encrypted password in db
        cur = db.cursor()
        try:
            result = cur.execute(
                fetch_query_string("select-login-from-user.sql"), {
                    "id": user
                }).fetchall()
        except IndexError:
            # user may have been added after a db rollback
            cur.close()
            return make_response("no user", 404)

        if not result:
            cur.close()
            return make_response("no user", 404)

        (result, col_names) = rowify(result, cur.description)
        user_data = result[0]

        cur.execute(
            fetch_query_string("update-password-for-user.sql"),
            {
                "id": user,
                "password": password
            },
        )
        db.commit()

        cur.close()
        data = {
            "bit":
            "".join(["", "/puzzle-api/bit/", user_data["login"], p_string])
        }
        return make_response(json.jsonify(data), 200)
Esempio n. 20
0
def add_puzzle_file(puzzle_id, file_name, url, attribution=None):
    cur = db.cursor()
    result = cur.execute(
        fetch_query_string("select-internal-puzzle-details-for-puzzle_id.sql"),
        {
            "puzzle_id": puzzle_id
        },
    ).fetchall()
    if not result:
        err_msg = {"msg": "No puzzle found", "status_code": 400}
        cur.close()
        return err_msg

    (result, col_names) = rowify(result, cur.description)
    puzzle_data = result[0]
    puzzle = puzzle_data["id"]

    if attribution:
        attribution_result = cur.execute(
            fetch_query_string("insert_attribution.sql"), attribution)
        attribution_id = attribution_result.lastrowid
        result = cur.execute(
            fetch_query_string("add-puzzle-file-with-attribution.sql"),
            {
                "puzzle": puzzle,
                "name": file_name,
                "url": url,
                "attribution": attribution_id,
            },
        )
    else:
        result = cur.execute(
            fetch_query_string("add-puzzle-file.sql"),
            {
                "puzzle": puzzle,
                "name": file_name,
                "url": url
            },
        )
    db.commit()
    cur.close()
    msg = {"rowcount": result.rowcount, "msg": "Inserted", "status_code": 200}
    return msg
Esempio n. 21
0
def reset_puzzle_pieces_and_handle_errors(puzzle):
    cur = db.cursor()
    result = cur.execute(
        fetch_query_string("select_all_from_puzzle_for_id.sql"),
        {
            "id": puzzle
        },
    ).fetchall()
    if not result:
        cur.close()
        raise DataError("No puzzle found with that id.")

    (result, col_names) = rowify(result, cur.description)
    puzzle_data = result[0]
    cur.close()

    try:
        reset_puzzle_pieces(puzzle)
    # TODO: Fix handling of errors on puzzle reset pieces
    except Error as err:
        # Update puzzle status to RENDERING_FAILED
        r = requests.patch(
            "http://{HOSTAPI}:{PORTAPI}/internal/puzzle/{puzzle_id}/details/".
            format(
                HOSTAPI=current_app.config["HOSTAPI"],
                PORTAPI=current_app.config["PORTAPI"],
                puzzle_id=puzzle_data["puzzle_id"],
            ),
            json={"status": RENDERING_FAILED},
        )
        sse.publish(
            "status:{}".format(RENDERING_FAILED),
            channel="puzzle:{puzzle_id}".format(
                puzzle_id=puzzle_data["puzzle_id"]),
        )
        if r.status_code != 200:
            raise Exception("Puzzle details api error")

    # Update puzzle status to ACTIVE and sse publish
    r = requests.patch(
        "http://{HOSTAPI}:{PORTAPI}/internal/puzzle/{puzzle_id}/details/".
        format(
            HOSTAPI=current_app.config["HOSTAPI"],
            PORTAPI=current_app.config["PORTAPI"],
            puzzle_id=puzzle_data["puzzle_id"],
        ),
        json={"status": ACTIVE},
    )
    sse.publish(
        "status:{}".format(ACTIVE),
        channel="puzzle:{puzzle_id}".format(
            puzzle_id=puzzle_data["puzzle_id"]),
    )
    if r.status_code != 200:
        raise Exception("Puzzle details api error")
    def post(self):
        "Route is protected by basic auth in nginx"
        args = {}
        if request.form:
            args.update(request.form.to_dict(flat=True))

        # Verify args
        action = args.get("action")
        if action not in ACTIONS:
            abort(400)

        name_register_ids = request.form.getlist("name_register_id")
        if len(name_register_ids) == 0:
            abort(400)
        if not isinstance(name_register_ids, list):
            name_register_ids = [name_register_ids]

        name_register_users = request.form.getlist("name_register_user")
        if len(name_register_users) == 0:
            abort(400)
        if not isinstance(name_register_users, list):
            name_register_users = [name_register_users]

        cur = db.cursor()

        if action == "reject":

            def each(name_register_ids):
                for id in name_register_ids:
                    yield {"id": id}

            cur.executemany(
                fetch_query_string("reject-name-on-name-register-for-id.sql"),
                each(name_register_ids),
            )

        db.commit()
        cur.close()

        routes_to_purge = []
        for user in name_register_users:
            routes_to_purge.append(
                "/chill/site/internal/player-bit/{}/".format(user))
        purge_route_from_nginx_cache(
            "\n".join(routes_to_purge),
            current_app.config.get("PURGEURLLIST"),
        )

        return redirect("/chill/site/admin/name-register-review/")
Esempio n. 23
0
 def get(self, user):
     cur = db.cursor()
     result = cur.execute(
         fetch_query_string("select-user-details-by-id.sql"),
         {
             "id": user,
         },
     ).fetchall()
     if not result:
         err_msg = {
             "msg": "No user found",
         }
         cur.close()
         return make_response(json.jsonify(err_msg), 404)
     (result, col_names) = rowify(result, cur.description)
     user_details = result[0]
     return make_response(json.jsonify(user_details), 200)
Esempio n. 24
0
def get_puzzle_details(puzzle_id):
    ""
    cur = db.cursor()
    # validate the puzzle_id
    result = cur.execute(
        fetch_query_string("select-internal-puzzle-details-for-puzzle_id.sql"),
        {"puzzle_id": puzzle_id},
    ).fetchall()
    if not result:
        # 404 if puzzle does not exist
        err_msg = {"msg": "No puzzle found", "status_code": 404}
        cur.close()
        return err_msg
    (result, col_names) = rowify(result, cur.description)
    puzzle_details = result[0]
    cur.close()
    msg = {"result": puzzle_details, "msg": "Success", "status_code": 200}
    return msg
Esempio n. 25
0
 def get_bid_amount(self, cur, puzzleData):
     "compute the winning bid amount"
     bid_amount = 0
     low, high = next(
         filter(
             lambda x: x[0] <= puzzleData["pieces"] and x[1] > puzzleData["pieces"],
             current_app.config["SKILL_LEVEL_RANGES"],
         )
     )
     queue_count_result = cur.execute(
         fetch_query_string("get-queue-count-for-skill-level.sql"),
         {"low": low, "high": high},
     ).fetchone()
     if queue_count_result and len(queue_count_result):
         bid_amount = (queue_count_result[0] + 1) * current_app.config[
             "BID_COST_PER_PUZZLE"
         ]
         return bid_amount
Esempio n. 26
0
def update_user_name_approved_for_approved_date_due():
    cur = db.cursor()
    try:
        result = cur.execute(
            fetch_query_string(
                "update-user-name-approved-for-approved_date-due.sql"), )
    except sqlite3.IntegrityError:
        err_msg = {
            "msg":
            "Database integrity error. update_user_name_approved_for_approved_date_due",
            "status_code": 400,
        }
        cur.close()
        return err_msg
    cur.close()
    db.commit()
    msg = {"rowcount": result.rowcount, "msg": "Executed", "status_code": 200}
    return msg
Esempio n. 27
0
    def get(self, puzzle_id):
        ""
        cur = db.cursor()
        result = cur.execute(
            fetch_query_string("_select-puzzle-by-puzzle_id.sql"),
            {"puzzle_id": puzzle_id},
        ).fetchall()
        if not result:
            # 404 if puzzle does not exist
            abort(404)

        (result, col_names) = rowify(result, cur.description)
        puzzle = result[0].get("id")
        now = int(time.time())

        timeline = redis_connection.zrevrange(
            "timeline:{puzzle}".format(puzzle=puzzle), 0, -1, withscores=True
        )
        score_puzzle = redis_connection.zrange(
            "score:{puzzle}".format(puzzle=puzzle), 0, -1, withscores=True
        )
        user_score = dict(score_puzzle)
        user_rank = {}
        for index, item in enumerate(score_puzzle):
            user_rank[int(item[0])] = index + 1

        players = []
        for index, item in enumerate(timeline):
            (user, timestamp) = item
            players.append(
                {
                    "id": int(user),
                    "score": int(user_score.get(user, 0)),
                    "rank": user_rank.get(
                        int(user), 0
                    ),  # a 0 value means the player hasn't joined any pieces
                    "seconds_from_now": int(now - timestamp),
                }
            )

        puzzle_stats = {"now": now, "players": players}

        cur.close()
        return encoder.encode(puzzle_stats)
    def test_get_puzzle_details(self):
        "Should get the puzzle details"
        with self.app.app_context():
            with self.app.test_client() as c:
                rv = c.get("/internal/puzzle/{puzzle_id}/details/".format(
                    puzzle_id=self.puzzle_id))
                self.assertEqual(200, rv.status_code)
                self.assertEqual(self.puzzle_data, rv.json)

                cur = self.db.cursor()
                result = cur.execute(
                    fetch_query_string(
                        "select-internal-puzzle-details-for-puzzle_id.sql"),
                    {
                        "puzzle_id": self.puzzle_id,
                    },
                ).fetchall()
                (result, col_names) = rowify(result, cur.description)
                self.assertEqual(result[0], self.puzzle_data)
Esempio n. 29
0
def update_points_to_minimum_for_all_users(minimum):
    cur = db.cursor()
    try:
        result = cur.execute(
            fetch_query_string("update_points_to_minimum_for_all_users.sql"),
            {"minimum": minimum},
        )
    except sqlite3.IntegrityError:
        err_msg = {
            "msg":
            "Database integrity error. update_points_to_minimum_for_all_users",
            "status_code": 400,
        }
        cur.close()
        return err_msg
    cur.close()
    db.commit()
    msg = {"rowcount": result.rowcount, "msg": "Executed", "status_code": 200}
    return msg
Esempio n. 30
0
    def register_new_user(self, user_id):
        """Update initial ip tracked user to now be cookie tracked with a password."""
        cur = db.cursor()

        login = generate_user_login()
        (p_string, password) = generate_password()

        cur.execute(
            fetch_query_string("set-initial-password-for-user.sql"),
            {
                "id": user_id,
                "password": password,
                "ip": request.headers.get("X-Real-IP"),
            },
        )
        # Other players on the same network that are tracked by shareduser
        # cookie will have it updated to a new value.
        db.commit()
        cur.close()