diff --git a/cogs/liveupdate.py b/cogs/liveupdate.py
index a4d6c47..8446d2a 100644
--- a/cogs/liveupdate.py
+++ b/cogs/liveupdate.py
@@ -5,6 +5,7 @@ from datetime import datetime, timedelta, timezone
import requests
import asyncio
import nextcord
+import aiohttp
import aiosqlite as sqlite3
from nextcord.ext import commands, application_checks, tasks
from nextcord import TextInputStyle, IntegrationType
@@ -15,66 +16,71 @@ async def livegameworker(self,serverid,userid,channelid,messageid,gameid,offset)
begin = timeit.default_timer()
lastserverid = serverid
try:
- channel = self.bot.get_channel(channelid)
- message = await channel.fetch_message(messageid)
- data = requests.get(f"https://mmolb.com/api/game/{gameid}/live?after={offset}").json()
- if len(data["entries"]) > 0:
- data = requests.get(f"https://mmolb.com/api/game/{gameid}/live?after={offset-((7-len(data["entries"]) if offset > 7 else offset))}").json()
- basedata = requests.get(f"https://mmolb.com/api/game/{gameid}").json()
- finalstr = ""
- offsetadd = 0
- for i in data["entries"]:
- finalstr += f"\n{i['message'].replace("", "**").replace("", "**")}"
- offsetadd += 1
- if i["event"] == "Recordkeeping":
- await self.bot.db.execute(f"""
- DELETE from liveupdate WHERE messageid = {messageid}
- """)
- #await self.bot.db.commit()
- color = tuple(int(basedata["HomeTeamColor"][i:i+2], 16) for i in (0, 2, 4))
- embed = nextcord.Embed(title=f"{basedata["AwayTeamName"]} {basedata["AwayTeamEmoji"]} **{data["entries"][-1]["away_score"]}** vs {basedata["HomeTeamName"]} {basedata["HomeTeamEmoji"]} **{data["entries"][-1]["home_score"]}**",
- description=f"{"Bottom" if data["entries"][-1]["inning_side"] == 1 else "Top"} of the {data["entries"][-1]["inning"]}",
- colour = nextcord.Color.from_rgb(color[0], color[1], color[2]))
- embed.set_footer(text=gameid)
- match data["entries"][-1]["balls"]:
- case 1:
- embed.add_field(name="Balls",value="🔴â•â•")
- case 2:
- embed.add_field(name="Balls",value="🔴🔴â•")
- case 3:
- embed.add_field(name="Balls",value="🔴🔴🔴")
- case _:
- embed.add_field(name="Balls",value="â•â•â•")
- match data["entries"][-1]["strikes"]:
- case 1:
- embed.add_field(name="Strikes",value="🔴â•")
- case 2:
- embed.add_field(name="Strikes",value="🔴🔴")
- case _:
- embed.add_field(name="Strikes",value="â•â•")
- match data["entries"][-1]["outs"]:
- case 1:
- embed.add_field(name="Outs",value="🔴â•")
- case 2:
- embed.add_field(name="Outs",value="🔴🔴")
- case _:
- embed.add_field(name="Outs",value="â•â•")
- embed.add_field(name="Batting",value=data["entries"][-1]["batter"], inline=True)
- embed.add_field(name="Pitching",value=data["entries"][-1]["pitcher"], inline=True)
- embed.add_field(name="On Deck",value=data["entries"][-1]["on_deck"], inline=True)
- embed.add_field(name=f"Last 7 events",value=finalstr,inline=False)
- embed.set_thumbnail(f"https://insertapp.net/mmolbbot/assets/diamond_{data["entries"][-1]["on_1b"]}_{data["entries"][-1]["on_2b"]}_{data["entries"][-1]["on_3b"]}.png")
- embed.set_footer(text=f"Embed too big? Need historical data? consider classic mode.")
- await message.edit(content="",embed=embed)
- await self.bot.db.execute(f"""
- UPDATE liveupdate set offset = {offset+offsetadd} WHERE messageid = '{messageid}'
- """)
+ async with aiohttp.ClientSession() as session:
+ channel = self.bot.get_channel(channelid)
+ message = await channel.fetch_message(messageid)
+ data = await session.get(f"https://mmolb.com/api/game/{gameid}/live?after={offset}")
+ data = await data.json()
+ if len(data["entries"]) > 0:
+ data = await session.get(f"https://mmolb.com/api/game/{gameid}/live?after={offset-((7-len(data["entries"]) if offset > 7 else offset))}")
+ data = await data.json()
+ basedata = await session.get(f"https://mmolb.com/api/game/{gameid}")
+ basedata = await basedata.json()
+ finalstr = ""
+ offsetadd = 0
+ for i in data["entries"]:
+ finalstr += f"\n{i['message'].replace("", "**").replace("", "**")}"
+ offsetadd += 1
+ if i["event"] == "Recordkeeping":
+ await self.bot.db.execute(f"""
+ DELETE from liveupdate WHERE messageid = {messageid}
+ """)
+ #await self.bot.db.commit()
+ color = tuple(int(basedata["HomeTeamColor"][i:i+2], 16) for i in (0, 2, 4))
+ embed = nextcord.Embed(title=f"{basedata["AwayTeamName"]} {basedata["AwayTeamEmoji"]} **{data["entries"][-1]["away_score"]}** vs {basedata["HomeTeamName"]} {basedata["HomeTeamEmoji"]} **{data["entries"][-1]["home_score"]}**",
+ description=f"{"Bottom" if data["entries"][-1]["inning_side"] == 1 else "Top"} of the {data["entries"][-1]["inning"]}",
+ colour = nextcord.Color.from_rgb(color[0], color[1], color[2]))
+ embed.set_footer(text=gameid)
+ match data["entries"][-1]["balls"]:
+ case 1:
+ embed.add_field(name="Balls",value="🔴â•â•")
+ case 2:
+ embed.add_field(name="Balls",value="🔴🔴â•")
+ case 3:
+ embed.add_field(name="Balls",value="🔴🔴🔴")
+ case _:
+ embed.add_field(name="Balls",value="â•â•â•")
+ match data["entries"][-1]["strikes"]:
+ case 1:
+ embed.add_field(name="Strikes",value="🔴â•")
+ case 2:
+ embed.add_field(name="Strikes",value="🔴🔴")
+ case _:
+ embed.add_field(name="Strikes",value="â•â•")
+ match data["entries"][-1]["outs"]:
+ case 1:
+ embed.add_field(name="Outs",value="🔴â•")
+ case 2:
+ embed.add_field(name="Outs",value="🔴🔴")
+ case _:
+ embed.add_field(name="Outs",value="â•â•")
+ embed.add_field(name="Batting",value=data["entries"][-1]["batter"], inline=True)
+ embed.add_field(name="Pitching",value=data["entries"][-1]["pitcher"], inline=True)
+ embed.add_field(name="On Deck",value=data["entries"][-1]["on_deck"], inline=True)
+ embed.add_field(name=f"Last 7 events",value=finalstr,inline=False)
+ embed.set_thumbnail(f"https://insertapp.net/mmolbbot/assets/diamond_{data["entries"][-1]["on_1b"]}_{data["entries"][-1]["on_2b"]}_{data["entries"][-1]["on_3b"]}.png")
+ embed.set_footer(text=f"Embed too big? Need historical data? consider classic mode.")
+ await message.edit(content="",embed=embed)
+ await self.bot.db.execute(f"""
+ UPDATE liveupdate set offset = {offset+offsetadd} WHERE messageid = '{messageid}'
+ """)
except Exception as e:
await self.bot.db.execute(f"""
DELETE from liveupdate WHERE messageid = {messageid}
""")
#await self.bot.db.commit()
- await message.edit(f"An error occoured in this live update\n{e}")
+ if message:
+ await message.edit(f"An error occoured in this live update\n{e}")
warning = self.bot.get_channel(1365478368555827270)
await warning.send(e)
except nextcord.Forbidden:
@@ -90,34 +96,35 @@ async def classiclivegameworker(self,serverid,userid,channelid,gameid,offset):
begin = timeit.default_timer()
lastserverid = serverid
try:
- channel = self.bot.get_channel(channelid)
- data = requests.get(f"https://mmolb.com/api/game/{gameid}/live?after={offset}").json()
- if len(data["entries"]) > 0:
- #data = requests.get(f"https://mmolb.com/api/game/{gameid}/live?after={offset-((7-len(data["entries"]) if offset > 7 else offset))}").json()
- basedata = requests.get(f"https://mmolb.com/api/game/{gameid}").json()
- finalstr = ""
- offsetadd = 0
- maysend = False
- for i in data["entries"]:
- if "scores" in i['message'] or "homers" in i['message']:
- finalstr += f"\n>>> {i['message'].replace(", ","\n").replace(". ","\n").replace("", "").replace("", "\n")}"
- maysend = True
- offsetadd += 1
- if i["event"] == "Recordkeeping":
- await self.bot.db.execute(f"""
- DELETE from liveupdate WHERE channelid = {channelid} AND gameid = '{gameid}'
- """)
- maysend = True
- finalstr += f"\n> {i['message'].replace("", "**").replace("", "**")}"
- #await self.bot.db.commit()
- if maysend:
- if data["entries"][-1]["inning_side"] == 1:
- await channel.send(f"Bottom of the {data["entries"][-1]["inning"]} | {basedata["AwayTeamName"]} {basedata["AwayTeamEmoji"]} {data["entries"][-1]["away_score"]} vs {basedata["HomeTeamName"]} {basedata["HomeTeamEmoji"]} **{data["entries"][-1]["home_score"]}**{finalstr}")
- else:
- await channel.send(f"Top of the {data["entries"][-1]["inning"]} | {basedata["AwayTeamName"]} {basedata["AwayTeamEmoji"]} **{data["entries"][-1]["away_score"]}** vs {basedata["HomeTeamName"]} {basedata["HomeTeamEmoji"]} {data["entries"][-1]["home_score"]}{finalstr}")
- await self.bot.db.execute(f"""
- UPDATE liveupdate set offset = {offset+offsetadd} WHERE channelid = '{channelid}' AND gameid = '{gameid}' AND classic = 1
- """)
+ async with aiohttp.ClientSession() as session:
+ channel = self.bot.get_channel(channelid)
+ data = await session.get(f"https://mmolb.com/api/game/{gameid}/live?after={offset}")
+ data = await data.json()
+ if len(data["entries"]) > 0:
+ basedata = await session.get(f"https://mmolb.com/api/game/{gameid}")
+ basedata = await basedata.json()
+ finalstr = "\n>>> "
+ offsetadd = 0
+ maysend = False
+ for i in data["entries"]:
+ if "scores" in i['message'] or "homers" in i['message']:
+ finalstr += f"{i['message'].replace(", ","\n").replace(". ","\n").replace("", "").replace("", "\n")}\n"
+ maysend = True
+ offsetadd += 1
+ if i["event"] == "Recordkeeping":
+ await self.bot.db.execute(f"""
+ DELETE from liveupdate WHERE channelid = {channelid} AND gameid = '{gameid}'
+ """)
+ maysend = True
+ finalstr += f"{i['message'].replace("", "**").replace("", "**")}\n"
+ if maysend:
+ if data["entries"][-1]["inning_side"] == 1:
+ await channel.send(f"Bottom of the {data["entries"][-1]["inning"]} | {basedata["AwayTeamName"]} {basedata["AwayTeamEmoji"]} {data["entries"][-1]["away_score"]} vs {basedata["HomeTeamName"]} {basedata["HomeTeamEmoji"]} **{data["entries"][-1]["home_score"]}**{finalstr}")
+ else:
+ await channel.send(f"Top of the {data["entries"][-1]["inning"]} | {basedata["AwayTeamName"]} {basedata["AwayTeamEmoji"]} **{data["entries"][-1]["away_score"]}** vs {basedata["HomeTeamName"]} {basedata["HomeTeamEmoji"]} {data["entries"][-1]["home_score"]}{finalstr}")
+ await self.bot.db.execute(f"""
+ UPDATE liveupdate set offset = {offset+offsetadd} WHERE channelid = '{channelid}' AND gameid = '{gameid}' AND classic = 1
+ """)
except Exception as e:
warning = self.bot.get_channel(1365478368555827270)
await warning.send(e)
@@ -129,6 +136,85 @@ async def classiclivegameworker(self,serverid,userid,channelid,gameid,offset):
await self.bot.db.commit()
await warning.send(f"Deleted {lastserverid} from the database due to 403 error")
+
+async def spotlightsubscriptionworker(self,serverid,channelid,classic,gameid,data):
+ try:
+ check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ? AND classic = ?", (channelid,gameid,classic))
+ test = await check.fetchone()
+ if test is None:
+ channel = self.bot.get_channel(channelid)
+ if data["State"] == "Complete":
+ return
+ check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ? AND classic = ?", (channelid,gameid,classic))
+ test = await check.fetchone()
+ if test is None: #no idea why it has to have two checks
+ if classic == 0:
+ 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"])}, 0)
+ """)
+ else:
+ await self.bot.db.execute(f"""
+ INSERT INTO liveupdate VALUES
+ ({channel.guild.id}, {self.bot.application_id}, {channelid}, NULL, "{gameid}", {len(data["EventLog"])}, 1)
+ """)
+ 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)
+ return
+
+async def teamsubscriptionworker(self,serverid,channelid,teamid,classic):
+ try:
+ async with aiohttp.ClientSession() as session:
+ game = await session.get(f"https://mmolb.com/api/game-by-team/{teamid}")
+ game = await game.json()
+ gameid = game["game_id"]
+ check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ? AND classic = ?", (channelid,gameid,classic))
+ test = await check.fetchone()
+ if test is None:
+ data = await session.get(f"https://mmolb.com/api/game/{gameid}")
+ data = await data.json()
+ channel = self.bot.get_channel(channelid)
+ if data["State"] == "Complete":
+ return
+ check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ? AND classic = ?", (channelid,gameid,classic))
+ test = await check.fetchone()
+ if test is None: #no idea why it has to have two checks
+ if classic == 0:
+ 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"])}, 0)
+ """)
+ else:
+ await self.bot.db.execute(f"""
+ INSERT INTO liveupdate VALUES
+ ({channel.guild.id}, {self.bot.application_id}, {channelid}, NULL, "{gameid}", {len(data["EventLog"])}, 1)
+ """)
+ except KeyError:
+ return
+ 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)
+ return
+
+
+
class liveupdate(commands.Cog):
def __init__(self, bot: commands.Bot):
@@ -408,14 +494,13 @@ class liveupdate(commands.Cog):
try:
begin = timeit.default_timer()
await self.bot.wait_until_ready()
- print("updating live games")
res = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE classic = 0")
res = await res.fetchall()
worklist = [livegameworker(self,serverid,userid,channelid,messageid,gameid,offset) for [serverid,userid,channelid,messageid,gameid,offset] in res]
res = await self.bot.db.execute("SELECT serverid,userid,channelid,gameid,offset FROM liveupdate WHERE classic = 1")
res = await res.fetchall()
worklist = worklist + [classiclivegameworker(self,serverid,userid,channelid,gameid,offset) for [serverid,userid,channelid,gameid,offset] in res]
- await asyncio.gather(*worklist)
+ await asyncio.gather(*worklist,return_exceptions=True)
await self.bot.db.commit()
timings.append(timeit.default_timer()-begin)
if len(timings) >= 12:
@@ -436,51 +521,17 @@ class liveupdate(commands.Cog):
async def checkspotlightsubscriptions(self):
try:
await self.bot.wait_until_ready()
- print("refreshing spotlight subscriptions")
- game = requests.get("https://mmolb.com/api/spotlight").json()
- gameid = game["game_id"]
+ async with aiohttp.ClientSession() as session:
+ game = await session.get("https://mmolb.com/api/spotlight")
+ game = await game.json()
+ gameid = game["game_id"]
+ data = await session.get(f"https://mmolb.com/api/game/{gameid}")
+ data = await data.json()
res = await self.bot.db.execute("SELECT serverid,channelid,classic FROM spotlightsubscriptions")
res = await res.fetchall()
- print(res)
- for [serverid,channelid,classic] in res:
- try:
- check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ? AND classic = ?", (channelid,gameid,classic))
- 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
- check = await self.bot.db.execute("SELECT serverid,userid,channelid,messageid,gameid,offset FROM liveupdate WHERE channelid = ? AND gameid = ? AND classic = ?", (channelid,gameid,classic))
- test = await check.fetchone()
- if test is None: #no idea why it has to have two checks
- if classic == 0:
- 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"])}, 0)
- """)
- else:
- await self.bot.db.execute(f"""
- INSERT INTO liveupdate VALUES
- ({channel.guild.id}, {self.bot.application_id}, {channelid}, NULL, "{gameid}", {len(data["EventLog"])}, 1)
- """)
- 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
+ worklist = [spotlightsubscriptionworker(self,serverid,channelid,classic,gameid,data) for [serverid,channelid,classic] in res]
+ await asyncio.gather(*worklist,return_exceptions=True)
+ await self.bot.db.commit()
except KeyError:
pass
except Exception as e:
@@ -488,57 +539,18 @@ class liveupdate(commands.Cog):
print(e)
warning = self.bot.get_channel(1365478368555827270)
await warning.send(e)
- print(e)
return
@tasks.loop(seconds=120.0)
async def checkteamsubscriptions(self):
try:
- print("refreshing team subscriptions")
await self.bot.wait_until_ready()
res = await self.bot.db.execute("SELECT serverid,channelid,teamid,classic FROM teamsubscriptions")
res = await res.fetchall()
- print(res)
- for [serverid,channelid,teamid,classic] in res:
- 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 = ? AND classic = ?", (channelid,gameid,classic))
- test = await check.fetchone()
- if test is None:
- 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 = ? AND classic = ?", (channelid,gameid,classic))
- test = await check.fetchone()
- if test is None: #no idea why it has to have two checks
- if classic == 0:
- 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"])}, 0)
- """)
- else:
- await self.bot.db.execute(f"""
- INSERT INTO liveupdate VALUES
- ({channel.guild.id}, {self.bot.application_id}, {channelid}, NULL, "{gameid}", {len(data["EventLog"])}, 1)
- """)
- 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
+ worklist = [teamsubscriptionworker(self,serverid,channelid,teamid,classic) for [serverid,channelid,teamid,classic] in res]
+ await asyncio.gather(*worklist,return_exceptions=True)
+ await self.bot.db.commit()
except Exception as e:
#I know this is bad practice but these loops must be running
warning = self.bot.get_channel(1365478368555827270)