1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-23 19:44:20 +00:00
royalnet/royalpack/database/base.py

269 lines
7.7 KiB
Python

from __future__ import annotations
import typing as t
import sqlalchemy as s
import sqlalchemy.sql as ss
import sqlalchemy.orm as so
import sqlalchemy.ext.declarative as sed
import sqlalchemy_utils as su
import royalnet.alchemist as ra
import colour
Base: sed.declarative_base = sed.declarative_base()
user_title_association = s.Table(
"user_title_association",
Base.metadata,
s.Column("user_fk", s.String, s.ForeignKey("users.sub")),
s.Column("title_fk", su.UUIDType, s.ForeignKey("titles.uuid"))
)
class User(Base, ra.ColRepr, ra.Updatable):
"""
An user, as returned by Auth0.
"""
__tablename__ = "users"
sub = s.Column(s.String, primary_key=True)
last_update = s.Column(su.ArrowType, nullable=False)
name = s.Column(s.String, nullable=False)
nickname = s.Column(s.String, nullable=False)
avatar = s.Column(s.String, nullable=False)
email = s.Column(s.String, nullable=False)
bio = s.Column(s.Text, nullable=False, default="")
color = s.Column(su.ColorType, nullable=False, default=colour.Color("#a0ccff"))
title_fk = s.Column(su.UUIDType, s.ForeignKey("titles.uuid"))
fiorygi = s.Column(s.Integer, nullable=False, default=0)
def __str__(self):
return self.name
class UserAlias(Base, ra.ColRepr, ra.Updatable):
"""
An alias for an User.
"""
__tablename__ = "user_aliases"
user_fk = s.Column(s.String, s.ForeignKey("users.sub"), primary_key=True)
user = so.relationship("User", backref="aliases")
name = s.Column(s.String, nullable=False, primary_key=True)
@so.validates("name")
def convert_lower(self, key, value: str) -> str:
return value.lower()
@classmethod
def find(cls, session: so.Session, string: str) -> t.Optional[User]:
ua = session.execute(
ss.select(cls).where(cls.name == string)
).scalar()
return ua.user if ua else None
def __str__(self):
return self.name
class TelegramAccount(Base, ra.ColRepr, ra.Updatable):
"""
A Telegram account.
"""
__tablename__ = "accounts_telegram"
user_fk = s.Column(s.String, s.ForeignKey("users.sub"), nullable=False)
user = so.relationship("User", backref="telegram_accounts")
id = s.Column(s.BigInteger, primary_key=True)
first_name = s.Column(s.String, nullable=False)
last_name = s.Column(s.String)
username = s.Column(s.String)
avatar_url = s.Column(su.URLType)
def name(self) -> str:
if self.username is not None:
return f"{self.username}"
elif self.last_name is not None:
return f"{self.first_name} {self.last_name}"
else:
return f"{self.first_name}"
def mention(self) -> str:
if self.username is not None:
return f"@{self.username}"
else:
return f"[{self.name}](tg://user?id={self.tg_id})"
def __str__(self):
return self.name()
class DiscordAccount(Base, ra.ColRepr, ra.Updatable):
"""
A Discord account.
"""
__tablename__ = "accounts_discord"
user_fk = s.Column(s.String, s.ForeignKey("users.sub"), nullable=False)
user = so.relationship("User", backref="discord_accounts")
id = s.Column(s.BigInteger, primary_key=True)
username = s.Column(s.String, nullable=False)
discriminator = s.Column(s.SmallInteger, nullable=False)
avatar_url = s.Column(su.URLType)
def name(self) -> str:
return f"{self.username}#{self.discriminator}"
def __str__(self):
return self.name()
class SteamAccount(Base, ra.ColRepr, ra.Updatable):
"""
A Steam account.
"""
__tablename__ = "accounts_steam"
user_fk = s.Column(s.String, s.ForeignKey("users.sub"), nullable=False)
user = so.relationship("User", backref="steam_accounts")
steamid = s.Column(s.BigInteger, primary_key=True)
persona_name = s.Column(s.String, nullable=False)
avatar_url = s.Column(su.URLType)
# TODO: make steamid return steam.steamid.SteamID objects
def __str__(self):
return self.persona_name
class OsuAccount(Base, ra.ColRepr, ra.Updatable):
"""
An osu! account.
"""
__tablename__ = "accounts_osu"
user_fk = s.Column(s.String, s.ForeignKey("users.sub"), nullable=False)
user = so.relationship("User", backref="osu_accounts")
id = s.Column(s.BigInteger, primary_key=True)
username = s.Column(s.String)
avatar_url = s.Column(su.URLType)
def __str__(self):
return self.username
class LeagueAccount(Base, ra.ColRepr, ra.Updatable):
"""
A League of Legends account.
"""
__tablename__ = "accounts_league"
user_fk = s.Column(s.String, s.ForeignKey("users.sub"), nullable=False)
user = so.relationship("User", backref="league_accounts")
region = s.Column(s.String, nullable=False)
puuid = s.Column(s.String, primary_key=True)
summoner_name = s.Column(s.String, nullable=False)
avatar_id = s.Column(s.Integer, nullable=False)
def __str__(self):
return self.summoner_name
class Title(Base, ra.ColRepr, ra.Updatable):
"""
Title available for users to unlock.
"""
__tablename__ = "titles"
uuid = s.Column(su.UUIDType, primary_key=True)
name = s.Column(s.String, nullable=False)
visible = s.Column(s.Boolean, nullable=False)
locked_description = s.Column(s.Text, nullable=False)
unlocked_description = s.Column(s.Text, nullable=False)
unlocked_by = so.relationship("User", secondary=user_title_association, backref="unlocked_titles")
def __str__(self):
return self.name
class DiarioGroup(Base, ra.ColRepr, ra.Updatable):
"""
Group of Diario entries.
"""
__tablename__ = "diario_groups"
id = s.Column(s.Integer, primary_key=True)
saved_by_fk = s.Column(s.String, s.ForeignKey("users.sub"), nullable=False)
saved_by = so.relationship("User", backref="diario_groups_saved")
context = s.Column(s.Text)
class DiarioLine(Base, ra.ColRepr, ra.Updatable):
"""
Single Diario quote.
"""
__tablename__ = "diario_lines"
id = s.Column(s.Integer, primary_key=True)
diario_group_fk = s.Column(s.Integer, s.ForeignKey("diario_groups.id"), nullable=False)
diario_group = so.relationship("DiarioGroup", backref="lines")
text = s.Column(s.Text)
media_url = s.Column(su.URLType)
timestamp = s.Column(su.ArrowType)
spoiler = s.Column(s.String)
quoted_str = s.Column(s.String)
quoted_user_fk = s.Column(s.String, s.ForeignKey("users.sub"))
quoted_user = so.relationship("DiarioGroup", backref="diario_quoted_in")
class Transaction(Base, ra.ColRepr, ra.Updatable):
"""
Single fiorygi transaction.
"""
__tablename__ = "fiorygi_transactions"
id = s.Column(s.Integer, primary_key=True)
minus_fk = s.Column(s.String, s.ForeignKey("users.sub"))
minus = so.relationship("User", foreign_keys=(minus_fk,), backref="transactions_minus")
plus_fk = s.Column(s.String, s.ForeignKey("users.sub"))
plus = so.relationship("User", foreign_keys=(plus_fk,), backref="transactions_plus")
amount = s.Column(s.Integer, nullable=False)
reason = s.Column(s.Text)
timestamp = s.Column(su.ArrowType)
class Treasure(Base, ra.ColRepr, ra.Updatable):
"""
A treasure code which rewards fiorygi.
"""
__tablename__ = "fiorygi_treasures"
slug = s.Column(s.String, primary_key=True)
creator_fk = s.Column(s.String, s.ForeignKey("users.sub"))
creator = so.relationship("User", foreign_keys=(creator_fk,))
creation_time = s.Column(su.ArrowType, nullable=False)
finder_fk = s.Column(s.String, s.ForeignKey("users.sub"))
finder = so.relationship("User", foreign_keys=(finder_fk,))
find_time = s.Column(su.ArrowType)
value = s.Column(s.Integer, nullable=False)
message = s.Column(s.Text)