90 lines
3.3 KiB
Python
90 lines
3.3 KiB
Python
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
|