""" file containing all classes to handle Face (and associated tables) from the database """ from main import db from shared import PA ################################################################################ class Face(PA,db.Model): """Class describing a Face in the database Attributes: id (int): database id of row in Face table / primary key face (bytes): the binary version of numpy array so we dont need to recalc it face_top (int): top-most pixel of face face_right (int): right-most pixel of face face_bottom (int): bottom-most pixel of face face_left (int): left-most pixel of face w (int) : width of face in pixels h (int) : height of face in pixels refimg_lnk (FaceRefimgLink): face_refimg_link data - viewOnly / just for convenience in viewer facefile_lnk (FaceFileLink): face_file_link data - viewOnly / just for convenience in viewer refimg (Refimg): link to the refimg used for this face (used in viewer). Set when there is a matched face, or None if no match """ __tablename__ = "face" id = db.Column(db.Integer, db.Sequence("face_id_seq"), primary_key=True ) face = db.Column( db.LargeBinary ) face_top = db.Column( db.Integer ) face_right = db.Column( db.Integer ) face_bottom = db.Column( db.Integer ) face_left = db.Column( db.Integer ) w = db.Column( db.Integer ) h = db.Column( db.Integer ) refimg_lnk = db.relationship("FaceRefimgLink", uselist=False, viewonly=True ) facefile_lnk = db.relationship("FaceFileLink", uselist=False, viewonly=True ) refimg =db.relationship("Refimg", secondary="face_refimg_link", uselist=False) fnmo = db.relationship("FaceNoMatchOverride", back_populates="face") ffmo = db.relationship("FaceForceMatchOverride", back_populates="face") ################################################################################ class FaceFileLink(PA, db.Model): """Class describing a Face_File_Link in the database NOTE: this data model is not perfect, each face in the same file is always found with the same model - so really should have ModelFileLink or something, in the long run this might even be better as ScanDetailsFileLink and ScanDetails Attributes: face_id (int): face id of row in Face table / foreign key - part primary key file_eid (int): entry id of a row in File table / foreign key - part primary key model_used(int): id of a row in AI_model table used to find the face / foreign key - part primary key """ __tablename__ = "face_file_link" face_id = db.Column(db.Integer, db.ForeignKey("face.id"), primary_key=True ) file_eid = db.Column(db.Integer, db.ForeignKey("file.eid"), primary_key=True ) model_used = db.Column(db.Integer, db.ForeignKey("ai_model.id"), primary_key=True ) ################################################################################ class FaceRefimgLink(PA, db.Model): """Class describing a Face_Regimg_Link in the database connects / implies a face has matched a refimg and we keep the distance too distance is mainly for debugging for now and shown in viewer Attributes: face_id (int): face id of row in Face table / foreign key - part primary key refimg_id (int): face id of row in Face table / foreign key - part primary key face_distance (float): distance value (how similar matched Face was) """ __tablename__ = "face_refimg_link" face_id = db.Column(db.Integer, db.ForeignKey("face.id"), primary_key=True ) refimg_id = db.Column(db.Integer, db.ForeignKey("refimg.id"), primary_key=True ) face_distance = db.Column(db.Float) ################################################################################ class FaceOverrideType(PA, db.Model): """Class describing a Face_Override_Type in the database when a face has an override, it will be a simple list of different types eg (forced match, no match, not a face, etc) Attributes: id (int): database id of row in FaceOverrideType table / part primary key name (str): name of the type of face override """ __tablename__ = "face_override_type" id = db.Column(db.Integer, db.Sequence("face_override_type_id_seq"), primary_key=True ) name = db.Column( db.String ) ################################################################################ class FaceNoMatchOverride(PA, db.Model): """Class describing a Face_No_Match_Override in the database used when a face does not match for some reason (type and face id connected) Attributes: id (int): database id of row in Face_No_Match_Override table / part primary key face_id (int): face id of row in Face table / foreign key - part primary key type_id (int): id of row in Face_Override_Type table / foreign key type (FaceOverrideType): convenience field for face override type for this face """ __tablename__ = "face_no_match_override" id = db.Column(db.Integer, db.Sequence("face_override_id_seq"), primary_key=True ) face_id = db.Column(db.Integer, db.ForeignKey("face.id"), primary_key=True ) type_id = db.Column(db.Integer, db.ForeignKey("face_override_type.id")) type = db.relationship("FaceOverrideType") face = db.relationship("Face", back_populates="fnmo") ################################################################################ class FaceForceMatchOverride(PA, db.Model): """Class describing a Face_Force_Match_Override in the database used when a face is forced to match for some reason (who and face id connected) Attributes: id (int): database id of row in Face_Force_Match_Override table / part primary key face_id (int): face id of row in Face table / foreign key - part primary key person_id (int): person id of row in Person table / foreign key - part primary key person (Person): convenience field for Person with forced match """ __tablename__ = "face_force_match_override" id = db.Column(db.Integer, db.Sequence("face_override_id_seq"), primary_key=True ) face_id = db.Column(db.Integer, db.ForeignKey("face.id"), primary_key=True ) person_id = db.Column(db.Integer, db.ForeignKey("person.id"), primary_key=True ) person = db.relationship("Person") face = db.relationship("Face", back_populates="ffmo")