feat: feed subscriptions

This commit is contained in:
insert 2025-07-16 01:04:13 -04:00
parent edaccdc684
commit 3d5f2e3de4
Signed by: insert
GPG key ID: A70775C389ACF105
2 changed files with 112 additions and 0 deletions

5
bot.py
View file

@ -21,6 +21,7 @@ class Bot(commands.Bot):
await cur.execute("DELETE from teamsubscriptions WHERE serverid = ?", (guild.id,))
await cur.execute("DELETE from liveupdate WHERE serverid = ?", (guild.id,))
await cur.execute("DELETE from spotlightsubscriptions WHERE serverid = ?", (guild.id,))
await cur.execute("DELETE from feedsubscriptions WHERE serverid = ?", (guild.id,))
await db.commit()
load_dotenv()
@ -49,6 +50,10 @@ async def on_ready():
if await res.fetchone() is None:
await cur.execute("CREATE TABLE teamsubscriptions(serverid INTEGER, channelid INTEGER NOT NULL, teamid TEXT, classic INTEGER NOT NULL)")
await db.commit()
res = await cur.execute("SELECT name FROM sqlite_master WHERE name='feedsubscriptions'")
if await res.fetchone() is None:
await cur.execute("CREATE TABLE feedsubscriptions(serverid INTEGER, channelid INTEGER NOT NULL, teamid TEXT, offset INTEGER)")
await db.commit()
#await cur.execute("ALTER TABLE liveupdate ADD classic INTEGER NOT NULL DEFAULT 0")
#await cur.execute("ALTER TABLE spotlightsubscriptions ADD classic INTEGER NOT NULL DEFAULT 0")
#await cur.execute("ALTER TABLE teamsubscriptions ADD classic INTEGER NOT NULL DEFAULT 0")

View file

@ -6,6 +6,7 @@ import requests
import asyncio
import nextcord
import aiohttp
import itertools
import aiosqlite as sqlite3
from nextcord.ext import commands, application_checks, tasks
from nextcord import TextInputStyle, IntegrationType
@ -191,6 +192,8 @@ async def teamsubscriptionworker(self,serverid,channelid,teamid,classic):
data = await session.get(f"https://mmolb.com/api/game/{gameid}")
data = await data.json()
channel = self.bot.get_channel(channelid)
if channel is None:
return
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))
@ -221,6 +224,36 @@ async def teamsubscriptionworker(self,serverid,channelid,teamid,classic):
print(e)
return
async def feedsubscriptionworker(self,serverid,channelid,teamid,offset):
begin = timeit.default_timer()
lastserverid = serverid
try:
async with aiohttp.ClientSession() as session:
channel = self.bot.get_channel(channelid)
if channel is None:
return
data = await session.get(f"https://mmolb.com/api/team/{teamid}")
data = await data.json()
data = data['Feed']
if len(data) > offset:
finalstr = ""
for index in itertools.islice(data, offset, len(data)):
finalstr += f"\n{index['emoji']} Season {index['season']} Day {index['day']}: {index['text']}"
await channel.send(finalstr)
await self.bot.db.execute(f"""
UPDATE feedsubscriptions set offset = {len(data)} WHERE channelid = '{channelid}' AND teamid = '{teamid}'
""")
except Exception as e:
warning = self.bot.get_channel(1365478368555827270)
await warning.send(e)
except nextcord.Forbidden:
warning = self.bot.get_channel(1365478368555827270)
await self.bot.db.execute("DELETE from teamsubscriptions WHERE serverid = ?", (lastserverid,))
await self.bot.db.execute("DELETE from liveupdate WHERE serverid = ?", (lastserverid,))
await self.bot.db.execute("DELETE from spotlightsubscriptions WHERE serverid = ?", (lastserverid,))
await self.bot.db.execute("DELETE from feedsubscriptions WHERE serverid = ?", (lastserverid,))
await self.bot.db.commit()
await warning.send(f"Deleted {lastserverid} from the database due to 403 error")
class liveupdate(commands.Cog):
@ -228,6 +261,7 @@ class liveupdate(commands.Cog):
def __init__(self, bot: commands.Bot):
self.bot = bot
self.updatelivegames.start()
self.checkfeedsubscriptions.start()
self.checkspotlightsubscriptions.start()
self.checkteamsubscriptions.start()
@ -235,6 +269,7 @@ class liveupdate(commands.Cog):
self.updatelivegames.cancel()
self.checkspotlightsubscriptions.cancel()
self.checkteamsubscriptions.cancel()
self.checkfeedsubscriptions.cancel()
@nextcord.slash_command(
name="spotlightgame",
@ -390,6 +425,36 @@ class liveupdate(commands.Cog):
thanksdiscord = closestteam[:20]
await interaction.response.send_autocomplete(thanksdiscord)
@subscribe.subcommand(
name="feed",
description="Subscribe to a team's feed",
)
async def feedsubscribe(self, interaction: nextcord.Interaction, team: str):
if team not in self.bot.teams_dict:
await interaction.response.send_message("Invalid Team!", ephemeral=True)
await interaction.response.defer()
teamid = self.bot.teams_dict[team]
async with aiohttp.ClientSession() as session:
data = await session.get(f"https://mmolb.com/api/team/{teamid}")
data = await data.json()
offset = len(data['Feed'])
await self.bot.db.execute(f"""
INSERT INTO feedsubscriptions VALUES
({interaction.guild_id}, {interaction.channel_id}, "{teamid}", {offset})
""")
await self.bot.db.commit()
await interaction.edit_original_message(content="This channel is now subscribed to feed updates")
@feedsubscribe.on_autocomplete("team")
async def feedsubscribeac(self, interaction: nextcord.Interaction, team: str):
if not team:
thanksdiscord = self.bot.teams_list[:20]
await interaction.response.send_autocomplete(thanksdiscord)
return
closestteam = [name for name in self.bot.teams_list if name.lower().startswith(team.lower())]
thanksdiscord = closestteam[:20]
await interaction.response.send_autocomplete(thanksdiscord)
@nextcord.slash_command(
name="watch",
description="Get live updates on a game",
@ -474,6 +539,32 @@ class liveupdate(commands.Cog):
thanksdiscord = closestteam[:20]
await interaction.response.send_autocomplete(thanksdiscord)
@unsubscribe.subcommand(
name="feed",
description="Unsubscribe to team feed updates in this channel",
)
async def unsubscribefeed(self, interaction: nextcord.Interaction, team: str):
if team not in self.bot.teams_dict:
await interaction.response.send_message("Invalid Team!", ephemeral=True)
await interaction.response.defer()
teamid = self.bot.teams_dict[team]
await self.bot.db.execute(f"""
DELETE from feedsubscriptions WHERE channelid = ? AND teamid = ?
""",(interaction.channel_id,teamid))
await self.bot.db.commit()
await interaction.edit_original_message(content="If existent, it has been removed")
@unsubscribefeed.on_autocomplete("team")
async def unsubscribefeedac(self, interaction: nextcord.Interaction, team: str):
if not team:
thanksdiscord = self.bot.teams_list[:20]
await interaction.response.send_autocomplete(thanksdiscord)
return
closestteam = [name for name in self.bot.teams_list if name.lower().startswith(team.lower())]
thanksdiscord = closestteam[:20]
await interaction.response.send_autocomplete(thanksdiscord)
@nextcord.slash_command(
name="liveupdatesdelete",
description="DEBUG: Delete a subscribed update",
@ -577,6 +668,22 @@ class liveupdate(commands.Cog):
await warning.send(e)
print(e)
return
@tasks.loop(seconds=120.0)
async def checkfeedsubscriptions(self):
try:
await self.bot.wait_until_ready()
res = await self.bot.db.execute("SELECT serverid,channelid,teamid,offset FROM feedsubscriptions")
res = await res.fetchall()
worklist = [feedsubscriptionworker(self,serverid,channelid,teamid,offset) for [serverid,channelid,teamid,offset] 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)
await warning.send(e)
print(e)
return
def setup(bot: commands.Bot):
bot.add_cog(liveupdate(bot))