From 1c1b11786980dacb53b73ce0521c77747b6ced21 Mon Sep 17 00:00:00 2001 From: Thomas Rubini <74205383+ThomasRubini@users.noreply.github.com> Date: Mon, 9 Jan 2023 08:33:27 +0100 Subject: [PATCH 1/4] add discord bot --- truthseeker/__init__.py | 17 +++++++++++++++++ truthseeker/discord_bot.py | 31 +++++++++++++++++++++++++++++++ truthseeker/routes/routes_api.py | 2 ++ 3 files changed, 50 insertions(+) create mode 100644 truthseeker/discord_bot.py diff --git a/truthseeker/__init__.py b/truthseeker/__init__.py index 14cbd3a..08f3077 100644 --- a/truthseeker/__init__.py +++ b/truthseeker/__init__.py @@ -2,6 +2,8 @@ import flask from flask_socketio import SocketIO import os +from truthseeker import discord_bot + class TruthSeekerApp(flask.Flask): def __init__(self): @@ -10,8 +12,15 @@ class TruthSeekerApp(flask.Flask): self.games_list = {} self.set_app_secret() + self.socketio_app = SocketIO(self) + token = self.get_discord_bot_token() + if token: + self.discord_bot = discord_bot.init_bot(token) + else: + print("No token set. Not starting discord bot") + def run_app(self): self.socketio_app.run(self) @@ -30,6 +39,14 @@ class TruthSeekerApp(flask.Flask): f.close() print("Generated secret and wrote to secret.txt !") + def get_discord_bot_token(self): + if os.path.isfile("instance/discord_bot_token.txt"): + f = open("instance/discord_bot_token.txt", "r") + token = f.read() + f.close() + return token + return None + APP = TruthSeekerApp() from truthseeker.routes import routes_api, routes_ui, routes_socketio diff --git a/truthseeker/discord_bot.py b/truthseeker/discord_bot.py new file mode 100644 index 0000000..3707636 --- /dev/null +++ b/truthseeker/discord_bot.py @@ -0,0 +1,31 @@ +import discord +import threading +import truthseeker + + +def init_bot(token): + discord_bot = DiscordBot() + + thr = threading.Thread(target=discord_bot.__run__, args=(token,)) + thr.start() + + return discord_bot + +class DiscordBot: + def __init__(self): + self.bot = discord.Client(intents=discord.Intents.default()) + + @self.bot.event + async def on_ready(): + print('Discord bot connected !') + + await self.update_games_presence() + + def __run__(self, token): + self.bot.run(token) + + async def update_games_presence(self): + games_n = len(truthseeker.APP.games_list) + activity_name = f"Handling {games_n} game{'' if games_n==1 else 's'} !" + activity = discord.Activity(name=activity_name, type=discord.ActivityType.watching) + await self.bot.change_presence(activity=activity) diff --git a/truthseeker/routes/routes_api.py b/truthseeker/routes/routes_api.py index df0e6db..fb26701 100644 --- a/truthseeker/routes/routes_api.py +++ b/truthseeker/routes/routes_api.py @@ -24,6 +24,8 @@ def create_game(): flask.session["is_owner"] = True flask.session["username"] = username + asyncio.run(APP.discord_bot.update_games_presence()) + return response @routes_api.route("/joinGame", methods=["GET", "POST"]) From e2846d342a2082804fa4836ebebc4d40d64df812 Mon Sep 17 00:00:00 2001 From: Thomas Rubini <74205383+ThomasRubini@users.noreply.github.com> Date: Wed, 11 Jan 2023 10:46:50 +0100 Subject: [PATCH 2/4] add channel API + @API decorator --- truthseeker/discord_bot.py | 30 +++++++++++++++++++++++++++++- truthseeker/routes/routes_api.py | 2 +- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/truthseeker/discord_bot.py b/truthseeker/discord_bot.py index 3707636..bc86c76 100644 --- a/truthseeker/discord_bot.py +++ b/truthseeker/discord_bot.py @@ -1,7 +1,10 @@ import discord import threading import truthseeker +import asyncio +async def empty_coro(): + return def init_bot(token): discord_bot = DiscordBot() @@ -14,18 +17,43 @@ def init_bot(token): class DiscordBot: def __init__(self): self.bot = discord.Client(intents=discord.Intents.default()) + self.__channel__ = None @self.bot.event async def on_ready(): print('Discord bot connected !') + self.event_loop = asyncio.get_event_loop() - await self.update_games_presence() + self.__setup__channel__() + self.update_games_presence() + + def __setup__channel__(self): + if len(self.bot.guilds) == 1: + self.__channel__ = discord.utils.get(self.bot.guilds[0].channels, name="bot") + else: + print("Could not find channel #bot") def __run__(self, token): self.bot.run(token) + def API(func): + def decorator(self, *args, **kwargs): + if self.bot and self.bot.is_ready(): + self.event_loop.create_task(func(self, *args, **kwargs)) + else: + print(f"Discord bot not ready, not processing function {func.__name__}()") + return decorator + + @API async def update_games_presence(self): games_n = len(truthseeker.APP.games_list) activity_name = f"Handling {games_n} game{'' if games_n==1 else 's'} !" activity = discord.Activity(name=activity_name, type=discord.ActivityType.watching) await self.bot.change_presence(activity=activity) + + @API + async def send_message(self, text): + if self.__channel__: + await self.__channel__.send(text) + else: + print("channel member not defined, not sending discord message") diff --git a/truthseeker/routes/routes_api.py b/truthseeker/routes/routes_api.py index fb26701..da09201 100644 --- a/truthseeker/routes/routes_api.py +++ b/truthseeker/routes/routes_api.py @@ -24,7 +24,7 @@ def create_game(): flask.session["is_owner"] = True flask.session["username"] = username - asyncio.run(APP.discord_bot.update_games_presence()) + APP.discord_bot.update_games_presence() return response From dd727310f7b28d5d2becd856e654b138d9dac260 Mon Sep 17 00:00:00 2001 From: Thomas Rubini <74205383+ThomasRubini@users.noreply.github.com> Date: Wed, 11 Jan 2023 10:53:49 +0100 Subject: [PATCH 3/4] add discord.py to requirements --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 826c927..1575c7f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ Flask==2.2.2 pyjwt==2.6.0 Flask-SocketIO==5.3.2 SQLAlchemy==1.4.20 -pymysql==1.0.2 \ No newline at end of file +pymysql==1.0.2 +discord.py==2.1.0 From f9504a1f86bd9b63bb78a26f6d06afa63036affc Mon Sep 17 00:00:00 2001 From: Thomas Rubini <74205383+ThomasRubini@users.noreply.github.com> Date: Wed, 11 Jan 2023 11:04:39 +0100 Subject: [PATCH 4/4] separate bot instance creation and start --- truthseeker/__init__.py | 4 +++- truthseeker/discord_bot.py | 14 ++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/truthseeker/__init__.py b/truthseeker/__init__.py index 08f3077..7f3c9de 100644 --- a/truthseeker/__init__.py +++ b/truthseeker/__init__.py @@ -15,9 +15,11 @@ class TruthSeekerApp(flask.Flask): self.socketio_app = SocketIO(self) + self.discord_bot = discord_bot.DiscordBot() token = self.get_discord_bot_token() if token: - self.discord_bot = discord_bot.init_bot(token) + pass + self.discord_bot.start(token) else: print("No token set. Not starting discord bot") diff --git a/truthseeker/discord_bot.py b/truthseeker/discord_bot.py index bc86c76..9d42acb 100644 --- a/truthseeker/discord_bot.py +++ b/truthseeker/discord_bot.py @@ -6,14 +6,6 @@ import asyncio async def empty_coro(): return -def init_bot(token): - discord_bot = DiscordBot() - - thr = threading.Thread(target=discord_bot.__run__, args=(token,)) - thr.start() - - return discord_bot - class DiscordBot: def __init__(self): self.bot = discord.Client(intents=discord.Intents.default()) @@ -33,8 +25,10 @@ class DiscordBot: else: print("Could not find channel #bot") - def __run__(self, token): - self.bot.run(token) + def start(self, token): + thr = threading.Thread(target=self.bot.run, args=(token,)) + thr.start() + return thr def API(func): def decorator(self, *args, **kwargs):