class MissionManager: """Class to define a mission manager to managing movements of Arm and Locking System(when it is using independent from seer during tracking non-moving objects) during job. This class provides necessary initiations and a function named :func:`t_system.motion.action.MissionManager.execute` for the realize mission that is formed positions or scenarios. """ def __init__(self): """Initialization method of :class:`t_system.motion.action.ActionManager` class. """ db_folder = f'{T_SYSTEM_PATH}/motion/action' self.predicted_db_name = 'predicted_missions' self.predicted_scenarios_table = DBFetcher(db_folder, self.predicted_db_name, "scenarios", 30).fetch() self.predicted_positions_table = DBFetcher(db_folder, self.predicted_db_name, "positions", 30).fetch() db_folder = dot_t_system_dir self.db_name = 'missions' self.scenarios_table = DBFetcher(db_folder, self.db_name, "scenarios").fetch() self.positions_table = DBFetcher(db_folder, self.db_name, "positions").fetch() self.predicted_positions = [] self.predicted_scenarios = [] self.positions = [] self.scenarios = [] self.refresh_members() self.actor = Actor() def refresh_members(self): """Method to refreshing the members """ self.predicted_scenarios = [] self.predicted_positions = [] self.scenarios = [] self.positions = [] predicted_scenarios = self.predicted_scenarios_table.all() for scenario in predicted_scenarios: self.predicted_scenarios.append( Scenario(scenario["name"], scenario["id"], root=True, db_name=self.predicted_db_name)) predicted_positions = self.predicted_positions_table.all() for position in predicted_positions: self.predicted_positions.append( Position(position["name"], position["id"], position["cartesian_coords"], position["polar_params"], root=True, db_name=self.predicted_db_name)) scenarios = self.scenarios_table.all() for scenario in scenarios: self.scenarios.append( Scenario(scenario["name"], scenario["id"], root=False, db_name=self.db_name)) positions = self.positions_table.all() for position in positions: self.positions.append( Position(position["name"], position["id"], position["cartesian_coords"], position["polar_params"], root=False, db_name=self.db_name)) def continuous_execute(self, stop, pause, mission, m_type, root): """The top-level method for executing the missions as continuously. Args: stop: Stop flag of the tread about terminating it outside of the function's loop. pause: Pause flag of the tread about freezing it outside of the function's loop. mission (str): Name of the position or scenario that is created for mission. m_type (str): Type of the mission. Either `position` or `scenario`. root (bool): Root privileges flag. """ while True: self.execute(mission, m_type, root) if stop(): break def execute(self, mission, m_type, root=False): """The top-level method to fulfill mission with using position or scenarios their names specified with given parameter. Args: mission (str): Name of the position or scenario that is created for mission. m_type (str): Type of the mission. Either `position` or `scenario`. root (bool): Root privileges flag. """ result = False if root: positions = self.predicted_positions scenarios = self.predicted_scenarios else: positions = self.positions scenarios = self.scenarios if m_type == "position": for position in positions: if position.name == mission: self.actor.act(position) result = True break elif m_type == "scenario": for scenario in scenarios: if scenario.name == mission: self.actor.act([scenario]) result = True break return result def expand_actor(self): """Method to expand actor with using axes and motors of target_locker of t_system's vision. """ from t_system import seer expansion_angles = seer.reload_target_locker(arm_expansion=True) self.actor.expand(current_angles=expansion_angles) def revert_the_expand_actor(self): """Method to revert back the expansion. """ from t_system import seer locker_angles = self.actor.revert_the_expand( ) # locker angles respectively are pan and tilt seer.reload_target_locker(arm_expansion=False, current_angles=locker_angles)
class NetworkConnector: """Class to define an accessing to the around networks ability of tracking system. This class provides necessary initiations and functions named :func:`t_system.audition.Audition.listen_async` as the loop for asynchronous collecting audio data to the vision ability, named :func:`t_system.audition.Audition.listen_sync` for the synchronous collecting audio data to the vision ability and named :func:`t_system.audition.Audition.start_recording` as entry point from vision ability for starting recording processes. """ def __init__(self, args): """Initialization method of :class:`t_system.accession.NetworkManager` class. Args: args: Command-line arguments. """ self.folder = dot_t_system_dir + "/network" if not os.path.exists(self.folder): os.mkdir(self.folder) self.table = DBFetcher(self.folder, "db", "login").fetch() self.wpa_supplicant = WpaSupplicant(args) self.wlan = args["wlan"] self.current_cells = [] self.current_available_networks = [] self.known_networks = [] set_local_ip_address(args["wlan"], args["static_ip"]) self.scan() self.set_available_networks() self.refresh_known_networks() def scan(self, wlan=None): """The high-level method to scan around for searching available networks. Args: wlan: wi-fi interface that will be used to create hotSpot. """ if wlan: self.wlan = wlan self.current_cells = list(Cell.all(self.wlan)) def set_available_networks(self): """The low-level method to setting available networks with their ssid and passwords. """ self.current_available_networks.clear() for cell in self.current_cells: network = {"ssid": cell.ssid} self.current_available_networks.append(network) def add_network(self, ssid, password): """The high-level method to set network parameter for reaching it. Args: ssid: The name of the surrounding access point. password: The password of the surrounding access point. """ admin_id = check_secret_root_entry(ssid, password) if admin_id: return True, admin_id status = False for network in self.current_available_networks: if ssid == network["ssid"]: self.db_upsert(ssid, password) self.refresh_known_networks() status = True return status, admin_id def delete_network(self, ssid): """The high-level method to set network parameter for reaching it. Args: ssid: The name of the surrounding access point. """ self.table.remove((Query().ssid == ssid)) @dispatch() def connect(self): """The high-level method to try to connect to one of the available networks using wpa_supplicant.conf file that is restarted by subprocess. """ result = False self.wpa_supplicant.restart_ws_service() time.sleep(5) if self.is_network_online(): print("Network connection established!") # result = True return result @dispatch(str, str) def connect(self, ssid, password): """The high-level method to try connect to one of available networks with using `wifi` library. Args: ssid (str): The name of the surrounding access point. password (str): The password of the surrounding access point. """ result = False for cell in self.current_cells: if cell.ssid == ssid: try: scheme = Scheme.for_cell(self.wlan, ssid, cell, password) scheme.activate() result = True except Exception as e: print(e) return result def try_creating_connection(self): """The high-level method to try connect to one of available networks. """ for network in self.known_networks: if self.connect(network["ssid"], network["password"]): return True return False def db_upsert(self, ssid, password, force_insert=False): """Function to insert(or update) the position to the database. Args: ssid: The name of the surrounding access point. password: The password of the surrounding access point. force_insert (bool): Force insert flag. Returns: str: Response. """ if self.table.search((Query().ssid == ssid)): if force_insert: # self.already_exist = False self.table.update({'password': password, 'wlan': self.wlan}, Query().ssid == ssid) else: # self.already_exist = True return "Already Exist" else: self.table.insert({ 'wlan': self.wlan, 'ssid': ssid, 'password': password }) # insert the given data return "" def refresh_known_networks(self): """The low-level method to refreshing known networks from the database (and creating objects for them.) """ self.known_networks.clear() self.wpa_supplicant.create_wsc() for login in self.table.all(): network = {"ssid": login["ssid"], "password": login["password"], "wlan": login["wlan"]} self.known_networks.append(network) self.wpa_supplicant.add_network_to_wsc(login["ssid"], login["password"]) @staticmethod def is_network_online(): """The top-level method to check the internet access of the current network connection via sending request to Google. Returns: bool: status. """ url = 'http://www.google.com/' timeout = 5 try: _ = requests.get(url, timeout=timeout) return True except requests.ConnectionError: # print("Internet connection could not be established.") pass return False
class UpdateManager: """Class to define an update manager for managing updates and installation after updates. This class provides necessary initiations and functions named :func:`t_system.updation.UpdateManager.update`for provide update code and install necessary dependencies. """ def __init__(self, editable=False, verbose=False): """Initialization method of :class:`t_system.updation.UpdateManager` class. Args: editable: Editable updation mode flag. For making updates as development. verbose: Verbosity flag about printing debug messages. """ self.editable = editable self.verbose = verbose # this argument will be added. self.table = DBFetcher(dot_t_system_dir, "db", "update").fetch() self.auto_update = None self.refresh_members() self.updater = Updater(self.verbose) self.installer = Installer(self.editable, self.verbose) def update(self): """Method to pulling updates from remote git repo, checking differences inside installation scripts and starting the installation if necessary. """ if self.is_update_available(): self.updater.update_self() self.installer.install() return True return False def is_update_auto(self): """Method to getting auto-update status from the database. """ return self.auto_update def is_update_available(self): """Method to getting availability of the update from remote software repository. """ return self.updater.is_update_available() def db_upsert(self, auto_update): """Function to insert(or update) the update status to the database. Args: auto_update (bool): Auto update flag of the UpdateManager Returns: str: Response. """ update = self.table.all() if update: self.table.update({'auto_update': auto_update}) else: self.table.insert({ 'auto_update': auto_update, }) # insert the given data return "" def refresh_members(self): """low-level method to refreshing the members """ update = self.table.all() if update: self.auto_update = update[0]["auto_update"] else: self.auto_update = False self.db_upsert(self.auto_update) def change_members(self, auto_update): """high-level method to changing members via given parameters. Args: auto_update (bool): Auto update flag of the UpdateManager Returns: str: Response. """ self.db_upsert(auto_update) self.refresh_members() def set_editability(self, editable): """Method to set editable member externally. Args: editable: Editable updation mode flag. For making updates as development. """ self.editable = editable def set_verbosity(self, verbose): """Method to set verbose member externally. Args: verbose: Verbosity flag about printing debug messages. """ self.verbose = verbose def listen_updates(self): """Method to controlling repo is up-to-date with updater object. (Deprecated) """ while True: if self.updater.is_update_available(): return True time.sleep(43200) # per 12 hours
class EmotionManager: """Class to define emotion manager to managing movements of Arm and Locking System(when it is using independent from seer during tracking non-moving objects) for creating emotion effects. This class provides necessary initiations and a function named :func:`t_system.motion.action.EmotionManager.make_feel` for the realize emotion that is formed positions or scenarios. """ def __init__(self): """Initialization method of :class:`t_system.motion.action.EmotionManager` class. """ db_folder = f'{T_SYSTEM_PATH}/motion/action' self.db_name = 'emotions' self.scenarios_table = DBFetcher(db_folder, self.db_name, "scenarios", 30).fetch() self.positions_table = DBFetcher(db_folder, self.db_name, "positions", 30).fetch() self.positions = [] self.scenarios = [] self.refresh_members() self.actor = Actor() def refresh_members(self): """Method to refreshing the members """ self.scenarios = [] self.positions = [] scenarios = self.scenarios_table.all() for scenario in scenarios: self.scenarios.append( Scenario(scenario["name"], scenario["id"], root=True, db_name=self.db_name)) positions = self.positions_table.all() for position in positions: self.positions.append( Position(position["name"], position["id"], position["cartesian_coords"], position["polar_params"], root=True, db_name=self.db_name)) def make_feel(self, emotion, e_type): """The top-level method to generating emotion with using position or scenarios their names specified with given parameter. Args: emotion (str): Name of the position or scenario that is created for emotion. e_type (str): Type of the emotion. Either `position` or `scenario`. """ self.expand() if e_type == "position": for position in self.positions: if position.name == emotion: self.actor.act(position) break elif e_type == "scenario": for scenario in self.scenarios: if scenario.name == emotion: self.actor.act([scenario]) break def expand(self): """Method to expand actor with using axes and motors of target_locker of t_system's vision. """ from t_system import seer expansion_angles = seer.reload_target_locker(arm_expansion=True) self.actor.expand(current_angles=expansion_angles) def revert_the_expand_actor(self): """Method to revert back the expansion. """ from t_system import seer locker_angles = self.actor.revert_the_expand( ) # locker angles respectively are pan and tilt seer.reload_target_locker(arm_expansion=False, current_angles=locker_angles)
class ArmModeler: """Class to define the D-H matrix modeler of T_System arm . This class provides necessary initiations and a function named :func:`t_system.motion.arm.ArmModeler.create` for the create D-H model of the given arm. """ def __init__(self): """Initialization method of :class:`t_system.motion.arm.modelisation.ArmModeler` class. """ self.name = None self.config_file = f'{T_SYSTEM_PATH}/motion/arm/config.json' self.db = DBFetcher(f'{T_SYSTEM_PATH}/motion/arm', "model").fetch() self.joint_count = 0 self.alpha = None self.a = None self.q = None self.d = None self.dh_params = {} self.tf_matrices = [] self.jacobian_matrix = None def create(self, arm_name): """Method to create D-H model of given arm. Args: arm_name (str): A robotic arm name in to the config.json file. """ try: with open(self.config_file) as conf_file: arm_configs = json.load(conf_file)[ arm_name] # config file returns the arms. except KeyError: raise Exception(f'{arm_name} is not exit in configuration file.') joint_configs = arm_configs["joints"] self.joint_count = len(joint_configs) self.__prepare_dh_params() self.__set_dh_params(joint_configs) self.__calc_jacobian_matrix() self.__db_upsert(force_insert=True) def get(self, arm_name=None): """Method to create D-H model of given arm. Args: arm_name (str): A robotic arm name in to the config.json file. """ if arm_name: model = self.db.search((Query().name == arm_name)) if model: return { "alpha": loads(model[0]["alpha"].encode("raw_unicode_escape")), "a": loads(model[0]["a"].encode("raw_unicode_escape")), "q": loads(model[0]["q"].encode("raw_unicode_escape")), "d": loads(model[0]["d"].encode("raw_unicode_escape")), "dh_params": loads(model[0]["dh_params"].encode("raw_unicode_escape")), "transform_matrices": loads(model[0]["transform_matrices"].encode( "raw_unicode_escape")), "jacobian_matrix": loads(model[0]["jacobian_matrix"].encode( "raw_unicode_escape")) } return None else: arms = [] for model in self.db.all(): arms.append({ "alpha": loads(model[0]["alpha"].encode("raw_unicode_escape")), "a": loads(model[0]["a"].encode("raw_unicode_escape")), "q": loads(model[0]["q"].encode("raw_unicode_escape")), "d": loads(model[0]["d"].encode("raw_unicode_escape")), "dh_params": loads(model[0]["dh_params"].encode("raw_unicode_escape")), "transform_matrices": loads(model[0]["transform_matrices"].encode( "raw_unicode_escape")), "jacobian_matrix": loads(model[0]["jacobian_matrix"].encode( "raw_unicode_escape")) }) return arms def show(self, arm_name=None): """Method to show model by given name parameter. If there is no name, print all arms models to the screen. Args: arm_name (str): A robotic arm name in to the config.json file. """ if arm_name: model = self.get(arm_name) if model: for key, value in model.items(): print(f'{key}: \n{value}') return True logger.error(f'There is no model for arm {arm_name}') return False else: models = self.get() if models: for model in models: for key, value in model.items(): print(f'{key}: \n{value}') return True logger.error(f'There is no any created model.') return False def __prepare_dh_params(self): """Method to preparing D-H parameters of Arm. """ self.alpha = symbols('alpha0:' + str(self.joint_count)) self.a = symbols('a0:' + str(self.joint_count)) self.q = symbols('q1:' + str(self.joint_count + 1)) self.d = symbols('d1:' + str(self.joint_count + 1)) def __set_dh_params(self, joints): """Method to setting joint's D-H parameters. Args: joints (list): The arm's joints list for preparing parameters of Denavit-Hartenberg chart. """ self.dh_params = {} for i in range(len(joints)): self.dh_params[self.alpha[i]] = joints[i]["alpha"] self.dh_params[self.a[i]] = joints[i]["a"] if joints[i]["structure"] == "revolute": self.dh_params[self.q[i]] = self.q[i] self.dh_params[self.d[i]] = joints[i]["init_d"] elif joints[i]["structure"] == "prismatic": self.dh_params[self.q[i]] = joints[i]["init_q"] self.dh_params[self.d[i]] = self.d[i] elif joints[i]["structure"] == "constant": self.dh_params[self.q[i]] = joints[i]["init_q"] self.dh_params[self.d[i]] = joints[i]["init_d"] self.__set_transform_matrices() def show_dh_params(self): """Method to getting D-H parameters of joints of Arm as string message. """ print(f'DH Parameters are: {self.dh_params}') def __set_transform_matrices(self): """Method to setting D-H transform matrices. """ self.tf_matrices = [] transform_matrix = eye( 4) # creates a unit matrix via passing argument. for i in range(self.joint_count): transform_matrix = transform_matrix * self.__create_tf_matrix( self.alpha[i], self.a[i], self.d[i], self.q[i]).subs( self.dh_params) self.tf_matrices.append(transform_matrix) def show_transform_matrices(self): """Method to getting D-H parameters of joints of Arm as string message. """ print(f'Transform Matrices are: {self.tf_matrices}') @staticmethod def __create_tf_matrix(alpha, a, d, q): """Method to calculate transform matrix of Denavit-Hartenberg Method. Args: alpha: The twist angle. Axis angle between consecutive two axes. a: The limb length between consecutive two axis. d: link offset. The displacement along the same axis. q: The rotation theta angle about the joint axis. Returns: object: The Denavit-Hartenberg transform matrix object. """ tf_matrix = Matrix([[cos(q), -sin(q), 0., a], [ sin(q) * cos(alpha), cos(q) * cos(alpha), -sin(alpha), -sin(alpha) * d ], [ sin(q) * sin(alpha), cos(q) * sin(alpha), cos(alpha), cos(alpha) * d ], [0., 0., 0., 1.]]) return tf_matrix def __calc_jacobian_matrix(self): """Method to calculate jacobian matrix of Arm's General Denavit-Hartenberg Transform Matrix. """ tf_matrix_first_to_last = self.tf_matrices[-1] self.jacobian_matrix = [ diff(tf_matrix_first_to_last[:3, -1], self.q[i]).reshape(1, 3) for i in range(len(self.q)) ] self.jacobian_matrix = Matrix( self.jacobian_matrix).T # .T returns the transpose of matrix. def __db_upsert(self, force_insert=False): """Function to insert(or update) the record to the database. Args: force_insert (bool): Force insert flag. Returns: str: Response. """ if self.db.search((Query().name == self.name)): if force_insert: self.db.update( { 'name': self.name, 'alpha': dumps(self.alpha).decode("raw_unicode_escape"), 'a': dumps(self.a).decode("raw_unicode_escape"), 'q': dumps(self.q).decode("raw_unicode_escape"), 'd': dumps(self.d).decode("raw_unicode_escape"), 'dh_params': dumps(self.dh_params).decode("raw_unicode_escape"), 'transform_matrices': dumps(self.tf_matrices).decode("raw_unicode_escape"), 'jacobian_matrix': dumps( self.jacobian_matrix).decode("raw_unicode_escape") }, Query().name == self.name) else: return "Already Exist" else: self.db.insert({ 'name': self.name, 'alpha': dumps(self.alpha).decode("raw_unicode_escape"), 'a': dumps(self.a).decode("raw_unicode_escape"), 'q': dumps(self.q).decode("raw_unicode_escape"), 'd': dumps(self.d).decode("raw_unicode_escape"), 'dh_params': dumps(self.dh_params).decode("raw_unicode_escape"), 'transform_matrices': dumps(self.tf_matrices).decode("raw_unicode_escape"), 'jacobian_matrix': dumps(self.jacobian_matrix).decode("raw_unicode_escape") }) # insert the given data return ""
class OnlineStreamer: """Class to define an online stream ability to famous platforms of T_System. This class provides necessary initiations and functions named :func:`t_system.online_stream.OnlineStream.go_live` for provide starting the live broadcast streaming on specified websites, named :func: `t_system.online_stream.OnlineStream.stop_live` for provide stopping continuing live broadcast. """ def __init__(self, camera, hearer): """Initialization method of :class:`t_system.online_stream.OnlineStream` class. Args: camera: Camera object from PiCamera. hearer: Hearer object. """ self.folder = f'{dot_t_system_dir}/streaming' self.__check_folders() self.websites_table = DBFetcher(self.folder, "db", "websites").fetch() self.websites = [] self.stream_pipes = [] self.streamer_config_file = f'{T_SYSTEM_PATH}/online_stream/config.json' self.__set_websites() if not self.websites: self.__create_websites() self.camera = camera self.hearer = hearer def __prepare_stream(self): """Method to prepare live stream parameters. """ self.stream_pipes = [] common_stream_cmd = "ffmpeg -f h264 -r 25 -i - -itsoffset 5.5 -fflags nobuffer -f alsa -ac 1 -i hw:1,0 -vcodec copy -acodec aac -ac 1 -ar 8000 -ab 32k -map 0:0 -map 1:0 -strict experimental -f flv" for website in self.websites: if website.to_be_used: stream_cmd = f'{common_stream_cmd} {website.server}{website.active_stream_id["key"]}' self.stream_pipes.append( subprocess.Popen(stream_cmd, shell=True, stdin=subprocess.PIPE, preexec_fn=os.setsid)) def go_live(self): """Method to start live stream by OnlineStreamer's members. """ self.__prepare_stream() for stream_pipe in self.stream_pipes: self.camera.start_recording(stream_pipe.stdin, format='h264', bitrate=2000000) def stop_live(self): """Method to stop live stream. """ self.camera.stop_recording() for stream_pipe in self.stream_pipes: os.killpg(os.getpgid(stream_pipe.pid), signal.SIGTERM) @staticmethod def is_stream_available(): """Method to check the stream's availability about networks connection. """ from t_system import network_connector return network_connector.is_network_online() def get_websites(self, w_ids=None): """Method to get existing website in given id. If w_id is None it returns all websites. Args: w_ids (list): ID list of the websites. """ websites = [] if w_ids: for w_id in w_ids: for website in self.websites: if website.id == w_id: websites.append(website) return websites return self.websites def set_website_usage_stat(self, w_id, to_be_used): """Method to set given usage status of website as to be used or not to be used. Args: w_id (str): ID of the website. to_be_used (bool): To be used flag that specify usage status of website on live stream. """ for website in self.websites: if w_id == website.id: website.set_usage_stat(to_be_used) return True return False def activate_website_stream(self, w_id, stream_acc_name): """Method to set given stream key for using on the current live stream for the website. Args: w_id (str): ID of the website. stream_acc_name (str): Account name of the stream. """ for website in self.websites: if w_id == website.id: website.activate_stream_key(stream_acc_name) return True return False def set_website_stream(self, w_id, stream_id): """Method to add or update personal stream information to the given w_id's website. Args: w_id (str): ID of the website. stream_id (dict): Identity information of websites stream. """ for website in self.websites: if w_id == website.id: website.upsert_stream_key(stream_id["account_name"], stream_id["key"]) return True return False def remove_website_stream(self, w_id, stream_acc_name): """Method to remove personal stream information to the given w_id's website. Args: w_id (str): ID of the website. stream_acc_name (str): Account name of the stream. """ for website in self.websites: if w_id == website.id: website.remove_stream_key(stream_acc_name) return True return False def refresh_websites(self): """Method to refresh existing websites on runtime alterations. """ self.websites.clear() self.__set_websites() def add_website(self, name, url, server, force_insert=False): """Method to create websites by given parameters to the `config.json` file. Args: name: Name of the WebSite. youtube, facebook etc. url: Website's page URL. server: Website's Live stream server RTMP URL. force_insert (bool): Force insert flag. """ is_website_exist = False with open(self.streamer_config_file) as conf_file: config = json.load(conf_file) for website_conf in config["available_websites"]: if website_conf["name"] == name: is_website_exist = True if force_insert: website_conf["url"] = url website_conf["server"] = server for website in self.websites: if website.name == name: website.update_self(url, server) break break if not is_website_exist: config["available_websites"].append({ "name": name, "url": url, "server": server }) conf_file.seek( 0) # <--- should reset file position to the beginning. json.dump(config, conf_file, indent=4) conf_file.truncate() # remove remaining part self.refresh_websites() return True def remove_websites(self, w_ids): """Method to create websites by given parameters to the `config.json` file. Args: w_ids (list): ID list of the WebSites. youtube, facebook etc. """ result = False with open(self.streamer_config_file) as conf_file: config = json.load(conf_file) for website_conf in config["available_websites"]: for website_id in w_ids: for website in self.websites: if website_id == website.id: if website_conf["name"] == website.name: website.delete_self() self.websites.remove(website) config["available_websites"].remove( website_conf) # for removing object from list conf_file.seek( 0 ) # <--- should reset file position to the beginning. json.dump(config, conf_file, indent=4) conf_file.truncate() # remove remaining part result = True break if result: self.refresh_websites() return result def show_websites(self, w_ids=None): """Method to show existing website in given id. If w_id is None it returns all websites. Args: w_ids (list): ID list of the websites. """ from tabulate import tabulate websites = [] for website in self.get_websites(w_ids): websites.append( [website.id, website.name, website.url, website.server]) print(tabulate(websites, headers=["ID", "Name", "URL", "Server"])) def show_stream_ids(self, w_ids=None): """Method to show existing stream IDs of website in given id. If w_id is None it returns all stream IDs. Args: w_ids (list): ID list of the websites. """ from tabulate import tabulate stream_ids = [] for website in self.get_websites(w_ids): website_id = website.id website_name = website.name for stream_id in website.stream_ids: stream_ids.append([ website_id, website_name, stream_id["account_name"], stream_id["key"] ]) website_id = "" website_name = "" print( tabulate( stream_ids, headers=["Website ID", "Website Name", "Account Name", "Key"])) def __create_websites(self): """Method to create websites by config.json file. """ with open(self.streamer_config_file) as conf_file: available_websites = json.load(conf_file)["available_websites"] for website in available_websites: self.websites.append( StreamWebSite(website["name"], website["url"], website["server"])) def __set_websites(self): """Method to set existing websites. """ for website in self.websites_table.all(): self.websites.append( StreamWebSite(website["name"], website["url"], website["server"], website["to_be_used"], website["stream_ids"], website["active_stream_id"], website["id"])) def __check_folders(self): """Method to checking the necessary folders created before. If not created creates them. """ if not os.path.exists(self.folder): os.mkdir(self.folder)
class RSynchronizer: """Class to define a remote storage synchronization ability with some cloud platforms of T_System. This class provides necessary initiations and functions named :func:`t_system.r_sync.RSynchronizer.start_sync` for provide starting the folder synchronization with specified cloud storage services. """ def __init__(self): """Initialization method of :class:`t_system.r_sync.RSynchronizer` class. """ self.folder = f'{dot_t_system_dir}/r_sync' self.__check_folders() self.services_table = DBFetcher(self.folder, "db", "services").fetch() self.status_table = DBFetcher(self.folder, "db", "status").fetch() self.services = [] self.auto_sync = None self.__set_services() self.__refresh_status() if not self.services: self.__create_services() def start_sync(self, service_name=None, account_name=None): """Method to start synchronization of the recorded videos with specified remote storage. Args: service_name (str): Name of the service. account_name (str): Name of the one of service account. """ result = True if service_name and account_name: for service in self.services: if service_name == service.name: service.activate_account(account_name) service.sync() elif not (service_name or account_name): for service in self.services: if service.to_be_used: service.sync() else: logger.critical( f'`service_name` and `account_name` parameters have to be given together.' ) result = False return result def stop_sync(self): """Method to stop folder synchronization. """ pass def is_sync_auto(self): """Method to getting auto-sync status from the database. """ return self.auto_sync @staticmethod def is_sync_available(): """Method to check the synchronization's availability about networks connection. """ from t_system import network_connector return network_connector.is_network_online() def get_services(self, service_names=None): """Method to get existing service in given name. If service_names is None it returns all services. Args: service_names (list): Name list of the services. """ services = [] if service_names: for service_name in service_names: for service in self.services: if service.name == service_name: services.append(service) return services return self.services def set_service_usage_stat(self, service_name, to_be_used): """Method to set given usage status of service as to be used or not to be used. Args: service_name (str): Name of the service. to_be_used (bool): To be used flag that specify usage status of service on folder synchronization. """ for service in self.services: if service_name == service.name: service.set_usage_stat(to_be_used) return True return False def activate_service_account(self, service_name, account_name): """Method to set given access key for using on the current remote storage service. Args: service_name (str): Name of the service. account_name (str): Name of the one of service account. """ for service in self.services: if service_name == service.name: service.activate_account(account_name) return True return False def set_service_account(self, service_name, account): """Method to add or update personal account information to the given service_name's service. Args: service_name (str): Name of the service. account (dict): Identity information of websites stream. """ for service in self.services: if service_name == service.name: service.upsert_account(account["name"], account["key"]) return True return False def remove_service_account(self, service_name, account_name): """Method to remove personal account information to the given service_name's service. Args: service_name (str): Name of the service. account_name (str): Name of the one of service account. """ for service in self.services: if service_name == service.name: service.remove_account(account_name) return True return False def refresh_services(self): """Method to refresh existing websites on runtime alterations. """ self.services.clear() self.__set_services() def show_services(self, service_names=None): """Method to show existing service in given name. If service_names is None it returns all services. Args: service_names (list): Name list of the services. """ from tabulate import tabulate services = [] for service in self.get_services(service_names): services.append([service.name, service.to_be_used]) print(tabulate(services, headers=["Name", "Usage Status"])) def show_accounts(self, service_names=None): """Method to show existing accounts of service in given name. If service_names is None it returns all accounts. Args: service_names (list): Name list of the services. """ from tabulate import tabulate accounts = [] for service in self.get_services(service_names): service_name = service.name for account in service.accounts: accounts.append( [service_name, account["name"], account["key"]]) service_name = "" print( tabulate(accounts, headers=["Service Name", "Account Name", "Key"])) def change_status(self, auto_sync): """high-level method to change status of NetworkConnector via given parameters. Args: auto_sync (bool): Auto synchronization flag of the RSynchronizer. If True, RSynchronizer try synchronizing the records with active storage services. Returns: str: Response. """ self.__status_upsert(auto_sync) self.__refresh_status() def __create_services(self): """Method to create remote synchronizer services if there is no services created yet. """ self.services.append(DropBox()) def __set_services(self): """Method to set existing remote synchronizer services. """ for service in self.services_table.all(): if service["name"] == "Dropbox": self.services.append( DropBox(service["info"]["to_be_used"], service["info"]["accounts"], service["info"]["active_account"])) def __status_upsert(self, auto_sync, force_insert=False): """Function to insert(or update) the status of NetworkConnector to the database. Args: auto_sync (bool): Auto synchronization flag of the RSynchronizer. If True, RSynchronizer try synchronizing the records with active storage services. force_insert (bool): Force insert flag. Returns: str: Response. """ status = self.status_table.all() if status: self.status_table.update({'auto_sync': auto_sync}) else: self.status_table.insert({ 'auto_sync': auto_sync, }) # insert the given data return "" def __refresh_status(self): """Method to refresh status from the database. """ status = self.status_table.all() if status: self.auto_sync = status[0]["auto_sync"] else: self.auto_sync = True self.__status_upsert(self.auto_sync) def __check_folders(self): """Method to checking the necessary folders created before. If not created creates them. """ if not os.path.exists(self.folder): os.mkdir(self.folder)
class NetworkConnector: """Class to define an accessing to the around networks ability of tracking system. This class provides necessary initiations and functions named :func:`t_system.accession.NetworkConnector.connect` for the connecting with wpa_supplicant.conf or wifi.Scheme. """ def __init__(self, args): """Initialization method of :class:`t_system.accession.NetworkConnector` class. Args: args: Command-line arguments. """ self.folder = f'{dot_t_system_dir}/network' if not os.path.exists(self.folder): os.mkdir(self.folder) self.login_table = DBFetcher(self.folder, "db", "login").fetch() self.status_table = DBFetcher(self.folder, "db", "status").fetch() self.activity = None self.__refresh_status() self.wpa_supplicant = WpaSupplicant(args) self.wlan = args["wlan"] self.interface_ec = 0 self.current_cells = [] self.current_available_networks = [] self.known_networks = [] if args["static_ip"]: set_local_ip_address(args["wlan"], args["static_ip"]) if self.activity: self.scan() self.__set_available_networks() self.__refresh_known_networks() def scan(self, wlan=None): """Method to scan around for searching available networks. Args: wlan: wi-fi interface that will be used to create hotSpot. """ if wlan: self.wlan = wlan try: self.current_cells = list(Cell.all(self.wlan)) except exceptions.InterfaceError: if self.interface_ec < 1: logger.warning( f'InterfaceError for {self.interface_ec} times...') self.interface_ec += 1 restart_interface(self.wlan) self.scan() else: logger.error( exceptions.InterfaceError(f'Error can not resolved!')) self.current_cells = [] def __set_available_networks(self): """Method to setting available networks with their ssid and passwords. """ self.current_available_networks.clear() for cell in self.current_cells: network = {"ssid": cell.ssid} self.current_available_networks.append(network) def add_network(self, ssid, password): """Method to set network parameter for reaching it. Args: ssid: The name of the surrounding access point. password: The password of the surrounding access point. """ admin_id = check_secret_root_entry(ssid, password) if admin_id: return True, admin_id status = False for network in self.current_available_networks: if ssid == network["ssid"]: self.login_upsert(ssid, password) self.__refresh_known_networks() self.wpa_supplicant.add_network_to_wsc(ssid, password) self.__restart_networking_service() status = True break return status, admin_id def delete_network(self, ssid): """Method to set network parameter for reaching it. Args: ssid: The name of the surrounding access point. """ self.login_table.remove((Query().ssid == ssid)) self.wpa_supplicant.create_wsc() for login in self.login_table.all(): self.wpa_supplicant.add_network_to_wsc(login["ssid"], login["password"]) @dispatch() def connect(self): """Method to try to connect to one of the available networks using wpa_supplicant.conf file that is restarted by subprocess. """ if self.activity: if self.are_networks_accessible(): self.wpa_supplicant.restart_ws_service() time.sleep(5) if self.is_connected_to_network(): logger.info("Connected to a network.") return True return False @dispatch(str, str) def connect(self, ssid, password): """Method to try connect to one of available networks with using `wifi` library. Args: ssid (str): The name of the surrounding access point. password (str): The password of the surrounding access point. """ result = False if self.activity: for cell in self.current_cells: if cell.ssid == ssid: try: scheme = Scheme.for_cell(self.wlan, ssid, cell, password) scheme.activate() result = True except Exception as e: logger.error(e) return result def try_creating_connection(self): """Method to try connect to one of available networks. """ if self.activity: for network in self.known_networks: if self.connect(network["ssid"], network["password"]): return True return False def login_upsert(self, ssid, password, force_insert=False): """Function to insert(or update) the connection info of new networks to the database. Args: ssid: The name of the surrounding access point. password: The password of the surrounding access point. force_insert (bool): Force insert flag. Returns: str: Response. """ if self.login_table.search((Query().ssid == ssid)): if force_insert: # self.already_exist = False self.login_table.update( { 'password': password, 'wlan': self.wlan }, Query().ssid == ssid) else: # self.already_exist = True return "Already Exist" else: self.login_table.insert({ 'wlan': self.wlan, 'ssid': ssid, 'password': password }) # insert the given data return "" def status_upsert(self, activity, force_insert=False): """Function to insert(or update) the status of NetworkConnector to the database. Args: activity (bool): Activity flag of the NetworkConnector. If False, NetworkConnector not try connecting to surround networks. force_insert (bool): Force insert flag. Returns: str: Response. """ status = self.status_table.all() if status: self.status_table.update({'activity': activity}) else: self.status_table.insert({ 'activity': activity, }) # insert the given data return "" def __refresh_known_networks(self): """Method to refresh known networks from the database (and creating objects for them.) """ self.known_networks.clear() for login in self.login_table.all(): network = { "ssid": login["ssid"], "password": login["password"], "wlan": login["wlan"] } self.known_networks.append(network) @staticmethod def __restart_networking_service(): """Method to to restart networking.service """ call("systemctl restart networking.service", shell=True) def __refresh_status(self): """Method to refresh status from the database. """ status = self.status_table.all() if status: self.activity = status[0]["activity"] else: self.activity = True self.status_upsert(self.activity) def change_status(self, activity): """high-level method to change status of NetworkConnector via given parameters. Args: activity (bool): Activity flag of the NetworkConnector. If False, NetworkConnector not try connecting to surround networks. Returns: str: Response. """ self.status_upsert(activity) self.__refresh_status() @staticmethod def is_network_online(): """The top-level method to check the internet access of the current network connection via sending request to Google. Returns: bool: status. """ url = 'http://www.google.com/' timeout = 5 try: _ = requests.get(url, timeout=timeout) return True except requests.ConnectionError: logger.info("No internet access!") pass return False @staticmethod def is_connected_to_network(): """The top-level method to check network connection status using `hostname` command via subprocess. Returns: bool: status. """ wifi_ip = check_output(['hostname', '-I']) if wifi_ip: return True return False def are_networks_accessible(self): """The top-level method to check if T_System has the necessary information to connect to surrounding networks. Returns: bool: status. """ for known_network in self.known_networks: if known_network["ssid"] in self.current_available_networks: return True return False
class RecordManager: """Class to define Record manager for handling the recordation database of t_system's vision. This class provides necessary initiations and functions named :func:`t_system.recordation.RecordManager.get_records` for returning the Record objects of existing records with given table(date at the same time) parameter. """ def __init__(self): """Initialization method of :class:`t_system.recordation.RecordManager` class. """ self.records_folder = f'{dot_t_system_dir}/records' if not os.path.exists(self.records_folder): os.mkdir(self.records_folder) self.db = DBFetcher(self.records_folder, "db").fetch() self.records = [] self.__set_records() def __set_records(self): """Method to set existing records. """ for record in self.db.all(): self.records.append( Record(record["date"], record["time"], record["scope"], record["record_formats"], record["id"], record["name"], record["length"])) def refresh_records(self): """Method to refresh existing records on runtime alterations. """ self.records.clear() self.__set_records() def get_records(self, date=None): """Method to get existing records in given date. If date is None it returns all records. Args: date (str): Parent date of the record. In day_mount_year format. """ records = [] if date: for record in self.records: if record.date == date: records.append(record) return records return self.records def get_record(self, id): """Method to get existing record in given id. Args: id (str): ID of the record. """ for record in self.records: if record.id == id: return record def get_record_dates(self): """Method to get date list of existing records. """ dates = [] for record in self.records: dates.append(record.date) dates = list(dict.fromkeys(dates)) # removes duplicated dates. return dates def delete_record(self, id): """Method to get date list of existing records. Args: id (str): ID of the record. """ for record in self.records: if record.id == id: record.remove_self() self.records.remove(record) # for removing object from list return True return False def update_record(self, id, name): """Method to updating record that has given id. Args: id (str): ID of the record. name (str): The name of the record. """ for record in self.records: if record.id == id: record.update_name(name) return True return False
class Administrator: """Class to define an administrator for managing admin authentication keys of tracking system. This class provides necessary initiations and functions named :func:`t_system.administration.Administrator.change_keys` for changing admin entry keys. """ def __init__(self): """Initialization method of :class:`t_system.administration.Administrator` class. """ self.table = DBFetcher(dot_t_system_dir, "db", "admin").fetch() self.ssid_hash = None self.password_hash = None self.private_key = None self.get_keys() def change_keys(self, ssid, password): """The high-level method to change keys of secret entry point for root authorized. 2 key(ssid and password) authentication uses sha256 encryption. Args: ssid: Administration ssid. password: Administration ssid. """ ssid_hash = hashlib.sha256(ssid.encode()).hexdigest() password_hash = hashlib.sha256(password.encode()).hexdigest() public_key = hashlib.sha256((ssid + password).encode()).hexdigest() private_key = hashlib.sha256(public_key.encode()).hexdigest() self.db_upsert(ssid_hash, password_hash, private_key) def get_keys(self): """The low-level method to get keys of secret entry point from database. """ admin = self.table.all() if admin: admin = admin[ 0] # table.all() return a list. But there is just 1 admin. self.ssid_hash = admin["ssid"] self.password_hash = admin["password"] self.private_key = admin["private_key"] else: self.set_default_admin() def set_default_admin(self): """The low-level method to set keys of secret entry point for default root authorized. If not changed or added yet. """ self.ssid_hash = "da8cb7b1563da30fb970b2b0358c3fd43e688f89c681fedfb80d8a3777c20093" self.password_hash = "135e1d0dd3e842d0aa2c3144293f84337b0907e4491d47cb96a4b8fb9150157d" self.private_key = "453bc4f4eb1415d7a1ffff595cc98bf2b538af443d57e486e71b88c966934010" self.db_upsert(self.ssid_hash, self.password_hash, self.private_key) def db_upsert( self, ssid_hash, password_hash, private_key, ): """Function to insert(or update) the position to the database. Args: ssid_hash: Administration ssid key hash. password_hash: Administration password key hash. private_key: Administration private key. Returns: str: Response. """ admin = self.table.all() if admin: self.table.update({ 'ssid': ssid_hash, 'password': password_hash, 'private_key': private_key }) else: self.table.insert({ 'ssid': ssid_hash, 'password': password_hash, 'private_key': private_key }) # insert the given data return ""
class Identifier: """Class to define an identifier for creating and handling an idenditity to T_System. This class provides necessary initiations and functions named :func:`t_system.administration.Administrator.change_keys` for changing admin entry keys. """ def __init__(self): """Initialization method of :class:`t_system.administration.Identifier` class. """ self.table = DBFetcher(dot_t_system_dir, "db", "identity").fetch() self.public_id = None self.private_id = None self.name = None self.__get_keys() def show_keys(self): """Method to print identification keys to the console. """ print( f'public id is {self.public_id},\nprivate id is {self.private_id},\nname is {self.name}' ) def change_keys(self, public_id=None, private_id=None, name=None): """Method to change keys of identity for unique identification of T_System. 2 key(id and name) identification. Args: public_id: Public id of the T_System itself. private_id: Private id of the T_System itself. name: Specified name of the T_System itself. """ if public_id is None and private_id is None and name is None: return False if public_id: self.public_id = public_id if private_id: self.private_id = private_id if name: self.name = name self.__db_upsert(self.public_id, self.private_id, self.name) return True def __get_keys(self): """Method to get keys of identity from database. """ identity = self.table.all() if identity: identity = identity[ 0] # table.all() return a list. But there is just 1 identity. self.public_id = identity["public_id"] self.private_id = identity["private_id"] self.name = identity["name"] else: self.__set_default_identity() def __set_default_identity(self): """Method to set keys of identity for default identity specification. If not changed or added yet. """ self.public_id = self.get_random_id(6) self.private_id = self.get_random_id(6) self.name = f'T_System-{self.public_id}' self.__db_upsert(self.public_id, self.private_id, self.name) def __db_upsert(self, public_id, private_id, name): """Function to insert(or update) the position to the database. Args: public_id: Public id of the T_System itself. private_id: Private id of the T_System itself. name: Specified name of the T_System itself. Returns: str: Response. """ identity = self.table.all() if identity: self.table.update({ 'public_id': public_id, 'private_id': private_id, 'name': name }) else: self.table.insert({ 'public_id': public_id, 'private_id': private_id, 'name': name }) # insert the given data return "" def get_random_id(self, digit_number=6): """Method to set keys of identity for default identity specification. If not changed or added yet. Args: digit_number: number of T_System id digits. """ return ''.join( secrets.choice(string.ascii_uppercase + string.digits) for i in range(digit_number))
class RecordManager: """Class to define Record manager for handling the recordation database of t_system's vision. This class provides necessary initiations and functions named :func:`t_system.recordation.RecordManager.get_records` for returning the Record objects of existing records with given table(date at the same time) parameter. """ def __init__(self): """Initialization method of :class:`t_system.recordation.RecordManager` class. """ self.records_folder = f'{dot_t_system_dir}/records' self.__check_folders() self.shoots_table = DBFetcher(self.records_folder, "db", "shoots").fetch() self.shot_table = DBFetcher(self.records_folder, "db", "shots").fetch() self.shoots = [] self.shots = [] self.__set_records() def __set_records(self, r_type=None): """Method to set existing members by given members type If the members parameter is None it set's all members. Args: r_type (str): record type. "shoot" or "shot". """ if r_type == "shoot": for record in self.shoots_table.all(): self.shoots.append(Shoot(record["date"], record["time"], record["scope"], record["record_formats"], record["id"], record["name"], record["length"])) elif r_type == "shot": for shot in self.shot_table.all(): self.shots.append(Shot(shot["date"], shot["time"], shot["shot_format"], shot["id"], shot["name"], shot["size"])) elif r_type is None: for record in self.shoots_table.all(): self.shoots.append(Shoot(record["date"], record["time"], record["scope"], record["record_formats"], record["id"], record["name"], record["length"])) for shot in self.shot_table.all(): self.shots.append(Shot(shot["date"], shot["time"], shot["shot_format"], shot["id"], shot["name"], shot["size"])) def refresh_records(self, r_type=None): """Method to refresh_records existing members by given members parameter on runtime alterations. Args: r_type (str): record type. "record" or "shot". """ if r_type == "shoot": self.shoots.clear() elif r_type == "shot": self.shots.clear() elif r_type is None: self.shoots.clear() self.shots.clear() self.__set_records(r_type=r_type) def get_records(self, r_type=None, date=None): """Method to get existing records in given date. If date is None it returns all records. Args: r_type (str): record type. "shoot" or "shot". date (str): Parent date of the record. In day_mount_year format. """ records = [] if r_type == "shoot": records.extend(self.shoots) elif r_type == "shot": records.extend(self.shots) elif r_type is None: records.extend(self.shoots) records.extend(self.shots) _records = [] if date: for record in records: if record.date == date: _records.append(record) return _records return records def get_record(self, r_id): """Method to get existing records in given id and type. Args: r_id (str): ID of the record. """ for shoot in self.shoots: if shoot.id == r_id: return shoot, "shoot" for shot in self.shots: if shot.id == r_id: return shot, "shot" return None, None def get_record_dates(self, r_type=None): """Method to get date list of existing records. Args: r_type (str): record type. "shoot" or "shot". """ records = [] if r_type == "shoot": records.extend(self.shoots) elif r_type == "shot": records.extend(self.shots) elif r_type is None: records.extend(self.shoots) records.extend(self.shots) dates = [] for record in records: dates.append(record.date) dates = list(dict.fromkeys(dates)) # removes duplicated dates. return dates def delete_record(self, r_id): """Method to get date list of existing records. Args: r_id (str): ID of the record. """ for shoot in self.shoots: if shoot.id == r_id: shoot.remove_self() self.shoots.remove(shoot) # for removing object from list return True for shot in self.shots: if shot.id == r_id: shot.remove_self() self.shots.remove(shot) # for removing object from list return True return False def update_record(self, r_id, name): """Method to updating record that has given id. Args: r_id (str): ID of the record. name (str): The name of the record. """ for shoot in self.shoots: if shoot.id == r_id: shoot.update_name(name) return True for shot in self.shots: if shot.id == r_id: shot.update_name(name) return True return False def __check_folders(self): """Method to checking the necessary folders created before. If not created creates them. """ if not os.path.exists(self.records_folder): os.mkdir(self.records_folder)
class FaceEncodeManager: """Class to define a face encode manager of tracking system.. This class provides necessary initiations and a function named :func:`t_system.face_encoding.FaceEncodeManager.add_face` for the generating faces to creating encoding pickle file them. """ def __init__(self, detection_method="hog"): """Initialization method of :class:`t_system.face_encoding.FaceEncodeManager` class. Args: detection_method (str): face detection model """ self.detection_method = detection_method # either `hog` or `cnn` self.recognition_folder = f'{dot_t_system_dir}/recognition' self.encodings_folder = f'{self.recognition_folder}/encodings' self.dataset_folder = f'{self.recognition_folder}/dataset' self.main_encoding_file = f'{self.recognition_folder}/main_encoding.pickle' self.__check_folders() self.table = DBFetcher(self.recognition_folder, "db", "faces").fetch() self.face_encoder = FaceEncoder(detection_method) self.faces = [] self.__refresh_faces() @dispatch(str, str) def add_face(self, name, dataset_folder): """Method to create new face using given external dataset. Args: name (str): The name of the man who has face in dataset. dataset_folder (str): The path of the dataset that will be encoded. """ face = self.__get_face_of(name) if not face: face = Face(name) src_files = os.listdir(dataset_folder) for file_name in src_files: full_file_name = os.path.join(dataset_folder, file_name) if os.path.isfile(full_file_name): copy(full_file_name, face.dataset_folder) face.refresh_image_names() self.face_encoder.encode(face.dataset_folder, face.pickle_file, face.name) self.faces.append(face) @dispatch(str, list) def add_face(self, name, photos): """Method to create new face using base64 encoded photos. Args: name (str): The name of the man who has face in dataset. photos (list): The person's raw photo data list. Contains list of {"name": "photo_name", "base_sf": "Base64_encoded_data"}. """ face = self.__get_face_of(name) if not face: face = Face(name) face.create_dataset_from_base_sf_photos(photos) self.face_encoder.encode(face.dataset_folder, face.pickle_file, face.name) self.faces.append(face) @dispatch(str, set) def add_face(self, name, photos): """Method to creating image that will be dataset for recognizing person's face later from FileStorage object that is coming from HTML input form element via Flask. Args: name (str): The name of the man who has face in dataset. photos (set): The FileStorage object set. that is been converted to list for becoming its indexing. """ face = self.__get_face_of(name) if not face: face = Face(name) face.create_dataset_from_file_storage_object(list(photos)) self.face_encoder.encode(face.dataset_folder, face.pickle_file, face.name) self.faces.append(face) def update_face(self, face_id, photos): """Method to update face. Args: face_id (str): The id of the face. photos (list): The person's raw photo data list. Contains list of {"name": "photo_name", "base_sf": "Base64_encoded_data"}. """ for face in self.faces: if face.id == face_id: # ELIMINATION OF EXISTING PHOTOS WILL BE HERE face.create_dataset_from_base_sf_photos(photos) self.face_encoder.encode(face.dataset_folder, face.pickle_file, face.name) return True return False @dispatch() def get_faces(self): """Method to return all existing faces. """ return self.faces @dispatch(list) def get_faces(self, ids): """Method to return all existing faces. Args: ids (list): The id list of faces. """ faces = [] for face in self.faces: if face.id in ids: faces.append(face) return faces def get_face(self, face_id): """Method to return face via given face id. Args: face_id (str): The id of the face. """ for face in self.faces: if face.id == face_id: return face def delete_face(self, face_id): """Method to delete face via given face id. Args: face_id (str): The id of the face. """ for face in self.faces: if face.id == face_id: face.remove_self() self.faces.remove(face) # for removing object from list return True return False def __refresh_faces(self): """Method to get existing images from the database. """ self.faces.clear() faces = self.table.all() for face in faces: # face is {"id": face_id, "name": face_name, "image_names": []} self.faces.append(Face(face["name"], face["id"])) def __check_folders(self): """Method to checking the necessary folders created before. If not created creates them. """ if not os.path.exists(self.recognition_folder): os.mkdir(self.recognition_folder) if not os.path.exists(self.encodings_folder): os.mkdir(self.encodings_folder) if not os.path.exists(self.dataset_folder): os.mkdir(self.dataset_folder) def __get_face_of(self, name): """Method to checking name of uploaded photo's face is recorded before. Args: name (str): The name of the man who has face in dataset. """ for face in self.faces: if face.name == name: return face return None