feat: Simple twitch component.

This commit is contained in:
2025-09-01 22:09:38 +10:00
parent 5fa0df66f5
commit 543a65b7fb
4 changed files with 99 additions and 0 deletions

View File

@@ -3,3 +3,9 @@ import logging
logger = logging.getLogger(__name__)
from .discord import setup
from .twitch import setup as twitch_setup
__all__ = (
'setup',
'twitch_setup',
)

View File

@@ -28,6 +28,7 @@ class ProfilesRegistry:
return await UserProfile.fetch(link.profileid)
async def get_profile_twitch(self, userid: str) -> Optional[UserProfile]:
userid = str(userid)
link = await TwitchProfileLink.fetch(userid)
if link:
return await UserProfile.fetch(link.profileid)
@@ -41,6 +42,7 @@ class ProfilesRegistry:
return await Community.fetch(link.communityid)
async def get_community_twitch(self, channelid: str) -> Optional[Community]:
channelid = str(channelid)
link = await TwitchCommunityLink.fetch(channelid)
if link:
return await Community.fetch(link.communityid)

View File

@@ -0,0 +1,10 @@
from typing import TYPE_CHECKING
from .. import logger
if TYPE_CHECKING:
from meta.bot import Bot
async def setup(bot: 'Bot'):
from .component import ProfileComponent
await bot.add_component(ProfileComponent(bot))

View File

@@ -0,0 +1,81 @@
from typing import Optional
import asyncio
import twitchio
from twitchio.ext import commands as cmds
from meta import Bot
from meta.logger import log_wrap
from utils.lib import utc_now
from . import logger
from ..data import ProfilesData, UserProfile, TwitchProfileLink, Community, TwitchCommunityLink
from ..profiles import ProfilesRegistry
class ProfilesComponent(cmds.Component):
def __init__(self, bot: Bot):
self.bot = bot
self.data = bot.dbconn.load_registry(ProfilesData())
self.profiles = ProfilesRegistry(self.data)
# ----- API -----
async def component_load(self):
await self.data.init()
async def component_teardown(self):
pass
# ------ Commands -----
@log_wrap(isolate=True, action="Fetch Profile")
async def fetch_profile(
self,
user: twitchio.PartialUser,
touch: bool = False,
) -> UserProfile:
"""
Fetch or create the profile for the given user.
"""
userid = str(user.id)
async with self.bot.dbconn.connection() as conn:
self.bot.dbconn.conn = conn
async with conn.transaction():
profile = await self.profiles.get_profile_twitch(userid)
if profile is None:
args = {}
try:
user = await user.user()
args['nickname'] = user.display_name
args['avatar'] = user.profile_image.url
except twitchio.HTTPException:
pass
profile = await UserProfile.create(**args)
await TwitchProfileLink.create(profileid=profile.profileid, userid=userid)
elif touch:
await profile.update(last_seen=utc_now())
return profile
@log_wrap(isolate=True, action="Fetch Community")
async def fetch_community(
self,
channel: twitchio.PartialUser,
touch: bool = False,
) -> Community:
"""
Fetch or create the community for this channel.
"""
chanid = channel.id
async with self.bot.dbconn.connection() as conn:
self.bot.dbconn.conn = conn
async with conn.transaction():
comm = await self.profiles.get_community_twitch(chanid)
if comm is None:
comm = await Community.create()
await TwitchCommunityLink.create(channelid=chanid, communityid=comm.communityid)
elif touch:
await comm.update(last_seen=utc_now())
return comm