From 78ded6d7b7532171b4b06dc92b2f043051887e64 Mon Sep 17 00:00:00 2001 From: insert Date: Thu, 12 Jun 2025 17:04:33 -0400 Subject: [PATCH] chore: better handle database issues and teams not playing --- bot.py | 73 +++++++++++++++-------------- cogs/liveupdate.py | 112 ++++++++++++++++++++++++++++----------------- 2 files changed, 109 insertions(+), 76 deletions(-) diff --git a/bot.py b/bot.py index 85a9294..607ddcc 100644 --- a/bot.py +++ b/bot.py @@ -11,6 +11,8 @@ import os import logging import sys +firstrun = False + class Bot(commands.Bot): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -28,41 +30,44 @@ bot = Bot() @bot.event async def on_ready(): - global db - global cur - db = await sqlite3.connect(os.getenv("DB_PATH")) - cur = await db.cursor() - res = await cur.execute("SELECT name FROM sqlite_master WHERE name='liveupdate'") - if await res.fetchone() is None: - await cur.execute("CREATE TABLE liveupdate(serverid INTEGER, userid INTEGER, channelid INTEGER NOT NULL, messageid INTEGER, gameid TEXT, offset INTEGER)") + global firstrun + if not firstrun: + firstrun = True + global db + global cur + db = await sqlite3.connect(os.getenv("DB_PATH"),timeout=30) + cur = await db.cursor() + res = await cur.execute("SELECT name FROM sqlite_master WHERE name='liveupdate'") + if await res.fetchone() is None: + await cur.execute("CREATE TABLE liveupdate(serverid INTEGER, userid INTEGER, channelid INTEGER NOT NULL, messageid INTEGER, gameid TEXT, offset INTEGER)") + await db.commit() + res = await cur.execute("SELECT name FROM sqlite_master WHERE name='spotlightsubscriptions'") + if await res.fetchone() is None: + await cur.execute("CREATE TABLE spotlightsubscriptions(serverid INTEGER, channelid INTEGER NOT NULL)") + await db.commit() + res = await cur.execute("SELECT name FROM sqlite_master WHERE name='teamsubscriptions'") + if await res.fetchone() is None: + await cur.execute("CREATE TABLE teamsubscriptions(serverid INTEGER, channelid INTEGER NOT NULL, teamid TEXT)") + await db.commit() + bot.db = db + bot.cur = cur + guild_list = [] + async for guild in bot.fetch_guilds(): + guild_list.append(guild.id) + res = await cur.execute("SELECT serverid FROM liveupdate UNION SELECT serverid FROM spotlightsubscriptions UNION SELECT serverid FROM teamsubscriptions") + res = await res.fetchall() + for [serverid] in res: + if serverid not in guild_list: + await cur.execute("DELETE from teamsubscriptions WHERE serverid = ?", (serverid,)) + await cur.execute("DELETE from liveupdate WHERE serverid = ?", (serverid,)) + await cur.execute("DELETE from spotlightsubscriptions WHERE serverid = ?", (serverid,)) await db.commit() - res = await cur.execute("SELECT name FROM sqlite_master WHERE name='spotlightsubscriptions'") - if await res.fetchone() is None: - await cur.execute("CREATE TABLE spotlightsubscriptions(serverid INTEGER, channelid INTEGER NOT NULL)") - await db.commit() - res = await cur.execute("SELECT name FROM sqlite_master WHERE name='teamsubscriptions'") - if await res.fetchone() is None: - await cur.execute("CREATE TABLE teamsubscriptions(serverid INTEGER, channelid INTEGER NOT NULL, teamid TEXT)") - await db.commit() - bot.db = db - bot.cur = cur - guild_list = [] - async for guild in bot.fetch_guilds(): - guild_list.append(guild.id) - res = await cur.execute("SELECT serverid FROM liveupdate UNION SELECT serverid FROM spotlightsubscriptions UNION SELECT serverid FROM teamsubscriptions") - res = await res.fetchall() - for [serverid] in res: - if serverid not in guild_list: - await cur.execute("DELETE from teamsubscriptions WHERE serverid = ?", (serverid,)) - await cur.execute("DELETE from liveupdate WHERE serverid = ?", (serverid,)) - await cur.execute("DELETE from spotlightsubscriptions WHERE serverid = ?", (serverid,)) - await db.commit() - bot.load_extension('cogs.league') #Must load first as it contains autofill code referenced in team - bot.load_extension('cogs.team') #Must load first as it contains autofill code - bot.load_extension('cogs.liveupdate') - bot.load_extension('cogs.error') - bot.add_all_application_commands() - await bot.sync_all_application_commands() + bot.load_extension('cogs.league') #Must load first as it contains autofill code referenced in team + bot.load_extension('cogs.team') #Must load first as it contains autofill code + bot.load_extension('cogs.liveupdate') + bot.load_extension('cogs.error') + bot.add_all_application_commands() + await bot.sync_all_application_commands() @bot.slash_command( name="managecog", diff --git a/cogs/liveupdate.py b/cogs/liveupdate.py index d86cccc..c115d4b 100644 --- a/cogs/liveupdate.py +++ b/cogs/liveupdate.py @@ -108,11 +108,8 @@ class liveupdate(commands.Cog): INSERT INTO liveupdate VALUES ({interaction.guild_id}, {interaction.user.id}, {interaction.channel_id}, {message.id}, "{gameid}", {len(data["EventLog"])}) """) - except Exception as e: + except KeyError: await interaction.edit_original_message(content="This channel is now subscribed to updates") - warning = self.bot.get_channel(1365478368555827270) - await warning.send(e) - print(e) await self.bot.db.execute(f""" INSERT INTO teamsubscriptions VALUES ({interaction.guild_id}, {interaction.channel_id}, "{teamid}") @@ -306,29 +303,46 @@ class liveupdate(commands.Cog): res = await res.fetchall() print(res) for [serverid,channelid] in res: - check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ?", (channelid,gameid)) - test = await check.fetchone() - print(test) - if test is None: - print("True") - data = requests.get(f"https://mmolb.com/api/game/{gameid}").json() - channel = self.bot.get_channel(channelid) - if data["State"] == "Complete": - continue + try: check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ?", (channelid,gameid)) test = await check.fetchone() - if test is None: #no idea why it has to have two checks - message = await channel.send(content=f"{data["AwayTeamName"]} {data["AwayTeamEmoji"]} **{data["EventLog"][-1]["away_score"]}** vs {data["HomeTeamName"]} {data["HomeTeamEmoji"]} **{data["EventLog"][-1]["home_score"]}**") - await self.bot.db.execute(f""" - INSERT INTO liveupdate VALUES - ({channel.guild.id}, {self.bot.application_id}, {channelid}, {message.id}, "{gameid}", {len(data["EventLog"])}) - """) - await self.bot.db.commit() - else: - print("false") + print(test) + if test is None: + print("True") + data = requests.get(f"https://mmolb.com/api/game/{gameid}").json() + channel = self.bot.get_channel(channelid) + if data["State"] == "Complete": + continue + check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ?", (channelid,gameid)) + test = await check.fetchone() + if test is None: #no idea why it has to have two checks + message = await channel.send(content=f"{data["AwayTeamName"]} {data["AwayTeamEmoji"]} **{data["EventLog"][-1]["away_score"]}** vs {data["HomeTeamName"]} {data["HomeTeamEmoji"]} **{data["EventLog"][-1]["home_score"]}**") + await self.bot.db.execute(f""" + INSERT INTO liveupdate VALUES + ({channel.guild.id}, {self.bot.application_id}, {channelid}, {message.id}, "{gameid}", {len(data["EventLog"])}) + """) + await self.bot.db.commit() + else: + print("false") + except sqlite3.OperationalError: + await self.bot.db.close() + self.checkspotlightsubscriptions.cancel() + self.checkteamsubscriptions.cancel() + warning = self.bot.get_channel(1365478368555827270) + await warning.send(f"<@{self.bot.owner_id}> database is locked!") + except Exception as e: + warning = self.bot.get_channel(1365478368555827270) + await warning.send(f"Ignoring exception in spotlight check: {e}") + print(e) + continue + except KeyError: + pass except Exception as e: #I know this is bad practice but these loops must be running print(e) + warning = self.bot.get_channel(1365478368555827270) + await warning.send(e) + print(e) return @@ -341,30 +355,44 @@ class liveupdate(commands.Cog): res = await res.fetchall() print(res) for [serverid,channelid,teamid] in res: - game = requests.get(f"https://mmolb.com/api/game-by-team/{teamid}").json() - gameid = game["game_id"] - check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ?", (channelid,gameid)) - test = await check.fetchone() - print(test) - if test is None: - print("True") - data = requests.get(f"https://mmolb.com/api/game/{gameid}").json() - channel = self.bot.get_channel(channelid) - if data["State"] == "Complete": - continue + try: + game = requests.get(f"https://mmolb.com/api/game-by-team/{teamid}").json() + gameid = game["game_id"] check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ?", (channelid,gameid)) test = await check.fetchone() - if test is None: #no idea why it has to have two checks - message = await channel.send(content=f"{data["AwayTeamName"]} {data["AwayTeamEmoji"]} **{data["EventLog"][-1]["away_score"]}** vs {data["HomeTeamName"]} {data["HomeTeamEmoji"]} **{data["EventLog"][-1]["home_score"]}**") - await self.bot.db.execute(f""" - INSERT INTO liveupdate VALUES - ({channel.guild.id}, {self.bot.application_id}, {channelid}, {message.id}, "{gameid}", {len(data["EventLog"])}) - """) - await self.bot.db.commit() - else: - print("false") + print(test) + if test is None: + print("True") + data = requests.get(f"https://mmolb.com/api/game/{gameid}").json() + channel = self.bot.get_channel(channelid) + if data["State"] == "Complete": + continue + check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ?", (channelid,gameid)) + test = await check.fetchone() + if test is None: #no idea why it has to have two checks + message = await channel.send(content=f"{data["AwayTeamName"]} {data["AwayTeamEmoji"]} **{data["EventLog"][-1]["away_score"]}** vs {data["HomeTeamName"]} {data["HomeTeamEmoji"]} **{data["EventLog"][-1]["home_score"]}**") + await self.bot.db.execute(f""" + INSERT INTO liveupdate VALUES + ({channel.guild.id}, {self.bot.application_id}, {channelid}, {message.id}, "{gameid}", {len(data["EventLog"])}) + """) + await self.bot.db.commit() + except KeyError: + continue + except sqlite3.OperationalError: + await self.bot.db.close() + self.checkspotlightsubscriptions.cancel() + self.checkteamsubscriptions.cancel() + warning = self.bot.get_channel(1365478368555827270) + await warning.send(f"<@{self.bot.owner_id}> database is locked!") + except Exception as e: + warning = self.bot.get_channel(1365478368555827270) + await warning.send(f"Ignoring exception in {teamid}: {e}") + print(e) + continue except Exception as e: #I know this is bad practice but these loops must be running + warning = self.bot.get_channel(1365478368555827270) + await warning.send(e) print(e) return