class Token(Model): __tablename__ = "tokens" __database__ = database __metadata__ = metadata id = Integer(primary_key=True) user_id = Text() scope = Text(allow_blank=True) access = Text() refresh = Text() expires_at = Integer() @staticmethod async def upsert(user_id: str, token: TekoreToken) -> None: try: token_row: Token = await Token.objects.get(user_id=user_id, scope=str(token.scope)) await token_row.update( access=token.access_token, refresh=token.refresh_token, expires_at=token.expires_at, ) except NoMatch: await Token.objects.create( user_id=user_id, scope=str(token.scope), access=token.access_token, refresh=token.refresh_token, expires_at=token.expires_at, )
class Player(Model): """Representation of a Player, this is a Database Object.""" __tablename__ = "player" __database__ = Database.database __metadata__ = Database.metadata id = BigInteger(primary_key=True, index=True) colour = Integer(default=lambda: Colour.random().value) coin = Integer(default=0) item_counter = Integer(default=0) join_date = DateTime(default=datetime.utcnow) @property async def embed(self) -> Embed: """Get a Embed that represents the Player""" bot = ArenaBot.instance if (discord_user := bot.get_user(self.id)) is None: discord_user = await bot.fetch_user(self.id) embed = Embed(title=discord_user.name, description=f"Coins: {self.coin}", colour=self.colour) embed.set_author(name=discord_user.display_name, icon_url=discord_user.avatar_url) return embed
def _schema(cls): return [ Column('users', ForeignKey('users')), Column(cls._fk_col, ForeignKey(cls._fk_col)), Column('progress', Integer(), default=0), Column('score', Integer(), default=-1), Column('comment', CodeString(1000), required=False, default=''), Column('status', String(50), default='NotStarted'), ]
class Item(Model): """Representation of an Item, this is a Database Object.""" __tablename__ = "item" __database__ = Database.database __metadata__ = Database.metadata __table_args__ = (UniqueConstraint('owner', 'item_id'),) id: int = Integer(primary_key=True, index=True) item_id: str = String(max_length=4) name: str = String(max_length=50) owner: Player = ForeignKey(Player) value: int = Integer() _rarity: int = Integer() _item_type: int = Integer() @property def embed_field(self) -> dict[str, str]: """Get a embed field that represents the Item""" return { "name": f"`{self.item_id}` | {self.rarity.emoji} {self.name}", "value": f"Value: {self.value} - Type: {self.item_type.name}" } @property async def embed(self) -> Embed: """Get a Embed that represents the Item""" embed = Embed(title=f"{self.rarity.emoji} {self.name}", colour=self.rarity.colour) embed.add_field(name="Item ID", value=f"`{self.item_id}`") embed.add_field(name="Value", value=str(self.value)) bot = ArenaBot.instance owner = bot.get_user(self.owner.id) if owner is None: owner = await bot.fetch_user(self.owner.id) embed.set_author(name=owner.display_name, icon_url=owner.avatar_url) return embed @property def rarity(self) -> Rarity: """Get the rarity of the item.""" return Rarity(self._rarity) @rarity.setter def rarity(self, value: Rarity) -> None: self._rarity = value.value @property def item_type(self) -> ItemType: """Get the type of the item.""" return ItemType(self._item_type) @item_type.setter def item_type(self, value: ItemType) -> None: self._item_type = value.value
class Config(Table): _name = 'config' _schema = [ Column('id', Integer, primary_key=True), Column('reg_active', Boolean(), default=True), Column('room_raws', Integer(), default=10), Column('room_columns', Integer(), default=10), ] @classmethod async def get_registration(cls): config = await cls.get_by_id(1) return config.reg_active
class Task(Model): """Representation of a Task, this is a Database Object.""" __tablename__ = "task" __database__ = Database.database __metadata__ = Database.metadata id = BigInteger(primary_key=True, index=True) player = ForeignKey(Player) completed = Boolean(default=False) _task_type = Integer() completion_date = DateTime() @property def task_type(self) -> TaskType: """Get the type of the task.""" return TaskType(self._task_type) @task_type.setter def task_type(self, value: TaskType) -> None: self._task_type = value.value @property async def embed(self) -> Embed: """Get the embed representing the task.""" return Embed(title=self.task_type.name, description=f"Completes at {self.completion_date}", colour=self.task_type.colour)
class User(Model): __tablename__ = "users" __database__ = db __metadata__ = metadata id = Integer(primary_key=True) name = String(max_length=100)
class QuizQuestions(Table): _name = 'quiz_questions' _schema = [ Column('quiz', ForeignKey('quiz')), Column('question', ForeignKey('question')), Column('question_order', Integer(), default=0), ]
class LiveQuizQuestion(Table): _name = 'live_quiz_questions' _schema = [ Column('live_quiz', ForeignKey('live_quiz')), Column('question', ForeignKey('question')), Column('question_order', Integer(), default=0), ] _unique = ['live_quiz', 'question_order']
class UserReview(Table): _name = 'user_review' _schema = [ Column('users', ForeignKey('users')), Column('reviewer', ForeignKey('users')), Column('score', Integer()), ] _unique = ['users', 'reviewer']
class EventSponsor(Table): _name = 'event_sponsor' _schema = [ Column('order_number', Integer()), Column('event', ForeignKey('event')), Column('sponsor', ForeignKey('sponsor')), Column('rank', String(255)), ]
class Feedback(Table): _name = 'feedback' _schema = [ Column('lesson_review', String(10000)), Column('teacher_review', String(10000)), Column('material', Integer()), Column('teacher', ForeignKey('users')), Column('users', ForeignKey('users')), ]
class EventMeetings(Table): _name = 'event_meetings' _schema = [ Column('order_number', Integer()), Column('event', ForeignKey('event')), Column('lesson', ForeignKey('lesson')), Column('date', DateTime(), default=datetime.utcnow), Column('lesson_active', Boolean(), default=False), ]
def _schema(cls): return [ Column('users', ForeignKey('users')), Column(cls._fk_col, ForeignKey(cls._fk_col)), Column('question', ForeignKey('question')), Column('answer', CodeString(5000)), Column('comment', CodeString(1000), required=False, default=''), Column('score', Integer(), default=-1), ]
class Seat(Table): _name = 'seat' _schema = [ Column('id', Integer, primary_key=True), Column('row', String(255)), Column('number', Integer()), Column('users', ForeignKey('users'), unique=True), Column('i_need_help', Boolean(), default=False), ]
class Users(Table): _restricted_keys = ['session_uuid', 'password'] _soft_restricted_keys = ['score', 'notes'] _name = 'users' _schema = [ Column('id', Integer, primary_key=True), Column('email', String(255), unique=True), Column('name', String(255)), Column('surname', String(255)), Column('password', String(1000)), Column('create_date', DateTime(), default=datetime.utcnow), Column('last_login', DateTime(), default=datetime.utcnow), Column('mentor', Boolean(), default=False), Column('organiser', Boolean(), default=False), Column('admin', Boolean(), default=False), Column('session_uuid', String(255), required=False), Column('img', String(255), required=False, default=''), Column('linkedin', String(255), required=False), Column('twitter', String(255), required=False), Column('facebook', String(255), required=False), Column('city', String(255), required=False), Column('education', String(255), required=False), Column('university', String(255), required=False), Column('t_shirt', String(10), required=False), # Column('telephone', String(20), required=False), #TODO: add everywhere Column('operating_system', String(10), required=False), Column('description', String(5000), required=False), Column('motivation', String(5000), required=False), Column('what_can_you_bring', String(5000), required=False), Column('experience', String(5000), required=False), Column('app_idea', String(5000), required=False), Column('pyfunction', String(255), required=False), Column('confirmation', String(10), default='noans'), Column('active', Boolean(), default=False), Column('accepted_rules', Boolean(), default=False), Column('accepted', Boolean(), default=False), Column('i_needed_help', Integer(), default=0), Column('notes', String(5000), default=''), Column('score', Float(), default=0, required=False), ] async def create(self): self.password = hash_password(self.password) return await super().create() @classmethod async def get_user_by_session_uuid(cls, session_uuid): try: return await cls.get_first('session_uuid', session_uuid) except DoesNoteExists: return None
class Lesson(Table): _name = 'lesson' _schema = [ Column('id', Integer, primary_key=True), Column('lesson_no', Integer()), Column('title', String(255)), Column('description', String(10000)), Column('author', ForeignKey('users'), default=DEFAULT_USER), Column('file', String(255), required=False), Column('time_created', DateTime(), default=datetime.utcnow), Column('active', Boolean(), default=False), Column('quiz', ForeignKey('quiz'), required=False), Column('live_quiz', ForeignKey('live_quiz'), required=False), ]
class Sponsor(Table): _name = 'sponsor' _schema = [ Column('id', Integer(), primary_key=True), Column('name', String(255)), Column('description', String(5000)), Column('logo', String(255), required=False, default=''), Column('webpage', String(255), required=False, default=''), Column('linkedin', String(255), required=False), Column('twitter', String(255), required=False), Column('facebook', String(255), required=False), Column('city', String(255), required=False), Column('country', String(255), required=False), ]
class Feedback(Table): _name = 'feedback' _schema = [ Column('lesson_review', String(10000)), Column('teacher_review', String(10000)), Column('material', Integer()), Column('teacher', ForeignKey('users')), Column('users', ForeignKey('users')), # O tym czy dobrze było zorganizowane # Czy polecilbys nasze warsztaty znajomym # Czy moglibyśmy lepiej się reklamować # Czy jakieś zagadnienia były za mało poruszone Albo za dużo # Czego brakowało # https://docs.google.com/forms/d/e/1FAIpQLSctlgSwoKQoB_3Hc5bfu3RYLbz0TNKQmg23jnc8MJ3wwRJn7g/viewform ]
class Event(Table): _name = 'event' _schema = [ Column('id', Integer(), primary_key=True), Column('title', String(500), unique=True), Column('description', String(1000)), Column('country', String(255)), Column('city', String(255)), Column('geo_location_lang', Float()), Column('geo_location_long', Float()), Column('address', String(500)), Column('address_picture', String(500)), Column('address_desc', String(500)), Column('create_date', DateTime(), default=datetime.utcnow), Column('start_date', DateTime(), default=datetime.utcnow), Column('end_date', DateTime(), default=datetime.utcnow), Column('registration_start_date', DateTime(), default=datetime.utcnow), Column('registration_end_date', DateTime(), default=datetime.utcnow), Column('reg_active', Boolean(), default=True), Column('event_active', Boolean(), default=True), ]
class Users(Table): _restricted_keys = ['session_uuid', 'password'] _soft_restricted_keys = ['score', 'notes'] _name = 'users' _schema = [ Column('id', Integer(), primary_key=True), Column('email', String(255), unique=True), Column('name', String(255)), Column('surname', String(255)), Column('password', String(1000)), Column('create_date', DateTime(), default=datetime.utcnow), Column('last_login', DateTime(), default=datetime.utcnow), Column('mentor', Boolean(), default=False), Column('organiser', Boolean(), default=False), Column('admin', Boolean(), default=False), Column('session_uuid', String(255), required=False), Column('img', String(255), required=False, default=''), Column('linkedin', String(255), required=False), Column('twitter', String(255), required=False), Column('facebook', String(255), required=False), Column('city', String(255), required=False), Column('education', String(255), required=False), Column('university', String(255), required=False), Column('t_shirt', String(10), required=False), Column('lang', String(20), required=False, default='pl'), Column('age', Integer(), required=False, default=99), Column('python', Boolean(), default=False), Column('operating_system', String(10), required=False), Column('description', String(5000), required=False), Column('motivation', String(5000), required=False), Column('what_can_you_bring', String(5000), required=False), Column('experience', String(5000), required=False), Column('app_idea', String(5000), required=False), Column('pyfunction', String(255), required=False), Column('confirmation', String(10), default='noans'), Column('active', Boolean(), default=False), Column('accepted_rules', Boolean(), default=False), Column('accepted', Boolean(), default=False), Column('bring_power_cord', Boolean(), default=False), Column('attend_weekly', Boolean(), default=False), Column('i_needed_help', Integer(), default=0), Column('notes', String(5000), default=''), Column('score', Float(), default=0, required=False), Column('i_helped', Boolean(), default=False), Column('helped', String(5000), required=False), ] _banned_user_keys = [ 'i_needed_help', 'accepted_rules', ] _public_keys = _banned_user_keys + [ 'education', 'university', 't_shirt', 'operating_system', 'motivation', 'experience', 'app_idea', 'accepted', 'confirmation', 'i_helped', 'helped', ] async def create(self): self.password = hash_string(self.password) return await super().create() async def set_password(self, password): self.password = hash_string(password) @classmethod async def get_user_by_session_uuid(cls, session_uuid): try: return await cls.get_first('session_uuid', session_uuid) except DoesNotExist: return None async def get_public_data(self): data = await self.to_dict() data = safe_del_key(data, self._public_keys) return data async def get_my_user_data(self): data = await self.to_dict() data = safe_del_key(data, self._banned_user_keys) return data
class TaskProficiency(Model): """Representation of a Player Task Proficiency, this is a Database Object.""" __tablename__ = "task_proficiency" __database__ = Database.database __metadata__ = Database.metadata id = Integer(primary_key=True, index=True) player = ForeignKey(Player) hunt_exp: int = Integer(default=0) gather_exp: int = Integer(default=0) mine_exp: int = Integer(default=0) lumber_exp: int = Integer(default=0) @staticmethod def _exp_to_level(exp: int) -> int: """ Get the current level from exp. This has been made as a function to make it easier to change the functionality at a later date. """ return exp // PROFICIENCY_EXP_PER_LEVEL @property def hunt_level(self) -> int: """Retrieve the hunt_level from the users exp""" return self._exp_to_level(self.hunt_exp) @property def gather_level(self) -> int: """Retrieve the gather_level from the users exp""" return self._exp_to_level(self.gather_exp) @property def mine_level(self) -> int: """Retrieve the mine_level from the users exp""" return self._exp_to_level(self.mine_exp) @property def lumber_level(self) -> int: """Retrieve the lumber_level from the users exp""" return self._exp_to_level(self.lumber_exp) def task_level(self, task_type: TaskType) -> int: """Get the level for the task supplied""" if task_type is TaskType.Hunt: return self.hunt_level elif task_type is TaskType.Gather: return self.gather_level elif task_type is TaskType.Mine: return self.mine_level elif task_type is TaskType.Lumber: return self.lumber_level async def increment_exp(self, task_type: TaskType, amount: int) -> None: """Add experience to a task.""" if task_type is TaskType.Hunt: await self.update(hunt_exp=self.hunt_exp + amount) elif task_type is TaskType.Gather: await self.update(gather_exp=self.gather_exp + amount) elif task_type is TaskType.Mine: await self.update(mine_exp=self.mine_exp + amount) elif task_type is TaskType.Lumber: await self.update(lumber_exp=self.lumber_exp + amount) @property def embed_fields(self) -> list[dict[str, str]]: """Get a list of embed fields that represents the Users Proficiencies""" return [{ "name": f"`{task.name}`", "value": f"{level}" } for task, level in [(task_type, self.task_level(task_type)) for task_type in list(TaskType)]]
class Users(Table): _restricted_keys = ['session_uuid', 'password', 'magic_string', 'magic_string_date'] _soft_restricted_keys = ['score', 'notes'] _name = 'users' _schema = [ Column('id', Integer(), primary_key=True), Column('email', String(255), unique=True), Column('name', String(255)), Column('surname', String(255)), Column('password', String(1000)), Column('magic_string', String(50), default='', required=False), Column('create_date', DateTime(), default=datetime.utcnow), Column('last_login', DateTime(), default=datetime.utcnow), Column('magic_string_date', DateTime(), default=datetime.utcnow), Column('mentor', Boolean(), default=False), Column('organiser', Boolean(), default=False), Column('admin', Boolean(), default=False), Column('session_uuid', String(255), required=False), Column('img', String(255), required=False, default=''), Column('linkedin', String(255), required=False), Column('twitter', String(255), required=False), Column('facebook', String(255), required=False), Column('city', String(255), required=False), Column('education', String(255), required=False), Column('university', String(255), required=False), Column('t_shirt', String(10), required=False), Column('lang', String(20), required=False, default='pl'), Column('age', Integer(), required=False, default=99), Column('python', Boolean(), default=False), Column('operating_system', String(10), required=False), Column('description', String(5000), required=False), Column('motivation', String(5000), required=False), Column('what_can_you_bring', String(5000), required=False), Column('experience', String(5000), required=False), Column('app_idea', String(5000), required=False), Column('pyfunction', String(255), required=False), Column('confirmation', String(10), default='noans'), Column('active', Boolean(), default=False), Column('accepted_rules', Boolean(), default=False), Column('accepted', Boolean(), default=False), Column('bring_power_cord', Boolean(), default=False), Column('attend_weekly', Boolean(), default=False), Column('i_needed_help', Integer(), default=0), Column('notes', String(5000), default=''), Column('score', Float(), default=0, required=False), Column('i_helped', Boolean(), default=False), Column('helped', String(5000), required=False), Column('gdpr', Boolean(), default=False), ] _banned_user_keys = [ 'i_needed_help', 'accepted_rules', ] _public_keys = _banned_user_keys + [ 'education', 'university', 't_shirt', 'operating_system', 'motivation', 'experience', 'app_idea', 'accepted', 'confirmation', 'i_helped', 'helped', ] async def create(self): self.password = hash_string(self.password) return await super().create() @staticmethod async def validate_password(new_password): if len(new_password) < 8: return {"success": False, "msg": "Password needs to be at least 8 characters long"} if new_password == new_password.lower() or new_password == new_password.upper(): return { "success": False, "msg": "Password needs to contain at least one small and one capital letter" } if not any([a for a in new_password if a.isnumeric()]): return { "success": False, "msg": "Password needs to contain at least one number" } if not any([a for a in new_password if not a.isalnum()]): return { "success": False, "msg": "Password needs to contain at least one small non alpha-numeric character like !, ? or *" } return {"success": True} async def set_password(self, password): self.password = hash_string(password) async def set_magic_string(self): self.magic_string = create_uuid() self.magic_string_date = datetime.utcnow() @classmethod async def get_user_by_session_uuid(cls, session_uuid): try: return await cls.get_first('session_uuid', session_uuid) except DoesNotExist: return None async def get_public_data(self): data = await self.to_dict() data = safe_del_key(data, self._public_keys) return data async def get_my_user_data(self): data = await self.to_dict() data = safe_del_key(data, self._banned_user_keys) return data async def update(self, **kwargs): if not self.magic_string_date: self.magic_string_date = datetime.utcnow() return await super().update(**kwargs) def is_only_attendee(self): return not (self.admin or self.mentor or self.organiser)
class Stock(Structure): name = String() shares = Integer() price = Float()
def _schema(cls): return [ Column(cls._fk_col, ForeignKey(cls._fk_col)), Column('question', ForeignKey('question')), Column('question_order', Integer(), default=0), ]