Пример #1
0
    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()
Пример #2
0
    def __init__(self, name, id=None):
        """Initialization method of :class:`t_system.face_encoder.Face` class.

        Args:
            name (str):             The name of the man who has face in dataset.
            id (str):               The id of the face.
        """

        self.name = name
        self.id = id

        self.id = id
        if not id:
            self.id = str(uuid.uuid1())

        self.recognition_folder = f'{dot_t_system_dir}/recognition'
        self.dataset_folder = f'{self.recognition_folder}/dataset/{self.name}'
        self.pickle_file = f'{self.recognition_folder}/encodings/{self.name}_encoding.pickle'

        self.__check_folders()

        self.table = DBFetcher(self.recognition_folder, "db", "faces").fetch()

        self.image_names = []
        self.refresh_image_names()

        self.__db_upsert()
Пример #3
0
    def __init__(self, to_be_used=False, accounts=None, active_account=None):
        """Initialization method of :class:`t_system.r_sync.DropBox` class.

        Args:
                to_be_used (bool):      To be used flag that specify usage status of service on folder synchronization.            
                accounts:               DropBox account owner name and account API key list.
                active_account:       hexadecimal stream key that use in current stream of the website.
        """

        self.accounts = accounts
        if not accounts:
            self.accounts = []

        self.active_account = active_account
        if not active_account:
            self.active_account = {}

        self.name = "Dropbox"
        self.to_be_used = to_be_used

        self.dbx = None

        self.folder = f'{dot_t_system_dir}/r_sync'

        self.sync_sou_dir = f'{dot_t_system_dir}/records'
        self.sync_tar_dir = "Media-from-T_System"

        self.table = DBFetcher(self.folder, "db", "services").fetch()

        self.__db_upsert()
Пример #4
0
    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()
Пример #5
0
    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
Пример #6
0
    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()
Пример #7
0
    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()
Пример #8
0
    def __get_db(self, db_folder, db_name, cache_size=30):
        """Function to set the database of the position.

        Args:
            db_folder (str):                Containing folder of the database file
            db_name (str):                  Database of the position abject.
            cache_size (int):               TinyDB caches query result for performance.
        """

        if self.is_for_scenario:
            return DBFetcher(db_folder, db_name, "scenarios", cache_size).fetch()
        else:
            return DBFetcher(db_folder, db_name, "positions", cache_size).fetch()
Пример #9
0
    def __init__(self,
                 name,
                 url,
                 server,
                 to_be_used=False,
                 stream_ids=None,
                 active_stream_id=None,
                 id=None):
        """Initialization method of :class:`t_system.online_stream.OnlineStream` class.

        Args:
                name:                   Name of the WebSite. youtube, facebook etc.
                url:                    Website's page URL.
                server:                 Website's Live stream server RTMP URL.
                to_be_used (bool):      To be used flag that specify usage status of website on live stream.
                stream_ids:             hexadecimal stream keys of the website.
                active_stream_id:       hexadecimal stream key that use in current stream of the website.
                id:                     Unique ID of the website.
        """

        self.id = id
        if not id:
            self.id = str(uuid.uuid1())

        self.stream_ids = stream_ids
        if not stream_ids:
            self.stream_ids = []

        self.active_stream_id = active_stream_id
        if not active_stream_id:
            self.active_stream_id = {}

        self.name = name
        self.url = url
        self.server = server

        self.to_be_used = to_be_used

        self.streaming_folder = f'{dot_t_system_dir}/streaming'
        self.keys_folder = f'{self.streaming_folder}/keys'
        self.parent_folder = f'{self.streaming_folder}/websites'
        self.folder = f'{self.parent_folder}/{self.name}'

        self.key_file = f'{self.keys_folder}/{self.name}.key'

        self.__check_folders()

        self.table = DBFetcher(self.streaming_folder, "db", "websites").fetch()

        self.__db_upsert()
Пример #10
0
    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()
Пример #11
0
    def __init__(self,
                 d_m_y,
                 h_m_s,
                 scope,
                 record_formats,
                 id=None,
                 name=None,
                 length=None):
        """Initialization method of :class:`t_system.recordation.Record` class.

        Args:
                d_m_y (str):            Date that is day_mount_year format.
                h_m_s (str):            Date that is hour_minute_second format.
                scope (str):            The working type during recording.
                record_formats (dict):  Formats of the records for video, audio and merged.
                id (str):               The id of the record.
                name (str):             The name of the record.
                length (str):           The length of the record as m:s.
        """

        self.id = id
        if not id:
            self.id = str(uuid.uuid1())

        self.name = name
        if not name:
            self.name = h_m_s

        self.date = d_m_y  # table name at the same time
        self.time = h_m_s
        self.scope = scope
        self.record_formats = record_formats
        self.length = length

        self.records_folder = f'{dot_t_system_dir}/records'
        self.parent_folder = f'{self.records_folder}/{self.date}'
        self.folder = f'{self.parent_folder}/{self.time}'

        self.video_file = f'{self.folder}/{self.time}.{self.record_formats["video"]}'
        self.audio_file = f'{self.folder}/{self.time}.{self.record_formats["audio"]}'
        self.merged_file = f'{self.folder}/{self.time}.{self.record_formats["merged"]}'

        self.db = DBFetcher(self.records_folder, "db").fetch()

        self.__check_folders()

        if length is None:
            self.length = self.__calc_length()

        self.__db_upsert()
Пример #12
0
    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()
Пример #13
0
def get_db_table(root, db_name):
    """Method to set work database by root.

    Args:
        root (bool):                    Root privileges flag.
        db_name (str):                  Name of the registered Database. It uses if administration privileges activated.
    """
    table = "scenarios"
    if root:
        db_folder = f'{T_SYSTEM_PATH}/motion/action'
        return DBFetcher(db_folder, db_name, table).fetch()
    else:
        db_folder = dot_t_system_dir
        db_name = 'missions'
        return DBFetcher(db_folder, db_name, table).fetch()
Пример #14
0
    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()
Пример #15
0
    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()
Пример #16
0
    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)
Пример #17
0
    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
Пример #18
0
    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()
Пример #19
0
    def __get_db(db_folder, db_name, cache_size=None):
        """Function to set the database of the scenario.

        Args:
            db_folder (str):                Containing folder of the database file
            db_name (str):                  Database file of the scenario abject.
            cache_size (int):               TinyDB caches query result for performance.
        """

        return DBFetcher(db_folder, db_name, "scenarios", cache_size).fetch()
Пример #20
0
    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()
Пример #21
0
    def __init__(self, d_m_y, h_m_s, shot_format, id=None, name=None, size=None):
        """Initialization method of :class:`t_system.recordation.Record` class.

        Args:
                d_m_y (str):            Date that is day_mount_year format.
                h_m_s (str):            Date that is hour_minute_second format.
                shot_format (str):      Format of the shot. (jpg, png etc.)
                id (str):               The id of the record.
                name (str):             The name of the record.
                size (str):           The length of the record as m:s.
        """

        self.id = id
        if not id:
            self.id = str(uuid.uuid1())

        self.name = name
        if not name:
            self.name = h_m_s

        self.date = d_m_y  # table name at the same time
        self.time = h_m_s
        self.shot_format = shot_format
        self.size = size

        self.records_folder = f'{dot_t_system_dir}/records'
        self.parent_folder = f'{self.records_folder}/{self.date}'
        self.folder = f'{self.parent_folder}/{self.time}'

        self.shot_file = f'{self.folder}/{self.time}.{self.shot_format}'

        self.table = DBFetcher(self.records_folder, "db", "shots").fetch()

        self.__check_folders()

        if size is None:
            self.size = self.__calc_size()

        self.__db_upsert()
Пример #22
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 ""
Пример #23
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
Пример #24
0
class DropBox:
    """Class to define a file synchronizer to an Dropbox account.

    This class provides necessary initiations and functions named :func:`t_system.r_sync.DropBox.sync`
    to provide synchronizing recorded videos with the Dropbox account.
    """
    def __init__(self, to_be_used=False, accounts=None, active_account=None):
        """Initialization method of :class:`t_system.r_sync.DropBox` class.

        Args:
                to_be_used (bool):      To be used flag that specify usage status of service on folder synchronization.            
                accounts:               DropBox account owner name and account API key list.
                active_account:       hexadecimal stream key that use in current stream of the website.
        """

        self.accounts = accounts
        if not accounts:
            self.accounts = []

        self.active_account = active_account
        if not active_account:
            self.active_account = {}

        self.name = "Dropbox"
        self.to_be_used = to_be_used

        self.dbx = None

        self.folder = f'{dot_t_system_dir}/r_sync'

        self.sync_sou_dir = f'{dot_t_system_dir}/records'
        self.sync_tar_dir = "Media-from-T_System"

        self.table = DBFetcher(self.folder, "db", "services").fetch()

        self.__db_upsert()

    def sync(self):
        """Method to synchronizing folder that keeps recorded videos with user's Dropbox account.
        """

        if self.__prepare_sync():

            for dn, dirs, files in os.walk(self.sync_sou_dir):
                sub_folder = dn[len(self.sync_sou_dir):].strip(os.path.sep)
                listing = self.list_folder(self.sync_tar_dir, sub_folder)
                logger.info(f'Descending into {sub_folder}...')

                # First do all the files.
                for file in files:
                    file_path = os.path.join(dn, file)

                    if isinstance(file, bytes):
                        file = file.decode('utf-8')

                    n_name = unicodedata.normalize('NFC', file)

                    if file.startswith('.'):
                        logger.info(f'Skipping dot file: {file}')

                    elif file.startswith('@') or file.endswith('~'):
                        logger.info(f'Skipping temporary file: {file}')

                    elif file.endswith('.pyc') or file.endswith('.pyo'):
                        logger.info(f'Skipping generated file: {file}')

                    elif file.endswith('.json'):
                        logger.info(f'Skipping database file: {file}')

                    elif n_name in listing:

                        md = listing[n_name]
                        mtime = os.path.getmtime(file_path)
                        mtime_dt = datetime.datetime(*time.gmtime(mtime)[:6])
                        size = os.path.getsize(file_path)

                        if isinstance(
                                md, dropbox.files.FileMetadata
                        ) and mtime_dt == md.client_modified and size == md.size:
                            logger.info(
                                f' {file} is already synced [stats match]')

                        else:
                            logger.info(
                                file,
                                f'{file} exists with different stats, downloading'
                            )
                            res = self.download(self.sync_tar_dir, sub_folder,
                                                file)

                            with open(file_path) as f:
                                data = f.read()

                            if res == data:
                                logger.info(
                                    f'{file} is already synced [content match]'
                                )
                            else:
                                logger.info(
                                    f'{file} has changed since last sync')
                                self.upload(file_path,
                                            self.sync_tar_dir,
                                            sub_folder,
                                            file,
                                            overwrite=True)
                    else:
                        self.upload(file_path, self.sync_tar_dir, sub_folder,
                                    file)

                # Then choose which subdirectories to traverse.
                keep = []
                for directory in dirs:
                    if directory.startswith('.'):
                        logger.info(f'Skipping dot directory: {directory}')
                    elif directory.startswith('@') or directory.endswith('~'):
                        logger.info(
                            f'Skipping temporary directory: {directory}')
                    elif directory == '__pycache__':
                        logger.info(
                            f'Skipping generated directory: {directory}')
                    else:
                        logger.info(f'Keeping directory: {directory}')
                        keep.append(directory)
                dirs[:] = keep

    def __prepare_sync(self):
        """Method to prepare DropBoxer to folder synchronization.
        """

        if self.activate_account:
            self.dbx = dropbox.Dropbox(self.active_account["key"])
            return True

        return False

    def list_folder(self, folder, sub_folder):
        """Method to list a folder.

        Args:
                folder (str):          Top-folder that contains synchronized items.
                sub_folder (str):      Sub-folder that belongs to top-folder.
        Returns:
                a dict mapping unicode filenames to FileMetadata|FolderMetadata entries.
        """
        path = '/%s/%s' % (folder, sub_folder.replace(os.path.sep, '/'))
        while '//' in path:
            path = path.replace('//', '/')
        path = path.rstrip('/')

        try:
            res = self.dbx.files_list_folder(path)
        except dropbox.exceptions.ApiError as err:
            logger.error(
                f'Folder listing failed for {path} -- assumed empty: {err}')
            return {}
        else:
            rv = {}
            for entry in res.entries:
                rv[entry.name] = entry
            return rv

    def download(self, folder, sub_folder, file_name):
        """Method to download a file from Dropbox account.

        Args:
                folder (str):          Top-folder that contains synchronized items.
                sub_folder (str):      Sub-folder that belongs to top-folder.
                file_name (str):       The name of the file that will be uploaded.

        Returns:
                The bytes of the file, or None if it doesn't exist.
        """
        path = '/%s/%s/%s' % (folder, sub_folder.replace(os.path.sep,
                                                         '/'), file_name)
        while '//' in path:
            path = path.replace('//', '/')

        try:
            md, res = self.dbx.files_download(path)

        except dropbox.exceptions.HttpError as err:
            print('*** HTTP error', err)
            return None

        data = res.content
        logger.info(f'{len(data)} bytes; md: {md}')

        return data

    def upload(self,
               file_path,
               folder,
               sub_folder,
               file_name,
               overwrite=False):
        """Method to upload a file to Dropbox account.

        Args:
                file_path (str):       The path of the file that will be uploaded.
                folder (str):          Top-folder that contains synchronized items.
                sub_folder (str):      Sub-folder that belongs to top-folder.
                file_name (str):       The name of the file that will be uploaded.
                overwrite (bool):      The overwriting flag of file that will be uploaded.

        Returns:
                The request response, or None in case of error.
        """

        path = '/%s/%s/%s' % (folder, sub_folder.replace(os.path.sep,
                                                         '/'), file_name)
        while '//' in path:
            path = path.replace('//', '/')

        mode = (dropbox.files.WriteMode.overwrite
                if overwrite else dropbox.files.WriteMode.add)

        mtime = os.path.getmtime(file_path)

        with open(file_path, 'rb') as f:
            data = f.read()

        try:
            res = self.dbx.files_upload(
                data,
                path,
                mode,
                client_modified=datetime.datetime(*time.gmtime(mtime)[:6]),
                mute=True)

        except dropbox.exceptions.ApiError as err:

            logger.error(f'API error {err}')
            return None
        logger.info(f'uploaded as {res.name.encode("utf8")}')

        return res

    def set_usage_stat(self, to_be_used):
        """Method to set website as to be used or not to be used.

        Args:
                to_be_used (bool):      To be used flag that specify usage status of service on folder synchronization.
        """

        self.to_be_used = to_be_used

        self.__db_upsert(force_insert=True)

    def activate_account(self, account_name):
        """Method to set given API key of given account for using on the current folder synchronization.

        Args:
            account_name (str):         Name of the Dropbox account.
        """

        for account in self.accounts:
            if account["is_active"]:
                account["is_active"] = False
                break

        for account in self.accounts:
            if account["name"] == account_name:

                account["is_active"] = True

                self.active_account = account
                self.__db_upsert(force_insert=True)

            return True

        return False

    def upsert_account(self, name, key):
        """Method to insert(or update) new API key and its account name for reaching the Dropbox.

        Args:
            name (str):                 Name of the Dropbox account.
            key (str):                  API key of Dropbox account.
        """
        is_update = False

        for account in self.accounts:
            if name == account["name"]:
                account["key"] = key
                is_update = True
                break

        if not is_update:
            self.accounts.append({
                "name": name,
                "key": key,
                "is_active": False
            })

        self.__db_upsert(force_insert=True)

        return True

    def remove_account(self, name):
        """Method to remove existing stream key and its account name.

        Args:
            name (str):                 Name of the Dropbox account.
        """

        for account in self.accounts:
            if name == account["name"]:
                self.accounts.remove(account)  # for removing object from list
                self.__db_upsert(force_insert=True)

                return True
        return False

    def delete_self(self):
        """Method to delete website itself.
        """
        self.table.remove((Query().name == self.name))

    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.table.search((Query().name == self.name)):
            if force_insert:
                self.table.update(
                    {
                        'info': {
                            'to_be_used': self.to_be_used,
                            'accounts': self.accounts,
                            'active_account': self.active_account
                        }
                    },
                    Query().name == self.name)

            else:
                return "Already Exist"
        else:
            self.table.insert({
                'name': self.name,
                'info': {
                    'to_be_used': self.to_be_used,
                    'accounts': self.accounts,
                    'active_account': self.active_account
                }
            })  # insert the given data

        return ""
Пример #25
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)
Пример #26
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)
Пример #27
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
Пример #28
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
Пример #29
0
class StreamWebSite:
    """Class to define website that will used as live stream platform.

    This class provides necessary initiations and functions named :func:`t_system.online_stream.StreamWebSite.upsert_stream_key`
    as the new account adding point and existing account updating point.
    """
    def __init__(self,
                 name,
                 url,
                 server,
                 to_be_used=False,
                 stream_ids=None,
                 active_stream_id=None,
                 id=None):
        """Initialization method of :class:`t_system.online_stream.OnlineStream` class.

        Args:
                name:                   Name of the WebSite. youtube, facebook etc.
                url:                    Website's page URL.
                server:                 Website's Live stream server RTMP URL.
                to_be_used (bool):      To be used flag that specify usage status of website on live stream.
                stream_ids:             hexadecimal stream keys of the website.
                active_stream_id:       hexadecimal stream key that use in current stream of the website.
                id:                     Unique ID of the website.
        """

        self.id = id
        if not id:
            self.id = str(uuid.uuid1())

        self.stream_ids = stream_ids
        if not stream_ids:
            self.stream_ids = []

        self.active_stream_id = active_stream_id
        if not active_stream_id:
            self.active_stream_id = {}

        self.name = name
        self.url = url
        self.server = server

        self.to_be_used = to_be_used

        self.streaming_folder = f'{dot_t_system_dir}/streaming'
        self.keys_folder = f'{self.streaming_folder}/keys'
        self.parent_folder = f'{self.streaming_folder}/websites'
        self.folder = f'{self.parent_folder}/{self.name}'

        self.key_file = f'{self.keys_folder}/{self.name}.key'

        self.__check_folders()

        self.table = DBFetcher(self.streaming_folder, "db", "websites").fetch()

        self.__db_upsert()

    def set_usage_stat(self, to_be_used):
        """Method to set website as to be used or not to be used.

        Args:
                to_be_used (bool):      To be used flag that specify usage status of website on live stream.
        """

        self.to_be_used = to_be_used

        self.__db_upsert(force_insert=True)

    def activate_stream_key(self, account_name):
        """Method to set given stream key for using on the current live stream for the website.

        Args:
            account_name (str):         Name of the website's account.
        """
        for stream_id in self.stream_ids:
            if stream_id["is_active"]:
                stream_id["is_active"] = False
                break

        for stream_id in self.stream_ids:
            if stream_id["account_name"] == account_name:
                with open(self.key_file, "w+") as key_file:
                    key_file.write(stream_id["key"])
                    key_file.close()

                stream_id["is_active"] = True

                self.active_stream_id = stream_id
                self.__db_upsert(force_insert=True)

            return True

        return False

    def upsert_stream_key(self, account_name, key):
        """Method to insert(or update) new stream key and its account name.

        Args:
            account_name (str):         Name of the website's account.
            key (str):                  Hexadecimal live stream key of the websites's account.
        """
        is_update = False

        for stream_id in self.stream_ids:
            if account_name == stream_id["account_name"]:
                stream_id["key"] = key
                is_update = True
                break

        if not is_update:
            self.stream_ids.append({
                "account_name": account_name,
                "key": key,
                "key_file": f'{self.folder}/{account_name}.key',
                "is_active": False
            })

        self.__db_upsert(force_insert=True)
        self.__set_key_files(account_name)

        return True

    def remove_stream_key(self, account_name):
        """Method to remove existing stream key and its account name.

        Args:
            account_name (str):         Name of the website's account.
        """

        for stream_id in self.stream_ids:
            if account_name == stream_id["account_name"]:
                self.stream_ids.remove(
                    stream_id)  # for removing object from list
                self.__db_upsert(force_insert=True)
                os.remove(stream_id["key_file"])

                return True
        return False

    def update_self(self, url, server):
        """Method to update website itself.
        """
        if url:
            self.url = url

        if server:
            self.server = server

        self.__db_upsert(force_insert=True)

    def delete_self(self):
        """Method to delete website itself.
        """
        self.table.remove((Query().id == self.id))

    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.table.search((Query().id == self.id)):
            if force_insert:
                self.table.update(
                    {
                        'id': self.id,
                        'name': self.name,
                        'url': self.url,
                        'server': self.server,
                        'to_be_used': self.to_be_used,
                        'stream_ids': self.stream_ids,
                        'active_stream_id': self.active_stream_id
                    },
                    Query().id == self.id)

            else:
                return "Already Exist"
        else:
            self.table.insert({
                'id': self.id,
                'name': self.name,
                'url': self.url,
                'server': self.server,
                'to_be_used': self.to_be_used,
                'stream_ids': self.stream_ids,
                'active_stream_id': self.active_stream_id
            })  # insert the given data

        return ""

    def __set_key_files(self, account_name=None):
        """Method to crete `.key` files that keeps stream keys of the websites live stream entry.

        Args:
            account_name (str):         Name of the website's account.
        """
        result = False
        stream_ids = []

        if account_name:
            for stream_id in self.stream_ids:
                if account_name == stream_id["account_name"]:
                    stream_ids.append(stream_id)
                    result = True
                    break
        else:
            stream_ids = self.stream_ids

        for stream_id in stream_ids:
            result = True
            with open(stream_id["key_file"], "w+") as key_file:
                key_file.write(stream_id["key"])
                key_file.close()

        return result

    def __check_folders(self):
        """Method to checking the necessary folders created before. If not created creates them.
        """

        if not os.path.exists(self.parent_folder):
            os.mkdir(self.parent_folder)

        if not os.path.exists(self.keys_folder):
            os.mkdir(self.keys_folder)

        if not os.path.exists(self.folder):
            os.mkdir(self.folder)
Пример #30
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)