Пример #1
0
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)
Пример #2
0
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
Пример #3
0
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
Пример #4
0
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)
Пример #5
0
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 ""
Пример #6
0
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)
Пример #7
0
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)
Пример #8
0
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
Пример #9
0
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
Пример #10
0
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 ""
Пример #11
0
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))
Пример #12
0
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)
Пример #13
0
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