class WorkshopModel(db.Document): """ This is an abstract class. Please inherit from it if you want to create a new type of workshop """ meta = {"collection": "workshops"} workshopId = db.StringField(primary_key=True, default=generate_id) name = db.StringField(required=True, max_length=128, min_length=1, default="Atelier CAPLC") createdAt = db.DateTimeField(default=datetime.datetime.utcnow) updatedAt = db.DateTimeField(default=datetime.datetime.utcnow) startAt = db.DateTimeField(required=True) creatorId = db.StringField(required=True) coachId = db.StringField(required=True) eventUrl = db.StringField(default="caplc.com") city = db.StringField(max_length=128, min_length=1) address = db.StringField(max_length=512) participants = db.ListField( db.EmbeddedDocumentField(WorkshopParticipantModel), default=[]) model = db.ReferenceField(Model, db_field="modelId") def __repr__(self): return ( f"<Workshop {self.workshopId} | {self.name} " f"- animated by {self.coachId} at {self.city} on {self.startAt} " f"- with {len(self.participants)} participants>") @classmethod def find_by_id(cls, workshop_id: str) -> WorkshopModel: try: workshop = cls.objects.get(workshopId=workshop_id) except db.DoesNotExist: workshop = None return workshop @classmethod def find_by_coach_id(cls, coach_id: str) -> WorkshopModel: try: workshops = cls.objects(coachId=coach_id) except db.DoesNotExist: workshops = [] return workshops def get_participant_ids(self) -> list: return [p.user.id for p in self.participants] def get_workshop_participant(self, participant_id: str): for workshop_participant in self.participants: if workshop_participant.user.id == participant_id: return workshop_participant return None
class Role(db.Document): name = db.StringField(max_length=255, required=True, unique=True) description = db.StringField(max_length=255) permissions = db.ListField(db.ReferenceField(Permission), default=[]) def __str__(self): return self.description def __unicode__(self): return self.description
class User(db.Document): username = db.StringField(max_length=255, verbose_name='用户名称', required=True, unique=True) _password = db.StringField(max_length=255, verbose_name='用户密码') active = db.BooleanField(default=True, verbose_name='当前账户是否激活') create_time = db.DateTimeField(default=datetime.datetime.now, verbose_name='创建时间') roles = db.ListField(db.ReferenceField(Role), default=[]) # 给这个用户增加角色 def add_role(self, role_names: list): for role_name in role_names: role = Role.objects(name=role_name).first() if not role: role = Role(name=role_name) role.save() self.roles.append(role) self.roles = list(set(self.roles)) @staticmethod def register(username, password): new_user = User(username=username, _password=generate_password_hash(password)) new_user.save() return new_user @property def password(self): return self._password @password.setter def password(self, passwd): self._password = generate_password_hash(passwd) def check_password(self, raw): return check_password_hash(self._password, raw) def __unicode__(self): return str(self.username)
class ActionCardBatchModel(db.Document): meta = {"collection": "actionCardBatches"} actionCardBatchId = db.StringField(primary_key=True, default=generate_id) coachId = db.StringField() name = db.StringField(required=True) actionCardIds = db.ListField(db.StringField(), required=True) type = db.StringField(required=True) default = db.BooleanField() createdAt = db.DateTimeField(default=datetime.datetime.utcnow) updatedAt = db.DateTimeField(default=datetime.datetime.utcnow) @classmethod def get_default_batches(cls): return cls.objects(default=True).all() @classmethod def find_default_batches(cls): return cls.objects(default=True).all() @classmethod def find_action_card_batches_by_coach(cls, coach_id): return cls.objects(coachId=coach_id).all()
class User(db.Document, UserMixin): first_name = db.StringField(required=True) last_name = db.StringField(required=True) email = db.StringField(required=True, unique=True) password_hash = db.StringField(required=True) course_type = db.StringField(choices=COURSE_TYPES + NULL_CHOICE) course_date = db.StringField(choices=COURSE_DATES + NULL_CHOICE) country_origin = db.StringField() company = db.StringField() employment_status = db.StringField() academic_degree = db.StringField() age = db.IntField() entrepreneurial_essay = db.StringField() problem_essay = db.StringField() permissions = db.ListField(db.StringField(choices=PERMISSION_TYPES)) airtable_id = db.StringField() airtable_map = dict(first_name='First Name', last_name='Last Name', course_type='Course Type', company='Company', employment_status='Employment Status', academic_degree='Academic Degree', age='Age', entrepreneurial_essay='Entrepreneurial Essay', problem_essay='Problems Essay') def __str__(self): return f'{self.first_name} {self.last_name}' @property def is_admin(self): return 'admin' in self.permissions
class UserModel(db.Document): meta = {"collection": "users"} # User specific fields userId = db.StringField(primary_key=True, default=generate_id) firstName = db.StringField(required=True, max_length=64, min_length=1) lastName = db.StringField(required=True, max_length=64, min_length=1) email = db.StringField(required=True, max_length=256, unique=True) password = db.StringField() role = db.ListField(db.StringField(max_length=32), required=True) createdAt = db.DateTimeField(default=datetime.datetime.utcnow) updatedAt = db.DateTimeField(default=datetime.datetime.utcnow) # Coach specific fields city = db.StringField(max_length=256) workshopsCount = db.IntField() awarenessRaisedCount = db.IntField() # Participant specific fields workshopParticipations = db.ListField(db.StringField(), default=[]) def __str__(self): return f"User {self.userId} - {self.firstName} {self.lastName}" def __repr__(self): return f"<User {self.userId} - {self.firstName} {self.lastName}>" def allowed(self, access_level: Roles) -> bool: return (max([ACCESS_LEVEL[r] for r in self.role]) >= ACCESS_LEVEL[access_level.value]) def send_reset_password_mail(self) -> str: # Genereate temporary access token for password resetting token = create_access_token(identity=self.id) reset_url = "{url}/reset_password?access_token={token}".format( url=current_app.config["PREFERRED_URL_SCHEME"], token=token) print(token) send_reset_password_mail(self.email, reset_url=reset_url) return token @classmethod def find_by_id(cls, user_id: str) -> UserModel: try: user = cls.objects.get(userId=user_id) except db.DoesNotExist: user = None return user @classmethod def find_by_email(cls, email: str) -> UserModel: try: user = cls.objects.get(email=email) except db.DoesNotExist: user = None return user @classmethod def find_coach_by_id(cls, user_id: str) -> UserModel: try: user = cls.objects.get( userId=user_id, role__in=[Roles.ADMIN.value, Roles.COACH.value]) except db.DoesNotExist: user = None return user @classmethod def find_coach_by_email(cls, email: str) -> UserModel: try: user = cls.objects.get( email=email, role__in=[Roles.ADMIN.value, Roles.COACH.value]) except db.DoesNotExist: user = None return user @classmethod def find_participant_by_email(cls, email: str) -> UserModel: try: user = cls.objects.get(email=email, role__in=[Roles.PARTICIPANT.value]) except db.DoesNotExist: user = None return user @classmethod def find_all_coaches(cls) -> QuerySet: return cls.objects( role__in=[Roles.ADMIN.value, Roles.COACH.value]).all() def add_participant_role(self) -> None: """ To use when we want to update the role of the user to participant. Init data specific to the participant :return: """ self.role.append(Roles.PARTICIPANT.value) self.workshopParticipations = [] return
class SignModel(db.Document): name = db.StringField(required=True) adminId = db.ReferenceField(AdminModel) classroomIds = db.ListField(db.ReferenceField(ClassModel)) signUsers = db.ListField(db.ReferenceField('UserModel'), default=[]) token = db.StringField(required=True) created_at = db.DateTimeField(default=datetime.datetime.utcnow, required=True) meta = { 'collection': 'sign', 'indexes': ['-created_at'], 'ordering': ['-created_at'], 'strict': False } # 保存签到表到数据库 @staticmethod def add_sign(data): name = data['name'] adminId = ObjectId(data['adminId']) classroomIds = [] for cls in data['classroomIds'].split('|'): classroomIds.append(ObjectId(cls)) token = data['token'] sign = SignModel(name=name, adminId=adminId, classroomIds=classroomIds, token=token) sign.save() return str(sign['id']) # 学生签到 @staticmethod def user_sign(token, userId): userId = ObjectId(userId) sign = SignModel.objects(token=token) sign.update_one(add_to_set__signUsers=userId) # 老师帮学生签到 @staticmethod def super_user_sign(signId, signUsers): signId = ObjectId(signId) sign = SignModel.objects(id=signId) sign.update_one(add_to_set__signUsers=signUsers) # 老师手动删除签到 @staticmethod def super_delete_user_sign(signId, signUsers): signId = ObjectId(signId) sign = SignModel.objects(id=signId) sign.update_one(pull_all__signUsers=signUsers) # 获取签到表列表 @staticmethod def get_sign_list(page, size, classId): if classId is not None: classId = ObjectId(classId) cls = ClassModel.objects(id=classId).first() if cls: clss = SignModel.objects( classroomIds__in=[classId]).order_by('-created_at').skip( (page - 1) * size).limit(size) count = SignModel.objects(classroomIds__in=[classId]).count() else: clss = [] count = 0 else: clss = SignModel.objects().order_by('-created_at').skip( (page - 1) * size).limit(size) count = SignModel.objects().count() data = [] for cls in clss: classrooms = [] for room in cls['classroomIds']: classrooms.append({ 'id': str(room['id']), 'name': room['name'], 'stuNum': room['stuNum'] }) data.append({ 'id': str(cls['id']), 'name': cls['name'], 'adminName': cls['adminId']['name'], 'classrooms': classrooms, 'created_at': cls['created_at'] }) res = { 'pagination': { 'count': count, 'size': size, 'page': page }, 'list': data } return res # 删除签到表 @staticmethod def delete_sign(signId): signId = ObjectId(signId) sign = SignModel.objects(id=signId) sign.delete()