Merge branch 'feat-target-seeker' into staging
This commit is contained in:
@@ -1,9 +1,12 @@
|
|||||||
|
from collections import defaultdict
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import twitchio
|
||||||
from twitchio.ext import commands
|
from twitchio.ext import commands
|
||||||
from twitchio.ext import pubsub
|
from twitchio.ext import pubsub
|
||||||
|
from twitchio.ext.commands.core import itertools
|
||||||
|
|
||||||
from data import Database
|
from data import Database
|
||||||
|
|
||||||
@@ -23,5 +26,51 @@ class CrocBot(commands.Bot):
|
|||||||
self.data = data
|
self.data = data
|
||||||
self.pubsub = pubsub.PubSubPool(self)
|
self.pubsub = pubsub.PubSubPool(self)
|
||||||
|
|
||||||
|
self._member_cache = defaultdict(dict)
|
||||||
|
|
||||||
async def event_ready(self):
|
async def event_ready(self):
|
||||||
logger.info(f"Logged in as {self.nick}. User id is {self.user_id}")
|
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
|
||||||
|
|||||||
@@ -17,9 +17,19 @@ class ShoutoutCog(LionCog):
|
|||||||
and drop a follow! \
|
and drop a follow! \
|
||||||
They {areorwere} streaming {game} at {channel}
|
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):
|
def __init__(self, bot: LionBot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.crocbot = bot.crocbot
|
self.crocbot: CrocBot = bot.crocbot
|
||||||
|
|
||||||
self.data = bot.db.load_registry(ShoutoutData())
|
self.data = bot.db.load_registry(ShoutoutData())
|
||||||
|
|
||||||
self.loaded = asyncio.Event()
|
self.loaded = asyncio.Event()
|
||||||
@@ -59,19 +69,28 @@ class ShoutoutCog(LionCog):
|
|||||||
return replace_multiple(text, mapping)
|
return replace_multiple(text, mapping)
|
||||||
|
|
||||||
@commands.command(aliases=['so'])
|
@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
|
# Make sure caller is mod/broadcaster
|
||||||
# Lookup custom shoutout for this user
|
# Lookup custom shoutout for this user
|
||||||
# If it exists use it, otherwise use default shoutout
|
# If it exists use it, otherwise use default shoutout
|
||||||
if (ctx.author.is_mod or ctx.author.is_broadcaster):
|
if (ctx.author.is_mod or ctx.author.is_broadcaster):
|
||||||
data = await self.data.CustomShoutout.fetch(int(user.id))
|
user = await self.crocbot.seek_user(target)
|
||||||
if data:
|
if user is None:
|
||||||
shoutout = data.content
|
await ctx.reply(f"Couldn't resolve '{target}' to a valid user.")
|
||||||
else:
|
else:
|
||||||
shoutout = self.DEFAULT_SHOUTOUT
|
data = await self.data.CustomShoutout.fetch(int(user.id))
|
||||||
formatted = await self.format_shoutout(shoutout, user)
|
if data:
|
||||||
await ctx.reply(formatted)
|
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: How to /shoutout with lib?
|
||||||
|
# TODO Shoutout queue
|
||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def editshoutout(self, ctx: commands.Context, user: twitchio.User, *, text: str):
|
async def editshoutout(self, ctx: commands.Context, user: twitchio.User, *, text: str):
|
||||||
|
|||||||
Reference in New Issue
Block a user