From a536e9c82b2f0df3fa85e9f43f851b3aae6c8c32 Mon Sep 17 00:00:00 2001 From: Thomas Rubini <74205383+ThomasRubini@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:56:08 +0100 Subject: [PATCH 1/6] add flask-socketio to requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index d0f5f12..4882615 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ Flask==2.2.2 pyjwt==2.6.0 +Flask-SocketIO==5.3.2 From 03ab987f7882e96018503fff86a2fdd9a074cece Mon Sep 17 00:00:00 2001 From: Thomas Rubini <74205383+ThomasRubini@users.noreply.github.com> Date: Tue, 3 Jan 2023 15:56:38 +0100 Subject: [PATCH 2/6] init flask-socketio + put app in a custom class --- truthseeker/__init__.py | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/truthseeker/__init__.py b/truthseeker/__init__.py index 0500b4e..2036856 100644 --- a/truthseeker/__init__.py +++ b/truthseeker/__init__.py @@ -2,27 +2,34 @@ import flask import os from truthseeker.routes import routes_api, routes_ui +from flask_socketio import SocketIO +class TruthSeekerApp(flask.Flask): -app = flask.Flask("truthseeker") + def __init__(self): + super().__init__("truthseeker") + self.set_app_secret() + self.socketio_app = SocketIO(self) -def set_secret(app): - if os.path.isfile("instance/secret.txt"): - f = open("instance/secret.txt", "r") - app.config["SECRET_KEY"] = f.read() - f.close() - print("Read secret from secret.txt !") - else: - import secrets - app.config["SECRET_KEY"] = secrets.token_hex() - os.makedirs("instance", exist_ok=True) - f = open("instance/secret.txt", "w") - f.write(app.config["SECRET_KEY"]) - f.close() - print("Generated secret and wrote to secret.txt !") + def run_app(self): + self.socketio_app.run(self) -set_secret(app) + def set_app_secret(self): + if os.path.isfile("instance/secret.txt"): + f = open("instance/secret.txt", "r") + self.config["SECRET_KEY"] = f.read() + f.close() + print("Read secret from secret.txt !") + else: + import secrets + self.config["SECRET_KEY"] = secrets.token_hex() + os.makedirs("instance", exist_ok=True) + f = open("instance/secret.txt", "w") + f.write(self.config["SECRET_KEY"]) + f.close() + print("Generated secret and wrote to secret.txt !") +app = TruthSeekerApp() app.register_blueprint(routes_api.routes_api, url_prefix="/api/v1") app.register_blueprint(routes_ui.routes_ui, url_prefix="/") From 9156793852f4d6c8af3c77ffe069a7c4457353db Mon Sep 17 00:00:00 2001 From: Thomas Rubini <74205383+ThomasRubini@users.noreply.github.com> Date: Tue, 3 Jan 2023 16:59:42 +0100 Subject: [PATCH 3/6] refactor 'app' to 'APP' --- app.py | 2 +- tests/test_api.py | 4 ++-- truthseeker/__init__.py | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app.py b/app.py index 85345e1..0a00714 100644 --- a/app.py +++ b/app.py @@ -1,4 +1,4 @@ -from truthseeker import app # the variable 'app' is detected by `flask run` +from truthseeker import APP as app # the variable 'app' is detected by `flask run` if __name__ == "__main__": app.run() diff --git a/tests/test_api.py b/tests/test_api.py index 4235864..f4924ae 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,8 +1,8 @@ import json import pytest -from truthseeker import app +from truthseeker import APP -test_app = app.test_client() +test_app = APP.test_client() class TestException(Exception): __test__ = False diff --git a/truthseeker/__init__.py b/truthseeker/__init__.py index 2036856..6229d31 100644 --- a/truthseeker/__init__.py +++ b/truthseeker/__init__.py @@ -29,7 +29,9 @@ class TruthSeekerApp(flask.Flask): f.close() print("Generated secret and wrote to secret.txt !") -app = TruthSeekerApp() +APP = TruthSeekerApp() -app.register_blueprint(routes_api.routes_api, url_prefix="/api/v1") -app.register_blueprint(routes_ui.routes_ui, url_prefix="/") +from truthseeker.routes import routes_api, routes_ui + +APP.register_blueprint(routes_api.routes_api, url_prefix="/api/v1") +APP.register_blueprint(routes_ui.routes_ui, url_prefix="/") From f1d371c5f2e6e333c58266509acf4fc763d5f295 Mon Sep 17 00:00:00 2001 From: Thomas Rubini <74205383+ThomasRubini@users.noreply.github.com> Date: Tue, 3 Jan 2023 17:00:56 +0100 Subject: [PATCH 4/6] refactor 'games_list' in app class --- truthseeker/__init__.py | 3 +++ truthseeker/logic/game_logic.py | 13 ++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/truthseeker/__init__.py b/truthseeker/__init__.py index 6229d31..6e8411b 100644 --- a/truthseeker/__init__.py +++ b/truthseeker/__init__.py @@ -8,6 +8,9 @@ class TruthSeekerApp(flask.Flask): def __init__(self): super().__init__("truthseeker") + + self.games_list = {} + self.set_app_secret() self.socketio_app = SocketIO(self) diff --git a/truthseeker/logic/game_logic.py b/truthseeker/logic/game_logic.py index b46f2f4..f9755c7 100644 --- a/truthseeker/logic/game_logic.py +++ b/truthseeker/logic/game_logic.py @@ -1,12 +1,11 @@ import string import random from datetime import datetime, timedelta -import truthseeker +from truthseeker import APP # Map of all actively running games # games_list["game.game_id"]-> game info linked to that id -games_list = {} def random_string(length: int) ->str: """ @@ -87,13 +86,13 @@ def create_game(owner): game.owner = owner game.members.append(Member(owner)) game.game_id = random_string(6) - games_list[game.game_id] = game + APP.games_list[game.game_id] = game #TODO ADD A WEBSOCKET IF THE GAME IS KNOWN TO BE MULTIPLAYER return game def get_game(game_id): - if game_id in games_list: - return games_list[game_id] + if game_id in APP.games_list: + return APP.games_list[game_id] else: return None @@ -107,7 +106,7 @@ def get_game_info(game_id): : return : The Game Object linked to the game_id : return type : Game """ - if game_id in games_list: - return games_list[game_id] + if game_id in APP.games_list: + return APP.games_list[game_id] else: return None \ No newline at end of file From a5bba9d3a4fd130bbad3035bebd8cdf1b80118e4 Mon Sep 17 00:00:00 2001 From: Thomas Rubini <74205383+ThomasRubini@users.noreply.github.com> Date: Tue, 3 Jan 2023 16:01:33 +0100 Subject: [PATCH 5/6] create socketio routes --- truthseeker/__init__.py | 6 ++---- truthseeker/routes/routes_socketio.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 truthseeker/routes/routes_socketio.py diff --git a/truthseeker/__init__.py b/truthseeker/__init__.py index 6e8411b..14cbd3a 100644 --- a/truthseeker/__init__.py +++ b/truthseeker/__init__.py @@ -1,8 +1,6 @@ import flask -import os - -from truthseeker.routes import routes_api, routes_ui from flask_socketio import SocketIO +import os class TruthSeekerApp(flask.Flask): @@ -34,7 +32,7 @@ class TruthSeekerApp(flask.Flask): APP = TruthSeekerApp() -from truthseeker.routes import routes_api, routes_ui +from truthseeker.routes import routes_api, routes_ui, routes_socketio APP.register_blueprint(routes_api.routes_api, url_prefix="/api/v1") APP.register_blueprint(routes_ui.routes_ui, url_prefix="/") diff --git a/truthseeker/routes/routes_socketio.py b/truthseeker/routes/routes_socketio.py new file mode 100644 index 0000000..d94816e --- /dev/null +++ b/truthseeker/routes/routes_socketio.py @@ -0,0 +1,19 @@ +from flask_socketio import join_room +import socketio + +from truthseeker import APP +from truthseeker.logic import game_logic + +@APP.socketio_app.on('connect') +def connect(auth): + if not (auth and "game_id" in auth): + raise socketio.exceptions.ConnectionRefusedError("Invalid connection data passed") + + game = game_logic.get_game(auth["game_id"]) + if not game: + raise socketio.exceptions.ConnectionRefusedError("No game with this ID") + + room = join_room("game."+auth["game_id"]) + join_room(room) + + From fc059670f4c6f6344cb094ea8afb24b8bce57f99 Mon Sep 17 00:00:00 2001 From: Thomas Rubini <74205383+ThomasRubini@users.noreply.github.com> Date: Fri, 6 Jan 2023 08:52:41 +0100 Subject: [PATCH 6/6] emit socket events on game start/join --- truthseeker/routes/routes_api.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/truthseeker/routes/routes_api.py b/truthseeker/routes/routes_api.py index c18b6e1..5b74e25 100644 --- a/truthseeker/routes/routes_api.py +++ b/truthseeker/routes/routes_api.py @@ -1,6 +1,6 @@ import flask -import truthseeker +from truthseeker import APP from truthseeker.logic import game_logic from truthseeker.utils import check_username @@ -46,6 +46,8 @@ def join_game(): flask.session["is_owner"] = False flask.session["username"] = username + APP.socketio_app.emit("playersjoin", [flask.session["username"]], room="game."+game.game_id) + return {"error": 0} @routes_api.route("/startGame", methods=["GET", "POST"]) @@ -65,6 +67,7 @@ def start_game(): game.has_started = True + APP.socketio_app.emit("gamestart", {}, room="game."+game.game_id) return {"error": 0}