Profile schema and discord hook

This commit is contained in:
2025-08-25 23:23:41 +10:00
parent fc3bdcbb5c
commit 5fa0df66f5
8 changed files with 307 additions and 0 deletions

89
profiles/discord/cog.py Normal file
View File

@@ -0,0 +1,89 @@
from typing import Optional
import asyncio
import discord
from discord.ext import commands as cmds
from discord import app_commands as appcmds
from meta import LionBot, LionCog, LionContext
from meta.logger import log_wrap
from utils.lib import utc_now
from ..data import ProfilesData, UserProfile, DiscordProfileLink, Community, DiscordCommunityLink
from ..profiles import ProfilesRegistry
class ProfilesCog(LionCog):
def __init__(self, bot: LionBot):
self.bot = bot
self.data = bot.db.load_registry(ProfilesData())
self.profiles = ProfilesRegistry(self.data)
async def cog_load(self):
await self.data.init()
await self.bot.version_check(*self.data.VERSION)
await self.profiles.init()
async def bot_check_once(self, ctx: LionContext):
profile = await self.fetch_profile(ctx.author, interaction=ctx.interaction, touch=True)
ctx.profile = profile
if ctx.guild:
community = await self.fetch_community(ctx.guild, interaction=ctx.interaction, touch=True)
ctx.community = community
else:
ctx.community = None
return True
@log_wrap(isolate=True, action="Fetch Profile")
async def fetch_profile(
self,
user: discord.User | discord.Member,
interaction: Optional[discord.Interaction] = None,
touch: bool = False,
) -> UserProfile:
"""
Fetch or create the profile for the given user.
"""
async with self.bot.db.connection() as conn:
self.bot.db.conn = conn
async with conn.transaction():
profile = await self.profiles.get_profile_discord(user.id)
if profile is None:
# Create a new profile
# Then link with discord
args = {
'nickname': user.display_name,
}
if interaction:
if interaction.locale:
args['locale_hint'] = interaction.locale.language_code
if user.avatar:
args['avatar'] = user.avatar.url
profile = await UserProfile.create(**args)
await DiscordProfileLink.create(profileid=profile.profileid, userid=user.id)
elif touch:
await profile.update(last_seen=utc_now())
return profile
@log_wrap(isolate=True, action="Fetch Community")
async def fetch_community(
self,
guild: discord.Guild,
interaction: Optional[discord.Interaction] = None,
touch: bool = False,
) -> Community:
"""
Fetch or create the community for the given guild.
"""
async with self.bot.db.connection() as conn:
self.bot.db.conn = conn
async with conn.transaction():
comm = await self.profiles.get_community_discord(guild.id)
if comm is None:
# Create a new Community and link to Discord
comm = await Community.create()
await DiscordCommunityLink.create(guildid=guild.id, communityid=comm.communityid)
elif touch:
await comm.update(last_seen=utc_now())
return comm