Пример #1
0
class WebApp:
    """
    web application
    """
    __instance = None

    def __init__(self):
        """
        init method
        """
        self.channel_mgr = ChannelManager(["image", "video"])

        self.request_list = set()

        self.lock = threading.Lock()

    def __new__(cls, *args, **kwargs):

        # if instance is None than create one
        if cls.__instance is None:
            cls.__instance = object.__new__(cls, *args, **kwargs)
        return cls.__instance

    def add_channel(self, channel_name):
        """
        add channel

        @param channel_name  name of channel
        @return: return add status and message (for error status)

        """
        ret = {"ret": "error", "msg": ""}

        # check channel_name validate,
        # channel_name can not be None or length = 0
        if channel_name is None:
            logging.info("Channel name is None , add channel failed")
            ret["msg"] = "Channel name can not be empty"
            return ret

        # strip channel name
        channel_name = channel_name.strip()

        # check channel_name emtpy or not
        if channel_name == "":
            logging.info("Channel name is emtpy , add channel failed")
            ret["msg"] = "Channel name can not be empty"
            return ret

        # length of channel name can not over 25
        if len(channel_name) > 25:
            logging.info("Length of channel name %s > 25 , add channel failed",
                         channel_name)
            ret["msg"] = "Length of channel name should less than 25"
            return ret

        # define pattern support a-z A-Z and /
        pattern = re.compile(r"[a-z]|[A-Z]|[0-9]|/")
        tmp = pattern.findall(channel_name)

        # check reuslt changed or not
        if len(tmp) != len(channel_name):
            logging.info("%s contain invalidate character, add channel failed",
                         channel_name)
            ret["msg"] = "Channel name only support 0-9, a-z, A-Z /"
            return ret

        # register channel
        flag = self.channel_mgr.register_one_channel(channel_name)

        #  check register result
        if self.channel_mgr.err_code_too_many_channel == flag:
            logging.info("Only supports up to 10 channels, add channel failed")
            ret["msg"] = "Only supports up to 10 channels"

        elif self.channel_mgr.err_code_repeat_channel == flag:
            logging.info("%s already exist, add channel failed", channel_name)
            ret["msg"] = "Channel %s already exist" % channel_name

        else:
            logging.info("add channel %s succeed", channel_name)
            ret["ret"] = "success"

        return ret

    def del_channel(self, names):
        """
        delete channel

        @param names: channel name to be deleted, separated by ','
        @return: return add status and message (for error status)
        """

        # init ret for return
        ret = {"ret": "error", "msg": ""}

        # check length of names
        if names.strip() == "":
            logging.info("Channel name is empty, delete channel failed")
            ret["msg"] = "Channel name should not be empty"
            return ret

        # split name for multi name
        listname = names.split(",")

        # unregister name
        for item in listname:
            item = item.strip()

            # if name is emtpy continu
            if item == "":
                continue

            self.channel_mgr.unregister_one_channel(item)
            logging.info("delete channel %s succeed", item)

        ret["ret"] = "success"

        return ret

    def list_channels(self):
        """
        list all channels information
        """

        # list register channels
        ret = self.channel_mgr.list_channels()

        # id for every channel item , start with 1
        idx = 1

        # set id for channel
        for item in ret:
            item['id'] = idx
            idx = idx + 1

        return ret

    def is_channel_exists(self, name):
        """
        view channel content via browser.

        @param  name : channel name
        @return return True if exists. otherwise return False.
        """
        return self.channel_mgr.is_channel_exist(name)

    def add_requst(self, request):
        """
        add request

        @param  requst: request item to be stored

        @note: request can not be same with other request.
               request is identified by   (channel name ,random number)
               so this method do not return value.
        """
        with self.lock:
            self.request_list.add(request)

    def has_request(self, request):
        """
        whether request exist or not

        @param  request:  request to be checked.
        @return:  return True if exists, otherwise return False.
        """
        with self.lock:

            for item in self.request_list:

                # check request equal
                if item[0] == request[0] and item[1] == request[1]:
                    return True

            return False

    def get_media_data(self, channel_name):
        """
        get media data by channel name

        @param channel_name: channel to be quest data.
        @return return dictionary which have for item
                 type: identify channel type, for image or video.
                 image: data to be returned.
                 fps:   just for video type
                 status:  can be error, ok, or loading.
        """
        # channel exists or not
        if self.is_channel_exists(channel_name) is False:
            return {'type': 'unkown', 'image': '', 'fps': 0, 'status': 'error'}

        image_data = self.channel_mgr.get_channel_image(channel_name)
        # only for image type.
        if image_data is not None:
            image_data = base64.b64encode(image_data).decode('utf-8')
            return {
                'type': 'image',
                'image': image_data,
                'fps': 0,
                'status': 'ok'
            }

        fps = 0  # fps for video
        image = None  # image for video & image
        rectangle_list = None
        handler = self.channel_mgr.get_channel_handler_by_name(channel_name)

        if handler is not None:
            media_type = handler.get_media_type()

            # if type is image then get image data
            if media_type == "image":
                image = handler.get_image_data()

            # for video
            else:
                frame_info = handler.get_frame()
                image = frame_info[0]
                fps = frame_info[1]
                rectangle_list = frame_info[4]

            status = "loading"

            # decode binary to utf-8 when image is not None
            if image is not None:
                status = "ok"
                image = base64.b64encode(image).decode('utf-8')

            return {
                'type': media_type,
                'image': image,
                'fps': fps,
                'status': status,
                'rectangle_list': rectangle_list
            }
        else:
            return {
                'type': 'unkown',
                'image': None,
                'fps': 0,
                'status': 'loading'
            }
Пример #2
0
class WebApp:
    """
    web application
    """
    __instance = None

    def __init__(self):
        """
        init method
        """
        self.channel_mgr = ChannelManager(["image", "video"])

        self.request_list = set()

        self.lock = threading.Lock()

        self.display_manager = display_server.DisplayServerManager()
        self.thread = None
        self._create_sending_thread()

    def __new__(cls, *args, **kwargs):

        # if instance is None than create one
        if cls.__instance is None:
            cls.__instance = object.__new__(cls, *args, **kwargs)
        return cls.__instance

    def add_channel(self, channel_name):
        """
        add channel

        @param channel_name  name of channel
        @return: return add status and message (for error status)

        """
        ret = {"ret": "error", "msg": ""}

        # check channel_name validate,
        # channel_name can not be None or length = 0
        if channel_name is None:
            logging.info("Channel name is None , add channel failed")
            ret["msg"] = "Channel name can not be empty"
            return ret

        # strip channel name
        channel_name = channel_name.strip()

        # check channel_name emtpy or not
        if channel_name == "":
            logging.info("Channel name is emtpy , add channel failed")
            ret["msg"] = "Channel name can not be empty"
            return ret

        # length of channel name can not over 25
        if len(channel_name) > 25:
            logging.info("Length of channel name %s > 25 , add channel failed",
                         channel_name)
            ret["msg"] = "Length of channel name should less than 25"
            return ret

        # define pattern support a-z A-Z and /
        pattern = re.compile(r"[a-z]|[A-Z]|[0-9]|/")
        tmp = pattern.findall(channel_name)

        # check reuslt changed or not
        if len(tmp) != len(channel_name):
            logging.info("%s contain invalidate character, add channel failed",
                         channel_name)
            ret["msg"] = "Channel name only support 0-9, a-z, A-Z /"
            return ret

        # register channel
        flag = self.channel_mgr.register_one_channel(channel_name)

        #  check register result
        if self.channel_mgr.err_code_too_many_channel == flag:
            logging.info("Only supports up to 10 channels, add channel failed")
            ret["msg"] = "Only supports up to 10 channels"

        elif self.channel_mgr.err_code_repeat_channel == flag:
            logging.info("%s already exist, add channel failed", channel_name)
            ret["msg"] = "Channel %s already exist" % channel_name

        else:
            logging.info("add channel %s succeed", channel_name)
            ret["ret"] = "success"

        return ret

    def del_channel(self, names):
        """
        delete channel

        @param names: channel name to be deleted, separated by ','
        @return: return add status and message (for error status)
        """

        # init ret for return
        ret = {"ret": "error", "msg": ""}

        # check length of names
        if names.strip() == "":
            logging.info("Channel name is empty, delete channel failed")
            ret["msg"] = "Channel name should not be empty"
            return ret

        # split name for multi name
        listname = names.split(",")

        # unregister name
        for item in listname:
            item = item.strip()

            # if name is emtpy continu
            if item == "":
                continue

            self.channel_mgr.unregister_one_channel(item)
            logging.info("delete channel %s succeed", item)

        ret["ret"] = "success"

        return ret

    def list_channels(self):
        """
        list all channels information
        """

        # list register channels
        ret = self.channel_mgr.list_channels()

        # id for every channel item , start with 1
        idx = 1

        # set id for channel
        for item in ret:
            item['id'] = idx
            idx = idx + 1

        return ret

    def is_channel_exists(self, name):
        """
        view channel content via browser.

        @param  name : channel name
        @return return True if exists. otherwise return False.
        """
        return self.channel_mgr.is_channel_exist(name)

    def add_requst(self, request):
        """
        add request

        @param  requst: request item to be stored

        @note: request can not be same with other request.
               request is identified by   (channel name ,random number)
               so this method do not return value.
        """
        with self.lock:
            self.request_list.add(request)

    def has_request(self, request):
        """
        whether request exist or not

        @param  request:  request to be checked.
        @return:  return True if exists, otherwise return False.
        """
        with self.lock:

            for item in self.request_list:

                # check request equal
                if item[0] == request[0] and item[1] == request[1]:
                    return True

            return False

    def get_media_data(self, channel_name):
        """
        get media data by channel name

        @param channel_name: channel to be quest data.
        @return return dictionary which have for item
                 type: identify channel type, for image or video.
                 image: data to be returned.
                 fps:   just for video type
                 status:  can be error, ok, or loading.
        """
        # channel exists or not
        if self.is_channel_exists(channel_name) is False:
            return {'type': 'unkown', 'image': '', 'fps': 0, 'status': 'error'}

        image_data = self.channel_mgr.get_channel_image(channel_name)
        # only for image type.
        if image_data is not None:
            image_data = base64.b64encode(image_data).decode('utf-8')
            return {
                'type': 'image',
                'image': image_data,
                'fps': 0,
                'status': 'ok'
            }

        fps = 0  # fps for video
        image = None  # image for video & image
        rectangle_list = None
        view = None
        handler = self.channel_mgr.get_channel_handler_by_name(channel_name)

        if handler is not None:
            media_type = handler.get_media_type()

            # if type is image then get image data
            if media_type == "image":
                image = handler.get_image_data()

            # for video
            else:
                frame_info = handler.get_frame()
                image = frame_info[0]
                fps = frame_info[1]
                rectangle_list = frame_info[4]
                width, height = frame_info[2], frame_info[2]
                if width == 256:
                    view = 'ColorMap'
                else:
                    view = 'ResultImage'

            status = "loading"

            # decode binary to utf-8 when image is not None
            if image is not None:
                status = "ok"
                image = base64.b64encode(image).decode('utf-8')

            return {
                'view': view,
                'type': media_type,
                'image': image,
                'fps': fps,
                'status': status,
                'rectangle_list': rectangle_list
            }
        else:
            return {
                'view': view,
                'type': 'unkown',
                'image': None,
                'fps': 0,
                'status': 'loading'
            }

    def _create_sending_thread(self):
        """Start the sending thread if it isn't running yet."""
        if self.thread is not None and self.thread.isAlive():
            return

        # start style type thread
        self.thread = threading.Thread(target=self.sending_thread_func,
                                       args=(self.display_manager, ))
        self.thread.start()

    def sending_thread_func(self, app_manager):
        global g_object_bytes, g_layout_bytes
        while True:
            event.wait()

            flag = app_manager.send_model_input_data(g_object_bytes,
                                                     g_layout_bytes)
            print("data package sending msg:", flag[1])
            if flag[0] is True:
                logging.info("Send model input data package success")
            else:
                logging.info("Send model input data package failed")

            event.clear()

    def update_model_input_data(self, objects_bytes, layout_bytes):
        ''' send model data to agent'''

        ### check if the input changed  same input

        ### type change, trigger the wait thread to register
        global g_object_bytes, g_layout_bytes
        g_object_bytes = b''
        g_layout_bytes = b''
        g_object_bytes = objects_bytes
        g_layout_bytes = layout_bytes

        if g_layout_bytes == b'' or g_object_bytes == b'':
            return ""
        # Here, you may not use thread event method to trigger the transfer manager
        # to register style type directly, it maybe ok. But here i use thread event instead.

        print("send model input data thread event set")
        event.set()