def _import_and_init_class(self, module_name, class_name, extend_path, init_para, as_name=''): """ 装载并初始化对象返回(如果对象已存在则直接返回) @param {string} module_name - 模块名 @param {string} class_name - 处理类名 @param {string} extend_path - 模块所在搜索路径 @param {string} init_para - 初始化的json字符串 @param {string} as_name - 对象别名,可以设置不一样的值让类可以多次实例化 @return {object} - 初始化后的模块对象 @throws {ImportError} - 初始化失败返回该异常 """ # 检查对象是否已存在 _key = as_name _class_tag = '%s.%s' % (module_name, class_name) if as_name == '': _key = _class_tag if self._import_object_dict is None: self._import_object_dict = dict() if _key in self._import_object_dict.keys(): # 已存在,直接返回即可 return self._import_object_dict[_key] # 装载模块 _class = None if ImportTool.check_module_imported(module_name): # 模块已存在 _class = ImportTool.get_member_from_module( ImportTool.get_imported_module(module_name), class_name ) else: # 动态装载模块 _class = ImportTool.get_member_from_module( ImportTool.import_module( module_name, extend_path=extend_path ), class_name ) if _class is None: raise ImportError(_("config file error: can't import module: $1!", (_class_tag, ))) # 初始化对象并返回 _init_para = dict() if init_para != '': _init_para = StringTool.json_to_object(init_para) self._import_object_dict[_key] = _class(**_init_para) return self._import_object_dict[_key]
def load_plugin(self, plugin_name: str): """ 装载已安装的插件到服务中 @param {str} plugin_name - 插件名 """ _fetchs = self._exec_sql( 'select dir_name from t_installed where plugin_name=?', para=(plugin_name, ), is_fetchall=True) _dir_name = _fetchs[0][0] # 获取插件配置 _plugin_config = SimpleXml( os.path.join(self.plugin_path, _dir_name, 'plugin.xml')).to_dict()['config'] # 装载后台服务 self.imported_moudles[plugin_name] = dict() _import = _plugin_config['import'] for _module_name in _import.keys(): # 装载模块 _extend_path = os.path.join(self.plugin_path, _dir_name, 'lib', _import[_module_name]['extend_path']) _module = ImportTool.import_module(_module_name, extend_path=_extend_path) self.imported_moudles[plugin_name][_module_name] = _module # 初始化类并加入Restful服务 _init_class = _import[_module_name]['init_class'] for _class_name in _init_class.keys(): _class_object = ImportTool.get_member_from_module( _module, _class_name) if _init_class[_class_name]['init_type'] == 'instance': _class_object = _class_object( config_services=self.config_services, device_services=self.device_services, config_path=os.path.join( self.config_path, 'plugin', _plugin_config['info']['plugin_name']), plugin_path=self.plugin_path, logger=self.logger) # 加入Restful服务 if _init_class[_class_name].get('add_route_by_class', False): # 处理服务黑名单 _blacklist = _init_class[_class_name].get('blacklist', []) for _i in range(len(_blacklist)): _blacklist[_i] = '%s/%s' % (_class_name, _blacklist[_i]) # 添加路由 self.flask_server.add_route_by_class([_class_object], blacklist=_blacklist) # 装载主页的入口路由 if _plugin_config['info'].get('url', '') != '': self.flask_server.add_route(_plugin_config['info']['url'], self.plugin_index, endpoint=plugin_name) # 处理插件内存信息 _plugin_config['info']['plugin_name'] = plugin_name # 避免中途被修改 self.plugins_dict[plugin_name] = _plugin_config['info'] if _plugin_config['info']['entrance_type'] == 'toolbar': self.plugins_toolbar.append(plugin_name) else: self.plugins_tab.append(plugin_name)