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' }
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()