class AbsenceMeta(Table): _name = 'absence_meta' _schema = [ Column('id', Integer, primary_key=True), Column('lesson', ForeignKey('lesson')), Column('code', String(10)), Column('active', Boolean(), default=True), Column('users', ForeignKey('users')), Column('time_created', DateTime(), default=datetime.utcnow), Column('time_ended', DateTime()), ]
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 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 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
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), ]
class Exercise(Table): _name = 'exercise' _schema = [ Column('id', Integer, primary_key=True), Column('title', String(255)), Column('task', CodeString(10000)), Column('possible_answare', CodeString(1000), required=False), Column('author', ForeignKey('users'), default=1), Column('time_created', DateTime(), default=datetime.utcnow), Column('lesson', ForeignKey('lesson')), ]
class Question(Table): _name = 'question' _schema = [ Column('id', Integer, primary_key=True), Column('question', String(1000)), Column('answares', CodeString(2000), default=''), Column('possible_answare', String(1000), default=''), Column('qtype', String(50), default='plain'), Column('img', String(255), required=False, default=''), Column('users', ForeignKey('users'), default=DEFAULT_USER), Column('time_created', DateTime(), default=datetime.utcnow), ]
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 Lesson(Table): _name = 'lesson' _schema = [ Column('id', Integer, primary_key=True), Column('title', String(255)), Column('description', String(10000)), Column('author', ForeignKey('users'), default=1), 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 Quiz(Table): _name = 'quiz' _schema = [ Column('id', Integer, primary_key=True), Column('title', String(255)), Column('description', String(10000)), Column('users', ForeignKey('users'), default=1), Column('time_created', DateTime(), default=datetime.utcnow), ] async def get_question(self, question_order=0): if question_order + 1 >= await self.get_question_amount(): return {'last': True, 'msg': 'That was last question in the quiz.'} qq = await QuizQuestions.get_first_by_many_field_value( quiz=self.id, question_order=question_order) return await Question.get_by_id(qq.question) async def get_question_amount(self): return len(await QuizQuestions.get_by_field_value('quiz', self.id))
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 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 CommonTestTemplate(Table): _name = '' _questions = None _status = None _answers = None _schema = [ Column('id', Integer, primary_key=True), Column('title', String(255)), Column('description', String(10000)), Column('users', ForeignKey('users'), default=DEFAULT_USER), Column('time_created', DateTime(), default=datetime.utcnow), Column('active', Boolean(), default=False), ] async def get_question(self, uid=0, as_json=True): return await self._questions.get_all_for_test(self.id, uid=uid, answer_cls=self._answers, as_json=as_json) async def get_status(self, uid): try: await self.update_status(uid, add=0) return await self._status.get_first_by_many_field_value( **{ self._name: self.id, 'users': uid }) except DoesNotExist: status = self._status(**{self._name: self.id, 'users': uid}) await status.create() return status async def get_question_amount(self): return await self._questions.count_by_field(**{self._name: self.id}) async def update_status(self, uid, add=1, new_status=''): question_amount = await self.get_question_amount() cond = {self._name: self.id, 'users': uid} status = await self._status.get_first_by_many_field_value(**cond) status.progress += add if status.progress < question_amount: status.status = 'inProgress' if not add: return elif new_status: status.status = new_status elif status.progress > question_amount: status.progress = question_amount elif status.progress == question_amount and status.status != 'Submitted': status.status = 'Done' await status.update(**cond) async def add_question(self, question_id, order): test_question = self._questions(**{ self._name: self.id, 'question': question_id, 'question_order': order }) await test_question.create() @classmethod async def get_all_available_questions(cls, as_json=True): available_questions = [] all_questions = await Question.get_all() used_questions = await cls._questions.get_all() used_questions = [q.question for q in used_questions] for question in all_questions: if question.id not in used_questions: if as_json: available_questions.append( {'question_details': await question.to_dict()}) else: available_questions.append(question) return available_questions @classmethod async def get_all_questions_to_grade(cls, tid, as_json=True): resp = [] questions = await cls._questions.get_all_for_test(tid) for quest in questions: try: quest['graded'] = await cls._answers.get_graded_count( quest['question']) quest['to_grade'] = await cls._answers.get_answer_count( quest['question']) - quest['graded'] except: raise resp.append(quest) return resp async def delete_old_questions(self): old_questions = self._questions(**{ self._name: 1, 'question': 1, 'question_order': 1 }) await old_questions.delete(**{self._name: self.id}) @classmethod async def get_by_anwers_to_grade_by_qid(cls, qid): answers = [] for ans in await cls._answers.get_answers_by_qid(qid): answers.append(await ans.to_dict()) return answers @classmethod async def grade_answer_by_uid(cls, qid, uid, score, comment=''): try: answer = await cls._answers.get_answer_by_uid(qid, uid) answer.score = score answer.comment = comment await answer.update(**{'question': qid, 'users': uid}) return True except Exception: logging.exception('error grading') return False