From 297eb434d44f7d7f1f889d285c176474563f0d58 Mon Sep 17 00:00:00 2001 From: Interitio Date: Wed, 22 Jul 2026 17:28:10 +0300 Subject: [PATCH] Lilac subathon customisations --- subathon/channel.py | 20 +++++++++++--- subathon/component.py | 61 +++++++++++++++++++++++++------------------ 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/subathon/channel.py b/subathon/channel.py index c0b8638..84efa49 100644 --- a/subathon/channel.py +++ b/subathon/channel.py @@ -106,8 +106,8 @@ async def prepare_subathon( if contrib.profileid: profile = await profiler.get_profile(contrib.profileid) assert profile is not None - name = profile.nickname or "Unknown" - user_id = str(profile.profileid) + name = profile.nickname + user_id = None else: name = "Anonymous" user_id = None @@ -196,7 +196,10 @@ class TimerChannel(Channel): async def on_connection(self, websocket, event): if not (cidstr := event.get("community")): - raise ValueError("Subathon timer connection missing communityid") + logger.warning("Subathon timer connection missing communityid") + await super().on_connection(websocket, event) + await self.send_sample(websocket=websocket) + return elif not cidstr.isdigit(): raise ValueError("Community id provided is not an integer") cid = int(cidstr) @@ -214,6 +217,17 @@ class TimerChannel(Channel): else: await self.send_no_subathon(cid, websocket) + async def send_sample(self, websocket): + import json + import random + with open("sample-payload.json") as f: + payload = json.load(f) + ending = utc_now() + timedelta(seconds=10) + payload['args']['end_at'] = ending.isoformat() + payload['args']['total_contribution'] = random.choice(range(1, 150)) + await self.send_event(payload, websocket=websocket) + + async def del_connection(self, websocket): for wss in self.communities.values(): wss.discard(websocket) diff --git a/subathon/component.py b/subathon/component.py index df31e36..3c5a445 100644 --- a/subathon/component.py +++ b/subathon/component.py @@ -96,7 +96,7 @@ class SubathonComponent(cmds.Component): # Should probably wait on a central messaging slow-lock bucketed by channel instead await asyncio.sleep(1) await channel.send_message( - f"We have reached Goal #{i + 1}: {goal.description} !! Thank you everyone for your support <3", + f"We have reached Goal #{i + 1}: {goal.description} !! Thank you everyone for your support cutecat", sender=self.bot.bot_id, ) await goal.update(notified=True) @@ -161,9 +161,9 @@ class SubathonComponent(cmds.Component): contrib_str = f"{name} contributed {score} point{pl}" if not await active.check_cap(): - contrib_str += f" and added {added} to the timer! Thank you <3" + contrib_str += f" and added {added} to the timer! Thank you cutecat" else: - contrib_str += " towards our subathon! Thank you <3" + contrib_str += " towards our subathon! Thank you cutecat" await bits_payload.broadcaster.send_message( contrib_str, sender=self.bot.bot_id @@ -211,9 +211,9 @@ class SubathonComponent(cmds.Component): contrib_str = f"{name} contributed {score} point{pl}" if not await active.check_cap(): - contrib_str += f" and added {added} to the timer! Thank you <3" + contrib_str += f" and added {added} to the timer! Thank you cutecat" else: - contrib_str += " towards our subathon! Thank you <3" + contrib_str += " towards our subathon! Thank you cutecat" await sub_payload.broadcaster.send_message( contrib_str, sender=self.bot.bot_id @@ -257,9 +257,9 @@ class SubathonComponent(cmds.Component): contrib_str = f"{name} contributed {score} points" if not await active.check_cap(): - contrib_str += f" and added {added} to the timer! Thank you <3" + contrib_str += f" and added {added} to the timer! Thank you cutecat" else: - contrib_str += " towards our subathon! Thank you <3" + contrib_str += " towards our subathon! Thank you cutecat" await gift_payload.broadcaster.send_message( contrib_str, sender=self.bot.bot_id @@ -289,7 +289,8 @@ class SubathonComponent(cmds.Component): else: raise ValueError(f"Unknown sub tier {sub_payload.tier}") - score = mult * 1 + # score = mult * 1 + score = 0 logger.info( f"Adding subathon contribution from subscription message payload {payload}" @@ -304,13 +305,13 @@ class SubathonComponent(cmds.Component): contrib_str = f"{name} contributed {score} points{pl}" if not await active.check_cap(): - contrib_str += f" and added {added} to the timer! Thank you <3" + contrib_str += f" and added {added} to the timer! Thank you cutecat" else: - contrib_str += " towards our subathon! Thank you <3" + contrib_str += " towards our subathon! Thank you cutecat" - await sub_payload.broadcaster.send_message( - contrib_str, sender=self.bot.bot_id - ) + # await sub_payload.broadcaster.send_message( + # contrib_str, sender=self.bot.bot_id + # ) await self.dispatch_update(active) # Check goals await self.goalcheck(active, sub_payload.broadcaster) @@ -335,7 +336,7 @@ class SubathonComponent(cmds.Component): # ----- Commands ----- - @cmds.group(name="subathon", aliases=["studython"], invoke_fallback=True) + @cmds.group(name="subathon", aliases=["studython", "suba"], invoke_fallback=True) async def group_subathon(self, ctx: cmds.Context): community = await self.bot.profiles.fetch_community(ctx.broadcaster) cid = community.communityid @@ -821,26 +822,34 @@ class SubathonComponent(cmds.Component): await ctx.reply("No active subathon to show leaderboard of!") # Subathon goals - @cmds.group(name="goals", invoke_fallback=True) - async def group_goals(self, ctx: cmds.Context): - # List the goals + @cmds.command(name="subnext", aliases=("nextgoal",)) + async def cmd_goals_nextgoal(self, ctx: cmds.Context, *, args: str): + if args.lower().split()[0] != 'goal': + return + community = await self.bot.profiles.fetch_community(ctx.broadcaster) cid = community.communityid if (active := await self.get_active_subathon(cid)) is not None: + score = await active.get_score() goals = await active.get_goals() - goalstrs = [] - for i, goal in enumerate(goals, start=1): - line = f"{goal.required_score} points: {goal.description}" - goalstrs.append(line) - - if goals: - text = ", ".join(goalstrs) - await ctx.reply(f"{active.name} Goals! -- {text}") + nextgoal = next( + (goal for goal in goals if goal.required_score > score), + None + ) + if nextgoal is None: + # None message + await ctx.reply("We have achieved all our goals for this subathon!") else: - await ctx.reply("No goals have been configured!") + await ctx.reply( + f"Gift {nextgoal.required_score - score} points for next goal: {nextgoal.description}" + ) else: await ctx.reply("No active subathon running!") + @cmds.group(name="subagoals") + async def group_goals(self, ctx: cmds.Context): + ... + @group_goals.command(name="remaining", aliases=("left",)) async def cmd_goals_remaining(self, ctx: cmds.Context): community = await self.bot.profiles.fetch_community(ctx.broadcaster)