class Tasks(db.Model): __tablename__ = "tasks" id = db.Column(db.Integer, primary_key=True) date_created = db.Column(db.DateTime(timezone=True), default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime(timezone=True), default=db.func.current_timestamp(), onupdate=db.func.current_timestamp()) state = db.Column(db.String(32), index=True) active = db.Column(db.Boolean, nullable=False, default=True) title = db.Column(db.String(256), index=True) description = db.Column(db.String(2048), index=True) final_artifact = db.Column(db.String(4096)) created_user_id = db.Column(db.Integer, db.ForeignKey('kb_users.id'), nullable=False) created_user = db.relationship( 'KBUser', foreign_keys=created_user_id, primaryjoin="KBUser.id==Tasks.created_user_id") modified_user_id = db.Column(db.Integer, db.ForeignKey('kb_users.id'), nullable=False) modified_user = db.relationship( 'KBUser', foreign_keys=modified_user_id, primaryjoin="KBUser.id==Tasks.modified_user_id") owner_user_id = db.Column(db.Integer, db.ForeignKey('kb_users.id'), nullable=True) owner_user = db.relationship('KBUser', foreign_keys=owner_user_id, primaryjoin="KBUser.id==Tasks.owner_user_id") comments = db.relationship( "Comments", foreign_keys=[id], primaryjoin= "and_(Comments.entity_id==Tasks.id, Comments.entity_type=='%s')" % (ENTITY_MAPPING["DNS"]), lazy="dynamic") def to_dict(self): comments = Comments.query.filter_by(entity_id=self.id).filter_by( entity_type=ENTITY_MAPPING["TASK"]).all() return dict( date_created=self.date_created.isoformat(), date_modified=self.date_modified.isoformat(), state=self.state, title=self.title, description=self.description, final_artifact=self.final_artifact, id=self.id, created_user=self.created_user.to_dict(), modified_user=self.modified_user.to_dict(), owner_user=self.owner_user.to_dict() if self.owner_user else None, comments=[comment.to_dict() for comment in comments]) def __repr__(self): return '<Tasks %r>' % (self.id)
class User(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(64), unique=True, index=True) username = db.Column(db.String(64), unique=True, index=True) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) password_hash = db.Column(db.String(128)) confirmed = db.Column(db.Boolean, default=False) name = db.Column(db.String(64)) location = db.Column(db.String(64)) about_me = db.Column(db.Text()) member_since = db.Column(db.DateTime(), default=datetime.utcnow) last_seen = db.Column(db.DateTime(), default=datetime.utcnow) posts = db.relationship('Post', backref='author', lazy='dynamic') followed = db.relationship('Follow', foreign_keys=[Follow.follower_id], backref=db.backref('follower', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan') followers = db.relationship('Follow', foreign_keys=[Follow.followed_id], backref=db.backref('followed', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan') comments = db.relationship('Comment', backref='author', lazy='dynamic') def __init__(self, **kwargs): # 定义默认的用户角色 super(User, self).__init__(**kwargs) if self.role is None: if self.email == current_app.config['FLASKY_ADMIN']: self.role = Role.query.filter_by(permissions=0xff).first() if self.role is None: self.role = Role.query.filter_by(default=True).first() # self.follow(self) # 构建用户时把用户设为自己的关注者 @property # 在user模型中加入密码散列 def password(self): raise ArithmeticError('password is not a readable attributes') @password.setter def password(self, password): self.password_hash = generate_password_hash(password) def verify_password(self, password): return check_password_hash(self.password_hash, password) def generate_confirmation_token(self, expiration=3600): s = Serializer(current_app.config['SECRET_KEY']) return s.dumps({'confirm': self.id}) def confirm(self, token): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except: return False if data.get('confirm') != self.id: return False self.confirmed = True db.session.add(self) return True def generate_reset_token(self, expiration=3600): s = Serializer(current_app.config['SECRET_KEY'], expiration) return s.dumps({'reset': self.id}) def reset_password(self, token, new_password): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except: return False if data.get('reset') != self.id: return False db.session.add(self) return True def generate_email_change_token(self, new_email, expiration=3600): s = Serializer(current_app.config['SECRET_KEY'], expiration) return s.dumps({'change_email': self.id, 'new_email': new_email}) def change_email(self, token): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except: return False if data.get('change_email') != self.id: return False new_email = data.get('new_email') if new_email is None: return False if self.query.filter_by(email=new_email).first() is not None: return False return True def can(self, permissions): # 检查用户是否有指定的权限 return self.role is not None and \ (self.role.permissions and permissions) == permissions def is_administrator(self): # 检查用户是否有指定的权限 return self.can(Permission.ADMINISTER) def ping(self): # 刷新用户的最后访问时间 self.last_seen = datetime.utcnow() db.session.add(self) def follow(self, user): # 关注关系的辅助方法 if not self.is_following(user): f = Follow(follower=self, followed=user) db.session.add(f) def unfollow(self, user): f = self.followed.filter_by(followed_id=user.id).first() if f: db.session.delete(f) def is_following(self, user): return self.followed.filter_by(followed_id=user.id).first() is not None def is_followed_by(self, user): return self.followers.filter_by( follower_id=user.id).first() is not None @property # 获取所关注用户的文章 def followed_posts(self): return Post.query.join(Follow, Follow.followed_id == Post.author_id) \ .filter(Follow.follower_id == self.id) def to_json(self): # 把用户转换成JSON格式的序列化字典 json_user = { 'url': url_for('api.get_post', id=self.id, _external=True), 'username': self.username, 'member_since': self.member_since, 'last_seen': self.last_seen, 'posts': url_for('api.get_user.posts', id=self.id, _external=True), 'followed_posts': url_for('api.get_user_followed_posts', id=self.id, _external=True), 'post_count': self.posts.count() } return json_user def generate_auth_token(self, expiration): # 支持基于令牌的认证 s = Serializer(current_app.config['SECRET_KEY'], expires_in=expiration) return s.dumps({'id': self.d}).decode('ascii') @staticmethod def verify_auth_token(token): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except: return None return User.query.get(data['id']) def __repr__(self): return '<User %r>' % self.username
class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(255), unique=True) #用户名 email = db.Column(db.String(255), unique=True) password = db.Column(db.String(255), nullable=False) active = db.Column(db.Boolean(), default=True) # 是否已经激活 role = db.Column(db.String(20), default='User') # 用户或者管理员 gender = db.Column(db.Enum('male', 'female', 'unknown'), default='unknown') identity = db.Column(db.Enum('Teacher', 'Student')) # 学生或者教师 register_time = db.Column(db.DateTime(), default=datetime.utcnow) confirmed_at = db.Column(db.DateTime()) last_login_time = db.Column(db.DateTime()) #TODO:login unread_notification_count = db.Column(db.Integer, default=0) homepage = db.Column(db.String(200)) # 用户博客、主页等 description = db.Column(db.Text) _avatar = db.Column(db.String(100)) following_count = db.Column(db.Integer, default=0) follower_count = db.Column(db.Integer, default=0) courses_following = db.relationship('Course', secondary=follow_course, backref='followers') courses_upvoted = db.relationship('Course', secondary=upvote_course, backref='upvote_users') courses_downvoted = db.relationship('Course', secondary=downvote_course, backref='downvote_users') _student_info = db.relationship('Student', backref='user', uselist=False) _teacher_info = db.relationship('Teacher', backref='user', uselist=False) reviewed_course = db.relationship('Course', secondary=review_course, backref='review_users') users_following = db.relationship( 'User', secondary=follow_user, primaryjoin=(follow_user.c.follower_id == id), secondaryjoin=(follow_user.c.followed_id == id), backref=db.backref('followers')) # followers: backref to User # notifications: backref to Notification def __init__(self, username, email, password): self.username = username self.email = email self.set_password(password) def __repr__(self): return '<User {} ({})>'.format(self.email, self.password) @property def url(self): return url_for('user.view_profile', user_id=self.id) @property def link(self): return Markup('<a href="' + self.url + '">') + Markup.escape( self.username) + Markup('</a>') @property def latest_notifications_text(self): text = latest_notifications_cache.get(self.id) if text is None: text = [] for notice in self.notifications[0:5]: text.append(notice.display_text) latest_notifications_cache.set(self.id, text) return text @property def reviews_count(self): return len(self.reviews) @property def courses_following_count(self): return len(self.courses_following) @property def courses_upvoted_count(self): return len(self.courses_upvoted) @property def courses_downvoted_count(self): return len(self.courses_downvoted) @property def courses_joined_count(self): return len(self.courses_joined) @property def courses_joined(self): if self.is_student and self.info: return self.info.courses_joined else: return [] @property def classes_joined_count(self): return len(self.classes_joined) @property def classes_joined(self): if self.is_student and self.info: return self.info.classes_joined else: return [] @property def avatar(self): if self._avatar: return '/uploads/images/' + self._avatar return '/static/image/user.png' def set_avatar(self, avatar): self._avatar = avatar @property def confirmed(self): if self.confirmed_at: return True return False @property def info(self): if self.identity == 'Student': return self._student_info elif self.identity == 'Teacher': return self._teacher_info else: return None @property def is_student(self): return self.identity == 'Student' @property def student_id(self): if self.is_student and self.info: return self.info.sno else: return None @property def is_teacher(self): return self.identity == 'Teacher' @property def is_authenticated(self): return True @property def is_admin(self): return self.role == 'Admin' def is_active(self): if self.active: return True return False def confirm(self): self.confirmed_at = datetime.utcnow() self.save() def set_password(self, password): self.password = generate_password_hash(password) self.save() def check_password(self, password): """Check passwords.Returns ture if matchs""" if self.password is None: return False return check_password_hash(self.password, password) @classmethod def authenticate(cls, login, password): """A classmethod for authenticating users It returns true if the user exists and has entered a correct password :param login: This can be either a username or a email address. :param password: The password that is connected to username and email. """ user = cls.query.filter( db.or_(User.username == login, User.email == login)).first() if user and user.confirmed: authenticated = user.check_password(password) else: authenticated = False return user, authenticated, user.confirmed if user else False def bind_student(self, sno): if self.identity == 'Student': student = Student.query.get(sno) if student: self._student_info = student return True, _('成功绑定!') else: return False, _('找不到这个学号:%(sno)s!', sno=sno) else: return False, _('无法绑定学号。') def bind_teacher(self, email): if self.identity == 'Teacher': teacher = Teacher.query.filter_by(email=email).first() if teacher: self._teacher_info = teacher self.description = teacher.description self.homepage = teacher.homepage return True, _('绑定成功!') else: return False, _('找不到教师邮箱:%(email)s!', email=email) else: return False, _('无法绑定教师身份。') def save(self): db.session.add(self) db.session.commit() def notify(self, operation, ref_obj, from_user=current_user, ref_display_class=None): # my operations should not be notified to myself if from_user == self: return False notification = Notification(self, from_user, operation, ref_obj, ref_display_class) notification.save() self.unread_notification_count += 1 db.session.commit() # clear cache latest_notifications_cache.set(self.id, None) return True def follow(self, followed): if followed in self.users_following: return False self.users_following.append(followed) self.following_count += 1 followed.follower_count += 1 db.session.commit() return True def unfollow(self, followed): if followed not in self.users_following: return False self.users_following.remove(followed) self.following_count -= 1 followed.follower_count -= 1 db.session.commit() return True def followed_by(self, user=current_user): return user in self.followers def following(self, user=current_user): return user in self.users_following
class User(db.Model): __tablename__ = 'users' uuid = db.Column(db.String(), primary_key=True, default=uuid4) username = db.Column(db.String(), unique=True) password = db.Column(db.String()) created = db.Column(db.DateTime(), default=datetime.datetime.now())
class AppUser(db.Model, UserMixin): id = db.Column(db.Integer(), primary_key=True) email = db.Column(db.String(255), unique=True, nullable=False) firstname = db.Column(db.String(100), nullable=False) lastname = db.Column(db.String(100), nullable=False) user_title = db.Column(db.String(20), nullable=False) nationality_country_id = db.Column(db.Integer(), db.ForeignKey('country.id'), nullable=False) residence_country_id = db.Column(db.Integer(), db.ForeignKey('country.id'), nullable=False) user_gender = db.Column(db.String(20), nullable=False) affiliation = db.Column(db.String(255), nullable=False) department = db.Column(db.String(255), nullable=False) user_disability = db.Column(db.String(255), nullable=False) user_category_id = db.Column(db.Integer(), db.ForeignKey('user_category.id'), nullable=False) user_dateOfBirth = db.Column(db.DateTime(), nullable=True) user_primaryLanguage = db.Column(db.String(255), nullable=True) password = db.Column(db.String(255), nullable=False) active = db.Column(db.Boolean(), nullable=False) is_admin = db.Column(db.Boolean(), nullable=False) is_deleted = db.Column(db.Boolean(), nullable=False) deleted_datetime_utc = db.Column(db.DateTime(), nullable=True) verified_email = db.Column(db.Boolean(), nullable=True) verify_token = db.Column(db.String(255), nullable=True, unique=True, default=make_code) nationality_country = db.relationship( 'Country', foreign_keys=[nationality_country_id]) residence_country = db.relationship('Country', foreign_keys=[residence_country_id]) user_category = db.relationship('UserCategory') event_roles = db.relationship('EventRole') def __init__(self, email, firstname, lastname, user_title, nationality_country_id, residence_country_id, user_gender, affiliation, department, user_disability, user_category_id, user_dateOfBirth, user_primaryLanguage, password, is_admin=False): self.email = email self.firstname = firstname self.lastname = lastname self.user_title = user_title self.nationality_country_id = nationality_country_id self.residence_country_id = residence_country_id self.user_gender = user_gender self.affiliation = affiliation self.department = department self.user_disability = user_disability self.user_category_id = user_category_id self.user_dateOfBirth = user_dateOfBirth self.user_primaryLanguage = user_primaryLanguage self.set_password(password) self.active = True self.is_admin = is_admin self.is_deleted = False self.deleted_datetime_utc = None self.verified_email = False def set_password(self, password): self.password = bcrypt.generate_password_hash(password) def deactivate(self): self.active = False def verify(self): self.verified_email = True def update_email(self, new_email): self.verified_email = False self.verify_token = make_code() self.email = new_email def delete(self): self.is_deleted = True self.deleted_datetime_utc = datetime.now() def _has_admin_role(self, event_id, admin_role_name): if self.is_admin: return True if self.event_roles is None: return False for event_role in self.event_roles: if event_role.event_id == event_id and event_role.role == admin_role_name: return True return False def is_event_admin(self, event_id): return self._has_admin_role(event_id, 'admin') def is_registration_admin(self, event_id): # An event admin is also a registration admin return self._has_admin_role( event_id, 'registration-admin') or self._has_admin_role( event_id, 'admin') def is_reviewer(self, event_id): if self.event_roles is None: return False for event_role in self.event_roles: if event_role.event_id == event_id and event_role.role == 'reviewer': return True return False def is_registration_volunteer(self, event_id): # An event admin is also a registration admin return (self._has_admin_role(event_id, 'registration-admin') or self._has_admin_role(event_id, 'admin') or self._has_admin_role(event_id, 'registration-volunteer'))
class User(db.Model): # The user model is used to manage interaction with the StarDrive system, including sign-in and access levels. Users # can be Admins, people with autism and/or their guardians wishing to manage their care and participate in studies, # as well professionals in the field of autism research and care. Anyone who wishes to use the system will have a # user account. Please note that there is a separate participant model for tracking enrollment and participation in # studies. __tablename__ = 'stardrive_user' # id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True, default=random_integer) last_updated = db.Column(db.DateTime(timezone=True), default=func.now()) email = db.Column(db.String, nullable=False, unique=True) role = db.Column(db.Enum(Role)) participants = db.relationship(Participant, back_populates="user") email_verified = db.Column(db.Boolean, nullable=False, default=False) _password = db.Column('password', db.Binary(60)) token = '' def related_to_participant(self, participant_id): for p in self.participants: if p.id == participant_id: return True return False @hybrid_property def password(self): return self._password @password.setter def password(self, plaintext): self._password = bcrypt.generate_password_hash(plaintext) def is_correct_password(self, plaintext): if not self._password: raise RestException(RestException.LOGIN_FAILURE) return bcrypt.check_password_hash(self._password, plaintext) def encode_auth_token(self): try: payload = { 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=2, minutes=0, seconds=0), 'iat': datetime.datetime.utcnow(), 'sub': self.id } return jwt.encode(payload, app.config.get('SECRET_KEY'), algorithm='HS256') except Exception as e: return e @staticmethod def decode_auth_token(auth_token): try: payload = jwt.decode(auth_token, app.config.get('SECRET_KEY'), algorithms='HS256') return payload['sub'] except jwt.ExpiredSignatureError: raise RestException(RestException.TOKEN_EXPIRED) except jwt.InvalidTokenError: raise RestException(RestException.TOKEN_INVALID) def get_contact(self): for p in self.participants: if p.contact: return { 'name': p.get_name(), 'relationship': p.relationship.name, 'contact': p.contact }
class User(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(64), unique=True) name = db.Column(db.String(64)) password_hash = db.deferred(db.Column(db.String(128))) major = db.Column(db.String(128)) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) headline = db.Column(db.String(32), nullable=True) about_me = db.deferred(db.Column(db.Text, nullable=True)) about_me_html = db.deferred(db.Column(db.Text, nullable=True)) avatar = db.Column(db.String(128)) member_since = db.Column(db.DateTime(), default=datetime.utcnow) @property def password(self): raise AttributeError('password is not readable attribute') @password.setter def password(self, password): self.password_hash = generate_password_hash(password) def verify_password(self, password): return check_password_hash(self.password_hash, password) def __init__(self, **kwargs): super(User, self).__init__(**kwargs) if self.role is None: if self.email.lower() == current_app.config['FLASKY_ADMIN'].lower( ): self.role = Role.query.filter_by(permissions=0x1ff).first() if self.role is None: self.role = Role.query.filter_by(default=True).first() self.member_since = datetime.now() def can(self, permissions): return self.role is not None and \ (self.role.permissions & permissions) == permissions def is_administrator(self): return self.can(Permission.ADMINISTER) logs = db.relationship('Log', backref=db.backref('user', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan') comments = db.relationship('Comment', backref=db.backref('user', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan') def __repr__(self): return '<User %r>' % self.email def borrowing(self, book): return self.logs.filter_by(book_id=book.id, returned=0).first() def can_borrow_book(self): return self.logs.filter( Log.returned == 0, Log.return_timestamp < datetime.now()).count() == 0 def borrow_book(self, book): if self.logs.filter(Log.returned == 0, Log.return_timestamp < datetime.now()).count() > 0: return False, u"Unable to borrow,You have not returned borrowed books" if self.borrowing(book): return False, u'You have already borrowed the book' if not book.can_borrow(): return False, u'This book is in demand, We do not have the collection,Please wait for someone to return' db.session.add(Log(self, book)) return True, u'Book is successfully added %s' % book.title def return_book(self, log): if log.returned == 1 or log.user_id != self.id: return False, u'Could not find the record' log.returned = 1 log.return_timestamp = datetime.now() db.session.add(log) return True, u'Returned the book %s' % log.book.title def avatar_url(self, _external=False): if self.avatar: avatar_json = json.loads(self.avatar) if avatar_json['use_out_url']: return avatar_json['url'] else: return url_for('_uploads.uploaded_file', setname=avatars.name, filename=avatar_json['url'], _external=_external) else: return url_for('static', filename='img/avatar.png', _external=_external) @staticmethod def on_changed_about_me(target, value, oldvalue, initiaor): allowed_tags = [ 'a', 'abbr', 'acronym', 'b', 'blockquate', 'code', 'em', 'i', 'li', 'ol', 'pre', 'strong', 'ul', 'h1', 'h2', 'h3', 'p' ] target.about_me_html = bleach.linkify( bleach.clean(markdown(value, output_format='html'), tags=allowed_tags, strip=True))
class User(UserMixin, db.Model): """ 因为继承了UserMixin类, 自动继承里面的属性和方法: Flask-Login 提供了一个 UserMixin 类,包含常用方法的默认实现,且能满足大多数需求。 1). is_authenticated 用户是否已经登录? 2). is_active 是否允许用户登录?False代表用户禁用 3). is_anonymous 是否匿名用户? 4). get_id() 返回用户的唯一标识符 """ __tablename__ = 'users' # 自定义数据表的表名 id = db.Column(db.Integer, primary_key=True, autoincrement=True) username = db.Column(db.String(100), unique=True, nullable=False) password_hash = db.Column(db.String(200), nullable=True) email = db.Column(db.String(50)) phone = db.Column(db.String(20)) # db.Boolean是布尔类型, 值只能是True或者False。 confirmed = db.Column(db.Boolean, default=False) # 账户是否已经确认 # 新添加的用户资料 name = db.Column(db.String(64)) # 用户的真实姓名 location = db.Column(db.String(64)) # 所在地 about_me = db.Column(db.Text()) # 自我介绍 # 注册日期 # default 参数可以接受函数作为默认值, # 所以每次生成默认值时,db.Column() 都会调用指定的函数。 create_time = db.Column(db.DateTime, default=datetime.utcnow) # 最后访问日期 last_seen = db.Column(db.DateTime(), default=datetime.utcnow) # 外键关联 role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) # 反向引用: 1). User添加属性todos 2). Todo添加属性user todos = db.relationship('Todo', backref='user') # 反向引用: 1). User添加属性categories 2). Category添加属性user categories = db.relationship('Category', backref='user') @property def password(self): raise AttributeError('password is not a readable attribute') @password.setter def password(self, password): # generate_password_hash(password, method= pbkdf2:sha1 , salt_length=8):密码加密的散列值。 self.password_hash = generate_password_hash(password) def verify_password(self, password): # check_password_hash(hash, password) :密码散列值和用户输入的密码是 return check_password_hash(self.password_hash, password) def generate_confirmation_token(self, expire=3600): """生成一个令牌,有效期默认为一小时。""" # secret_key = "westos" s = TimedJSONWebSignatureSerializer(current_app.config['SECRET_KEY'], expire) return s.dumps({'confirm': self.id}) def confirm(self, token): """ http://127.0.0.1:8000/auth/confirm/hdhewufdiheryiufhyruiiiiiiigyuhgh :param token: :return: """ s = TimedJSONWebSignatureSerializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) # {'confirm': 1} except Exception as e: return False else: self.confirmed = True db.session.add(self) db.session.commit() return True def ping(self): """刷新用户的最后访问时间""" self.last_seen = datetime.utcnow() db.session.add(self) def __repr__(self): return "<User: %s>" % (self.username)
class User(db.Model, UserMixin): __tablename__ = 'users' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(100), nullable=False) second_name = db.Column(db.String(100), nullable=False) last_name = db.Column(db.String(100), nullable=False) username = db.Column(db.String(50), nullable=False, unique=True) email = db.Column(db.String(100)) phone = db.Column(db.String(50)) internal_phone = db.Column(db.String(50)) password_hash = db.Column(db.String(100), nullable=False) description = db.Column(db.String(255)) created_on = db.Column(db.DateTime(), default=datetime.now) updated_on = db.Column(db.DateTime(), default=datetime.now, onupdate=datetime.now) department_id = db.Column(db.Integer(), db.ForeignKey('departments.id'), nullable=False) role_id = db.Column(db.Integer(), db.ForeignKey('roles.id'), nullable=False) position_id = db.Column(db.Integer(), db.ForeignKey('positions.id'), nullable=False) orders = db.relationship('Order', backref='user') notes = db.relationship('Note', backref='user') consultations = db.relationship('Consultation', backref='user') theme_consultations = db.relationship('ThemeConsultation', backref='user') recommendations = db.relationship('Recommendation', backref='user') versions = db.relationship('Version', backref='user') performer = db.relationship('GroupOrder', backref='user_performer') def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, password): return check_password_hash(self.password_hash, password) @property def is_administrator(self): if self.role.name == 'admin': return True @property def is_moderator(self): if self.role.name in ['moderator', 'admin']: return True @property def is_speaker_consultations(self): if self.role.name in ['speaker_consultations', 'moderator', 'admin']: return True @property def is_user(self): if self.role.name == 'user': return True @property def full_name(self): return '{} {} {}'.format(self.last_name, self.name, self.second_name) def __repr__(self): return "<{}:{}>".format(self.id, self.username)
class DeRegDetails(db.Model): """Database model for deregdetails table.""" __tablename__ = 'deregdetails' id = db.Column(db.Integer, primary_key=True) reviewer_id = db.Column(db.String(64), nullable=True) reviewer_name = db.Column(db.String(64), nullable=True) file = db.Column(db.String(30)) device_count = db.Column(db.Integer, nullable=False) reason = db.Column(db.Text, nullable=False) user_id = db.Column(db.String(64), nullable=False) user_name = db.Column(db.String) tracking_id = db.Column(db.String(64)) created_at = db.Column(db.DateTime(timezone=False), default=db.func.now()) updated_at = db.Column(db.DateTime(timezone=False), onupdate=db.func.now(), default=db.func.now()) processing_status = db.Column(db.Integer, db.ForeignKey('status.id')) report_status = db.Column(db.Integer, db.ForeignKey('status.id')) status = db.Column(db.Integer, db.ForeignKey('status.id')) summary = db.Column(db.UnicodeText) report = db.Column(db.String) invalid_imeis_file = db.Column(db.String()) comments = db.relationship('DeRegComments', backref='deregdetails', passive_deletes=True, lazy=True) documents = db.relationship('DeRegDocuments', backref='deregdetails', passive_deletes=True, lazy=True) devices = db.relationship('DeRegDevice', backref='deregdetails', passive_deletes=True, lazy=True) def __init__(self, args, tracking_id): """Constructor.""" status_id = Status.get_status_id('New Request') self.file = args.get('file') self.device_count = args.get('device_count') self.user_id = args.get('user_id') self.user_name = args.get('user_name') self.reason = args.get('reason') self.tracking_id = tracking_id self.status = status_id self.processing_status = status_id self.report_status = status_id @classmethod def create_index(cls, engine): """ Create Indexes for De-Registration detail table class. """ # device_count_index = db.Index('dereg_device_count', cls.device_count) # device_count_index.create(bind=engine) # tracking_id_index = db.Index('dereg_tracking_id', cls.tracking_id) # tracking_id_index.create(bind=engine) status_index = db.Index('dereg_status', cls.status, postgresql_concurrently=True) status_index.create(bind=engine) # processing_status_index = db.Index('dereg_processing_status', cls.processing_status) # processing_status_index.create(bind=engine) # report_status_index = db.Index('dereg_report_status', cls.report_status) # report_status_index.create(bind=engine) # created_at_index = db.Index('dereg_created_at', cls.created_at) # created_at_index.create(bind=engine) # updated_at_index = db.Index('dereg_updated_at', cls.updated_at) # updated_at_index.create(bind=engine) def save(self): """Save current model state to the table.""" try: db.session.add(self) db.session.flush() except Exception: db.session.rollback() raise Exception def save_with_commit(self): """Save and commit current model state to the table.""" try: db.session.add(self) db.session.commit() except Exception: db.session.rollback() raise Exception @classmethod def create(cls, args, tracking_id): """Add new request data to the table.""" reg_request = cls(args, tracking_id) status_id = Status.get_status_id('New Request') reg_request.status = status_id reg_request.save() return reg_request @staticmethod def exists(request_id): """Method to check weather the request exists or not.""" return db.session.query( exists() .where(DeRegDetails.id == request_id)) \ .scalar() @staticmethod def un_assign_request(request_id): """Un-assign a request.""" request = DeRegDetails.get_by_id(request_id) request.reviewer_id = None request.reviewer_name = None request.status = 3 DeRegDetails.commit_case_changes(request) @classmethod def get_by_id(cls, dereg_details_id): """Get a request details by ID.""" return DeRegDetails.query.filter_by(id=dereg_details_id).first() @classmethod def get_all(cls): """Get all the data from the table.""" return DeRegDetails.query.order_by( DeRegDetails.created_at.desc()).all() def update_status(self, status): """Update current status of the request.""" self.status = Status.get_status_id(status) self.save() def update_processing_status(self, status): """Update current processing status of the request.""" try: self.processing_status = Status.get_status_id(status) self.save() except Exception: raise Exception def update_summary(self, summary): """Update compliance summary of the request.""" self.summary = json.dumps({'summary': summary}) self.save() def update_report_file(self, filename): """Update report file name column.""" self.report = filename self.save() def update_report_status(self, status): """Updates report status of the requests.""" self.report_status = Status.get_status_id(status) self.save() @staticmethod def curate_args(request): """Curate http request args.""" args = request.form.to_dict() file = request.files.get('file') if file: args.update({'file': file.filename}) return args @classmethod def get_update_status(cls, status): """Get updated status of request.""" if status in ['Pending Review', 'Information Requested']: return Status.get_status_id('Pending Review') else: return None @classmethod def is_update_allowed(cls, status): """Check if updating the request is allowed or not.""" restricted_status = ['In Review', 'Approved', 'Rejected', 'Closed'] if status in restricted_status: return False else: return True @classmethod def close(cls, dereg_details): """Close currently active request.""" closed = Status.get_status_id('Closed') if dereg_details.status == closed: return {'message': 'The request is already closed'} else: dereg_details.status = closed dereg_details.save_with_commit() return dereg_details @classmethod def update(cls, args, dereg_details, file): """Update current request details.""" try: status = Status.get_status_type(dereg_details.status) processing_required = True if file else False if cls.is_update_allowed(status): if 'device_count' in args: dereg_details.device_count = args.get('device_count') if 'file' in args: dereg_details.file = args.get('file') if 'reason' in args: dereg_details.reason = args.get('reason') if processing_required: new_status_id = Status.get_status_id('New Request') dereg_details.processing_status = new_status_id dereg_details.report_status = new_status_id dereg_details.summary = None dereg_details.report = None # dereg_details.status = cls.get_update_status(status) or dereg_details.status dereg_details.save_with_commit() return dereg_details except Exception: raise Exception @classmethod def add_comment(cls, section, comment, user_id, user_name, status, request_id): """Method to add comment on request.""" request = cls.get_by_id(request_id) DeRegComments.add(section, comment, user_id, user_name, status, request.id) try: db.session.add(request) db.session.commit() except Exception: db.session.rollback() raise Exception @classmethod def update_reviewer_id(cls, reviewer_id, reviewer_name, request_id, status=4): """Update reviewer id of the request. Expected default behavior is to change request status to In-Review. """ if reviewer_id and request_id: request = cls.get_by_id(request_id) # if request is already in pending state if request.status == 3: request.reviewer_id = reviewer_id request.reviewer_name = reviewer_name request.status = status try: db.session.add(request) db.session.commit() return True except Exception: db.session.rollback() raise Exception else: return False # noinspection SqlDialectInspection,SqlNoDataSourceInspection @staticmethod def get_imeis_count(user_id): """Method to return total imeis count of user requests.""" pending_query = """SELECT SUM(device_count) as pending_count FROM public.deregdevice WHERE dereg_details_id IN ( SELECT id FROM public.deregdetails WHERE (status = '3' or status = '4') AND user_id = '{0}' )""".format( user_id) approved_query = """SELECT SUM(device_count) as approved_count FROM public.deregdevice WHERE dereg_details_id IN ( SELECT id FROM public.deregdetails WHERE status = 6 AND user_id = '{0}' )""".format( user_id) rejected_query = """SELECT SUM(device_count) as rejected_count FROM public.deregdevice WHERE dereg_details_id IN ( SELECT id FROM public.deregdetails WHERE status = '7' AND user_id = '{0}' )""".format( user_id) try: pending_requests = db.engine.execute( pending_query).fetchone().pending_count approved_requests = db.engine.execute( approved_query).fetchone().approved_count rejected_requests = db.engine.execute( rejected_query).fetchone().rejected_count return { 'pending_registration': pending_requests if pending_requests is not None else 0, 'registered': approved_requests if approved_requests is not None else 0, 'not_registered': rejected_requests if rejected_requests is not None else 0 } except Exception as e: app.logger.error( 'exception encountered in deregdetails.get_imeis_count() see below:' ) app.logger.exception(e) return { 'pending_registration': 0, 'registered': 0, 'not_registered': 0 } @classmethod def get_section_by_state(cls, request_id, section_type): """Method to return most recent state of a section.""" request = DeRegDetails.get_by_id(request_id) section_data = DeRegComments.get_all_by_section_type( request.id, section_type) if len(section_data) > 0: section_status = section_data[0].status section_type = section_type comments = [] for sec in section_data: comment = { 'user_id': sec.user_id, 'user_name': sec.user_name, 'comment': sec.comment, 'datetime': sec.added_at } comments.append(comment) return { 'section_type': section_type, 'section_status': section_status, 'comments': comments } else: return { 'section_type': section_type, 'section_status': None, 'comments': None } @staticmethod def commit_case_changes(request): """Commit changes to the case object.""" try: db.session.add(request) db.session.commit() except Exception: db.session.rollback() raise Exception @staticmethod def get_normalized_imeis(request): """Method to get normalized imeis of the request.""" normalized_imeis = [] devices = request.devices for device in devices: device_imeis = device.dereg_device_imei for imei in device_imeis: normalized_imeis.append(imei.norm_imei) return normalized_imeis
class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(64), unique=True, index=True) username = db.Column(db.String(64), unique=True, index=True) password_hash = db.Column(db.String(128)) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) confirmed = db.Column(db.Boolean, default=False) name = db.Column(db.String(64)) location = db.Column(db.String(64)) about_me = db.Column(db.Text()) member_since = db.Column(db.DateTime(), default=datetime.utcnow, verbose_name="记住时间") last_seen = db.Column(db.DateTime(), default=datetime.utcnow, verbose_name="登录时间") avatar_hash = db.Column(db.String(32), verbose_name="头像") articles = db.relationship('Article', backref='author', lazy='dynamic') followed = db.relationship('Follow', foreign_keys=[Follow.follower_id], backref=db.backref('follower', lazy='joined'), lazy='dynamic', cascade='all,delete-orphan') followers = db.relationship('Follow', foreign_keys=[Follow.followed_id], backref=db.backref('followed', lazy='joined'), lazy='dynamic', cascade='all,delete-orphan') comments = db.relationship('Comment', backref='author', lazy='dynamic') def __init__(self, **kwargs): super(User, self).__init__(**kwargs) # 给用户赋予角色 if self.role is None: # 若email是管理员的邮箱则赋予管理员角色 if self.email == current_app.config['ADMIN'][0]: self.role = Role.query.filter_by(permissions=0xff).first() else: self.role = Role.query.filter_by(default=True).first() if self.email is not None and self.avatar_hash is None: self.avatar_hash = hashlib.md5( self.email.encode('utf-8')).hexdigest() @property def password(self): raise AttributeError('password is not a readable attribute') @password.setter def password(self, password): """ 设置密码 :param password: 密码 :return: """ self.password_hash = generate_password_hash(password) def verify_password(self, password): """ 验证密码 :param password: 密码 :return: bool """ return check_password_hash(self.password_hash, password) def generate_confirmation_token(self, expiration=3600): """ 生成token :param expiration: 有效时间 :return: str """ s = Serializer(current_app.config["SECRET_KEY"], expiration) return s.dumps({'confirm': self.id}) def confirm(self, token): """ 账号验证 :param token: token :return: bool """ s = Serializer(current_app.config["SECRET_KEY"]) try: data = s.loads(token) except Exception as e: return False if data.get('confirm') != self.id: return False self.confirmed = True db.session.add(self) return True def can(self, permissions): """ 角色验证 :param permissions: 权限(int) :return: bool """ # 进行and运算再对比验证 return self.role is not None and \ (self.role.permissions & permissions) == permissions def is_administrator(self): """ 管理员权限 :return: bool """ return self.can(Permission.ADMINISTER) def ping(self): """ 用户一登录就写入登录时间 :return: """ self.last_seen = datetime.utcnow() db.session.add(self) def gravatar(self, size=100, default='identicon', rating='g'): """ 生成头像 :param size: 图片大小(像素) :param default: 默认图片生成方式 :param rating: 图片级别 :return: URL """ if request.is_secure: url = 'https://secure.gravatar.com/avator' else: url = 'http://www.gravatar.com/avatar' hash = self.avatar_hash or hashlib.md5( self.email.encode('utf-8')).hexdigest() params = { "url": url, "hash": hash, "size": size, "default": default, "rating": rating } return '{url}/hash?s={size}&d={default}&r={rating}'.format(**params) @staticmethod def generate_fake(count=100): """ 生成假用户 :param count: 数量 :return: """ from sqlalchemy.exc import IntegrityError from random import seed import forgery_py seed() for i in range(count): u = User(email=forgery_py.internet.email_address(), username=forgery_py.internet.user_name(True), password=forgery_py.lorem_ipsum.word(), confirmed=True, name=forgery_py.name.full_name(), location=forgery_py.address.city(), about_me=forgery_py.lorem_ipsum.sentence(), member_since=forgery_py.date.date(True)) db.session.add(u) try: db.session.commit() except IntegrityError: db.session.rollback() def follow(self, user): if not self.is_following(user): f = Follow(follower=self, followed=user) db.session.add(f) def unfollow(self, user): f = self.followed.filter_by(followed_id=user.id).first() if f: db.session.delete(f) def is_following(self, user): return self.followed.filter_by(followed_id=user.id).first() is not None def is_followed_by(self, user): return self.followers.filter_by( follower_id=user.id).first() is not None @property def followed_articles(self): return Article.query.join(Follow, Follow.followed_id == Article.author_id) \ .filter(Follow.follower_id == self.id) @staticmethod def add_self_follows(): for user in User.query.all(): if not user.is_following(user): print(user.username) user.follow(user) db.session.add(user) db.session.commit() def __repr__(self): return self.username
class RefreshToken(db.Model, BaseMixin): __tablename__ = "refresh_token" token = db.Column(db.String(256), primary_key=True) issued_at = db.Column(db.DateTime(), default=datetime.utcnow()) expires_at = db.Column(db.DateTime(), default=datetime.utcnow() + timedelta(days=7)) mapped_token = db.Column(db.String(512)) user_id = db.Column(db.String(256)) revoked = db.Column(db.Boolean(), default=False) def __repr__(self): return f"<Token {self.token}>" def check_user(self, user_id): return self.user_id == user_id def has_expired(self): return self.expires_at < datetime.utcnow() def is_valid(self): return not (self.has_expired() or self.revoked) def is_compromised(self, access_token): return self.mapped_token != access_token @classmethod def is_token_valid(cls, token): _token = cls.first(token=token) return _token is not None and _token.is_valid() @classmethod def revoke_token(cls, token="", instance=None): _token = None if instance is not None: _token = instance else: _token = cls.first(token=token) if _token is not None and _token.is_valid(): _token.revoked = True @classmethod def revoke_user_tokens(cls, user_id="", refresh_token=""): user = user_id if refresh_token: token = cls.first(token=refresh_token) if token is None: return user = token.user_id elif user_id: user = user_id table = cls.__table__ table.update().where( and_(table.c.user_id == user, table.c.expires_at > datetime.utcnow(), table.c.revoked == False)).values(revoked=True)
class Medication(db.Model): __tablename__ = "medication" __label__ = "Medication" __no_export__ = True # This will be transferred as a part of a parent class symptom_other_hide_expression = '!(model.symptom && (model.symptom === "symptomOther"))' id = db.Column(db.Integer, primary_key=True) last_updated = db.Column(db.DateTime(timezone=True), default=func.now()) supports_questionnaire_id = db.Column( "supports_questionnaire_id", db.Integer, db.ForeignKey("supports_questionnaire.id"), ) symptom = db.Column( db.String, info={ "display_order": 1, "type": "select", "template_options": { "label": "Select symptom", "placeholder": "Please select", "required": True, "options": [ {"value": "symptomAnxiety", "label": "Anxiety"}, {"value": "symptomDepression", "label": "Depression"}, {"value": "symptomInsomnia", "label": "Insomnia"}, {"value": "symptomADHD", "label": "ADHD"}, {"value": "symptomOther", "label": "Other"}, ], }, } ) symptom_other = db.Column( db.String, info={ "display_order": 1.2, "type": "textarea", "template_options": { "label": "Enter symptom", "appearance": "standard", "required": True, }, "hide_expression": symptom_other_hide_expression, "expression_properties": { "template_options.required": '!' + symptom_other_hide_expression } }, ) name = db.Column( db.String, info={ "display_order": 2, "type": "textarea", "template_options": { "label": "Name of Medication (if known)", }, }, ) notes = db.Column( db.String, info={ "display_order": 3, "type": "textarea", "template_options": { "label": "Notes on use and/or issues with medication", "required": False, }, }, ) def get_field_groups(self): info = { "symptom_group": { "fields": ["symptom", "symptom_other"], "display_order": 1, "wrappers": ["card"], "template_options": { "label": "" }, "expression_properties": { "template_options.label": { "RELATIONSHIP_SPECIFIC": { "self_participant": '"Symptom for which you are taking medication"', "self_guardian": '"Symptom for which you are taking medication"', "self_professional": '"Symptom for which you are taking medication"', "dependent": '"Symptom for which " + (formState.preferredName || "your child") + " is taking medication"' } } }, } } return info
class IdentificationQuestionnaire(db.Model): __tablename__ = "identification_questionnaire" __label__ = "Identification" __question_type__ = ExportService.TYPE_IDENTIFYING __estimated_duration_minutes__ = 5 relationship_to_participant_other_hide_expression = '!(model.relationship_to_participant && (model.relationship_to_participant === "other"))' id = db.Column(db.Integer, primary_key=True) last_updated = db.Column(db.DateTime(timezone=True), default=func.now()) time_on_task_ms = db.Column(db.BigInteger, default=0) participant_id = db.Column("participant_id", db.Integer, db.ForeignKey("stardrive_participant.id")) user_id = db.Column("user_id", db.Integer, db.ForeignKey("stardrive_user.id")) relationship_to_participant = db.Column( db.String, info={ "RELATIONSHIP_REQUIRED": ['dependent'], "display_order": 1.1, "type": "radio", "template_options": { "required": False, "label": "", "options": [ { "value": "bioMother", "label": "Biological mother" }, { "value": "bioFather", "label": "Biological father" }, { "value": "adoptMother", "label": "Adoptive mother" }, { "value": "adoptFather", "label": "Adoptive father" }, { "value": "other", "label": "Other" }, ], }, }, ) relationship_to_participant_other = db.Column( db.String, info={ "RELATIONSHIP_REQUIRED": ['dependent'], "display_order": 1.2, "type": "input", "template_options": { "label": "Enter your relationship", "required": True, }, "hide_expression": relationship_to_participant_other_hide_expression, "expression_properties": { "template_options.required": '!' + relationship_to_participant_other_hide_expression } }, ) first_name = db.Column( db.String, info={ "display_order": 2, "type": "input", "template_options": { "label": "First name", "required": True }, }, ) middle_name = db.Column( db.String, info={ "display_order": 3, "type": "input", "template_options": { "label": "Middle name" }, "hide_expression": 'model.no_middle_name', "expression_properties": { "template_options.required": '!model.no_middle_name' } }, ) no_middle_name = db.Column( db.Boolean, info={ "display_order": 3.5, "type": "checkbox", "defaultValue": False, "template_options": { "label": "If NO Middle Name click here", "required": False, }, }, ) last_name = db.Column( db.String, info={ "display_order": 4, "type": "input", "template_options": { "label": "Last name", "required": True }, }, ) is_first_name_preferred = db.Column( db.Boolean, info={ "display_order": 5, "type": "radio", "template_options": { "required": False, "label": { "RELATIONSHIP_SPECIFIC": { "self_participant": "Is this your preferred name?", "self_guardian": "Is this your preferred name?", "self_professional": "Is this your preferred name?", "self_interested": "Is this your preferred name?", "dependent": "Is this your child\'s preferred name?", } }, "options": [ { "value": True, "label": "Yes" }, { "value": False, "label": "No" }, ], }, }, ) nickname = db.Column( db.String, info={ "display_order": 6, "type": "input", "template_options": { "label": "Nickname", "required": False, }, "hide_expression": "model.is_first_name_preferred", }, ) birthdate = db.Column( db.DateTime, info={ "display_order": 7, "type": "datepicker", "template_options": { "required": True, "label": { "RELATIONSHIP_SPECIFIC": { "self_participant": "Your date of birth", "self_guardian": "Your date of birth", "self_professional": "Your date of birth", "self_interested": "Your date of birth", "dependent": "Your child\'s date of birth", } }, }, }, ) birth_city = db.Column( db.String, info={ "display_order": 8, "type": "input", "template_options": { "required": True, "label": { "RELATIONSHIP_SPECIFIC": { "self_participant": "Your city/municipality of birth", "self_guardian": "Your city/municipality of birth", "self_professional": "Your city/municipality of birth", "self_interested": "Your city/municipality of birth", "dependent": "Your child\'s city/municipality of birth", } }, }, }, ) birth_state = db.Column( db.String, info={ "display_order": 9, "type": "input", "template_options": { "required": True, "label": { "RELATIONSHIP_SPECIFIC": { "self_participant": "Your state of birth", "self_guardian": "Your state of birth", "self_professional": "Your state of birth", "self_interested": "Your state of birth", "dependent": "Your child\'s state of birth", } }, }, }, ) is_english_primary = db.Column( db.Boolean, info={ "display_order": 10, "type": "radio", "template_options": { "required": False, "label": { "RELATIONSHIP_SPECIFIC": { "self_participant": "Is your primary language English?", "self_guardian": "Is your primary language English?", "self_professional": "Is your primary language English?", "self_interested": "Is your primary language English?", "dependent": "Is your child\'s primary language English?", } }, "options": [ { "value": True, "label": "Yes" }, { "value": False, "label": "No" }, ], }, }, ) def get_name(self): if not self.is_first_name_preferred: return self.nickname else: return self.first_name def get_field_groups(self): return { "relationship": { "RELATIONSHIP_REQUIRED": ['dependent'], "fields": [ "relationship_to_participant", "relationship_to_participant_other", ], "display_order": 0, "wrappers": ["card"], "template_options": { "label": "Your relationship to your child or the person with autism on whom you are providing information:" }, }, "intro": { "fields": [], "display_order": 1, "wrappers": ["help"], "template_options": { "description": { "RELATIONSHIP_SPECIFIC": { "self_participant": "Please answer the following questions about yourself (* indicates required response):", "self_guardian": "Please answer the following questions about yourself (* indicates required response):", "self_professional": "Please answer the following questions about yourself (* indicates required response):", "dependent": "Please answer the following questions about your child or the person with autism on whom you are providing information", } } }, }, }
class Posts(db.Model): __tablename__ = 'posts' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String()) email = db.Column(db.String()) tel = db.Column(db.String()) social_account = db.Column(db.String()) user_uid = db.Column(db.String()) post_type = db.Column(db.String()) is_found = db.Column(db.Boolean) topic = db.Column(db.String()) pic_url = db.Column(db.String()) description = db.Column(db.String()) size = db.Column(db.Integer()) gender = db.Column(db.String()) breed = db.Column(db.String()) pet_type = db.Column(db.String()) color = db.Column(db.String()) address = db.Column(db.String()) province = db.Column(db.String()) missing_found_date = db.Column(db.DateTime()) created_at = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) def __repr__(self): return '<id {}>'.format(self.id) # All data in Database def detail(self): return { 'id': self.id, 'name': self.name, 'email': self.email, 'tel': self.tel, 'social_account': self.social_account, 'user_uid': self.user_uid, 'post_type': self.post_type, 'is_found': self.is_found, 'topic': self.topic, 'pic_url': self.pic_url, 'description': self.description, 'size': self.size, 'gender': self.gender, 'breed': self.breed, 'pet_type': self.pet_type, 'color': self.color, 'address': self.address, 'province': self.province, 'missing_found_date': self.format_date(self.missing_found_date), 'created_at': self.format_date(self.created_at) } # Data show only on card (short info.) def card(self): return { 'id': self.id, 'user_uid': self.user_uid, 'post_type': self.post_type, 'is_found': self.is_found, 'topic': self.topic, 'pic_url': self.pic_url, 'gender': self.gender, 'pet_type': self.pet_type, 'province': self.province, 'missing_found_date': self.format_date(self.missing_found_date) } # Date format def format_date(self, date): return date.strftime("%d/%m/%Y")
class Yara_rule(db.Model): __tablename__ = "yara_rules" id = db.Column(db.Integer, primary_key=True) creation_date = db.Column(db.DateTime(timezone=True), default=db.func.current_timestamp()) last_revision_date = db.Column(db.DateTime(timezone=True), default=db.func.current_timestamp(), onupdate=db.func.current_timestamp()) state = db.Column(db.String(32), index=True) revision = db.Column(db.Integer(unsigned=True), default=1) name = db.Column(db.String(128), index=True) category = db.Column(db.String(32), index=True) condition = db.Column(db.String(2048), index=True) strings = db.Column(db.String(30000), index=True) imports = db.Column(db.String(512)) description = db.Column(db.TEXT(), index=True) references = db.Column(db.TEXT(), index=True) active = db.Column(db.Boolean, nullable=False, default=True, index=True) eventid = db.Column(db.Integer(unsigned=True), index=True, nullable=False) _mitre_techniques = db.Column(db.String(256), index=True) _mitre_tactics = db.Column(db.String(256), index=True) tags = [] created_user_id = db.Column(db.Integer, db.ForeignKey('kb_users.id'), nullable=False) created_user = db.relationship( 'KBUser', foreign_keys=created_user_id, primaryjoin="KBUser.id==Yara_rule.created_user_id") modified_user_id = db.Column(db.Integer, db.ForeignKey('kb_users.id'), nullable=False) modified_user = db.relationship( 'KBUser', foreign_keys=modified_user_id, primaryjoin="KBUser.id==Yara_rule.modified_user_id") owner_user_id = db.Column(db.Integer, db.ForeignKey('kb_users.id'), nullable=True) owner_user = db.relationship( 'KBUser', foreign_keys=owner_user_id, primaryjoin="KBUser.id==Yara_rule.owner_user_id") comments = db.relationship( "Comments", foreign_keys=[id], primaryjoin= "and_(Comments.entity_id==Yara_rule.id, Comments.entity_type=='%s')" % (ENTITY_MAPPING["SIGNATURE"]), cascade="all,delete", uselist=True) files = db.relationship( "Files", foreign_keys=[id], primaryjoin= "and_(Files.entity_id==Yara_rule.id, Files.entity_type=='%s')" % (ENTITY_MAPPING["SIGNATURE"]), cascade="all,delete", uselist=True) history = db.relationship( "Yara_rule_history", foreign_keys=[id], primaryjoin="Yara_rule_history.yara_rule_id==Yara_rule.id", cascade="all,delete", uselist=True) test_history = db.relationship( "Yara_testing_history", foreign_keys=[id], primaryjoin="Yara_testing_history.yara_rule_id==Yara_rule.id", cascade="all,delete", uselist=True) @property def mitre_techniques(self): if self._mitre_techniques: return self._mitre_techniques.split(",") or [] return [] @property def mitre_tactics(self): if self._mitre_tactics: return self._mitre_tactics.split(",") return [] @mitre_techniques.setter def mitre_techniques(self, value): self._mitre_techniques = ",".join(value) @mitre_tactics.setter def mitre_tactics(self, value): self._mitre_tactics = ",".join(value) @property def metadata_fields(self): return db.session.query(Metadata).filter( Metadata.artifact_type == ENTITY_MAPPING["SIGNATURE"]).all() @property def metadata_values(self): return db.session.query(MetadataMapping) \ .join(Metadata, Metadata.id == MetadataMapping.metadata_id) \ .filter(Metadata.active > 0) \ .filter(Metadata.artifact_type == ENTITY_MAPPING["SIGNATURE"]) \ .filter(MetadataMapping.artifact_id == self.id) \ .all() def to_dict(self, include_yara_rule_string=None, short=False, include_relationships=True, include_metadata=True, include_tags=True, include_comments=True): yara_dict = dict( creation_date=self.creation_date.isoformat() if self.creation_date else None, last_revision_date=self.last_revision_date.isoformat() if self.last_revision_date else None, state=self.state, name=self.name, category=self.category, eventid=self.eventid, id=self.id, description=self.description, references=self.references, revision=self.revision, condition="condition:\n\t%s" % self.condition, strings="strings:\n\t%s" % self.strings if self.strings and self.strings.strip() else "", imports=self.imports, mitre_tactics=self.mitre_tactics, mitre_techniques=self.mitre_techniques, active=self.active) if include_tags: yara_dict["tags"] = tags_mapping.get_tags_for_source( self.__tablename__, self.id) if include_comments: yara_dict["comments"] = [ comment.to_dict() for comment in Comments.query.filter_by( entity_id=self.id).filter_by( entity_type=ENTITY_MAPPING["SIGNATURE"]).all() ] if include_metadata: metadata_values_dict = {} metadata_keys = Metadata.get_metadata_keys("SIGNATURE") metadata_values_dict = { m["metadata"]["key"]: m for m in [entity.to_dict() for entity in self.metadata_values] } for key in list( set(metadata_keys) - set(metadata_values_dict.keys())): metadata_values_dict[key] = {} yara_dict.update( dict(metadata=Metadata.get_metadata_dict("SIGNATURE"), metadata_values=metadata_values_dict)) if include_relationships: yara_dict["created_user"] = self.created_user.to_dict() yara_dict["modified_user"] = self.modified_user.to_dict() yara_dict["owner_user"] = self.owner_user.to_dict( ) if self.owner_user else None if not short: revisions = Yara_rule_history.query.filter_by( yara_rule_id=self.id).all() comments = Comments.query.filter_by(entity_id=self.id).filter_by( entity_type=ENTITY_MAPPING["SIGNATURE"]).all() files = Files.query.filter_by(entity_id=self.id).filter_by( entity_type=ENTITY_MAPPING["SIGNATURE"]).all() yara_dict.update( dict( comments=[comment.to_dict() for comment in comments], revisions=[ revision.to_dict(include_json=False) for revision in revisions ], files=[file.to_dict() for file in files], )) if include_yara_rule_string: yara_dict["yara_rule_string"] = Yara_rule.to_yara_rule_string( yara_dict) return yara_dict def to_revision_dict(self): dict = self.to_dict() del dict["comments"] del dict["revisions"] del dict["tags"] return dict def to_release_dict(self, metadata_cache, user_cache): return dict( creation_date=self.creation_date.isoformat(), last_revision_date=self.last_revision_date.isoformat(), state=self.state, name=self.name, category=self.category, eventid=self.eventid, id=self.id, description=self.description, references=self.references, created_user=user_cache[self.created_user_id], modified_user=user_cache[self.modified_user_id], owner_user=user_cache[self.owner_user_id] if self.owner_user_id else None, revision=self.revision, metadata=metadata_cache["SIGNATURE"][self.id]["metadata"] if metadata_cache["SIGNATURE"].get(self.id, None) and metadata_cache["SIGNATURE"][self.id].get("metadata", None) else {}, metadata_values=metadata_cache["SIGNATURE"][ self.id]["metadata_values"] if metadata_cache["SIGNATURE"].get(self.id, None) and metadata_cache["SIGNATURE"][self.id].get( "metadata_values", None) else {}, condition="condition:\n\t%s" % self.condition, strings="strings:\n\t%s" % self.strings if self.strings and self.strings.strip() else "", imports=self.imports, mitre_tactics=self.mitre_tactics, mitre_techniques=self.mitre_techniques) def __repr__(self): return '<Yara_rule %r>' % (self.id) @staticmethod def get_imports_from_string(imports_string): if not imports_string: return "" return "\n".join([ imp.strip() for imp in set( re.findall(r'^import[\t\s]+\"[A-Za-z0-9_]+\"[\t\s]*$', imports_string, re.MULTILINE)) ]) @staticmethod def to_yara_rule_string(yara_dict, include_imports=True): yr = Yara_rule() metadata_fields_to_show = [ "creation_date", "last_revision_date", "revision", "name", "category", "eventid", "description", "references", "mitre_tactics", "mitre_techniques" ] metadata_field_mapping = [ attr for attr in dir(yr) if not callable(getattr(yr, attr)) and not attr.startswith("__") ] yara_rule_text = "" if yara_dict.get("imports", None) and include_imports: yara_rule_text = yara_dict.get("imports") + "\n\n" yara_rule_text += "rule %s\n{\n\n" % (yara_dict.get("name")) yara_rule_text += "\tmeta:\n" metadata_strings = [] for field in metadata_field_mapping: if yara_dict.get( field, None ) and not "metadata" in field and field in metadata_fields_to_show: try: yara_dict[field] = re.sub("[^\x00-\x7F]", "", yara_dict[field]) except: pass if field.lower() == "references": r_val = str(yara_dict[field]).replace("\"", "'").replace( "\n", ",") elif field.lower().startswith("mitre"): r_val = ",".join(yara_dict[field]) else: r_val = str(yara_dict[field]).replace("\"", "'") metadata_strings.append( "\t\t%s = \"%s\"\n" % (field.title() if not field.lower() == "eventid" else "EventID", r_val)) try: for type_, metalist in yara_dict["metadata"].iteritems(): for meta in metalist: if meta["export_with_release"]: value = yara_dict["metadata_values"][meta["key"]]["value"] if "value" in \ yara_dict["metadata_values"][ meta["key"]] else "NA" try: value = re.sub("[^\x00-\x7F]", "", value) except: pass metadata_strings.append( "\t\t%s = \"%s\"\n" % (meta["key"], str(value).replace("\"", "'"))) except Exception as e: pass yara_rule_text += "".join(sorted(metadata_strings)) formatted_strings = "" if yara_dict["strings"] and yara_dict["strings"].strip( ) and not "strings:" in yara_dict["strings"]: formatted_strings = "\n\tstrings:\n\t\t" formatted_strings += "\n".join( [line for line in yara_dict["strings"].split("\n")]) # yara_rule_text += "\n\tstrings:\n\t\t%s" % (yara_dict["strings"]) else: if not yara_dict["strings"] or not yara_dict["strings"].strip(): formatted_strings += "" else: formatted_strings = "\n\tstrings:\n\t\t" formatted_strings += "\n".join( [line for line in yara_dict["strings"].split("\n")[1:]]) # yara_rule_text += "\n\t%s" % (yara_dict["strings"]) yara_rule_text += formatted_strings formatted_condition = "" if not "condition" in yara_dict["condition"]: formatted_condition = "\n\tcondition:\n\t\t" formatted_condition += "\n".join( [line for line in yara_dict["condition"].split("\n")]) #yara_rule_text += "\n\tcondition:\n\t\t%s\n\n}" % (yara_dict["condition"]) else: formatted_condition = "\n\tcondition:\n\t\t" formatted_condition += "\n".join( [line for line in yara_dict["condition"].split("\n")[1:]]) # yara_rule_text += "\n\t%s\n\n}" % (yara_dict["condition"]) yara_rule_text += formatted_condition + "\n}\n" yara_rule_text = Yara_rule.expand_macros(yara_rule_text) return yara_rule_text.encode("utf-8") @staticmethod def expand_macros(yara_rule_text): all_macros = macros.Macros.get_macros() tag_template = cfg_settings.Cfg_settings.get_setting( "MACRO_TAG_TEMPLATE") for m in all_macros: yara_rule_text = yara_rule_text.replace(tag_template % m['tag'], m['value']) return yara_rule_text @staticmethod def make_yara_sane(text, type_): if not text or not text.strip() or not text.strip("\t"): return "" type_ = "%s:" if not type_.endswith(":") else type_ text = re.sub("[^\x00-\x7f]", "", text) return "\n".join([ string for string in text.split("\n") if type_ not in string ]).strip() @classmethod def get_yara_rule_from_yara_dict(cls, yara_dict, metadata_field_mapping={}): condition = yara_dict["condition"] strings = yara_dict["strings"] imports = yara_dict["imports"] yara_dict = yara_dict["rule"] metadata_fields = { entity.key.lower(): entity for entity in db.session.query(Metadata).filter( Metadata.active > 0).filter(Metadata.artifact_type == ENTITY_MAPPING["SIGNATURE"]).all() } fields_to_add = [] clobber_on_import = cfg_settings.Cfg_settings.get_setting( "IMPORT_CLOBBER") try: clobber_on_import = distutils.util.strtobool(clobber_on_import) except: clobber_on_import = clobber_on_import yara_rule = Yara_rule() yara_rule.name = yara_dict["rule_name"] yara_metadata = { key.lower(): val.strip().strip("\"") for key, val in yara_dict["metadata"].iteritems() } if "metadata" in yara_dict else {} for possible_field, mapped_to in metadata_field_mapping.iteritems(): mapped_to = mapped_to.lower() possible_field = possible_field.lower() if possible_field in yara_metadata.keys(): field = yara_metadata[possible_field] if not mapped_to in [ "confidence", "eventid" ] else int(yara_metadata[possible_field]) if mapped_to in ["last_revision_date", "creation_date"]: try: field = parser.parse(field) except: field = datetime.datetime.now() ## If the eventid already exists. Skip it. if possible_field == "eventid": existing_yara_rule = Yara_rule.query.filter_by( eventid=field).first() if existing_yara_rule: if not clobber_on_import: continue else: db.session.query(Yara_testing_history).filter_by( yara_rule_id=existing_yara_rule.id).delete() db.session.query(Yara_rule_history).filter_by( yara_rule_id=existing_yara_rule.id).delete() db.session.query(Yara_rule).filter_by( id=existing_yara_rule.id).delete() if mapped_to in cls.__table__.columns.keys(): setattr(yara_rule, mapped_to, field) else: if mapped_to in metadata_fields.keys(): to_field = metadata_fields[mapped_to] fields_to_add.append( MetadataMapping(value=field, metadata_id=to_field.id)) # yara_rule.condition = " ".join(yara_dict["condition_terms"]) # yara_rule.strings = "\n".join( # ["%s = %s %s" % (r["name"], r["value"], " ".join(r["modifiers"]) if "modifiers" in r else "") for r in # yara_dict["strings"]]) yara_rule.condition = "\n" + condition yara_rule.strings = "\n" + strings if strings else "" yara_rule.imports = imports for key, val in yara_rule.__dict__.items(): if not key.startswith('_') and type(val) in [str, unicode]: val.decode("ascii") if not yara_rule.category: yara_rule.category = CfgCategoryRangeMapping.DEFAULT_CATEGORY return yara_rule, fields_to_add
class DemographicsQuestionnaire(db.Model): __tablename__ = "demographics_questionnaire" __label__ = "Demographics" __question_type__ = ExportService.TYPE_SENSITIVE __estimated_duration_minutes__ = 8 gender_identity_other_hide_expression = '!(model.gender_identity && (model.gender_identity === "genderOther"))' race_ethnicity_other_hide_expression = '!(model.race_ethnicity && model.race_ethnicity.includes("raceOther"))' id = db.Column(db.Integer, primary_key=True) last_updated = db.Column(db.DateTime(timezone=True), default=func.now()) time_on_task_ms = db.Column(db.BigInteger, default=0) participant_id = db.Column("participant_id", db.Integer, db.ForeignKey("stardrive_participant.id")) user_id = db.Column("user_id", db.Integer, db.ForeignKey("stardrive_user.id")) birth_sex = db.Column( db.String, info={ "display_order": 1, "type": "radio", "template_options": { "required": True, "label": { "RELATIONSHIP_SPECIFIC": { "self_participant": "Your sex at birth", "self_guardian": "Your sex at birth", "self_professional": "Your sex at birth" } }, "options": [ { "value": "male", "label": "Male" }, { "value": "female", "label": "Female" }, { "value": "intersex", "label": "Intersex" }, ], }, "expression_properties": { "template_options.label": { "RELATIONSHIP_SPECIFIC": { "dependent": '(formState.preferredName || "your child") + "\'s" ' '+ " sex at birth"', } }, }, }, ) gender_identity = db.Column( db.String, info={ "display_order": 2.1, "type": "select", "template_options": { "required": True, "options": [ { "value": "male", "label": "Male" }, { "value": "female", "label": "Female" }, { "value": "intersex", "label": "Intersex" }, { "value": "transgender", "label": "Transgender" }, { "value": "genderOther", "label": "Other" }, { "value": "no_answer", "label": "Prefer not to answer" }, ], "label": "Your current gender identity:", }, "expression_properties": { "template_options.label": { "RELATIONSHIP_SPECIFIC": { "dependent": '(formState.preferredName || "Your child") + "\'s current gender identity"', } }, "template_options.placeholder": { "RELATIONSHIP_SPECIFIC": { "dependent": '"Please select " + (formState.preferredName || "your child") + "\'s gender"', } } }, }, ) gender_identity_other = db.Column( db.String, info={ "display_order": 2.2, "type": "input", "template_options": { "label": "Enter gender identity", "appearance": "standard", "required": True, }, "hide_expression": gender_identity_other_hide_expression, "expression_properties": { "template_options.required": '!' + gender_identity_other_hide_expression } }, ) race_ethnicity = db.Column( db.ARRAY(db.String), info={ "display_order": 3.1, "type": "multicheckbox", "template_options": { "label": "Race/Ethnicity", "type": "array", "required": True, "options": [ { "value": "raceBlack", "label": "Black / African / African American" }, { "value": "raceAsian", "label": "Asian / Asian American" }, { "value": "raceWhite", "label": "White / Caucasian" }, { "value": "raceHispanic", "label": "Hispanic / Latin(o / a)" }, { "value": "raceNative", "label": "Native American / Alaskan Native" }, { "value": "racePacific", "label": "Pacific Islander" }, { "value": "raceNoAnswer", "label": "Prefer not to answer" }, { "value": "raceOther", "label": "Other" }, ], "description": "(select all that apply)" }, "validators": { "required": "multicheckbox" }, }, ) race_ethnicity_other = db.Column( db.String, info={ "display_order": 3.2, "type": "input", "template_options": { "label": "Enter race/ethnicity", "appearance": "standard", "required": True, }, "hide_expression": race_ethnicity_other_hide_expression, "expression_properties": { "template_options.required": '!' + race_ethnicity_other_hide_expression } }, ) def get_field_groups(self): return { "gender": { "fields": ["birth_sex", "gender_identity", "gender_identity_other"], "display_order": 2, "wrappers": ["card"], "template_options": { "label": "Gender" } }, "race": { "fields": ["race_ethnicity", "race_ethnicity_other"], "display_order": 3, "wrappers": ["card"], "template_options": { "label": { "RELATIONSHIP_SPECIFIC": { "self_participant": "What is your race/ethnicity?", "self_guardian": "What is your race/ethnicity?", "self_professional": "What is your race/ethnicity?", } } }, "expression_properties": { "template_options.label": { "RELATIONSHIP_SPECIFIC": { "dependent": '"What is " + (formState.preferredName || "your child") + "\'s" + ' '" race/ethnicity?"', } }, }, }, }
class Yara_testing_history(db.Model): TEST_TYPE_POSITIVE = "POSITIVE" TEST_TYPE_NEGATIVE = "NEGATIVE" STATUS_SUBMITTED = "SUBMITTED" STATUS_RUNNING = "RUNNING" STATUS_COMPLETE = "COMPLETE" STATUS_ERROR = "ERROR" __tablename__ = "yara_testing_history" id = db.Column(db.Integer, primary_key=True) test_type = db.Column(db.String(32), nullable=False) yara_rule_id = db.Column(db.Integer, db.ForeignKey("yara_rules.id"), nullable=False) revision = db.Column(db.Integer(unsigned=True), nullable=False) start_time = db.Column(db.DateTime(timezone=True), nullable=False) end_time = db.Column(db.DateTime(timezone=True)) status = db.Column(db.String(32), nullable=False) total_files = db.Column(db.Integer(unsigned=True), nullable=False) files_tested = db.Column(db.Integer(unsigned=True)) files_matched = db.Column(db.Integer(unsigned=True)) avg_millis_per_file = db.Column(db.Float, nullable=False) yara_rule = db.relationship( 'Yara_rule', foreign_keys=[yara_rule_id], primaryjoin='Yara_rule.id==Yara_testing_history.yara_rule_id') user_id = db.Column(db.Integer, db.ForeignKey('kb_users.id'), nullable=False) user = db.relationship( 'KBUser', foreign_keys=[user_id], primaryjoin="KBUser.id==Yara_testing_history.user_id") def to_dict(self, include_results=False): res = dict( yara_rule_id=self.yara_rule_id, revision=self.revision, start_time=self.start_time.isoformat(), end_time=self.end_time.isoformat() if self.end_time else None, files_tested=self.files_tested, files_matched=self.files_matched, test_type=self.test_type, user=self.user.to_dict(), user_email=self.user.to_dict()["email"], id=self.id, status=self.status, avg_millis_per_file=self.avg_millis_per_file, yara_rule_name=self.yara_rule.name) if include_results: res["file_matches"] = [ result.to_dict() for result in self.file_matches ] return res def __repr__(self): return '<YaraTestingHistory %r>' % self.id
class DailyStatistics(db.Model): __tablename__ = 'daily_stat' # naive Date(tzinfo=None, but actually KST) date = db.Column(db.Date, primary_key=True) pet_id = db.Column(db.Integer, db.ForeignKey('pet.id'), primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) count = db.Column(db.Integer, nullable = False) success = db.Column(db.Integer, nullable = False) ratio = db.Column(db.Float, nullable = False) # (timezone=True) make DATETIME to TIMESTAMP in Mysql created_date = db.Column(db.DateTime(timezone=True), nullable = False, default=datetime.datetime.now()) last_modified_date = db.Column(db.DateTime(timezone=True), nullable = False, default=datetime.datetime.now()) pet = db.relationship('Pet', backref = db.backref('daily_stats'), lazy = True ) # def __repr__(self): # return f"<DailyStatistics : {self.count}, {self.success}, {self.fail}>" @staticmethod def update(pet_id: int, user_id: int, new_datetime: datetime.datetime, old_datetime: datetime.datetime) -> None: """ update daily_stat by new pet record """ # check that date of record is changed old_day = old_datetime.date() new_day = new_datetime.date() try: if old_day == new_day: # 1 day update DailyStatistics.update_day(pet_id, user_id, new_day) else: # 2 day update DailyStatistics.update_day(pet_id, user_id, new_day) DailyStatistics.update_day(pet_id, user_id, old_day) except Exception as e: # bubbling for transaction raise e @staticmethod def update_day(pet_id: int, user_id: int, selected_day: datetime.date) -> None: """ Update one day_record by check all records of day :Params: Integer, Integer, datetime.date :Return: """ from app.models.pet_record import PetRecord from sqlalchemy.exc import IntegrityError # find all pet records of the day selected_daytime_min = datetime.datetime.combine(selected_day, datetime.time.min) selected_daytime_max = datetime.datetime.combine(selected_day, datetime.time.max) pet_records = PetRecord.query.filter_by(pet_id=pet_id).\ filter(PetRecord.timestamp >= selected_daytime_min).\ filter(PetRecord.timestamp <= selected_daytime_max).\ all() # find day record day_record = DailyStatistics.query.\ filter_by(date=selected_day, pet_id=pet_id).first() # if last pet_record of the day deleted if len(pet_records) == 0: if day_record: db.session.delete(day_record) db.session.commit() return # update day record total_count = 0 total_success = 0 if day_record: # exists # update day record by all pet records for r in pet_records: total_count += 1 if(r.result == 'SUCCESS'): total_success += 1 day_record.count = total_count day_record.success = total_success logging.debug(f'not first: {total_success}, {total_count}') day_record.ratio = total_success/total_count day_record.last_modified_date = datetime.datetime.now() else: # first day record for r in pet_records: total_count += 1 if(r.result == 'SUCCESS'): total_success += 1 logging.debug(f'first: {total_success}, {total_count}') selected_day_record = DailyStatistics( date = selected_day, pet_id = pet_id, user_id = user_id, count = total_count, success = total_success, ratio = total_success/total_count ) db.session.add(selected_day_record) try: db.session.commit() except IntegrityError as e: # db.session.rollback() # bubbling for transaction raise e
class Pad(db.Model): ''' Dog size = 224 * 224 Ppcam(raspb cam) size = 800 * 600 So, 0 <= x <= 800 0 <= y <= 600 ''' __tablename__ = 'pad' id = db.Column(db.Integer, primary_key=True, autoincrement=True) ppcam_id = db.Column(db.Integer, db.ForeignKey('ppcam.id'), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) ldx = db.Column(db.Integer, nullable=False) ldy = db.Column(db.Integer, nullable=False) lux = db.Column(db.Integer, nullable=False) luy = db.Column(db.Integer, nullable=False) rdx = db.Column(db.Integer, nullable=False) rdy = db.Column(db.Integer, nullable=False) rux = db.Column(db.Integer, nullable=False) ruy = db.Column(db.Integer, nullable=False) created_date = db.Column(db.DateTime(timezone=True), nullable=False, default=datetime.datetime.now()) last_modified_date = db.Column(db.DateTime(timezone=True), nullable=False, default=datetime.datetime.now()) ppcam = db.relationship('Ppcam', backref=db.backref('pads'), lazy=True) @staticmethod def generate_fake(count: int): # Generate a number of fake pads for testing from sqlalchemy.exc import IntegrityError from random import seed, randint from faker import Faker fake = Faker() seed() for i in range(count): p = Pad( # 0 <= x <= 800 lux=randint(0, 800), ldx=randint(0, 800), rux=randint(0, 800), rdx=randint(0, 800), # 0 <= y <= 600 luy=randint(0, 600), ldy=randint(0, 600), ruy=randint(0, 600), rdy=randint(0, 600), # match one foreign_key by one user # id start from 1 ppcam_id=i + 1, user_id=i + 1) try: db.session.add(p) db.session.commit() except IntegrityError: db.session.rollback() logging.info('Successed to set fake pads')
class Whitelist(db.Model): __tablename__ = 'whitelist' uuid_user = db.Column(db.String(), primary_key=True) created = db.Column(db.DateTime(), default=datetime.datetime.now()) token = db.Column(db.String(), unique=True)
class Event(Base): __tablename__ = "event" __table_args__ = {'extend_existing': True} id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(50), nullable=False) description = db.Column(db.String(255), nullable=False) start_date = db.Column(db.DateTime(), nullable=False) end_date = db.Column(db.DateTime(), nullable=False) key = db.Column(db.String(255), nullable=False, unique=True) organisation_id = db.Column(db.Integer(), db.ForeignKey('organisation.id'), nullable=False) email_from = db.Column(db.String(255), nullable=False) url = db.Column(db.String(255), nullable=False) application_open = db.Column(db.DateTime(), nullable=False) application_close = db.Column(db.DateTime(), nullable=False) review_open = db.Column(db.DateTime(), nullable=False) review_close = db.Column(db.DateTime(), nullable=False) selection_open = db.Column(db.DateTime(), nullable=False) selection_close = db.Column(db.DateTime(), nullable=False) offer_open = db.Column(db.DateTime(), nullable=False) offer_close = db.Column(db.DateTime(), nullable=False) registration_open = db.Column(db.DateTime(), nullable=False) registration_close = db.Column(db.DateTime(), nullable=False) def __init__(self, name, description, start_date, end_date, key, organisation_id, email_from, url, application_open, application_close, review_open, review_close, selection_open, selection_close, offer_open, offer_close, registration_open, registration_close): self.name = name self.description = description self.start_date = start_date self.end_date = end_date self.key = key self.organisation_id = organisation_id self.email_from = email_from self.url = url self.application_open = application_open self.application_close = application_close self.review_open = review_open self.review_close = review_close self.selection_open = selection_open self.selection_close = selection_close self.offer_open = offer_open self.offer_close = offer_close self.registration_open = registration_open self.registration_close = registration_close
class DucatusAddress(db.Model): __tablename__ = 'ducatus_address' id = db.Column(db.Integer, primary_key=True) address = db.Column(db.String(64), index=True, unique=True, nullable=False) last_transaction_date = db.Column(db.DateTime(timezone=False), nullable=False)
class Therapy(db.Model): __tablename__ = "therapy" __label__ = "Therapy or Service" __no_export__ = True # This will be transferred as a part of a parent class type_other_hide_expression = '!(model.type && (model.type === "other"))' id = db.Column(db.Integer, primary_key=True) last_updated = db.Column(db.DateTime(timezone=True), default=func.now()) supports_questionnaire_id = db.Column( "supports_questionnaire_id", db.Integer, db.ForeignKey("supports_questionnaire.id"), ) type = db.Column( db.String, info={ "display_order": 1, "type": "radio", "className": "vertical-radio-group", "template_options": { "label": "Select type", "placeholder": "Please select", "required": True, "options": [ { "value": "speechLanguage", "label": "Speech/Language Therapy", }, { "value": "occupational", "label": "Occupational Therapy" }, { "value": "physical", "label": "Physical Therapy" }, { "value": "behavioral", "label": "Behavior Therapy (ABA, Lovaas, Discrete Trial Training)", }, { "value": "natDevBehavioral", "label": "Naturalistic Developmental Behavioral (Pivotal Response Training, Early Start Denver Model, JASPER, etc)", }, { "value": "developmental", "label": "Developmental or relationship-based Therapy (DIR/Floortime)", }, { "value": "family", "label": "Family Therapy and/or counseling", }, { "value": "behavioralParent", "label": "Behavioral parent training (non ASD specific)", }, { "value": "individual", "label": "Individual counseling or therapy", }, { "value": "medication", "label": "Medication management/Psychiatry", }, { "value": "socialSkills", "label": "Social skills training", }, { "value": "parentEducation", "label": "Parent education workshops", }, { "value": "alternativeTreatments", "label": "Complementary or alternative treatments (e.g., vitamin/nutrient supplements, special diet, food restrictions)", }, { "value": "other", "label": "Others (please specify)" }, ], }, }, ) type_other = db.Column( db.String, info={ "display_order": 1.2, "type": "textarea", "template_options": { "label": "Enter therapy or service", "required": True, }, "hide_expression": type_other_hide_expression, "expression_properties": { "template_options.required": '!' + type_other_hide_expression } }, ) timeframe = db.Column( db.String, info={ "display_order": 3, "type": "radio", "template_options": { "label": "", "required": False, "options": [ { "value": "current", "label": "Currently receiving" }, { "value": "past", "label": "Received in the past" }, { "value": "futureInterest", "label": "Interested in receiving" }, ], }, }, ) notes = db.Column( db.String, info={ "display_order": 4, "type": "textarea", "template_options": { "label": "Notes on use and/or issues with therapy or service", "required": False, }, }, ) def get_field_groups(self): info = { "type_group": { "fields": ["type", "type_other"], "display_order": 1, "wrappers": ["card"], "template_options": { "label": "Type of therapy or service" }, } } return info
class KBUser(db.Model): __tablename__ = "kb_users" id = db.Column(db.Integer, primary_key=True, autoincrement=True) email = db.Column(db.String(255), unique=True, nullable=False) password = db.Column(db.String(255), nullable=False) registered_on = db.Column(db.DateTime(timezone=True), default=db.func.current_timestamp()) admin = db.Column(db.Boolean, nullable=False, default=False) active = db.Column(db.Boolean, nullable=False, default=True) first_name = db.Column(db.String(255), nullable=True) last_name = db.Column(db.String(255), nullable=True) picture = db.Column(db.LargeBinary, nullable=True) def is_authenticated(self): return True def is_active(self): return self.active def is_admin(self): return self.admin def is_anonymous(self): return False def get_id(self): return unicode(self.id) def __repr__(self): return '<User {0}>'.format(self.email) def to_dict(self): return dict(email=self.email, registered_on=self.registered_on.isoformat(), admin=self.admin, active=self.active, id=self.id, first_name=self.first_name, last_name=self.last_name) def generate_auth_token(self, s_key): s = Serializer(s_key) return s.dumps({'id': self.id}) @staticmethod def get_user_cache(): users = {} for user in db.session.query(KBUser).all(): users[user.id] = user.to_dict() return users @staticmethod def verify_auth_token(token, s_key): s = Serializer(s_key) try: data = s.loads(token) except BadSignature: return None # invalid token user = KBUser.query.get(data['id']) return user
class User(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), unique=True, index=True) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) password_hash = db.Column(db.String(64)) confirmed = db.Column(db.Boolean, default=False) name = db.Column(db.String(32), index=True) surname = db.Column(db.String(32), index=True) performance_story_points = db.Column(db.Integer, default=100) email = db.Column(db.String(64), index=True, unique=True) location = db.Column(db.String(64)) about_me = db.Column(db.Text()) member_since = db.Column(db.DateTime(), default=datetime.utcnow) last_seen = db.Column(db.DateTime(), default=datetime.utcnow) avatar_hash = db.Column(db.String(32)) posts = db.relationship('Post', backref='author', lazy='dynamic') avatar_url = db.Column(db.String(64), default='uploads/default-user-image.png') comments = db.relationship('Comment', backref='author', lazy='dynamic') followed = db.relationship('Follow', foreign_keys='Follow.follower_id', backref=db.backref('follower', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan') @staticmethod def add_self_follows(): for user in User.query.all(): if not user.is_following(user): user.follow(user) db.session.add(user) db.session.commit() def __init__(self, **kwargs): super(User, self).__init__(**kwargs) if self.role is None: if self.email == current_app.config['ADMIN']: self.role = Role.query.filter_by(permissions=0xff).first() if self.role is None: self.role = Role.query.filter_by(default=True).first() # self.followed.append(Follow(followed=self)) @property def password(self): raise AttributeError('you cannot get password') @password.setter def password(self, password): self.password_hash = generate_password_hash(password) def verify_password(self, password): return check_password_hash(self.password_hash, password) def generate_confirmation_token(self, expiration=3600): s = Serializer(current_app.config['SECRET_KEY'], expires_in=expiration) return s.dumps({'confirm': self.id}) def confirm(self, token): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except: return False if data.get('confirm') != self.id: return False self.confirmed = True db.session.add(self) return True def generate_reset_token(self, expiration=3600): s = Serializer(current_app.config['SECRET_KEY'], expiration) return s.dumps({'reset': self.id}) def reset_password(self, token, new_password): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except: return False if data.get('reset') != self.id: return False self.password = new_password db.session.add(self) return True def generate_email_change_token(self, new_email, expiration=3600): s = Serializer(current_app.config['SECRET_KEY'], expiration) return s.dumps({'change_email': self.id, 'new_email': new_email}) def change_email(self, token): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except: return False if data.get('change_email') != self.id: return False new_email = data.get('new_email') if new_email is None: return False if self.query.filter_by(email=new_email).first() is not None: return False self.email = new_email db.session.add(self) return True def can(self, permissions): return self.role is not None and \ (self.role.permissions & permissions) == permissions def is_administrator(self): return self.can(Permission.ADMINISTER) def ping(self): self.last_seen = datetime.utcnow() db.session.add(self) def follow(self, user): if not self.is_following(user): f = Follow(follower=self, followed=user) user.task_status = 'sheduled' db.session.add(f) def unfollow(self, user): f = self.followed.filter_by(followed_id=user.id).first() if f: user.task_status = 'open' db.session.delete(f) def is_following(self, user): return self.followed.filter_by(followed_id=user.id).first() is not None def is_followed_by(self, user): return self.followers.filter_by( follower_id=user.id).first() is not None @property def followed_posts(self): return Post.query.join(Follow, Follow.followed_id == Post.id) \ .filter(Follow.follower_id == self.id) def followed_tasks_pts(self): user_tasks = Post.query.join(Follow, Follow.followed_id == Post.id) \ .filter(Follow.follower_id == self.id) reserved_pts = [x.task_story_points for x in user_tasks] return sum(reserved_pts) def __repr__(self): return '<User {0}>'.format(self.username)
class Datastreams(db.Model): __tablename__ = "datastream" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String()) description = db.Column(db.String()) observedarea = db.Column(db.String()) unitofmeasurement = db.Column(db.String()) observationtype = db.Column(db.String()) phenomenontime_begin = db.Column(db.DateTime()) phenomenontime_end = db.Column(db.DateTime()) resulttime_begin = db.Column(db.DateTime()) resulttime_end = db.Column(db.DateTime()) sensor_link = db.Column(db.String()) thing_link = db.Column(db.String()) observedproperty_link = db.Column(db.String()) def __repr__(self): return f"<Observation {self.name}, {self.description}>" def to_json(x): return { "datastream_id": x.id, "name": x.name, "description": x.description, "thing_link": x.thing_link, "sensor_link": x.sensor_link } @classmethod def filter_by_id(cls, id): FoI_list = [] if (id): FoI_list = Datastreams.query.filter(Datastreams.id == id) if FoI_list.count() == 0: result = None else: result = {f"Datastream {id}": Datastreams.to_json(FoI_list[0])} return result @classmethod def filter_by_thing_sensor(cls, thing, sensor): datastream_list = [] if (not thing) and sensor: datastream_list = Datastreams.query.filter( Datastreams.sensor_link == sensor) elif (not sensor) and thing: datastream_list = Datastreams.query.filter( Datastreams.thing_link == thing) else: datastream_list = Datastreams.query.filter( and_( Datastreams.thing_link == thing, Datastreams.sensor_link == sensor, )) return { "Datastreams": list(map(lambda x: Datastreams.to_json(x), datastream_list)) } @classmethod def return_all(cls): return { "Observations": list(map(lambda x: Datastreams.to_json(x), Datastreams.query.all())) }
class EmploymentQuestionnaire(db.Model): __tablename__ = 'employment_questionnaire' __label__ = "Employment" __question_type__ = ExportService.TYPE_UNRESTRICTED __estimated_duration_minutes__ = 2 id = db.Column(db.Integer, primary_key=True) last_updated = db.Column(db.DateTime(timezone=True), default=func.now()) time_on_task_ms = db.Column(db.BigInteger, default=0) participant_id = db.Column('participant_id', db.Integer, db.ForeignKey('stardrive_participant.id')) user_id = db.Column('user_id', db.Integer, db.ForeignKey('stardrive_user.id')) is_currently_employed = db.Column(db.Boolean, info={ 'display_order': 1.1, 'type': 'radio', 'template_options': { 'label': 'Are you currently employed?', 'required': False, 'options': [{ 'value': True, 'label': 'Yes' }, { 'value': False, 'label': 'No' }] } }) employment_capacity = db.Column( db.String, info={ 'display_order': 1.2, 'type': 'radio', 'default_value': 'n/a', 'template_options': { 'label': 'In what capacity?', "appearance": "standard", 'required': False, 'options': [{ 'value': 'fullTime', 'label': 'Full time (> 35 hours per week)' }, { 'value': 'partTime', 'label': 'Part time' }] }, 'hide_expression': '!(model.is_currently_employed)', }) has_employment_support = db.Column( db.String, info={ 'display_order': 2, 'type': 'radio', 'template_options': { 'label': 'Receiving Support?', 'description': 'Do you currently receive supports to help you work successfully, such as job coaching ' 'or vocational training?', 'required': False, 'options': [{ 'value': 'yes', 'label': 'Yes' }, { 'value': 'interested', 'label': 'No, but I am interested' }, { 'value': 'no', 'label': 'No' }] } }) def get_field_groups(self): return {}
class Account(db.Model): __tablename__ = 'account' id = db.Column(UUID(as_uuid=True), primary_key=True, default=lambda: uuid.uuid4().hex) user = db.relationship('User', back_populates='account') account_history = db.relationship("AccountHistory", backref='account', lazy='dynamic') # payment information payment_method = db.Column(db.String()) # May be: 'card', 'paypal' or anything else payment_method_info = db.Column(db.String()) # Vendor - specific information payment_method_text = db.Column(db.String(150)) # Any text information for user that will be shown as current payment info account_status_text = db.Column(db.String(150)) # Ane text information describing the current account status (trial, paid, paused etc.) vendor_name = db.Column(db.String(64)) subscription_id = db.Column(db.String(128)) plan_id = db.Column(db.String(64)) plan_name = db.Column(db.String(128)) # Below is current actual information # If account is valid that is has access to some plan valid_status = db.Column(db.String(32)) # It's string because alembic cannot update Enums # Current status: trial, paid, or paused account_status = db.Column(db.String(32)) # Additional fields trial_expiration = db.Column(db.DateTime(), nullable=True) payment_expiration = db.Column(db.DateTime(), nullable=True) def __init__(self): self.valid_status = ValidStatus.invalid.value # It's invalid by default self.start_trial() #self.account_status = AccountStatus.trial.value # when user signs up, he gets the trial automatically #trial_days = current_app.config['TRIAL_PERIOD_IN_DAYS'] #self.trial_expiration = DateTime.today() + TimeDelta(days = trial_days) # Checks if account is active or not, change fields and the current status def check_account_status(self):#trial_status, purchase_status, payment_method_status, plan_status): current_valid_status = ValidStatus.valid current_account_status = AccountStatus(self.account_status) if self.account_status == AccountStatus.trial.value: # Check if the trial's not expired yet if DateTime.today() > self.trial_expiration: current_valid_status = ValidStatus.invalid current_account_status = AccountStatus.undefined self.account_status_text = 'Your trial is expired. Please buy a subscription to continue using the service.' self.trial_expiration = None self.plan_id = '' else: # Trial is inactive or not started yet. Check payment status. if (self.account_status == AccountStatus.cancelled.value or self.account_status == AccountStatus.paused.value or self.account_status == AccountStatus.undefined.value): current_valid_status = ValidStatus.invalid else: # Account status is paid, check if it's still valid if self.payment_expiration != None and DateTime.now() > self.payment_expiration: current_valid_status = ValidStatus.invalid if current_valid_status.value != self.valid_status or current_account_status.value != self.account_status: self.valid_status = current_valid_status.value self.account_status = current_account_status.value db.session.add(self) db.session.commit() def create_history_event(self, event: EventType, comment: str): new_event = AccountHistory() new_event.account_id = self.id new_event.date = datetime.now() new_event.event = event.value new_event.comment = comment db.session.add(new_event) def start_trial(self): vendor = get_vendor() self.plan_id = vendor.get_default_trial_plan_id() trial_days = current_app.config['TRIAL_PERIOD_IN_DAYS'] self.trial_expiration = DateTime.today() + TimeDelta(days = trial_days) self.account_status = AccountStatus.trial.value str_valid_time = self.trial_expiration.strftime('%d, %b %Y %H:%M') self.account_status_text = ('Your trial is activated and valid till ' + str_valid_time) db.session.add(self) db.session.flush() account_event = self.create_history_event(EventType.trial_started, 'Started a trial, expiration date is ' + str_valid_time)
class User(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) password_hash = db.Column(db.String(128)) email = db.Column(db.String(64), unique=True, index=True) username = db.Column(db.String(64), unique=True, index=True) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) confirmed = db.Column(db.Boolean, default=False) name = db.Column(db.String(64)) location = db.Column(db.String(64)) about_me = db.Column(db.Text()) member_since = db.Column(db.DateTime(), default=datetime.utcnow) last_seen = db.Column(db.DateTime(), default=datetime.utcnow) def ping(self): self.last_seen = datetime.utcnow() db.session.add(self) def __init__(self, **kwargs): super(User, self).__init__(**kwargs) if self.role is None: if self.email == current_app.config['FLASKY_ADMIN']: self.role = Role.query.filter_by(permission=0xff).first() if self.email == current_app.config['FLASKY_MODER']: self.role = Role.query.filter_by(permission=0x0f).first() if self.role is None: self.role = Role.query.filter_by(default=True).first() def can(self, permissions): return self.role is not None and \ (self.role.permission & permissions) == permissions def is_administrator(self): return self.can(Permission.ADMINISTER) def generate_confirmation_token(self, expiration=3600): s = Serializer(current_app.config['SECRET_KEY'], expiration) return s.dumps({'confirm': self.id}) def confirm(self, token): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except: return False if data.get('confirm') != self.id: return False self.confirmed = True db.session.add(self) db.session.commit() return True def __repr__(self): return '<User> {}'.format(self.username) @property def password(self): raise AttributeError('password is not a readeble attribute') @password.setter def password(self, password): self.password_hash = generate_password_hash(password) def verify_password(self, password): return check_password_hash(self.password_hash, password) def generate_reset_token(self, expiration=3600): s = Serializer(current_app.config['SECRET_KEY'], expiration) return s.dumps({'reset': self.id}).decode('utf-8') @staticmethod def reset_password(token, new_password): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token.encode('utf-8')) except: return False user = User.query.get(data.get('reset')) if user is None: return False user.password = new_password db.session.add(user) return True def generate_change_email(self, new_email, expiration=3600): s = Serializer(current_app.config['SECRET_KEY'], expiration) return s.dumps({'change_email': self.id, 'new_email': new_email}) def change_email(self, token): s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token.encode('utf-8')) except: return False if data.get('change_email') != self.id: return False new_email = data.get('new_email') if new_email is None: return False if self.query.filter_by(email=new_email).first() is not None: return False self.email = new_email db.session.add(self) return True