fix: Add lock to prevent update race.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import asyncio
|
||||||
from string import punctuation
|
from string import punctuation
|
||||||
import datetime as dt
|
import datetime as dt
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
@@ -40,6 +41,7 @@ class FocusComponent(cmds.Component):
|
|||||||
register_channel(self.channel.name, self.channel)
|
register_channel(self.channel.name, self.channel)
|
||||||
|
|
||||||
self._last_deleted: dict[int, datetime] = {}
|
self._last_deleted: dict[int, datetime] = {}
|
||||||
|
self.hyperfocus_lock = asyncio.Lock()
|
||||||
|
|
||||||
# ----- API -----
|
# ----- API -----
|
||||||
async def component_load(self):
|
async def component_load(self):
|
||||||
@@ -88,6 +90,10 @@ class FocusComponent(cmds.Component):
|
|||||||
|
|
||||||
@cmds.Component.listener()
|
@cmds.Component.listener()
|
||||||
async def event_message(self, payload: twitchio.ChatMessage):
|
async def event_message(self, payload: twitchio.ChatMessage):
|
||||||
|
async with self.hyperfocus_lock:
|
||||||
|
await self.handle_message(payload)
|
||||||
|
|
||||||
|
async def handle_message(self, payload: twitchio.ChatMessage):
|
||||||
# Check if chatter is currently hyperfocused
|
# Check if chatter is currently hyperfocused
|
||||||
profile = await self.bot.profiles.fetch_profile(payload.chatter, touch=True)
|
profile = await self.bot.profiles.fetch_profile(payload.chatter, touch=True)
|
||||||
hyperfocused = await self.get_hyperfocus(profile.profileid)
|
hyperfocused = await self.get_hyperfocus(profile.profileid)
|
||||||
@@ -173,35 +179,37 @@ class FocusComponent(cmds.Component):
|
|||||||
pid = profile.profileid
|
pid = profile.profileid
|
||||||
comm = await self.bot.profiles.fetch_community(ctx.broadcaster, touch=True)
|
comm = await self.bot.profiles.fetch_community(ctx.broadcaster, touch=True)
|
||||||
|
|
||||||
await Hyperfocuser.table.delete_where(profileid=pid)
|
async with self.hyperfocus_lock:
|
||||||
focuser = await Hyperfocuser.create(
|
await Hyperfocuser.table.delete_where(profileid=pid)
|
||||||
profileid=pid,
|
focuser = await Hyperfocuser.create(
|
||||||
started_at=now,
|
profileid=pid,
|
||||||
ends_at=end_at,
|
started_at=now,
|
||||||
started_in=comm.communityid,
|
ends_at=end_at,
|
||||||
)
|
started_in=comm.communityid,
|
||||||
|
)
|
||||||
|
|
||||||
await self.channel.send_hyperfocus_patch(comm.communityid, focuser)
|
await self.channel.send_hyperfocus_patch(comm.communityid, focuser)
|
||||||
|
|
||||||
minutes = ceil(dur / 60)
|
minutes = ceil(dur / 60)
|
||||||
await ctx.reply(
|
await ctx.reply(
|
||||||
f"{ctx.chatter.name} has gone into HYPERFOCUS! "
|
f"{ctx.chatter.name} has gone into HYPERFOCUS! "
|
||||||
f"They will be in emote and command only mode for the next {minutes} minutes! "
|
f"They will be in emote and command only mode for the next {minutes} minutes! "
|
||||||
"Use !unfocus to come back if you need to, best of luck! ☘️🍀☘️ "
|
"Use !unfocus to come back if you need to, best of luck! ☘️🍀☘️ "
|
||||||
)
|
)
|
||||||
|
|
||||||
@cmds.command(name="unfocus")
|
@cmds.command(name="unfocus")
|
||||||
async def unfocus_cmd(self, ctx):
|
async def unfocus_cmd(self, ctx):
|
||||||
profile = await self.bot.profiles.fetch_profile(ctx.chatter, touch=True)
|
profile = await self.bot.profiles.fetch_profile(ctx.chatter, touch=True)
|
||||||
row = await Hyperfocuser.fetch(profile.profileid)
|
async with self.hyperfocus_lock:
|
||||||
if row:
|
row = await Hyperfocuser.fetch(profile.profileid)
|
||||||
await row.delete()
|
if row:
|
||||||
await self.channel.send_hyperfocus_del(profile.profileid)
|
await row.delete()
|
||||||
|
await self.channel.send_hyperfocus_del(profile.profileid)
|
||||||
|
|
||||||
await ctx.reply(
|
await ctx.reply(
|
||||||
"Welcome back from focus, hope it went well!"
|
"Welcome back from focus, hope it went well!"
|
||||||
" Remember to have a sip and stretch if you need it~"
|
" Remember to have a sip and stretch if you need it~"
|
||||||
)
|
)
|
||||||
|
|
||||||
@cmds.command(name="hyperfocused")
|
@cmds.command(name="hyperfocused")
|
||||||
async def hyperfocused_cmd(self, ctx, user: twitchio.User | None = None):
|
async def hyperfocused_cmd(self, ctx, user: twitchio.User | None = None):
|
||||||
@@ -209,22 +217,30 @@ class FocusComponent(cmds.Component):
|
|||||||
|
|
||||||
profile = await self.bot.profiles.fetch_profile(user, touch=False)
|
profile = await self.bot.profiles.fetch_profile(user, touch=False)
|
||||||
|
|
||||||
if hyper := (await self.get_hyperfocus(profile.profileid)):
|
async with self.hyperfocus_lock:
|
||||||
durstr = strfdelta(hyper.ends_at - utc_now())
|
if hyper := (await self.get_hyperfocus(profile.profileid)):
|
||||||
await ctx.reply(
|
durstr = strfdelta(hyper.ends_at - utc_now())
|
||||||
f"{user.name} is in HYPERFOCUS for another {durstr}! "
|
await ctx.reply(
|
||||||
"They can only write emojis and commands in this time. Good luck!"
|
f"{user.name} is in HYPERFOCUS for another {durstr}! "
|
||||||
)
|
"They can only write emojis and commands in this time. Good luck!"
|
||||||
elif own:
|
)
|
||||||
await ctx.reply(
|
elif own:
|
||||||
"You are not hyperfocused!"
|
await ctx.reply(
|
||||||
" Enter HYPERFOCUS mode for e.g. 10 minutes with '!hyperfocus 10'"
|
"You are not hyperfocused!"
|
||||||
)
|
" Enter HYPERFOCUS mode for e.g. 10 minutes with '!hyperfocus 10'"
|
||||||
else:
|
)
|
||||||
await ctx.reply(f"{user.name} is not hyperfocused!")
|
else:
|
||||||
|
await ctx.reply(f"{user.name} is not hyperfocused!")
|
||||||
|
|
||||||
@cmds.command(name="addfocus")
|
@cmds.command(name="addfocus")
|
||||||
async def addfocus_cmd(self, ctx):
|
async def addfocus_cmd(self, ctx):
|
||||||
await ctx.reply(
|
await ctx.reply(
|
||||||
"Add HYPERFOCUS to your channel by authorising me here: https://croccyfocus.thewisewolf.dev/invite"
|
"Add HYPERFOCUS to your channel by authorising me here: https://croccyfocus.thewisewolf.dev/invite"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@cmds.command(name="focuslist")
|
||||||
|
@cmds.is_moderator()
|
||||||
|
async def focuslist_cmd(self, ctx):
|
||||||
|
comm = await self.bot.profiles.fetch_community(ctx.broadcaster, touch=True)
|
||||||
|
link = f"https://croccyfocus.thewisewolf.dev/widget/?community={comm}"
|
||||||
|
await ctx.reply(f"Browser source link for your channel's hyperfocus: {link}")
|
||||||
|
|||||||
Reference in New Issue
Block a user