diff --git a/src/meta/CrocBot.py b/src/meta/CrocBot.py index a4742424..897bd03b 100644 --- a/src/meta/CrocBot.py +++ b/src/meta/CrocBot.py @@ -1,9 +1,12 @@ +from collections import defaultdict from typing import TYPE_CHECKING import logging +import twitchio from twitchio.ext import commands from twitchio.ext import pubsub +from twitchio.ext.commands.core import itertools from data import Database @@ -23,5 +26,51 @@ class CrocBot(commands.Bot): self.data = data self.pubsub = pubsub.PubSubPool(self) + self._member_cache = defaultdict(dict) + async def event_ready(self): logger.info(f"Logged in as {self.nick}. User id is {self.user_id}") + + async def event_join(self, channel: twitchio.Channel, user: twitchio.User): + self._member_cache[channel.name][user.name] = user + + async def event_message(self, message: twitchio.Message): + if message.channel and message.author: + self._member_cache[message.channel.name][message.author.name] = message.author + await self.handle_commands(message) + + async def seek_user(self, userstr: str, matching=True, fuzzy=True): + if userstr.startswith('@'): + matching = False + userstr = userstr.strip('@ ') + + result = None + if matching and len(userstr) >= 3: + lowered = userstr.lower() + full_matches = [] + for user in itertools.chain(*(cmems.values() for cmems in self._member_cache.values())): + matchstr = user.name.lower() + print(matchstr) + if matchstr.startswith(lowered): + result = user + break + if lowered in matchstr: + full_matches.append(user) + if result is None and full_matches: + result = full_matches[0] + print(result) + + if result is None: + lookup = userstr + elif result.id is None: + lookup = result.name + else: + lookup = None + + if lookup: + found = await self.fetch_users(names=[lookup]) + if found: + result = found[0] + + # No matches found + return result diff --git a/src/modules/shoutouts/cog.py b/src/modules/shoutouts/cog.py index 1ebf56d7..8f52dbd4 100644 --- a/src/modules/shoutouts/cog.py +++ b/src/modules/shoutouts/cog.py @@ -17,9 +17,19 @@ class ShoutoutCog(LionCog): and drop a follow! \ They {areorwere} streaming {game} at {channel} """ + COWO_SHOUTOUT = """ + We think that {name} is a great coworker and you should check them out for more productive vibes! \ + They {areorwere} streaming {game} at {channel} + """ + ART_SHOUTOUT = """ + We think that {name} is an awesome artist and you should check them out for cool art and cosy vibes! \ + They {areorwere} streaming {game} at {channel} + """ + def __init__(self, bot: LionBot): self.bot = bot - self.crocbot = bot.crocbot + self.crocbot: CrocBot = bot.crocbot + self.data = bot.db.load_registry(ShoutoutData()) self.loaded = asyncio.Event() @@ -59,19 +69,28 @@ class ShoutoutCog(LionCog): return replace_multiple(text, mapping) @commands.command(aliases=['so']) - async def shoutout(self, ctx: commands.Context, user: twitchio.User): + async def shoutout(self, ctx: commands.Context, target: str, typ: Optional[str]=None): # Make sure caller is mod/broadcaster # Lookup custom shoutout for this user # If it exists use it, otherwise use default shoutout if (ctx.author.is_mod or ctx.author.is_broadcaster): - data = await self.data.CustomShoutout.fetch(int(user.id)) - if data: - shoutout = data.content + user = await self.crocbot.seek_user(target) + if user is None: + await ctx.reply(f"Couldn't resolve '{target}' to a valid user.") else: - shoutout = self.DEFAULT_SHOUTOUT - formatted = await self.format_shoutout(shoutout, user) - await ctx.reply(formatted) + data = await self.data.CustomShoutout.fetch(int(user.id)) + if data: + shoutout = data.content + elif typ == 'cowo': + shoutout = self.COWO_SHOUTOUT + elif typ == 'art': + shoutout = self.ART_SHOUTOUT + else: + shoutout = self.DEFAULT_SHOUTOUT + formatted = await self.format_shoutout(shoutout, user) + await ctx.reply(formatted) # TODO: How to /shoutout with lib? + # TODO Shoutout queue @commands.command() async def editshoutout(self, ctx: commands.Context, user: twitchio.User, *, text: str):