def test_pieces_are_updated_after_reset(self): "The puzzle piece positions should be randomly placed after reset" with self.app.app_context(): with self.app.test_client() as c: cur = self.db.cursor() result = cur.execute( "select * from Piece where puzzle = :puzzle order by id", { "puzzle": self.puzzle }, ).fetchall() (before_positions, cols) = rowify(result, cur.description) pr.reset_puzzle_pieces(self.puzzle) result = cur.execute( "select * from Piece where puzzle = :puzzle order by id", { "puzzle": self.puzzle }, ).fetchall() (after_positions, cols) = rowify(result, cur.description) has_changed = False for (index, before_piece) in enumerate(before_positions): after_piece = after_positions[index] if (before_piece["x"] != after_piece["x"] or before_piece["y"] != after_piece["y"]): has_changed = True break self.assertTrue(has_changed, msg="piece positions change") cur.close()
def migrate_next_puzzle(puzzle): cur = db.cursor() logging.info("migrating puzzle {}".format(puzzle)) # Update any original that have an empty url cur.execute(query_update_puzzle_file_original_null_url, {'puzzle': puzzle}) # Update any original that have a '0' for url cur.execute(query_update_puzzle_file_original_s3_url, {'puzzle': puzzle}) db.commit() result = cur.execute(query_select_puzzle_file_to_migrate_from_s3, { 'puzzle': puzzle }).fetchall() if result: (result, col_names) = rowify(result, cur.description) for item in result: migrate_s3_puzzle(item) result = cur.execute(query_select_puzzle_file_to_migrate_from_unsplash, { 'puzzle': puzzle, }).fetchall() if result: (result, col_names) = rowify(result, cur.description) for item in result: migrate_unsplash_puzzle(item) cur.close()
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
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
def test_move_piece_to_join_immovable(self): "Move a piece to join immovable group" cur = self.db.cursor() (results, col_names) = rowify(cur.execute(self.query_puzzle_255), cur.description) testPuzzle = results[0] r = 0 # Move 6 to join piece 4 which is immovable (piece, x, y) = (6, 446, 222) (topic, msg) = translate(0, testPuzzle, piece, x, y, r, db_file=self.tmp_db.name) expectedMsg = ":{piece}:{x}:{y}:0::\n:6:428:218:0:4:1\n:4::::4:".format( **locals()) print("({0})".format(expectedMsg)) print("[{0}]".format(msg)) assert len(expectedMsg) == len(msg) for l in expectedMsg.split("\n"): assert l in msg
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
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 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)
def setUp(self): self.query_puzzle_255 = "select id as puzzle, table_width, table_height, mask_width, puzzle_id, pieces from Puzzle where id = 255" self.tmp_db = tempfile.NamedTemporaryFile(delete=False) self.db = sqlite3.connect(self.tmp_db.name) cur = self.db.cursor() for file_path in ( "../queries/create_table_puzzle.sql", "../queries/create_table_piece.sql", "../queries/create_table_user.sql", "../queries/create_table_timeline.sql", "examplePuzzle.sql", "examplePiece.sql", ): with open( os.path.normpath( os.path.join(os.path.dirname(__file__), file_path)), "r", ) as f: for statement in f.read().split(";"): # print statement cur.execute(statement) self.db.commit() (results, col_names) = rowify(cur.execute("select id as puzzle from Puzzle"), cur.description) for result in results: self.puzzles.append(result["puzzle"]) convert(result["puzzle"], db_file=self.tmp_db.name) cur.close()
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)
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)
def test_join_two_pieces_not_in_group(self): "Join two pieces that are not grouped" cur = self.db.cursor() (results, col_names) = rowify(cur.execute(self.query_puzzle_255), cur.description) testPuzzle = results[0] r = 0 (piece, x, y) = (6, 54, 61) (topic, msg) = translate(0, testPuzzle, piece, x, y, r, db_file=self.tmp_db.name) (piece, x, y) = (5, 130, 77) (topic, msg) = translate(0, testPuzzle, piece, x, y, r, db_file=self.tmp_db.name) # Piece 5 gets shifted to join piece 6, piece group 6 is created and both pieces join expectedMsg = ":{piece}:{x}:{y}:0::\n:5:119:61:0:6:\n:6::::6:".format( **locals()) assert len(expectedMsg) == len(msg) for l in expectedMsg.split("\n"): assert l in msg
def do_task(self): super().do_task() cur = db.cursor() result = cur.execute( read_query_file( "select-user-name-waiting-to-be-approved.sql")).fetchall() if result: self.log_task() names = [] (result, col_names) = rowify(result, cur.description) for item in result: names.append("{approved_date} - {display_name}".format(**item)) message = "\n".join(names) # Send a notification email (silent fail if not configured) current_app.logger.debug(message) if not current_app.config.get("DEBUG", True): try: send_message( current_app.config.get("EMAIL_MODERATOR"), "Puzzle Massive - new names", message, current_app.config, ) except Exception as err: current_app.logger.warning( "Failed to send notification message. {}".format(err)) pass cur.close()
def test_move_grouped_piece_to_join_immovable(self): "Move a grouped piece to join immovable group" cur = self.db.cursor() (results, col_names) = rowify(cur.execute(self.query_puzzle_255), cur.description) testPuzzle = results[0] r = 0 # Move 8 to join piece 4 which is immovable # (8,1,11) -> 4 (piece, x, y) = (8, 367, 296) (topic, msg) = translate(0, testPuzzle, piece, x, y, r, db_file=self.tmp_db.name) expectedMsg = ":{piece}:{x}:{y}:90:8:\n:1:493:283::4:1\n:11:428:283::4:1\n:8::::4:\n:8:363:283:90:4:1".format( **locals()) assert len(expectedMsg) == len(msg) for l in expectedMsg.split("\n"): assert l in msg
def test_join_two_grouped_pieces_to_a_piece_not_grouped(self): "Join two grouped pieces to a piece not grouped" cur = self.db.cursor() (results, col_names) = rowify(cur.execute(self.query_puzzle_255), cur.description) testPuzzle = results[0] r = 0 # Move piece 7 (piece, x, y) = (7, 55, 118) (topic, msg) = translate(0, testPuzzle, piece, x, y, r, db_file=self.tmp_db.name) (piece, x, y) = (3, 46, 196) (topic, msg) = translate(0, testPuzzle, piece, x, y, r, db_file=self.tmp_db.name) # Piece 3 and 2 are grouped, 3 is moved to join piece 7 expectedMsg = ( ":{piece}:{x}:{y}:0:3:\n:7::::3:\n:2:120:183:::\n:3:55:183:0:3:". format(**locals())) assert len(expectedMsg) == len(msg) for l in expectedMsg.split("\n"): assert l in msg
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)
def test_join_two_pieces_that_are_both_in_group(self): "Join two pieces that are grouped when moving piece group is smaller or same size" cur = self.db.cursor() (results, col_names) = rowify(cur.execute(self.query_puzzle_255), cur.description) testPuzzle = results[0] r = 0 # Move piece 9 which is in group 10 (piece, x, y) = (9, 809, 139) (topic, msg) = translate(0, testPuzzle, piece, x, y, r, db_file=self.tmp_db.name) # Move piece 2 to join piece 9; group 3 pieces are now in group 10 (piece, x, y) = (2, 731, 140) (topic, msg) = translate(0, testPuzzle, piece, x, y, r, db_file=self.tmp_db.name) expectedMsg = ":{piece}:{x}:{y}:270:3:\n:3:679:139::10:\n:2::::10:\n:2:744:139:270:10:".format( **locals()) assert len(expectedMsg) == len(msg) for l in expectedMsg.split("\n"): assert l in msg
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_join_two_pieces_that_are_both_in_group_when_adjacent_group_smaller( self): "Join two pieces that are grouped when moving piece group is larger then adjacent piece group" cur = self.db.cursor() (results, col_names) = rowify(cur.execute(self.query_puzzle_255), cur.description) testPuzzle = results[0] r = 0 # Move piece 1 to join piece 10. Piece 1 is in larger group 8, and piece 10 is in smaller group 10 # (1,8,11) (9,10) (piece, x, y) = (1, 499, 580) (topic, msg) = translate(0, testPuzzle, piece, x, y, r, db_file=self.tmp_db.name) expectedMsg = ":{piece}:{x}:{y}:0:8:\n:9::::8:\n:10::::8:\n:8:365:592:::\n:11:430:592:::\n:1:495:592:0:8:".format( **locals()) assert len(expectedMsg) == len(msg) for l in expectedMsg.split("\n"): assert l in msg
def __init__(self, ip): self.ip = ip self.headers = {"X-Real-IP": ip} self.api_host = "http://localhost:{PORTAPI}".format( PORTAPI=current_app.config["PORTAPI"]) self.publish_host = "http://localhost:{PORTPUBLISH}".format( PORTPUBLISH=current_app.config["PORTPUBLISH"]) cur = db.cursor() result = cur.execute( read_query_file("select-user-id-by-ip-and-no-password.sql"), { "ip": ip }).fetchall() if result: (result, col_names) = rowify(result, cur.description) shareduser = result[0]["id"] redis_connection.zrem("bannedusers", shareduser) cur.close() # get test user current_user_id = requests.get("{0}/current-user-id/".format( self.api_host), headers=self.headers) # print('ip {} and {}'.format(ip, current_user_id.cookies)) self.shareduser_cookie = current_user_id.cookies["shareduser"] self.shareduser = int(current_user_id.content)
def test_move_three_pieces_in_group(self): "Move three pieces that are grouped" cur = self.db.cursor() (results, col_names) = rowify(cur.execute(self.query_puzzle_255), cur.description) testPuzzle = results[0] r = 0 (piece, x, y) = (11, 368, 31) (topic, msg) = translate(0, testPuzzle, piece, x, y, r, db_file=self.tmp_db.name) # Pieces 11, 1 and 8 are grouped. 11 gets moved and then the others move as well. expectedMsg = ":{piece}:{x}:{y}:90:8:\n:1:433:31:::\n:8:303:31:::".format( **locals()) print("({0})".format(expectedMsg)) print("[{0}]".format(msg)) assert len(expectedMsg) == len(msg) for l in expectedMsg.split("\n"): assert l in msg
def get_offset_of_adjacent_pieces(piece, mask_width, piece_width): cur = db.cursor() offsets = {} x = piece['x'] y = piece['y'] t = mask_width - piece_width sides = [ {'side':{ (360, 0):'top_path', }, 'other_side':{ (360, 0):'bottom_path', }, 'x':x, 'y':((y+t) - mask_width)}, {'side':{ (360, 0):'right_path', }, 'other_side':{ (360, 0):'left_path', }, 'x':((x-t) + mask_width), 'y':y}, {'side':{ (360, 0):'bottom_path', }, 'other_side':{ (360, 0):'top_path', }, 'x':x, 'y':((y-t) + mask_width)}, {'side':{ (360, 0):'left_path', }, 'other_side':{ (360, 0):'right_path', }, 'x':((x+t) - mask_width), 'y':(y)}, ] piece_alignment = (360, 0) query = """select * from Piece where (id != :id) and (puzzle = :puzzle) and ((top_path = :bottom_path) or (bottom_path = :top_path) or (right_path = :left_path) or (left_path = :right_path))""" (d, col_names) = rowify(cur.execute(query, piece).fetchall(), cur.description) for adjacent_piece in d: for s in sides: try: if adjacent_piece[s['other_side'][piece_alignment]] == piece[s['side'][piece_alignment]]: # always check if the sides match offset = { 'x': int(math.ceil(piece_width)*FITS_MAPPING[s['side'][piece_alignment]]['x']), 'y': int(math.ceil(piece_width)*FITS_MAPPING[s['side'][piece_alignment]]['y']) } offsets[adjacent_piece['id']] = '{x},{y}'.format(**offset) break except KeyError: continue cur.close() return offsets
def test_connection(self): "Connection to db" with self.app.app_context(): with self.app.test_client(): cursor = db.cursor() result = cursor.execute("select 'test' as test") (result, col_names) = rowify(result, cursor.description) assert result[0]["test"] == "test"
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)
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
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 __init__(self, puzzle_id, ip): self.puzzle_id = puzzle_id self.ip = ip cur = db.cursor() result = cur.execute( "select id, table_width, table_height from Puzzle where puzzle_id = :puzzle_id;", { "puzzle_id": self.puzzle_id }, ).fetchall() (result, col_names) = rowify(result, cur.description) self.puzzle_details = result[0] cur.close()
def __init__(self, puzzle_id, ips, max_delay=0.1): self.puzzle_id = puzzle_id self.ips = ips self.max_delay = max_delay self.user_sessions = list(map(lambda ip: UserSession(ip=ip), self.ips)) cur = db.cursor() result = cur.execute( "select id, table_width, table_height from Puzzle where puzzle_id = :puzzle_id;", { "puzzle_id": self.puzzle_id }, ).fetchall() (result, col_names) = rowify(result, cur.description) self.puzzle_details = result[0] cur.close() redis_connection.delete("testdata:too_active")
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)
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