Add subathon timer websocket.

This commit is contained in:
2025-07-28 14:49:17 +10:00
parent 03d50fbe92
commit bf835e2529

View File

@@ -8,10 +8,58 @@ from twitchio.ext import commands as cmds
from datamodels import BotChannel, Communities, UserProfile from datamodels import BotChannel, Communities, UserProfile
from meta import CrocBot from meta import CrocBot
from utils.lib import utc_now, strfdelta from utils.lib import utc_now, strfdelta
from sockets import Channel, register_channel
from . import logger from . import logger
from .data import SubathonData, Subathon, RunningSubathon, SubathonContribution, SubathonGoal from .data import SubathonData, Subathon, RunningSubathon, SubathonContribution, SubathonGoal
class TimerChannel(Channel):
name = 'Timer'
def __init__(self, cog: 'SubathonComponent', **kwargs):
super().__init__(**kwargs)
self.cog = cog
self.communityid = 1
async def on_connection(self, websocket, event):
await super().on_connection(websocket, event)
await self.send_set(
**await self.get_args_for(self.communityid),
websocket=websocket,
)
async def send_updates(self):
await self.send_set(
**await self.get_args_for(self.communityid),
)
async def get_args_for(self, channelid):
active = await self.cog.get_active_subathon(channelid)
if active is not None:
ending = utc_now() + timedelta(seconds=await active.get_remaining())
return {
'end_at': ending,
'running': active.running
}
else:
return {
'end_at': utc_now,
'running': False,
}
async def send_set(self, end_at, running, websocket=None):
await self.send_event({
'type': "DO",
'method': 'setTimer',
'args': {
'end_at': end_at.isoformat(),
'running': running,
}
}, websocket=websocket)
class ActiveSubathon: class ActiveSubathon:
def __init__(self, subathondata: Subathon, runningdata: RunningSubathon | None): def __init__(self, subathondata: Subathon, runningdata: RunningSubathon | None):
self.subathondata = subathondata self.subathondata = subathondata
@@ -74,6 +122,8 @@ class SubathonComponent(cmds.Component):
def __init__(self, bot: CrocBot): def __init__(self, bot: CrocBot):
self.bot = bot self.bot = bot
self.data = bot.dbconn.load_registry(SubathonData()) self.data = bot.dbconn.load_registry(SubathonData())
self.channel = TimerChannel(self)
register_channel('SubTimer', self.channel)
# ----- API ----- # ----- API -----
@@ -135,7 +185,7 @@ class SubathonComponent(cmds.Component):
f"{name} contributed {bits_payload.bits} bit{pl} and added {added} to the timer! Thank you <3", f"{name} contributed {bits_payload.bits} bit{pl} and added {added} to the timer! Thank you <3",
sender=self.bot.bot_id sender=self.bot.bot_id
) )
# TODO: Websocket update await self.channel.send_updates()
await self.goalcheck(active, bits_payload.broadcaster) await self.goalcheck(active, bits_payload.broadcaster)
# Check goals # Check goals
@@ -174,7 +224,7 @@ class SubathonComponent(cmds.Component):
f"{name} contributed {score} sub{pl} and added {added} to the timer! Thank you <3", f"{name} contributed {score} sub{pl} and added {added} to the timer! Thank you <3",
sender=self.bot.bot_id sender=self.bot.bot_id
) )
# TODO: Websocket update await self.channel.send_updates()
# Check goals # Check goals
await self.goalcheck(active, sub_payload.broadcaster) await self.goalcheck(active, sub_payload.broadcaster)
@@ -209,7 +259,7 @@ class SubathonComponent(cmds.Component):
f"{name} contributed {score} subs and added {added} to the timer! Thank you <3", f"{name} contributed {score} subs and added {added} to the timer! Thank you <3",
sender=self.bot.bot_id sender=self.bot.bot_id
) )
# TODO: Websocket update await self.channel.send_updates()
# Check goals # Check goals
await self.goalcheck(active, gift_payload.broadcaster) await self.goalcheck(active, gift_payload.broadcaster)
@@ -225,7 +275,7 @@ class SubathonComponent(cmds.Component):
"Paused the subathon timer because the stream went offline!", "Paused the subathon timer because the stream went offline!",
sender=self.bot.bot_id sender=self.bot.bot_id
) )
# TODO: Websocket update await self.channel.send_updates()
# ----- Commands ----- # ----- Commands -----
@@ -239,7 +289,7 @@ class SubathonComponent(cmds.Component):
goals = await active.get_goals() goals = await active.get_goals()
total_goals = len(goals) total_goals = len(goals)
donegoals = len([goal for goal in goals if score >= goal.required_score]) donegoals = len([goal for goal in goals if score >= goal.required_score])
goalstr = f"{donegoals}/{total_goals} achieved" goalstr = f"{donegoals}/{total_goals} goals achieved"
secs = await active.get_remaining() secs = await active.get_remaining()
remaining = strfdelta(timedelta(seconds=secs)) remaining = strfdelta(timedelta(seconds=secs))
@@ -275,7 +325,7 @@ class SubathonComponent(cmds.Component):
score_time=timescore score_time=timescore
) )
await ctx.reply("Setup a new subathon! Use !subathon resume to get the timer running.") await ctx.reply("Setup a new subathon! Use !subathon resume to get the timer running.")
# TODO: Websocket broadcast await self.channel.send_updates()
# subathon stop # subathon stop
@group_subathon.command(name='stop') @group_subathon.command(name='stop')
@@ -286,7 +336,7 @@ class SubathonComponent(cmds.Component):
if (active := await self.get_active_subathon(cid)) is not None: if (active := await self.get_active_subathon(cid)) is not None:
if active.running: if active.running:
await active.pause() await active.pause()
# TODO: Websocket update await self.channel.send_updates()
await active.subathondata.update(ended_at=utc_now()) await active.subathondata.update(ended_at=utc_now())
total = await active.get_score() total = await active.get_score()
dursecs = active.get_duration() dursecs = active.get_duration()
@@ -308,7 +358,7 @@ class SubathonComponent(cmds.Component):
if active.running: if active.running:
await active.pause() await active.pause()
await ctx.reply("Subathon timer paused!") await ctx.reply("Subathon timer paused!")
# TODO: Websocket update await self.channel.send_updates()
else: else:
await ctx.reply("Subathon timer already paused!") await ctx.reply("Subathon timer already paused!")
else: else:
@@ -324,7 +374,7 @@ class SubathonComponent(cmds.Component):
if not active.running: if not active.running:
await active.resume() await active.resume()
await ctx.reply("Subathon timer resumed!") await ctx.reply("Subathon timer resumed!")
# TODO: Websocket update await self.channel.send_updates()
else: else:
await ctx.reply("Subathon timer already running!") await ctx.reply("Subathon timer already running!")
else: else: