class Card(BaseDB): # Nombre de la tabla __tablename__ = 'cards' user_id = db.Column(db.Integer, db.ForeignKey('users.id'), default=None) ref = db.Column(db.String(150), unique=True, default=None) user = db.relationship('User', lazy='select', backref='Card') def __init__(self, **kwargs): """ Inicializa los datos de una tarjeta RFID --- :param \**kwargs: See below :type kwargs: dict :keyword user (int): The user id :keyword ref (int): The tag id """ super(Card, self).__init__(**kwargs) for key, value in kwargs.items(): if key == 'user': if isinstance(value, (int, float, str)): value = User.is_validated(value) self.user_id = value if key == 'ref': self.ref = value @classmethod def get_user_from_tag(cls, **kwargs): """Devuelve el usuario a quién corresponda la tarjeta recibida por parámetro --- :rtype: Card :param \**kwargs: See below :type kwargs: dict :keyword id_tag: id de la targeta RFID que identifica al usuario. None si no está habilitado o no existe""" response = None id_tag = kwargs.get("id_tag") if id_tag: card = Card.query.filter_by(ref=id_tag).first() if card: user = card.user if user.validated: response = user return response
class TransitLog(BaseDB): """ Modelo de datos del transito que se registra """ #: Nombre de tabla __tablename__ = 'transits_log' user_id = db.Column( db.Integer, db.ForeignKey('users.id'), nullable=False) #: False = fuera // True = Dentro action = db.Column( db.Boolean, default=False, nullable=False) ocurred = db.Column( db.DateTime, default=datetime.now) #: Establece la relación con la tabla 'groups' user = db.relationship( 'User', lazy='select', backref='TransitLog') def __init__(self, user_id, action, ocurred=datetime.now(), **kwargs): super(TransitLog, self).__init__(**kwargs) self.user_id = user_id self.action = action self.ocurred = ocurred @staticmethod def record_move(**kwargs): user = kwargs.get('user') action = kwargs.get('action') now = datetime.now() move = TransitLog(user=user, action=action, ocurred=now) db.session.add(move) db.session.commit() @staticmethod def get_last_move_by_id_user(id_user): return TransitLog.query.filter_by(user_id=id_user).order_by(desc(TransitLog.ocurred)).first()
class Group(BaseDB): """ Modelo de datos de los grupos """ #: Nombre de tabla __tablename__ = 'groups' category = db.Column(db.String(25), nullable=False, unique=True) definition = db.Column(db.Text()) def __init__(self, category=None, definition=None, **kwargs): super(Group, self).__init__(**kwargs) self.category = category self.definition = definition
class BaseDB(db.Model): """ Define los elementos comunes a todas las tablas que lo heredarán """ __abstract__ = True id = db.Column(db.Integer, primary_key=True) date_created = db.Column(db.DateTime, default=db.func.current_timestamp()) date_modified = db.Column(db.DateTime, onupdate=db.func.current_timestamp()) def save(self): """ Guarda el objeto en la BBDD """ db.session.add(self) db.session.commit()
class Family(BaseDB): """ Modelo que recoge las acciones que tiene definidas un dispositivo """ #: Nombre de la tabla __tablename__ = 'family' name = db.Column(db.String(32), nullable=False) description = db.Column(db.String(255)) def __init__(self, name, description, **kwargs): super(Family, self).__init__(**kwargs) self.name = name self.description = description @staticmethod def get_by_id(id: int = 1): """ :return: Familia con la id indicada. Default <Family:1> """ return Family.query.filter_by(id=id).first() @staticmethod def get_by_name(familis_names: list): """Familias cuyo nombre coincida ocn el filtro""" return Family.query.filter(Family.name.in_(familis_names)).all() @staticmethod def get_all(): """ :return: Lista de todas las familias del sitema """ return Family.query.all() @staticmethod def get_list(): """:return Lista de tuplas de (id, nombre) de todas las familias del sistema. \ El primer elemento es (0, "Selecciona las familias del dispositivo")""" fam_list = [(f.id, f.name) for f in Family.query.all()] fam_list.insert(0, (0, "Selecciona las familias del dispositivo")) return fam_list
class User(BaseDB): """ Modelo de datos del usuario """ #: Nombre de tabla __tablename__ = 'users' group_Id = db.Column(db.Integer, db.ForeignKey('groups.id'), nullable=False) name = db.Column(db.String(25), unique=True) label = db.Column(db.String(25)) email = db.Column(db.String(56), unique=True) password = db.Column(db.String(93), nullable=False) validated = db.Column(db.Boolean, default=False, nullable=False) # signedIn = db.Column( # db.DateTime, # default=datetime.datetime.now) #: Establece la relación con la tabla 'groups' group = db.relationship('Group', lazy='select', backref='User') def __init__(self, name, email, password, label=None, group_id=1, validated=False, **kwargs): """ Inicializa un usuario Por defecto: - Tiene que contener los datos requeridos del formulario 'log_in': - Nombre - Email - Password - No tiene ningún 'label' asignado - Pertenece al grupo 'Estandar' """ super(User, self).__init__(**kwargs) _hash_str = self.__hash_pwd(password) self.group_Id = group_id self.name = name self.label = label self.password = _hash_str self.validated = validated self.email = email @staticmethod def __hash_pwd(password): """ Metodo privado para generar el 'hash' del usuario """ return generate_password_hash(password) def verificar_hash(self, password): """ Metodo público para contrastar los 'hash´s' de las pwd """ return check_password_hash(self.password, password)
class User(BaseDB): """ Modelo de datos del usuario """ #: Nombre de tabla __tablename__ = 'users' __table_args__ = (UniqueConstraint("name", "email"), ) group_Id = db.Column(db.Integer, db.ForeignKey('groups.id'), nullable=False) name = db.Column(db.String(25)) label = db.Column(db.String(25)) email = db.Column(db.String(56), unique=True) password = db.Column(db.String(255), nullable=False) validated = db.Column(db.Boolean, default=False, nullable=False) #: Establece la relación con la tabla 'groups' group = db.relationship('Group', lazy='select', backref='User') def __init__(self, name, email, password, label=None, group_id=1, validated=False, **kwargs): """ Inicializa un usuario Por defecto: - Tiene que contener los datos requeridos del formulario 'log_in': - Nombre - Email - Password - No tiene ningún 'label' asignado - Pertenece al grupo 'Estandar' """ super(User, self).__init__(**kwargs) _hash_str = self.__hash_pwd(password) self.group_Id = group_id self.name = name self.label = label self.password = _hash_str self.validated = validated self.email = email @staticmethod def __hash_pwd(password): """ Metodo privado para generar el 'hash' del usuario """ return generate_password_hash(password) def verificar_hash(self, password): """ Metodo público para contrastar los 'hash´s' de las pwd """ return check_password_hash(self.password, password) @staticmethod def get_mails_of_groups(id_groups: []): """Recupera una lista de los emaiĺ de los usuarios que pertenezcan a los grupos indicados por parámetro --- :param id_groups: Lista con los grupos de los que se desea obtener los mail de los usuarios :return: list: Lista de los mail de los usuarios que pertenecen a ese grupo """ users = User.query.filter(User.group_Id.in_(id_groups)).all() mails = [] for user in users: mails.append(user.email) return mails @staticmethod def is_validated(id_user): """Informa si el usuario con la id informada por parámetro, está validado --- :return: - True, si el usuario está validado; - False, si no está validado; - None, si no existe el usuario :param id_user: Id del usuario del que se desea conocer si está validado """ response = None try: response = User.query.filter(User.id == id_user).first() except: pass return response @staticmethod def get_by_id(id_user): return User.query.filter_by(id=id_user).first()
class FamilyDevice(BaseDB): """ Modelo que recoge las familias a las que está relacionado un dispositivo """ #: Nombre de la tabla __tablename__ = 'family_device' id_device = db.Column(db.Integer, db.ForeignKey('devices.id'), nullable=False) device = db.relationship('Device', lazy='select', backref='Family') id_family = db.Column(db.Integer, db.ForeignKey('family.id'), nullable=False) family = db.relationship('Family', lazy='select', backref='Device') __table_args__ = (UniqueConstraint('id_device', 'id_family', name="uk_FamilyDevice"), ) def __init__(self, **kwargs): """ :type kwargs: ** :rtype: FamilyDevice :param kwargs: :keyword device (Device): Dispositivo al que se le quiere asignar a una familia :keyword family (Family): Familia a la que se quiere asignar el dispositivo """ super(FamilyDevice, self).__init__(**kwargs) for key, value in kwargs.items(): if key == 'device': self.device = value if key == 'family': self.family = value @staticmethod def get_familys(device: Device): """Retorna las familias a las que pertenece un dispositivo""" rels = FamilyDevice.query.filter_by(id_device=device.id).order_by( desc(FamilyDevice.id_family)).all() return [rel.family for rel in rels] @staticmethod def get_devices_by_family(familis_names: list): """Retorna las familias a las que pertenece un dispositivo""" res = [] families = Family.get_by_name(familis_names) for fam in families: rels = FamilyDevice.query.filter_by(id_family=fam.id).order_by( FamilyDevice.id_device).all() for rel in rels: if rel.device not in res: res.append(rel.device) return res
class Action(BaseDB): """ Modelo que recoge las acciones que puede tener definidas un dispositivo """ #: Nombre de la tabla __tablename__ = 'actions' id_family = db.Column(db.Integer, db.ForeignKey('family.id'), nullable=False) family = db.relationship('Family', lazy='select', backref='Action') name = db.Column(db.String(32), nullable=False) description = db.Column(db.String(255)) #: Define el nombre del comando a realizar cmd = db.Column(db.String(64), nullable=False) #: Define si es un comando de entrada is_executable = db.Column(db.Boolean, nullable=False, default=1) response_needed = db.Column(db.Boolean, nullable=False, default=0) def __init__(self, **kwargs): super(Action, self).__init__(**kwargs) for key, value in kwargs.items(): if key == 'family': self.family = value if key == 'name': self.name = value if key == 'cmd': self.cmd = value if key == 'way': self.is_executable = value if key == 'response_needed': self.response_needed = value @staticmethod def get_executable_action(action, device: Device): """@param action id de la acciona a ejecutar @param device type:Device Dispositivo que realizará la acción @raise Exception Si la acciona a realizar no está especificada para el dispositivo""" if device: family_list = FamilyDevice.get_familys(device) actions = [] for family in family_list: for _action in family.Action: actions.append(_action.id) if action in actions: return Action.query.filter_by(id=action, is_executable=1).first() else: return None @staticmethod def get_executable_actions(device: Device = None): if device: familys = FamilyDevice.get_familys(device) actions = [] for family in familys: for action in family.Action: actions.append(action) return actions else: return Action.query.filter_by(is_executable=1).all() @staticmethod def get_actions_from_family(family: Family): """Devuelve las acciones de una familia""" return Action.query.filter_by(id_family=family.id, is_executable=1).all().order_by( desc(Action.id)) @staticmethod def get_by_cmd(action_name: str): return Action.query.filter_by(cmd=action_name, is_executable=1).first()
class Device(BaseDB): """ Modelo que recogera la información relativa a un dispositivo """ #: Nombre de la tabla __tablename__ = 'devices' name = db.Column(db.String(32), nullable=False, unique=True) interface = db.Column(db.String(32)) id_external = db.Column(db.String(64), nullable=False, unique=True) id_remote = db.Column(db.String(64), nullable=False, unique=False) enabled = db.Column(db.Boolean, default=False) def __init__(self, name, id_external, id_remote=None, enabled=False, interface=None, **kwargs): super(Device, self).__init__(**kwargs) if name: self.name = name if interface: self.interface = interface if enabled: self.enabled = enabled self.id_external = id_external self.id_remote = id_remote @staticmethod def get_active_device_by_id(id: int): """Retorna el dispositivo si estaá habilitado""" return Device.query.filter_by(id=id, enabled=1).first() @staticmethod def get_active_devices(): """Retorna los dispositivos que estén habilitados""" return Device.query.filter_by(enabled=1).all() @staticmethod def get_devices(): """Retorna los dispositivos que estén habilitados""" return Device.query.all() @staticmethod def get_device_by_mac(device_mac): """Busca el elemento al que corresponda la dirección indicada :key device_mac: (id_external) id del dispositivo a buscar""" return Device.query.filter_by(id_external=device_mac).first() @staticmethod def disable_device(**kwargs): """@param device: Device @param id: Device.id @return device updated""" device = kwargs.get('device') id = kwargs.get('id') if device: id = device.id device = Device.query.filter_by(id=id).one() device.enabled = False db.session.commit() return device @staticmethod def enable_device(**kwargs): """@param device: Device @param id: Device.id @return device updated""" device = kwargs.get('device') id = kwargs.get('id') if device: id = device.id device = Device.query.filter_by(id=id).one() device.enabled = True db.session.commit() return device