class AnalysisComment(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) datetime = db.Column(db.DateTime) comment = db.Column(db.UnicodeText) # Foreign keys analysis_id = db.Column(db.Integer, db.ForeignKey('analysis.id')) profile_id = db.Column(db.Integer, db.ForeignKey('profile.id')) # Relationships analysis = db.relationship('Analysis', backref=db.backref( 'analysis_comments', lazy='dynamic', cascade='all, delete-orphan', )) profile = db.relationship('Profile', backref=db.backref('analysis_comments', lazy='dynamic')) def __init__(self, datetime, comment, analysis_id, profile_id): self.datetime = datetime self.comment = comment self.analysis_id = analysis_id self.profile_id = profile_id def __repr__(self): return '<AnalysisComment: %r>' % self.id
class GroupMembership(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) is_admin = db.Column(db.Boolean) # Foreign keys group_id = db.Column(db.Integer, db.ForeignKey('group.id')) group_membership_type_id = db.Column(db.Integer, db.ForeignKey('group_membership_type.id')) permission_type_id = db.Column(db.Integer, db.ForeignKey('permission_type.id')) profile_id = db.Column(db.Integer, db.ForeignKey('profile.id')) # Relationships group = db.relationship('Group', backref=db.backref('memberships', lazy='dynamic', cascade='all, delete-orphan', ) ) group_membership_type = db.relationship('GroupMembershipType', backref=db.backref('memberships', lazy='dynamic')) permission_type = db.relationship('PermissionType', backref=db.backref('memberships', lazy='dynamic')) profile = db.relationship('Profile', backref=db.backref('memberships', lazy='dynamic')) def __init__(self, is_admin, group_id, group_membership_type_id, permission_type_id, profile_id): self.is_admin = is_admin self.group_id = group_id self.group_membership_type_id = group_membership_type_id self.permission_type_id = permission_type_id self.profile_id = profile_id def __repr__(self): return '<GroupMembership: %r>' % self.id
class AnalysisFile(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) upload_time = db.Column(db.DateTime) path = db.Column(db.String(255)) description = db.Column(db.String(255)) is_encrypted = db.Column(db.Boolean) # Foreign keys analysis_id = db.Column(db.Integer, db.ForeignKey('analysis.id')) storage_location_id = db.Column(db.Integer, db.ForeignKey('storage_location.id')) # Relationships analysis = db.relationship('Analysis', backref=db.backref('analysis_files', lazy='dynamic', cascade='all, delete-orphan', ) ) storage_location = db.relationship('StorageLocation', backref=db.backref('analysis_files', lazy='dynamic')) def __init__(self, upload_time, path, description, analysis_id, storage_location_id, is_encrypted): self.upload_time = upload_time self.path = path self.description = description self.analysis_id = analysis_id self.storage_location_id = storage_location_id self.is_encrypted = is_encrypted def __repr__(self): return '<AnalysisFile: %r>' % self.id
class AnalysisFileEncryption(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) encrypted_secret_key = db.Column(db.Text) # Foreign keys analysis_file_id = db.Column(db.Integer, db.ForeignKey('analysis_file.id')) profile_id = db.Column(db.Integer, db.ForeignKey('profile.id')) # Relationships analysis_file = db.relationship('AnalysisFile', backref=db.backref( 'analysis_file_encryptions', lazy='dynamic', cascade='all, delete-orphan', )) profile = db.relationship('Profile', backref=db.backref('analysis_file_encryptions', lazy='dynamic')) def __init__(self, encrypted_secret_key, analysis_file_id, profile_id): self.encrypted_secret_key = encrypted_secret_key self.analysis_file_id = analysis_file_id self.profile_id = profile_id def __repr__(self): return '<AnalysisFileEncryption: %r>' % self.id
class Permission(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) # Foreign keys analysis_id = db.Column(db.Integer, db.ForeignKey('analysis.id')) permission_type_id = db.Column(db.Integer, db.ForeignKey('permission_type.id')) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # Relationships analysis = db.relationship('Analysis', backref=db.backref( 'permissions', lazy='dynamic', cascade='all, delete-orphan', )) permission_type = db.relationship('PermissionType', backref=db.backref('permissions', lazy='dynamic')) user = db.relationship('User', backref=db.backref('permissions', lazy='dynamic')) def __init__(self, analysis_id, permission_type_id, user_id): self.analysis_id = analysis_id self.permission_type_id = permission_type_id self.user_id = user_id def __repr__(self): return '<PermissionType: %r>' % self.id
class TypeUnitValidation(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) min_value = db.Column(db.Float) max_value = db.Column(db.Float) # Foreign keys measurement_type_id = db.Column(db.Integer, db.ForeignKey('measurement_type.id')) measurement_unit_id = db.Column(db.Integer, db.ForeignKey('measurement_unit.id')) # Relationships measurement_type = db.relationship('MeasurementType', backref=db.backref('validations', lazy='dynamic')) measurement_unit = db.relationship('MeasurementUnit', backref=db.backref('validations', lazy='dynamic')) def __init__(self, min_value=0, max_value=0, type_id=None, unit_id=None): self.min_value = min_value self.max_value = max_value self.measurement_type_id = type_id self.measurement_unit_id = unit_id def __repr__(self): return '<TypeUnitValidation: %r>' % self.id
class NotificationNewAnalysisFromGroup(Notification): # Attributes id = db.Column(db.Integer, db.ForeignKey('notification.id'), primary_key=True) # Foreign keys analysis_id = db.Column(db.Integer, db.ForeignKey('analysis.id')) group_id = db.Column(db.Integer, db.ForeignKey('group.id')) # Relationships analysis = db.relationship('Analysis', backref=db.backref('notifications', lazy='dynamic', cascade='all, delete-orphan' ) ) group = db.relationship('Group', backref=db.backref('notifications', lazy='dynamic', cascade='all, delete-orphan', ) ) __mapper_args__ = { 'polymorphic_identity': 'notificationNewAnalysisFromGroup', } def __init__(self, notification_owner_id, notification_author_id, analysis_id, group_id): Notification.__init__(self, notification_owner_id, notification_author_id) self.analysis_id = analysis_id self.group_id = group_id def get_title(self): author = self.notification_author title = u'¡%s ha cargado un nuevo análisis en un grupo!' % ( author.first_name + ' ' + author.last_name, ) return title def get_description(self): description = (u'Un nuevo análisis, con el nombre "%s", ha sido ' 'cargado en el grupo "%s".') % ( self.analysis.description, self.group.name, ) return description @staticmethod def get_detail_object_type(): return 'analysis' def get_detail_object_id(self): return self.analysis.id @staticmethod def get_notification_type(): return 'event' def __repr__(self): return '<NotificationNewAnalysisFromGroup: %r>' % self.id
class Measurement(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) datetime = db.Column(db.DateTime) value = db.Column(db.Float) # Foreign keys analysis_id = db.Column(db.Integer, db.ForeignKey('analysis.id')) profile_id = db.Column(db.Integer, db.ForeignKey('profile.id')) measurement_source_id = db.Column(db.Integer, db.ForeignKey('measurement_source.id')) measurement_type_id = db.Column(db.Integer, db.ForeignKey('measurement_type.id')) measurement_unit_id = db.Column(db.Integer, db.ForeignKey('measurement_unit.id')) # Relationships analysis = db.relationship('Analysis', backref=db.backref( 'measurements', lazy='dynamic', cascade='all', )) profile = db.relationship('Profile', backref=db.backref('measurements', lazy='dynamic')) measurement_source = db.relationship('MeasurementSource', backref=db.backref('measurements', lazy='dynamic')) measurement_type = db.relationship('MeasurementType', backref=db.backref('measurements', lazy='dynamic')) measurement_unit = db.relationship('MeasurementUnit', backref=db.backref('measurements', lazy='dynamic')) def __init__(self, datetime, value, analysis_id, profile_id, source_id, type_id, unit_id): self.datetime = datetime self.value = value self.analysis_id = analysis_id self.profile_id = profile_id self.measurement_source_id = source_id self.measurement_type_id = type_id self.measurement_unit_id = unit_id def __repr__(self): return '<Measurement: %r>' % (self.datetime)
class NotificationNewGroupMembership(Notification): # Attributes id = db.Column(db.Integer, db.ForeignKey('notification.id'), primary_key=True) # Foreign keys group_membership_id = db.Column(db.Integer, db.ForeignKey('group_membership.id')) # Relationships group_membership = db.relationship('GroupMembership', backref=db.backref( 'notifications', lazy='dynamic', cascade='all, delete-orphan', )) __mapper_args__ = { 'polymorphic_identity': 'notificationNewGroupMembership', } def __init__(self, notification_owner_id, notification_author_id, group_membership_id): Notification.__init__(self, notification_owner_id, notification_author_id) self.group_membership_id = group_membership_id def get_title(self): author = self.notification_author title = u'¡%s te ha agregado a un grupo!' % (author.first_name + ' ' + author.last_name, ) return title def get_description(self): author = self.notification_author description = u'%s te ha agregado al grupo "%s".' % ( author.first_name + ' ' + author.last_name, self.group_membership.group.name, ) return description @staticmethod def get_detail_object_type(): return 'group' def get_detail_object_id(self): return self.group_membership.group.id @staticmethod def get_notification_type(): return 'event' def __repr__(self): return '<NotificationNewGroupMembership: %r>' % self.id
class NotificationNewAnalysisComment(Notification): # Attributes id = db.Column(db.Integer, db.ForeignKey('notification.id'), primary_key=True) # Foreign keys analysis_comment_id = db.Column(db.Integer, db.ForeignKey('analysis_comment.id')) # Relationships analysis_comment = db.relationship('AnalysisComment', backref=db.backref( 'notifications', lazy='dynamic', cascade='all, delete-orphan', )) __mapper_args__ = { 'polymorphic_identity': 'notificationNewAnalysisComment', } def __init__(self, notification_owner_id, notification_author_id, analysis_comment_id): Notification.__init__(self, notification_owner_id, notification_author_id) self.analysis_comment_id = analysis_comment_id def get_title(self): author = self.notification_author title = u'¡%s ha comentado un análisis tuyo!' % ( author.first_name + ' ' + author.last_name, ) return title def get_description(self): author = self.notification_author description = u'%s ha comentado en el análisis "%s".' % ( author.first_name + " " + author.last_name, self.analysis_comment.analysis.description, ) return description @staticmethod def get_detail_object_type(): return 'analysis' def get_detail_object_id(self): return self.analysis_comment.analysis.id @staticmethod def get_notification_type(): return 'message' def __repr__(self): return '<NotificationNewAnalysisComment: %r>' % self.id
class GroupPermission(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) # Foreign keys analysis_id = db.Column(db.Integer, db.ForeignKey('analysis.id')) group_id = db.Column(db.Integer, db.ForeignKey('group.id')) # Relationships analysis = db.relationship('Analysis', backref=db.backref( 'group_permissions', lazy='dynamic', cascade='all, delete-orphan', )) group = db.relationship('Group', backref=db.backref('group_permissions', lazy='dynamic')) def __init__(self, analysis_id, group_id): self.analysis_id = analysis_id self.group_id = group_id def __repr__(self): return '<GroupPermission: %r>' % self.id
class StorageCredential(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) token = db.Column(db.String(255)) # Foreign keys owner_id = db.Column(db.Integer, db.ForeignKey('user.id')) storage_location_id = db.Column(db.Integer, db.ForeignKey('storage_location.id')) # Relationships owner = db.relationship('User', backref=db.backref('storage_credentials', lazy='dynamic')) storage_location = db.relationship('StorageLocation', backref=db.backref( 'storage_credentials', lazy='dynamic')) def __init__(self, token, owner_id, storage_location_id): self.token = token self.owner_id = owner_id self.storage_location_id = storage_location_id def __repr__(self): return '<StorageCredential: %r>' % self.id
class Notification(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) created_datetime = db.Column(db.DateTime) read_datetime = db.Column(db.DateTime) type = db.Column(db.String(50)) # Foreign keys notification_author_id = db.Column(db.Integer, db.ForeignKey('profile.id')) notification_owner_id = db.Column(db.Integer, db.ForeignKey('profile.id')) # Relationships notification_author = db.relationship( 'Profile', foreign_keys=[notification_author_id]) notification_owner = db.relationship('Profile', backref=db.backref('notifications', lazy='dynamic'), foreign_keys=[notification_owner_id]) __mapper_args__ = { 'polymorphic_identity': 'notification', 'polymorphic_on': type } def __init__(self, notification_owner_id, notification_author_id): self.created_datetime = datetime.utcnow() self.read_datetime = None self.notification_author_id = notification_author_id self.notification_owner_id = notification_owner_id def set_as_read(self): self.read_datetime = datetime.utcnow() def get_title(self): raise NotImplementedError(u'Método no implementado.') def get_description(self): raise NotImplementedError(u'Método no implementado.') def get_detail_object_type(self): raise NotImplementedError(u'Método no implementado.') def get_detail_object_id(self): raise NotImplementedError(u'Método no implementado.') def get_notification_type(self): raise NotImplementedError(u'Método no implementado.') def __repr__(self): return '<Notification: %r>' % self.id
class Profile(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) last_name = db.Column(db.String(50)) first_name = db.Column(db.String(50)) birthday = db.Column(db.Date) is_health_professional = db.Column(db.Boolean) # Foreign keys gender_id = db.Column(db.Integer, db.ForeignKey('gender.id')) # Relationships gender = db.relationship('Gender', backref=db.backref('profiles', lazy='dynamic')) def __init__(self, last_name, first_name, birthday, gender_id, is_health_professional): self.last_name = last_name self.first_name = first_name self.birthday = birthday self.gender_id = gender_id self.is_health_professional = is_health_professional def __repr__(self): return '<Profile: %r %r>' % (self.first_name, self.last_name)
class User(db.Model): # Attributes id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(32), unique=True, index=True) email = db.Column(db.String(64), unique=True) password_hash = db.Column(db.String(128)) rsa_private_key = db.Column(db.Text) rsa_public_key = db.Column(db.Text) is_admin = db.Column(db.Boolean) # Foreign keys profile_id = db.Column(db.Integer, db.ForeignKey('profile.id')) # Relationships profile = db.relationship('Profile', backref=db.backref('user', lazy='dynamic')) def __init__(self, username, email, password, profile_id, is_admin=False): self.username = username self.email = email self.hash_password(password) self.profile_id = profile_id self.is_admin = is_admin self.create_rsa_keys(2048) def __repr__(self): return '<User: %r>' % (self.username) def hash_password(self, password): self.password_hash = pwd_context.encrypt(password) def verify_password(self, password): return pwd_context.verify(password, self.password_hash) def generate_auth_token(self, expiration=600): s = Serializer(Config.SECRET_KEY, expires_in=expiration) return s.dumps({'id': self.id}) @staticmethod def verify_auth_token(token): s = Serializer(Config.SECRET_KEY) try: data = s.loads(token) except SignatureExpired: # Token válido, pero expirado. return None except BadSignature: # Token inválido. return None user = User.query.get(data['id']) return user def create_rsa_keys(self, key_size=2048): # Verifica que el usuario no tenga una clave privada asociada. if (self.rsa_private_key is None or self.rsa_private_key == ''): # Crea el par de claves RSA. private_key = RSA.generate(key_size) public_key = private_key.publickey() # Asocia las claves al usuario. self.rsa_private_key = private_key.exportKey() self.rsa_public_key = public_key.exportKey() # Flask-Login integration @property def is_authenticated(self): return self.is_admin @property def is_active(self): return True @property def is_anonymous(self): return False def get_id(self): return self.id