(profiles): Start internal API.

This commit is contained in:
2024-09-26 21:22:42 +10:00
parent a7eb8d0f09
commit 9d0d19d046
3 changed files with 83 additions and 12 deletions

View File

@@ -1505,12 +1505,13 @@ CREATE INDEX profiles_discord_userid ON profiles_discord (userid);
CREATE TABLE profiles_twitch(
linkid SERIAL PRIMARY KEY,
profileid INTEGER NOT NULL REFERENCES user_profiles (profileid) ON DELETE CASCADE ON UPDATE CASCADE,
userid BIGINT NOT NULL,
userid TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX profiles_twitch_profileid ON profiles_twitch (profileid);
CREATE INDEX profiles_twitch_userid ON profiles_twitch (userid);
CREATE TABLE communities(
communityid SERIAL PRIMARY KEY,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
@@ -1524,7 +1525,7 @@ CREATE TABLE communities_discord(
CREATE UNIQUE INDEX communities_discord_communityid ON communities_discord (communityid);
CREATE TABLE communities_twitch(
channelid BIGINT PRIMARY KEY,
channelid TEXT PRIMARY KEY,
communityid INTEGER NOT NULL REFERENCES communities (communityid) ON DELETE CASCADE ON UPDATE CASCADE,
linked_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
@@ -1532,10 +1533,10 @@ CREATE UNIQUE INDEX communities_twitch_communityid ON communities_twitch (commun
CREATE TABLE community_members(
memberid SERIAL PRIMARY KEY,
communityid INTEGER NOT NULL REFERENCES communities (communityud) ON DELETE CASCADE ON UPDATE CASCADE,
communityid INTEGER NOT NULL REFERENCES communities (communityid) ON DELETE CASCADE ON UPDATE CASCADE,
profileid INTEGER NOT NULL REFERENCES user_profiles (profileid) ON DELETE CASCADE ON UPDATE CASCADE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
)
);
CREATE UNIQUE INDEX community_members_communityid_profileid ON community_members (communityid, profileid);
-- }}}

View File

@@ -7,6 +7,7 @@ import discord
from discord.ext import commands as cmds
import twitchio
from twitchio.ext import commands
from twitchAPI.object.api import TwitchUser
from data.queries import ORDER
@@ -17,9 +18,53 @@ from .data import ProfileData
class UserProfile:
def __init__(self):
def __init__(self, data, profile_row, *, discord_row=None, twitch_row=None):
self.data: ProfileData = data
self.profile_row: ProfileData.UserProfileRow = profile_row
self.discord_row: Optional[ProfileData.DiscordProfileRow] = discord_row
self.twitch_row: Optional[ProfileData.TwitchProfileRow] = twitch_row
@property
def profileid(self):
return self.profile_row.profileid
async def attach_discord(self, user: discord.User | discord.Member):
"""
Attach a new discord user to this profile.
"""
# TODO: Attach whatever other data we want to cache here.
# Currently Lion also caches most of this data
discord_row = await self.data.DiscordProfileRow.create(
profileid=self.profileid,
userid=user.id
)
async def attach_twitch(self, user: TwitchUser):
"""
Attach a new Twitch user to this profile.
"""
...
@classmethod
async def fetch_profile(
cls, data: ProfileData,
*,
profile_id: Optional[int] = None,
profile_row: Optional[ProfileData.UserProfileRow] = None,
discord_row: Optional[ProfileData.DiscordProfileRow] = None,
twitch_row: Optional[ProfileData.TwitchProfileRow] = None,
):
if not any((profile_id, profile_row, discord_row, twitch_row)):
raise ValueError("UserProfile needs an id or a data row to construct.")
if profile_id is None:
profile_id = (profile_row or discord_row or twitch_row).profileid
profile_row = profile_row or await data.UserProfileRow.fetch(profile_id)
discord_row = discord_row or await data.DiscordProfileRow.fetch_profile(profile_id)
twitch_row = twitch_row or await data.TwitchProfileRow.fetch_profile(profile_id)
return cls(data, profile_row, discord_row=discord_row, twitch_row=twitch_row)
class ProfileCog(LionCog):
def __init__(self, bot: LionBot):
@@ -37,7 +82,11 @@ class ProfileCog(LionCog):
"""
Fetch or create a UserProfile from the given Discord userid.
"""
...
# TODO: (Extension) May be context dependent
# Current model assumes profile (one->0..n) discord
discord_row = next(await self.data.DiscordProfileRow.fetch_where(userid=userid), None)
if discord_row is None:
profile_row = await self.data.UserProfileRow.create()
async def fetch_profile_twitch(self, userid: int, create=True):
"""

View File

@@ -41,6 +41,12 @@ class ProfileData(Registry):
userid = Integer()
created_at = Integer()
@classmethod
async def fetch_profile(cls, profileid: int):
rows = await cls.fetch_where(profiled=profileid)
return next(rows, None)
class TwitchProfileRow(RowModel):
"""
Schema
@@ -48,7 +54,7 @@ class ProfileData(Registry):
CREATE TABLE profiles_twitch(
linkid SERIAL PRIMARY KEY,
profileid INTEGER NOT NULL REFERENCES user_profiles (profileid) ON DELETE CASCADE ON UPDATE CASCADE,
userid BIGINT NOT NULL,
userid TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX profiles_twitch_profileid ON profiles_twitch (profileid);
@@ -59,9 +65,14 @@ class ProfileData(Registry):
linkid = Integer(primary=True)
profileid = Integer()
userid = Integer()
userid = String()
created_at = Timestamp()
@classmethod
async def fetch_profile(cls, profileid: int):
rows = await cls.fetch_where(profiled=profileid)
return next(rows, None)
class CommunityRow(RowModel):
"""
Schema
@@ -95,12 +106,17 @@ class ProfileData(Registry):
communityid = Integer()
linked_at = Timestamp()
@classmethod
async def fetch_community(cls, communityid: int):
rows = await cls.fetch_where(communityd=communityid)
return next(rows, None)
class TwitchCommunityRow(RowModel):
"""
Schema
------
CREATE TABLE communities_twitch(
channelid BIGINT PRIMARY KEY,
channelid TEXT PRIMARY KEY,
communityid INTEGER NOT NULL REFERENCES communities (communityid) ON DELETE CASCADE ON UPDATE CASCADE,
linked_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
@@ -109,20 +125,25 @@ class ProfileData(Registry):
_tablename_ = 'communities_twitch'
_cache_ = {}
channelid = Integer(primary=True)
channelid = String(primary=True)
communityid = Integer()
linked_at = Timestamp()
@classmethod
async def fetch_community(cls, communityid: int):
rows = await cls.fetch_where(communityd=communityid)
return next(rows, None)
class CommunityMemberRow(RowModel):
"""
Schema
------
CREATE TABLE community_members(
memberid SERIAL PRIMARY KEY,
communityid INTEGER NOT NULL REFERENCES communities (communityud) ON DELETE CASCADE ON UPDATE CASCADE,
communityid INTEGER NOT NULL REFERENCES communities (communityid) ON DELETE CASCADE ON UPDATE CASCADE,
profileid INTEGER NOT NULL REFERENCES user_profiles (profileid) ON DELETE CASCADE ON UPDATE CASCADE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
)
);
CREATE UNIQUE INDEX community_members_communityid_profileid ON community_members (communityid, profileid);
"""
_tablename_ = 'community_members'