From def3c36ec4ab3faff7a643a038909c0509823c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Wed, 12 Apr 2023 11:16:00 +0800 Subject: [PATCH 01/20] =?UTF-8?q?=E5=90=AF=E5=8A=A8=E6=96=87=E5=AD=97?= =?UTF-8?q?=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/bootAPI.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index 011f67bc..812e4e25 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -28,6 +28,8 @@ import psutil import atexit import importlib +if '_PYIBoot_SPLASH' in os.environ and importlib.util.find_spec("pyi_splash"): + import pyi_splash import OlivOS @@ -702,14 +704,14 @@ def kill_process_children(p): # 启动画面的操作 def setSplashClose(): if '_PYIBoot_SPLASH' in os.environ and importlib.util.find_spec("pyi_splash"): - import pyi_splash + #import pyi_splash pyi_splash.close() def setSplashText(text:str): if '_PYIBoot_SPLASH' in os.environ and importlib.util.find_spec("pyi_splash"): - import pyi_splash + #import pyi_splash pyi_splash.update_text(text) def preLoadPrint(text:str): print(text) - #setSplashText(text) + setSplashText(text) From 19de46d7e091fc618dce76ac09cc8e5b320a90ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Wed, 12 Apr 2023 11:39:27 +0800 Subject: [PATCH 02/20] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=96=87=E5=AD=97?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/bootAPI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index 812e4e25..311bada3 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -714,4 +714,4 @@ def setSplashText(text:str): def preLoadPrint(text:str): print(text) - setSplashText(text) + #setSplashText(text) From 5d928f39b781c6b907d902ba580538e54b8aaeaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Fri, 14 Apr 2023 11:24:37 +0800 Subject: [PATCH 03/20] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E6=96=87=E4=BB=B6=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 允许在插件目录中使用data目录作为资源文件,将会被自动释放至./plugin/data/插件命名空间/data目录 --- OlivOS/pluginAPI.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/OlivOS/pluginAPI.py b/OlivOS/pluginAPI.py index 6afb044e..79af0552 100644 --- a/OlivOS/pluginAPI.py +++ b/OlivOS/pluginAPI.py @@ -129,6 +129,7 @@ def run(self): time.sleep(1) # 此处延迟用于在终端第一次启动时等待终端初始化,避免日志丢失,后续需要用异步(控制包流程)方案替代 self.load_plugin_list() self.check_plugin_list() + self.run_plugin_data_release() self.run_plugin_func(None, 'init_after') self.log(2, OlivOS.L10NAPI.getTrans('OlivOS plugin shallow [{0}] is running', [self.Proc_name], modelName)) self.sendPluginList() @@ -349,6 +350,40 @@ def check_plugin_list(self): )) self.plugin_models_call_list = new_list + def run_plugin_data_release(self): + func_name = 'release_data' + for plugin_models_index_this in self.plugin_models_call_list: + if plugin_models_index_this in self.plugin_models_dict: + dataPath = './plugin/data/%s/data' % plugin_models_index_this + dataPathFromList = [ + './plugin/app/%s/data' % plugin_models_index_this, + './plugin/tmp/%s/data' % plugin_models_index_this + ] + for dataPathFrom in dataPathFromList: + if os.path.exists(dataPathFrom) \ + and os.path.isdir(dataPathFrom): + try: + removeDir(dataPath) + shutil.copytree(dataPathFrom, dataPath) + self.log(2, OlivOS.L10NAPI.getTrans( + 'OlivOS plugin [{0}] call [{1}] done', [ + self.plugin_models_dict[plugin_models_index_this]['name'], + func_name + ], + modelName + )) + except Exception as e: + self.log(4, OlivOS.L10NAPI.getTrans( + 'OlivOS plugin [{0}] call [{1}] failed: {2}\n{3}', [ + self.plugin_models_dict[plugin_models_index_this]['name'], + func_name, + str(e), + traceback.format_exc() + ], + modelName + )) + break + def run_plugin_func(self, plugin_event, func_name): for plugin_models_index_this in self.plugin_models_call_list: if plugin_models_index_this in self.plugin_models_dict: From b2bdc52cee8d13381372484145791e6a7857d528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Fri, 14 Apr 2023 11:50:23 +0800 Subject: [PATCH 04/20] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=92=88=E5=AF=B9?= =?UTF-8?q?=E6=89=93=E5=8C=85=E5=90=8E=E7=9A=84opk=E7=9A=84=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E6=96=87=E4=BB=B6=E9=87=8A=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/pluginAPI.py | 65 ++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/OlivOS/pluginAPI.py b/OlivOS/pluginAPI.py index 79af0552..b6beb0a1 100644 --- a/OlivOS/pluginAPI.py +++ b/OlivOS/pluginAPI.py @@ -129,7 +129,6 @@ def run(self): time.sleep(1) # 此处延迟用于在终端第一次启动时等待终端初始化,避免日志丢失,后续需要用异步(控制包流程)方案替代 self.load_plugin_list() self.check_plugin_list() - self.run_plugin_data_release() self.run_plugin_func(None, 'init_after') self.log(2, OlivOS.L10NAPI.getTrans('OlivOS plugin shallow [{0}] is running', [self.Proc_name], modelName)) self.sendPluginList() @@ -351,38 +350,41 @@ def check_plugin_list(self): self.plugin_models_call_list = new_list def run_plugin_data_release(self): - func_name = 'release_data' for plugin_models_index_this in self.plugin_models_call_list: if plugin_models_index_this in self.plugin_models_dict: - dataPath = './plugin/data/%s/data' % plugin_models_index_this - dataPathFromList = [ - './plugin/app/%s/data' % plugin_models_index_this, - './plugin/tmp/%s/data' % plugin_models_index_this - ] - for dataPathFrom in dataPathFromList: - if os.path.exists(dataPathFrom) \ - and os.path.isdir(dataPathFrom): - try: - removeDir(dataPath) - shutil.copytree(dataPathFrom, dataPath) - self.log(2, OlivOS.L10NAPI.getTrans( - 'OlivOS plugin [{0}] call [{1}] done', [ - self.plugin_models_dict[plugin_models_index_this]['name'], - func_name - ], - modelName - )) - except Exception as e: - self.log(4, OlivOS.L10NAPI.getTrans( - 'OlivOS plugin [{0}] call [{1}] failed: {2}\n{3}', [ - self.plugin_models_dict[plugin_models_index_this]['name'], - func_name, - str(e), - traceback.format_exc() - ], - modelName - )) - break + self.run_plugin_data_release_by_name(plugin_models_index_this) + + def run_plugin_data_release_by_name(self, plugin_models_index_this): + func_name = 'release_data' + dataPath = './plugin/data/%s/data' % plugin_models_index_this + dataPathFromList = [ + './plugin/app/%s/data' % plugin_models_index_this, + './plugin/tmp/%s/data' % plugin_models_index_this + ] + for dataPathFrom in dataPathFromList: + if os.path.exists(dataPathFrom) \ + and os.path.isdir(dataPathFrom): + try: + removeDir(dataPath) + shutil.copytree(dataPathFrom, dataPath) + self.log(2, OlivOS.L10NAPI.getTrans( + 'OlivOS plugin [{0}] call [{1}] done', [ + self.plugin_models_dict[plugin_models_index_this]['name'], + func_name + ], + modelName + )) + except Exception as e: + self.log(4, OlivOS.L10NAPI.getTrans( + 'OlivOS plugin [{0}] call [{1}] failed: {2}\n{3}', [ + self.plugin_models_dict[plugin_models_index_this]['name'], + func_name, + str(e), + traceback.format_exc() + ], + modelName + )) + break def run_plugin_func(self, plugin_event, func_name): for plugin_models_index_this in self.plugin_models_call_list: @@ -708,6 +710,7 @@ def load_plugin_list(self): modelName )) # doOpkRemove(plugin_path_tmp, plugin_dir_this_tmp) + self.run_plugin_data_release_by_name(plugin_models_dict_this_key) continue else: skip_result = plugin_dir_this + '.main.Event' + ' not found' From 8929300e93a300069befa9bec34ae61005a02ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Fri, 14 Apr 2023 15:00:20 +0800 Subject: [PATCH 05/20] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E7=94=9F=E6=88=90=E7=9A=84=E7=AE=A1=E7=90=86=E9=80=9A=E4=BF=A1?= =?UTF-8?q?=E7=AE=A1=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/API.py | 30 ++++++++++++++++++++++++++++-- OlivOS/bootAPI.py | 5 +++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/OlivOS/API.py b/OlivOS/API.py index 7b7114be..81130ca8 100644 --- a/OlivOS/API.py +++ b/OlivOS/API.py @@ -1460,6 +1460,7 @@ def __init__(self, rx_queue, tx_queue, control_queue, logger_proc, scan_interval self.rx_queue = rx_queue self.tx_queue = tx_queue self.control_queue = control_queue + self.control_rx_queue = multiprocessing.Queue() self.logger_proc = logger_proc self.scan_interval = scan_interval self.dead_interval = dead_interval @@ -1467,15 +1468,40 @@ def __init__(self, rx_queue, tx_queue, control_queue, logger_proc, scan_interval def run(self): pass + def run_total(self): + t_this = StoppableThread( + name=self.Proc_name + '+on_control_rx', + target=self.on_control_rx_init, + args=() + ) + t_this.daemon = self.deamon + t_this.start() + self.run() + + def on_control_rx_init(self): + while True: + if self.Proc_info.rx_queue.empty(): + time.sleep(0.02) + else: + try: + packet = self.Proc_info.control_rx_queue.get(block=False) + except: + continue + self.on_control_rx(packet) + + def on_control_rx(self, packet): + #print("!!!! " + self.Proc_name + str(packet.__dict__)) + pass + def start(self): - proc_this = multiprocessing.Process(name=self.Proc_name, target=self.run, args=()) + proc_this = multiprocessing.Process(name=self.Proc_name, target=self.run_total, args=()) proc_this.daemon = self.deamon proc_this.start() # self.Proc = proc_this return proc_this def start_lite(self): - proc_this = StoppableThread(name=self.Proc_name, target=self.run, args=()) + proc_this = StoppableThread(name=self.Proc_name, target=self.run_total, args=()) proc_this.daemon = self.deamon proc_this.start() # self.Proc = proc_this diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index 311bada3..d86f9e82 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -631,6 +631,11 @@ def start(self): rx_packet_data.key['target']['hash'] ) if model_name in Proc_dict: + if Proc_dict[model_name].Proc_info.control_rx_queue is not None: + Proc_dict[model_name].Proc_info.control_rx_queue.put( + rx_packet_data, + block=False + ) if Proc_dict[model_name].Proc_info.rx_queue is not None: Proc_dict[model_name].Proc_info.rx_queue.put( rx_packet_data, From a320eda6052dd4f227a061cd5a5b05e31f92f564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Fri, 14 Apr 2023 21:32:43 +0800 Subject: [PATCH 06/20] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E4=B9=8B=E9=97=B4=E7=9A=84=E8=B7=A8=E8=BF=9B?= =?UTF-8?q?=E7=A8=8B=E6=95=B0=E6=8D=AE=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/API.py | 2 +- OlivOS/bootAPI.py | 93 ++++++++++++++++++++++++++++++++------- OlivOS/bootDataAPI.py | 38 +++++++++++++++- OlivOS/multiLoginUIAPI.py | 65 ++++++++++++++++++++++++++- OlivOS/nativeWinUIAPI.py | 27 +++++++++++- OlivOS/pluginAPI.py | 10 +++++ 6 files changed, 214 insertions(+), 21 deletions(-) diff --git a/OlivOS/API.py b/OlivOS/API.py index 81130ca8..e7adb8f0 100644 --- a/OlivOS/API.py +++ b/OlivOS/API.py @@ -1480,7 +1480,7 @@ def run_total(self): def on_control_rx_init(self): while True: - if self.Proc_info.rx_queue.empty(): + if self.Proc_info.control_rx_queue.empty(): time.sleep(0.02) else: try: diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index d86f9e82..891f1d53 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -28,6 +28,7 @@ import psutil import atexit import importlib +import traceback if '_PYIBoot_SPLASH' in os.environ and importlib.util.find_spec("pyi_splash"): import pyi_splash @@ -520,17 +521,35 @@ def start(self): elif basic_conf_models_this['type'] == 'multiLoginUI' and not flag_noblock: if platform.system() == 'Windows': tmp_callbackData = {'res': False} - Proc_dict[basic_conf_models_this['name']] = OlivOS.multiLoginUIAPI.HostUI( + HostUI_obj = OlivOS.multiLoginUIAPI.HostUI( Model_name=basic_conf_models_this['name'], Account_data=plugin_bot_info_dict, logger_proc=Proc_dict[basic_conf_models_this['logger_proc']], callbackData=tmp_callbackData ) - tmp_res = Proc_dict[basic_conf_models_this['name']].start() + tmp_res = HostUI_obj.start() if tmp_res != True: killMain() - if Proc_dict[basic_conf_models_this['name']].UIData['flag_commit']: - plugin_bot_info_dict = Proc_dict[basic_conf_models_this['name']].UIData['Account_data'] + if HostUI_obj.UIData['flag_commit']: + plugin_bot_info_dict = HostUI_obj.UIData['Account_data'] + elif basic_conf_models_this['type'] == 'multiLoginUI_asayc' and not flag_noblock: + if platform.system() == 'Windows': + main_control.control_queue.put( + main_control.packet( + 'send', + { + 'target': { + 'type': 'nativeWinUI' + }, + 'data': { + 'action': 'account_edit', + 'event': 'account_edit_on', + 'bot_info': plugin_bot_info_dict + } + } + ), + block=False + ) elif basic_conf_models_this['type'] == 'nativeWinUI': if platform.system() == 'Windows': if basic_conf_models_this['name'] not in Proc_dict: @@ -621,9 +640,14 @@ def start(self): if type(rx_packet_data.key) == dict: if 'target' in rx_packet_data.key: if 'type' in rx_packet_data.key['target']: + flag_target_all = (rx_packet_data.key['target']['type'] == 'all') + flag_fliter = 'all' + if 'fliter' in rx_packet_data.key['target']: + flag_fliter = rx_packet_data.key['target']['fliter'] for tmp_Proc_name in basic_conf_models: basic_conf_models_this = basic_conf_models[tmp_Proc_name] - if basic_conf_models_this['type'] == rx_packet_data.key['target']['type']: + + if flag_target_all or basic_conf_models_this['type'] == rx_packet_data.key['target']['type']: model_name = basic_conf_models_this['name'] if 'hash' in rx_packet_data.key['target']: model_name = '%s=%s' % ( @@ -631,16 +655,55 @@ def start(self): rx_packet_data.key['target']['hash'] ) if model_name in Proc_dict: - if Proc_dict[model_name].Proc_info.control_rx_queue is not None: - Proc_dict[model_name].Proc_info.control_rx_queue.put( - rx_packet_data, - block=False - ) - if Proc_dict[model_name].Proc_info.rx_queue is not None: - Proc_dict[model_name].Proc_info.rx_queue.put( - rx_packet_data, - block=False - ) + if flag_fliter in ['all', 'control_only']: + try: + if Proc_dict[model_name].Proc_info.control_rx_queue is not None: + Proc_dict[model_name].Proc_info.control_rx_queue.put( + rx_packet_data, + block=False + ) + except Exception as e: + traceback.print_exc() + if flag_fliter in ['all', 'rx_only']: + try: + if Proc_dict[model_name].Proc_info.rx_queue is not None: + Proc_dict[model_name].Proc_info.rx_queue.put( + rx_packet_data, + block=False + ) + except Exception as e: + traceback.print_exc() + elif rx_packet_data.action == 'call_system_event': + if type(rx_packet_data.key) is dict \ + and 'action' in rx_packet_data.key \ + and type(rx_packet_data.key['action']) is list: + for event_this in rx_packet_data.key['action']: + if event_this in basic_conf['system']['event']: + for model_this in basic_conf['system']['event'][event_this]: + main_control.control_queue.put( + main_control.packet('init', model_this), + block=False + ) + elif rx_packet_data.action == 'call_account_update': + if type(rx_packet_data.key) is dict \ + and 'data' in rx_packet_data.key \ + and type(rx_packet_data.key['data']) is dict: + plugin_bot_info_dict = rx_packet_data.key['data'] + main_control.control_queue.put( + main_control.packet( + 'send', { + 'target': { + 'type': 'all', + 'fliter': 'control_only' + }, + 'data': { + 'action': 'account_update', + 'data': plugin_bot_info_dict + } + } + ), + block=False + ) elif rx_packet_data.action == 'init_type': for tmp_Proc_name in basic_conf_models: basic_conf_models_this = basic_conf_models[tmp_Proc_name] diff --git a/OlivOS/bootDataAPI.py b/OlivOS/bootDataAPI.py index 441f5215..93c661d0 100644 --- a/OlivOS/bootDataAPI.py +++ b/OlivOS/bootDataAPI.py @@ -33,7 +33,6 @@ "OlivOS_walleq_lib_exe_model", "OlivOS_cwcb_lib_exe_model", "OlivOS_hackChat_link", - "OlivOS_account_config_safe", "OlivOS_plugin", "OlivOS_virtual_terminal_link", "OlivOS_flask_post_rx", @@ -47,6 +46,28 @@ "OlivOS_biliLive_link", "OlivOS_update_check" ], + "event": { + "account_edit": [ + "OlivOS_account_config", + "OlivOS_multiLoginUI", + "OlivOS_account_fix", + "OlivOS_account_config_save", + "OlivOS_account_config", + "OlivOS_account_config_update" + ], + "account_edit_asayc_start": [ + "OlivOS_account_config" + ], + "account_edit_asayc_do": [ + "OlivOS_multiLoginUI_asayc", + ], + "account_edit_asayc_end": [ + "OlivOS_account_fix", + "OlivOS_account_config_save", + "OlivOS_account_config", + "OlivOS_account_config_update" + ], + }, "control_queue": "OlivOS_control_queue", "interval": 0.2, "proc_mode": "auto" @@ -84,6 +105,12 @@ "type": "multiLoginUI", "logger_proc": "OlivOS_logger" }, + "OlivOS_multiLoginUI_asayc": { + "enable": True, + "name": "OlivOS_multiLoginUI_asayc", + "type": "multiLoginUI_asayc", + "logger_proc": "OlivOS_logger" + }, "OlivOS_nativeWinUIAPI": { "enable": True, "name": "OlivOS_nativeWinUIAPI", @@ -130,6 +157,15 @@ "path": "./conf/account.json" } }, + "OlivOS_account_config_update": { + "enable": True, + "name": "OlivOS_account_config_update", + "type": "account_config_update", + "logger_proc": "OlivOS_logger", + "data": { + "path": "./conf/account.json" + } + }, "OlivOS_logger": { "enable": True, "name": "OlivOS_logger", diff --git a/OlivOS/multiLoginUIAPI.py b/OlivOS/multiLoginUIAPI.py index ec9593f3..f4b48356 100644 --- a/OlivOS/multiLoginUIAPI.py +++ b/OlivOS/multiLoginUIAPI.py @@ -20,6 +20,8 @@ import hashlib import random import shutil +import platform +import traceback from tkinter import ttk from tkinter import messagebox @@ -35,15 +37,70 @@ 'color_006': '#80D7FF' } +def run_HostUI_asayc(plugin_bot_info_dict, control_queue): + if platform.system() == 'Windows': + try: + tmp_callbackData = {'res': False} + tmp_t = OlivOS.multiLoginUIAPI.HostUI( + Model_name='OlivOS_multiLoginUI_asayc', + Account_data=plugin_bot_info_dict, + logger_proc=None, + callbackData=tmp_callbackData, + asaycMode=True, + rootMode=True, + control_queue=control_queue + ) + tmp_res = tmp_t.start() + if tmp_res != True: + pass + if tmp_t.UIData['flag_commit']: + pass + except Exception as e: + traceback.print_exc() + +def sendAccountUpdate(obj, control_queue, account_data): + if control_queue is not None: + control_queue.put( + OlivOS.API.Control.packet( + 'call_system_event', + { + 'action': [ + 'account_edit_asayc_end' + ] + } + ), + block=False + ) + control_queue.put( + OlivOS.API.Control.packet( + 'call_account_update', + { + 'data': account_data + } + ), + block=False + ) class HostUI(object): - def __init__(self, Model_name, Account_data, logger_proc=None, callbackData=None): + def __init__( + self, + Model_name, + Account_data, + logger_proc=None, + callbackData=None, + asaycMode=False, + rootMode=True, + control_queue=None + ): self.Model_name = Model_name self.UIObject = {} self.UIData = {} self.UIConfig = {} self.logger_proc = logger_proc self.callbackData = callbackData + self.asaycMode = asaycMode + self.rootMode = rootMode + self.control_queue = control_queue self.res = False self.UIData['Account_data'] = Account_data self.UIData['flag_commit'] = False @@ -55,7 +112,10 @@ def log(self, log_level, log_message): self.logger_proc.log(log_level, log_message) def start(self): - self.UIObject['root'] = tkinter.Tk() + if self.rootMode: + self.UIObject['root'] = tkinter.Tk() + else: + self.UIObject['root'] = tkinter.Toplevel() self.UIObject['root'].title('OlivOS 登录管理器') self.UIObject['root'].geometry('518x400') self.UIObject['root'].resizable( @@ -227,6 +287,7 @@ def account_data_commit(self): self.res = True if type(self.callbackData) == dict: self.callbackData['res'] = self.res + sendAccountUpdate(self, self.control_queue, self.UIData['Account_data']) self.UIObject['root'].destroy() diff --git a/OlivOS/nativeWinUIAPI.py b/OlivOS/nativeWinUIAPI.py index d380afd1..260c9c56 100644 --- a/OlivOS/nativeWinUIAPI.py +++ b/OlivOS/nativeWinUIAPI.py @@ -42,7 +42,6 @@ 'color_006': '#80D7FF' } - class StoppableThread(threading.Thread): def __init__(self, *args, **kwargs): super(StoppableThread, self).__init__(*args, **kwargs) @@ -156,6 +155,15 @@ def mainrun(self): else: self.updateShallow() self.updatePluginEdit() + elif 'account_edit' == rx_packet_data.key['data']['action']: + if 'event' in rx_packet_data.key['data'] \ + and 'account_edit_on' == rx_packet_data.key['data']['event'] \ + and 'bot_info' in rx_packet_data.key['data'] \ + and type(rx_packet_data.key['data']['bot_info']) is dict: + OlivOS.multiLoginUIAPI.run_HostUI_asayc( + plugin_bot_info_dict=rx_packet_data.key['data']['bot_info'], + control_queue=self.Proc_info.control_queue + ) elif 'plugin_edit_menu_on' == rx_packet_data.key['data']['action']: self.startPluginEdit() elif 'logger' == rx_packet_data.key['data']['action']: @@ -376,7 +384,7 @@ def mainrun(self): def updateShallowMenuList(self): tmp_new = [] self.UIData['shallow_menu_list'] = [ - ['账号管理', False], + ['账号管理', self.startAccountEditSendFunc()], ['打开终端', self.startOlivOSTerminalUISend], ['gocqhttp管理', self.UIData['shallow_gocqhttp_menu_list']], ['walleq管理', self.UIData['shallow_walleq_menu_list']], @@ -396,6 +404,21 @@ def updateShallowMenuList(self): tmp_new.append(data_this) self.UIData['shallow_menu_list'] = tmp_new + def startAccountEditSendFunc(self): + def resFunc(): + self.startAccountEditSend() + return resFunc + + def startAccountEditSend(self): + self.sendControlEventSend( + 'call_system_event', { + 'action': [ + 'account_edit_asayc_start', + 'account_edit_asayc_do' + ] + } + ) + def startGoCqhttpTerminalUISendFunc(self, hash): def resFunc(): self.startGoCqhttpTerminalUISend(hash) diff --git a/OlivOS/pluginAPI.py b/OlivOS/pluginAPI.py index b6beb0a1..bede0355 100644 --- a/OlivOS/pluginAPI.py +++ b/OlivOS/pluginAPI.py @@ -169,6 +169,16 @@ def run(self): if rx_count == self.Proc_config['step_to_restart']: self.set_restart() + def on_control_rx(self, packet): + if type(packet) is OlivOS.API.Control.packet: + if 'send' == packet.action: + if type(packet.key) is dict \ + and 'data' in packet.key \ + and type(packet.key['data']) \ + and 'action' in packet.key['data']: + if 'account_update' == packet.key['data']['action']: + self.set_restart() + def set_restart(self): self.log(2, OlivOS.L10NAPI.getTrans( 'OlivOS plugin shallow [{0}] call restart', [ From 8a09044e64f7c34a83714df3e8948d5314961005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Sat, 15 Apr 2023 16:39:12 +0800 Subject: [PATCH 07/20] =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=8E=E7=BB=84=E4=BB=B6=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/API.py | 32 ++++++++++++++++++++++- OlivOS/bootAPI.py | 49 ++++++++++++++++++++++++++++-------- OlivOS/bootDataAPI.py | 40 ++++++++++++++++++++++++++--- OlivOS/libCWCBEXEModelAPI.py | 18 ++++++++++--- OlivOS/libEXEModelAPI.py | 21 ++++++++++++---- OlivOS/libWQEXEModelAPI.py | 23 ++++++++++++----- OlivOS/multiLoginUIAPI.py | 22 ++++++++++++++++ OlivOS/nativeWinUIAPI.py | 17 +++++++++++++ 8 files changed, 193 insertions(+), 29 deletions(-) diff --git a/OlivOS/API.py b/OlivOS/API.py index e7adb8f0..7ffe2329 100644 --- a/OlivOS/API.py +++ b/OlivOS/API.py @@ -21,6 +21,8 @@ import hashlib import time import traceback +import inspect +import ctypes from functools import wraps @@ -1423,18 +1425,42 @@ class StoppableThread(threading.Thread): def __init__(self, *args, **kwargs): super(StoppableThread, self).__init__(*args, **kwargs) self._stop_event = threading.Event() + self.root = None def terminate(self): + if self.root is not None: + try: + self.root.on_terminate() + except Exception as e: + traceback.print_exc() self._stop_event.set() + self.stop_thread() def stop(self): - self._stop_event.set() + self.terminate() def join(self): pass def stopped(self): return self._stop_event.is_set() + + def _async_raise(self, tid, exctype): + """raises the exception, performs cleanup if needed""" + tid = ctypes.c_long(tid) + if not inspect.isclass(exctype): + exctype = type(exctype) + res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype)) + if res == 0: + raise ValueError("invalid thread id") + elif res != 1: + # """if it returns a number greater than one, you're in trouble, + # and you should call it again with exc=NULL to revert the effect""" + ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None) + raise SystemError("PyThreadState_SetAsyncExc failed") + + def stop_thread(self): + self._async_raise(self.ident, SystemExit) class Proc_templet(object): @@ -1493,6 +1519,9 @@ def on_control_rx(self, packet): #print("!!!! " + self.Proc_name + str(packet.__dict__)) pass + def on_terminate(self): + pass + def start(self): proc_this = multiprocessing.Process(name=self.Proc_name, target=self.run_total, args=()) proc_this.daemon = self.deamon @@ -1502,6 +1531,7 @@ def start(self): def start_lite(self): proc_this = StoppableThread(name=self.Proc_name, target=self.run_total, args=()) + proc_this.root = self proc_this.daemon = self.deamon proc_this.start() # self.Proc = proc_this diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index 891f1d53..3e476b2e 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -214,7 +214,7 @@ def start(self): bot_info_dict=plugin_bot_info_dict[bot_info_key], debug_mode=False ) - Proc_Proc_dict[basic_conf_models_this['name']] = Proc_dict[tmp_Proc_name].start_unity( + Proc_Proc_dict[tmp_Proc_name] = Proc_dict[tmp_Proc_name].start_unity( tmp_proc_mode) elif basic_conf_models_this['type'] == 'post': flag_need_enable = False @@ -262,7 +262,7 @@ def start(self): bot_info_dict=plugin_bot_info_dict[bot_info_key], debug_mode=False ) - Proc_Proc_dict[basic_conf_models_this['name']] = Proc_dict[tmp_Proc_name].start_unity( + Proc_Proc_dict[tmp_Proc_name] = Proc_dict[tmp_Proc_name].start_unity( tmp_proc_mode) elif basic_conf_models_this['type'] == 'account_config': plugin_bot_info_dict = OlivOS.accountAPI.Account.load( @@ -318,7 +318,7 @@ def start(self): bot_info_dict=plugin_bot_info_dict[bot_info_key], debug_mode=False ) - Proc_Proc_dict[basic_conf_models_this['name']] = Proc_dict[tmp_Proc_name].start_unity( + Proc_Proc_dict[tmp_Proc_name] = Proc_dict[tmp_Proc_name].start_unity( tmp_proc_mode) elif basic_conf_models_this['type'] == 'discord_link': flag_need_enable = False @@ -340,7 +340,7 @@ def start(self): bot_info_dict=plugin_bot_info_dict[bot_info_key], debug_mode=False ) - Proc_Proc_dict[basic_conf_models_this['name']] = Proc_dict[tmp_Proc_name].start_unity( + Proc_Proc_dict[tmp_Proc_name] = Proc_dict[tmp_Proc_name].start_unity( tmp_proc_mode) elif basic_conf_models_this['type'] == 'kaiheila_link': flag_need_enable = False @@ -362,7 +362,7 @@ def start(self): bot_info_dict=plugin_bot_info_dict[bot_info_key], debug_mode=False ) - Proc_Proc_dict[basic_conf_models_this['name']] = Proc_dict[tmp_Proc_name].start_unity( + Proc_Proc_dict[tmp_Proc_name] = Proc_dict[tmp_Proc_name].start_unity( tmp_proc_mode) elif basic_conf_models_this['type'] == 'biliLive_link': flag_need_enable = False @@ -387,7 +387,7 @@ def start(self): bot_info_dict=plugin_bot_info_dict[bot_info_key], debug_mode=False ) - Proc_Proc_dict[basic_conf_models_this['name']] = Proc_dict[tmp_Proc_name].start_unity( + Proc_Proc_dict[tmp_Proc_name] = Proc_dict[tmp_Proc_name].start_unity( tmp_proc_mode) elif basic_conf_models_this['type'] == 'hackChat_link': flag_need_enable = False @@ -411,7 +411,7 @@ def start(self): bot_info_dict=plugin_bot_info_dict[bot_info_key], debug_mode=False ) - Proc_Proc_dict[basic_conf_models_this['name']] = Proc_dict[tmp_Proc_name].start_unity( + Proc_Proc_dict[tmp_Proc_name] = Proc_dict[tmp_Proc_name].start_unity( tmp_proc_mode) elif basic_conf_models_this['type'] == 'telegram_poll': flag_need_enable = False @@ -471,7 +471,7 @@ def start(self): bot_info_dict=plugin_bot_info_dict[bot_info_key], debug_mode=False ) - Proc_Proc_dict[basic_conf_models_this['name']] = Proc_dict[tmp_Proc_name].start_unity( + Proc_Proc_dict[tmp_Proc_name] = Proc_dict[tmp_Proc_name].start_unity( tmp_proc_mode) elif basic_conf_models_this['type'] == 'dodo_poll': flag_need_enable = False @@ -678,12 +678,25 @@ def start(self): and 'action' in rx_packet_data.key \ and type(rx_packet_data.key['action']) is list: for event_this in rx_packet_data.key['action']: - if event_this in basic_conf['system']['event']: + if 'event' in basic_conf['system'] \ + and event_this in basic_conf['system']['event']: for model_this in basic_conf['system']['event'][event_this]: main_control.control_queue.put( main_control.packet('init', model_this), block=False ) + elif rx_packet_data.action == 'call_system_stop_type_event': + if type(rx_packet_data.key) is dict \ + and 'action' in rx_packet_data.key \ + and type(rx_packet_data.key['action']) is list: + for event_this in rx_packet_data.key['action']: + if 'type_event' in basic_conf['system'] \ + and event_this in basic_conf['system']['type_event']: + for model_this in basic_conf['system']['type_event'][event_this]: + main_control.control_queue.put( + main_control.packet('stop_type', model_this), + block=False + ) elif rx_packet_data.action == 'call_account_update': if type(rx_packet_data.key) is dict \ and 'data' in rx_packet_data.key \ @@ -712,6 +725,20 @@ def start(self): main_control.packet('init', basic_conf_models_this['name']), block=False ) + elif rx_packet_data.action == 'stop_type': + list_stop = [] + for tmp_Proc_name in Proc_Proc_dict: + try: + if tmp_Proc_name in Proc_dict \ + and rx_packet_data.key == Proc_dict[tmp_Proc_name].Proc_type: + Proc_Proc_dict[tmp_Proc_name].terminate() + Proc_Proc_dict[tmp_Proc_name].join() + list_stop.append(tmp_Proc_name) + except Exception as e: + traceback.print_exc() + for tmp_Proc_name in list_stop: + Proc_dict.pop(tmp_Proc_name) + Proc_Proc_dict.pop(tmp_Proc_name) elif rx_packet_data.action == 'exit_total': killMain() @@ -734,12 +761,14 @@ def update_get_func( block=False ) +def killByPid(pid): + parent = psutil.Process(pid) + kill_process_and_its_children(parent) def killMain(): parent = psutil.Process(os.getpid()) kill_process_and_its_children(parent) - def kill_process(p): try: p.terminate() diff --git a/OlivOS/bootDataAPI.py b/OlivOS/bootDataAPI.py index 93c661d0..c1114881 100644 --- a/OlivOS/bootDataAPI.py +++ b/OlivOS/bootDataAPI.py @@ -36,7 +36,7 @@ "OlivOS_plugin", "OlivOS_virtual_terminal_link", "OlivOS_flask_post_rx", - "OlivOS_onebotv12_link", + "OlivOS_onebotV12_link", "OlivOS_qqGuild_link", "OlivOS_discord_link", "OlivOS_telegram_poll", @@ -67,6 +67,40 @@ "OlivOS_account_config", "OlivOS_account_config_update" ], + "account_update": [ + "OlivOS_gocqhttp_lib_exe_model", + "OlivOS_walleq_lib_exe_model", + "OlivOS_cwcb_lib_exe_model", + "OlivOS_hackChat_link", + "OlivOS_virtual_terminal_link", + "OlivOS_flask_post_rx", + "OlivOS_onebotV12_link", + "OlivOS_qqGuild_link", + "OlivOS_discord_link", + "OlivOS_telegram_poll", + "OlivOS_fanbook_poll", + "OlivOS_kaiheila_link", + "OlivOS_dodo_link", + "OlivOS_biliLive_link", + ] + }, + "type_event": { + "account_update": [ + "gocqhttp_lib_exe_model", + "walleq_lib_exe_model", + "cwcb_lib_exe_model", + "hackChat_link", + "terminal_link", + "flask_post_rx", + "onebotV12_link", + "qqGuild_link", + "discord_link", + "telegram_poll", + "fanbook_poll", + "kaiheila_link", + "dodo_link", + "biliLive_link", + ] }, "control_queue": "OlivOS_control_queue", "interval": 0.2, @@ -226,9 +260,9 @@ "port": 55001 } }, - "OlivOS_onebotv12_link": { + "OlivOS_onebotV12_link": { "enable": True, - "name": "OlivOS_onebotv12_link", + "name": "OlivOS_onebotV12_link", "type": "onebotV12_link", "interval": 0.002, "dead_interval": 1, diff --git a/OlivOS/libCWCBEXEModelAPI.py b/OlivOS/libCWCBEXEModelAPI.py index 937799c3..72e135c1 100644 --- a/OlivOS/libCWCBEXEModelAPI.py +++ b/OlivOS/libCWCBEXEModelAPI.py @@ -102,7 +102,7 @@ def __init__(self, Proc_name, scan_interval=0.001, dead_interval=1, rx_queue=Non OlivOS.API.Proc_templet.__init__( self, Proc_name=Proc_name, - Proc_type='lib_cwcb_exe_model', + Proc_type='cwcb_lib_exe_model', scan_interval=scan_interval, dead_interval=dead_interval, rx_queue=rx_queue, @@ -115,14 +115,15 @@ def __init__(self, Proc_name, scan_interval=0.001, dead_interval=1, rx_queue=Non self.Proc_config['target_proc'] = target_proc self.Proc_data['check_qrcode_flag'] = False self.Proc_data['check_stdin'] = False + self.Proc_data['model_Proc'] = None + self.flag_run = True def run(self): - flag_run = True if self.Proc_data['bot_info_dict'].platform['model'] in [ 'ComWeChatBotClient' ]: self.send_init_event() - while flag_run: + while self.flag_run: releaseDir('./lib') if not os.path.exists('./lib/ComWeChat-Client.exe'): self.log(3, OlivOS.L10NAPI.getTrans( @@ -174,9 +175,11 @@ def run(self): creationflags=subprocess.CREATE_NEW_CONSOLE, env=tmp_env ) + self.Proc_data['model_Proc'] = model_Proc threading.Thread( target=self.check_stdin, - args=(model_Proc,) + args=(model_Proc,), + daemon=self.deamon ).start() self.get_model_stdout(model_Proc) # model_Proc.communicate(timeout = None) @@ -184,8 +187,15 @@ def run(self): 'OlivOS libCWCBEXEModel server [{0}] will retry in 10s...', [self.Proc_name], modelName )) + self.Proc_data['model_Proc'] = None time.sleep(8) + def on_terminate(self): + self.flag_run = False + if 'model_Proc' in self.Proc_data \ + and self.Proc_data['model_Proc'] is not None: + OlivOS.bootAPI.killByPid(self.Proc_data['model_Proc'].pid) + def getBotIDStr(self): tmp_self_data = self.Proc_data['bot_info_dict'].platform['platform'] if self.Proc_data['bot_info_dict'].id is not None: diff --git a/OlivOS/libEXEModelAPI.py b/OlivOS/libEXEModelAPI.py index 93e74c59..4e108c68 100644 --- a/OlivOS/libEXEModelAPI.py +++ b/OlivOS/libEXEModelAPI.py @@ -107,9 +107,10 @@ def __init__(self, Proc_name, scan_interval=0.001, dead_interval=1, rx_queue=Non self.Proc_config['target_proc'] = target_proc self.Proc_data['check_qrcode_flag'] = False self.Proc_data['check_stdin'] = False + self.Proc_data['model_Proc'] = None + self.flag_run = True def run(self): - flag_run = True if self.Proc_data['bot_info_dict'].platform['model'] in [ 'gocqhttp_show', 'gocqhttp_show_Android_Phone', @@ -119,7 +120,7 @@ def run(self): 'gocqhttp_show_Android_Pad' ]: self.send_init_event() - while flag_run: + while self.flag_run: releaseDir('./lib') if not os.path.exists('./lib/go-cqhttp.exe'): self.log(3, OlivOS.L10NAPI.getTrans( @@ -175,7 +176,8 @@ def run(self): self.Proc_data['check_stdin'] = True threading.Thread( target=self.check_qrcode, - args=() + args=(), + daemon=self.deamon ).start() tmp_env = dict(os.environ) # 依据 https://github.com/Mrs4s/go-cqhttp/pull/1772 的改动 @@ -190,9 +192,11 @@ def run(self): creationflags=subprocess.CREATE_NEW_CONSOLE, env=tmp_env ) + self.Proc_data['model_Proc'] = model_Proc threading.Thread( target=self.check_stdin, - args=(model_Proc,) + args=(model_Proc,), + daemon=self.deamon ).start() self.get_model_stdout(model_Proc) # model_Proc.communicate(timeout = None) @@ -200,6 +204,7 @@ def run(self): 'OlivOS libEXEModel server [{0}] will retry in 10s...', [self.Proc_name], modelName )) + self.Proc_data['model_Proc'] = None time.sleep(8) elif self.Proc_data['bot_info_dict'].platform['model'] in [ 'gocqhttp_show_old' @@ -216,7 +221,13 @@ def run(self): cwd='.\\conf\\gocqhttp\\' + self.Proc_data['bot_info_dict'].hash, env=tmp_env ) - flag_run = False + self.flag_run = False + + def on_terminate(self): + self.flag_run = False + if 'model_Proc' in self.Proc_data \ + and self.Proc_data['model_Proc'] is not None: + OlivOS.bootAPI.killByPid(self.Proc_data['model_Proc'].pid) def getBotIDStr(self): tmp_self_data = self.Proc_data['bot_info_dict'].platform['platform'] diff --git a/OlivOS/libWQEXEModelAPI.py b/OlivOS/libWQEXEModelAPI.py index 43cfbfce..54d4a396 100644 --- a/OlivOS/libWQEXEModelAPI.py +++ b/OlivOS/libWQEXEModelAPI.py @@ -93,7 +93,7 @@ def __init__(self, Proc_name, scan_interval=0.001, dead_interval=1, rx_queue=Non OlivOS.API.Proc_templet.__init__( self, Proc_name=Proc_name, - Proc_type='lib_wq_exe_model', + Proc_type='walleq_lib_exe_model', scan_interval=scan_interval, dead_interval=dead_interval, rx_queue=rx_queue, @@ -106,9 +106,10 @@ def __init__(self, Proc_name, scan_interval=0.001, dead_interval=1, rx_queue=Non self.Proc_config['target_proc'] = target_proc self.Proc_data['check_qrcode_flag'] = False self.Proc_data['check_stdin'] = False + self.Proc_data['model_Proc'] = None + self.flag_run = True def run(self): - flag_run = True if self.Proc_data['bot_info_dict'].platform['model'] in [ 'walleq_show', 'walleq_show_Android_Phone', @@ -118,7 +119,7 @@ def run(self): 'walleq_show_Android_Pad' ]: self.send_init_event() - while flag_run: + while self.flag_run: releaseDir('./lib') if not os.path.exists('./lib/walle-q.exe'): self.log(3, OlivOS.L10NAPI.getTrans( @@ -151,7 +152,8 @@ def run(self): self.Proc_data['check_stdin'] = True threading.Thread( target=self.check_qrcode, - args=() + args=(), + daemon=self.deamon ).start() tmp_env = dict(os.environ) model_Proc = subprocess.Popen( @@ -164,9 +166,11 @@ def run(self): creationflags=subprocess.CREATE_NEW_CONSOLE, env=tmp_env ) + self.Proc_data['model_Proc'] = model_Proc threading.Thread( target=self.check_stdin, - args=(model_Proc,) + args=(model_Proc,), + daemon=self.deamon ).start() self.get_model_stdout(model_Proc) # model_Proc.communicate(timeout = None) @@ -174,6 +178,7 @@ def run(self): 'OlivOS libWQEXEModel server [{0}] will retry in 10s...', [self.Proc_name], modelName )) + self.Proc_data['model_Proc'] = None time.sleep(8) elif self.Proc_data['bot_info_dict'].platform['model'] in [ 'walleq_show_old' @@ -189,7 +194,13 @@ def run(self): cwd='.\\conf\\walleq\\' + self.Proc_data['bot_info_dict'].hash, env=tmp_env ) - flag_run = False + self.flag_run = False + + def on_terminate(self): + self.flag_run = False + if 'model_Proc' in self.Proc_data \ + and self.Proc_data['model_Proc'] is not None: + OlivOS.bootAPI.killByPid(self.Proc_data['model_Proc'].pid) def getBotIDStr(self): tmp_self_data = self.Proc_data['bot_info_dict'].platform['platform'] diff --git a/OlivOS/multiLoginUIAPI.py b/OlivOS/multiLoginUIAPI.py index f4b48356..753b7c6e 100644 --- a/OlivOS/multiLoginUIAPI.py +++ b/OlivOS/multiLoginUIAPI.py @@ -80,6 +80,28 @@ def sendAccountUpdate(obj, control_queue, account_data): ), block=False ) + control_queue.put( + OlivOS.API.Control.packet( + 'call_system_stop_type_event', + { + 'action': [ + 'account_update' + ] + } + ), + block=False + ) + control_queue.put( + OlivOS.API.Control.packet( + 'call_system_event', + { + 'action': [ + 'account_update' + ] + } + ), + block=False + ) class HostUI(object): def __init__( diff --git a/OlivOS/nativeWinUIAPI.py b/OlivOS/nativeWinUIAPI.py index 260c9c56..3d1f2040 100644 --- a/OlivOS/nativeWinUIAPI.py +++ b/OlivOS/nativeWinUIAPI.py @@ -126,6 +126,23 @@ def run(self): self.process_msg() self.UIObject['main_tk'].mainloop() + def on_control_rx(self, packet): + if type(packet) is OlivOS.API.Control.packet: + if 'send' == packet.action: + if type(packet.key) is dict \ + and 'data' in packet.key \ + and type(packet.key['data']) \ + and 'action' in packet.key['data']: + if 'account_update' == packet.key['data']['action']: + if 'data' in packet.key['data'] \ + and type(packet.key['data']['data']) is dict: + self.bot_info = packet.key['data']['data'] + self.UIData['shallow_gocqhttp_menu_list'] = None + self.UIData['shallow_walleq_menu_list'] = None + self.UIData['shallow_cwcb_menu_list'] = None + self.UIData['shallow_virtual_terminal_menu_list'] = None + self.updateShallowMenuList() + def process_msg(self): self.UIObject['main_tk'].after(50, self.process_msg) self.mainrun() From 63522c2e7113b5420e7264dd032c13b57ce85a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Sat, 15 Apr 2023 17:07:52 +0800 Subject: [PATCH 08/20] =?UTF-8?q?Revert=20"=E4=BF=AE=E6=AD=A3=E6=96=87?= =?UTF-8?q?=E5=AD=97=E6=98=BE=E7=A4=BA=E9=97=AE=E9=A2=98"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 19de46d7e091fc618dce76ac09cc8e5b320a90ba. --- OlivOS/bootAPI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index 3e476b2e..4e98dab2 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -811,4 +811,4 @@ def setSplashText(text:str): def preLoadPrint(text:str): print(text) - #setSplashText(text) + setSplashText(text) From 5d0c4dfae3aee8c558ddcda1926a6d1d464bb4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Sat, 15 Apr 2023 17:14:37 +0800 Subject: [PATCH 09/20] =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/bootAPI.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index 4e98dab2..9390cb5b 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -29,8 +29,6 @@ import atexit import importlib import traceback -if '_PYIBoot_SPLASH' in os.environ and importlib.util.find_spec("pyi_splash"): - import pyi_splash import OlivOS @@ -801,14 +799,14 @@ def kill_process_children(p): # 启动画面的操作 def setSplashClose(): if '_PYIBoot_SPLASH' in os.environ and importlib.util.find_spec("pyi_splash"): - #import pyi_splash + import pyi_splash pyi_splash.close() def setSplashText(text:str): if '_PYIBoot_SPLASH' in os.environ and importlib.util.find_spec("pyi_splash"): - #import pyi_splash + import pyi_splash pyi_splash.update_text(text) def preLoadPrint(text:str): print(text) - setSplashText(text) + #setSplashText(text) From 3d0c39f870f35298b96fb0599cb2277b2602e940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Sat, 15 Apr 2023 17:54:31 +0800 Subject: [PATCH 10/20] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E7=9A=84WalleQ=E5=AF=86=E7=A0=81=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/libWQEXEModelAPI.py | 1 - 1 file changed, 1 deletion(-) diff --git a/OlivOS/libWQEXEModelAPI.py b/OlivOS/libWQEXEModelAPI.py index 54d4a396..e96a7c14 100644 --- a/OlivOS/libWQEXEModelAPI.py +++ b/OlivOS/libWQEXEModelAPI.py @@ -370,7 +370,6 @@ def setConfig(self): self.config_file_format['password'] = '' if self.bot_info_dict.password != '': self.config_file_format['password'] = 'password = "%s"' % self.bot_info_dict.password - self.config_file_format['password'] = self.bot_info_dict.password self.config_file_format['token'] = self.bot_info_dict.post_info.access_token self.config_file_format['port'] = str(self.bot_info_dict.post_info.port) self.config_file_format['host'] = '127.0.0.1' From 13178ad385bc2d03ce65996765ed1f09514308e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Mon, 17 Apr 2023 11:47:02 +0800 Subject: [PATCH 11/20] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E8=B7=9F=E8=B8=AA=E6=89=AB=E6=8F=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closed #64 --- OlivOS/L10NDataAPI.py | 12 +++++++ OlivOS/bootAPI.py | 73 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/OlivOS/L10NDataAPI.py b/OlivOS/L10NDataAPI.py index ad27cc29..064bf78d 100644 --- a/OlivOS/L10NDataAPI.py +++ b/OlivOS/L10NDataAPI.py @@ -93,6 +93,12 @@ 'libCWCBEXEModelAPI_0004': 'OlivOS libCWCBEXEModel failed: {0}\n{1}', 'libCWCBEXEModelAPI_0005': 'OlivOS libCWCBEXEModel server [{0}] is running', 'libCWCBEXEModelAPI_0006': 'OlivOS libCWCBEXEModel server [{0}] exited', + 'bootAPI_0001': 'OlivOS model [{0}] will init', + 'bootAPI_0002': 'OlivOS model [{0}] init', + 'bootAPI_0003': 'OlivOS model [{0}] will try init', + 'bootAPI_0004': 'OlivOS model [{0}] type init', + 'bootAPI_0005': 'OlivOS model [{0}] stopped', + 'bootAPI_0006': 'OlivOS model [{0}] will stop', }, 'zh-CN': { 'diagnoseAPI_0001': '欢迎使用 青果核心交互栈 OlivOS {0}', @@ -166,5 +172,11 @@ 'libCWCBEXEModelAPI_0004': 'OlivOS ComWeChatBotClient进程托管服务组件 错误: {0}\n{1}', 'libCWCBEXEModelAPI_0005': 'OlivOS ComWeChatBotClient进程托管服务组件 [{0}] 正在运作', 'libCWCBEXEModelAPI_0006': 'OlivOS ComWeChatBotClient进程托管服务组件 [{0}] 已经存在', + 'bootAPI_0001': 'OlivOS 组件 [{0}] 即将初始化', + 'bootAPI_0002': 'OlivOS 组件 [{0}] 初始化', + 'bootAPI_0003': 'OlivOS 组件 [{0}] 即将尝试初始化', + 'bootAPI_0004': 'OlivOS 组件 [{0}] 类型 即将初始化', + 'bootAPI_0005': 'OlivOS 组件 [{0}] 已被停止', + 'bootAPI_0006': 'OlivOS 组件 [{0}] 即将停止', } } diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index 9390cb5b..a3a11ea7 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -29,9 +29,14 @@ import atexit import importlib import traceback +import copy import OlivOS +modelName = 'bootAPI' + +gMonitorReg = {} +gLoggerProc = None def releaseDir(dir_path): if not os.path.exists(dir_path): @@ -45,6 +50,7 @@ def __init__(self, basic_conf=None): self.Config['basic_conf_path'] = basic_conf def start(self): + global gLoggerProc # 兼容Win平台多进程,避免形成fork-bomb multiprocessing.freeze_support() atexit.register(killMain) @@ -55,6 +61,7 @@ def start(self): Proc_Proc_dict = {} Proc_logger_name = [] plugin_bot_info_dict = {} + logger_proc = None preLoadPrint('OlivOS - Witness Union') start_up_show_str = (''' @@ -140,6 +147,11 @@ def start(self): if 'auto' == tmp_proc_mode_raw: tmp_proc_mode = 'threading' if basic_conf_models_this['enable']: + logG(1, OlivOS.L10NAPI.getTrans('OlivOS model [{0}] will init', [ + basic_conf_models_this['name'] + ], + modelName + )) if basic_conf_models_this['type'] == 'sleep': time.sleep(10) elif basic_conf_models_this['type'] == 'update_check': @@ -164,6 +176,8 @@ def start(self): basic_conf_models_this['name']].start_unity(tmp_proc_mode) for this_bot_info in plugin_bot_info_dict: plugin_bot_info_dict[this_bot_info].debug_logger = Proc_dict[basic_conf_models_this['name']] + logger_proc = Proc_dict[basic_conf_models_this['name']] + gLoggerProc = Proc_dict[basic_conf_models_this['name']] elif basic_conf_models_this['type'] == 'plugin': proc_plugin_func_dict = {} tmp_tx_queue_list = [] @@ -723,6 +737,11 @@ def start(self): main_control.packet('init', basic_conf_models_this['name']), block=False ) + logG(1, OlivOS.L10NAPI.getTrans('OlivOS model [{0}] type init', [ + tmp_Proc_name + ], + modelName + )) elif rx_packet_data.action == 'stop_type': list_stop = [] for tmp_Proc_name in Proc_Proc_dict: @@ -732,6 +751,11 @@ def start(self): Proc_Proc_dict[tmp_Proc_name].terminate() Proc_Proc_dict[tmp_Proc_name].join() list_stop.append(tmp_Proc_name) + logG(1, OlivOS.L10NAPI.getTrans('OlivOS model [{0}] will stop', [ + tmp_Proc_name + ], + modelName + )) except Exception as e: traceback.print_exc() for tmp_Proc_name in list_stop: @@ -739,6 +763,7 @@ def start(self): Proc_Proc_dict.pop(tmp_Proc_name) elif rx_packet_data.action == 'exit_total': killMain() + bootMonitor(varDict=locals()) def update_get_func( @@ -759,6 +784,36 @@ def update_get_func( block=False ) +# 进程监控 +def bootMonitor(varDict:dict): + global gMonitorReg + try: + gMonitorReg.setdefault('Proc_dict', {'keys': []}) + if 'Proc_dict' in varDict \ + and type(varDict['Proc_dict']) is dict: + flagNeedRefresh = False + for Proc_name in gMonitorReg['Proc_dict']['keys']: + if Proc_name not in varDict['Proc_dict']: + flagNeedRefresh = True + logG(2, OlivOS.L10NAPI.getTrans('OlivOS model [{0}] stopped', [ + Proc_name + ], + modelName + )) + for Proc_name in varDict['Proc_dict']: + if Proc_name not in gMonitorReg['Proc_dict']['keys']: + flagNeedRefresh = True + logG(2, OlivOS.L10NAPI.getTrans('OlivOS model [{0}] init', [ + Proc_name + ], + modelName + )) + if flagNeedRefresh: + gMonitorReg['Proc_dict']['keys'] = copy.deepcopy(list(varDict['Proc_dict'].keys())) + except Exception as e: + traceback.print_exc() + +# 进程管理 def killByPid(pid): parent = psutil.Process(pid) kill_process_and_its_children(parent) @@ -795,6 +850,24 @@ def kill_process_children(p): else: kill_process(child) +# 日志工具 +def log(logger_proc, log_level, log_message, log_segment=None): + if log_segment is None: + log_segment = [] + try: + if logger_proc is not None: + logger_proc.log(log_level, log_message, log_segment) + except Exception as e: + traceback.print_exc() + +def logG(log_level, log_message, log_segment=None): + global gLoggerProc + log( + logger_proc=gLoggerProc, + log_level=log_level, + log_message=log_message, + log_segment=log_segment + ) # 启动画面的操作 def setSplashClose(): From 4614a97376904c0a27ff1b07ea0579f0a4e4635b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Mon, 17 Apr 2023 17:25:38 +0800 Subject: [PATCH 12/20] =?UTF-8?q?=E6=94=B9=E8=BF=9B=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E7=9A=84=E8=BF=9B=E7=A8=8B=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/bootAPI.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index a3a11ea7..beb3ca16 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -639,6 +639,8 @@ def start(self): time.sleep(Proc_dict[rx_packet_data.key].Proc_info.dead_interval) Proc_Proc_dict[rx_packet_data.key].terminate() Proc_Proc_dict[rx_packet_data.key].join() + Proc_dict.pop(rx_packet_data.key) + Proc_Proc_dict.pop(rx_packet_data.key) elif rx_packet_data.action == 'restart_send': for tmp_Proc_name in basic_conf_models: basic_conf_models_this = basic_conf_models[tmp_Proc_name] From 33721182dfd2485b1e6bfbc71d06499edfb329c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Tue, 18 Apr 2023 10:10:27 +0800 Subject: [PATCH 13/20] =?UTF-8?q?=E6=96=B0=E5=A2=9Epywebview=E4=BE=9D?= =?UTF-8?q?=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements310_win.txt | 1 + requirements_win.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/requirements310_win.txt b/requirements310_win.txt index 11cd7d59..edce992c 100644 --- a/requirements310_win.txt +++ b/requirements310_win.txt @@ -25,3 +25,4 @@ httpx prompt_toolkit regex rich +pywebview diff --git a/requirements_win.txt b/requirements_win.txt index 26b411f4..80b74884 100644 --- a/requirements_win.txt +++ b/requirements_win.txt @@ -25,3 +25,4 @@ httpx prompt_toolkit regex rich +pywebview From a4ce6010c17ce967590016ba9769c664a7b4f978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Tue, 18 Apr 2023 10:22:03 +0800 Subject: [PATCH 14/20] =?UTF-8?q?hook=E5=BC=95=E5=85=A5pywebview?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/hook_pack.py | 1 + 1 file changed, 1 insertion(+) diff --git a/OlivOS/hook_pack.py b/OlivOS/hook_pack.py index a1b7e681..e9a45091 100644 --- a/OlivOS/hook_pack.py +++ b/OlivOS/hook_pack.py @@ -26,6 +26,7 @@ if platform.system() == 'Windows': import win32com.client import pythoncom + import webview # ext pack # lxml From 20975cbf50b36134814525bb09b46ca738982b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Tue, 18 Apr 2023 11:28:55 +0800 Subject: [PATCH 15/20] =?UTF-8?q?=E5=B0=9D=E8=AF=95=E8=A7=A3=E5=86=B3tty?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/bootAPI.py | 8 +++---- OlivOS/hook_pack.py | 15 +++++++++++++ OlivOS/multiprocessing_win.py | 42 ----------------------------------- 3 files changed, 19 insertions(+), 46 deletions(-) delete mode 100644 OlivOS/multiprocessing_win.py diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index beb3ca16..1b38e713 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -877,11 +877,11 @@ def setSplashClose(): import pyi_splash pyi_splash.close() -def setSplashText(text:str): +def setSplashText(msg:str): if '_PYIBoot_SPLASH' in os.environ and importlib.util.find_spec("pyi_splash"): import pyi_splash - pyi_splash.update_text(text) + pyi_splash.update_text(msg) -def preLoadPrint(text:str): - print(text) +def preLoadPrint(msg:str): + print(msg) #setSplashText(text) diff --git a/OlivOS/hook_pack.py b/OlivOS/hook_pack.py index e9a45091..44f1683b 100644 --- a/OlivOS/hook_pack.py +++ b/OlivOS/hook_pack.py @@ -50,3 +50,18 @@ import prompt_toolkit import regex import rich + +import sys + +# Are we running in a PyInstaller bundle +# https://pyinstaller.org/en/stable/runtime-information.html#run-time-information +if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): + class NullOutput(object): + def write(self, string): + pass + + def isatty(self): + return False + + sys.stdout = NullOutput() + sys.stderr = NullOutput() diff --git a/OlivOS/multiprocessing_win.py b/OlivOS/multiprocessing_win.py deleted file mode 100644 index bcdda146..00000000 --- a/OlivOS/multiprocessing_win.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- encoding: utf-8 -*- -''' -_______________________ ________________ -__ __ \__ /____ _/_ | / /_ __ \_ ___/ -_ / / /_ / __ / __ | / /_ / / /____ \ -/ /_/ /_ /____/ / __ |/ / / /_/ /____/ / -\____/ /_____/___/ _____/ \____/ /____/ - -@File : OlivOS/multiprocessing_win.py -@Author : lunzhiPenxil仑质 -@Contact : lunzhipenxil@gmail.com -@License : AGPL -@Copyright : (C) 2020-2023, OlivOS-Team -@Desc : None -''' - -import os -import sys -import multiprocessing - -try: - if sys.platform.startswith('win'): - import multiprocessing.popen_spawn_win32 as forking - else: - import multiprocessing.popen_fork as forking -except ImportError: - import multiprocessing.forking as forking - -if sys.platform.startswith('win'): - class _Popen(forking.Popen): - def __init__(self, *args, **kw): - if hasattr(sys, 'frozen'): - os.putenv('_MEIPASS2', sys._MEIPASS) - try: - super(_Popen, self).__init__(*args, **kw) - finally: - if hasattr(sys, 'frozen'): - if hasattr(os, 'unsetenv'): - os.unsetenv('_MEIPASS2') - else: - os.putenv('_MEIPASS2', '') - forking.Popen = _Popen From a2aeaccbefec6dec4aba1eb6bf40e9969e00aaf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Tue, 18 Apr 2023 11:49:00 +0800 Subject: [PATCH 16/20] =?UTF-8?q?=E9=87=8A=E6=94=BEdebug=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E7=9A=84tty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 14 +++++----- OlivOS/hook_pack_debug.py | 54 +++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 OlivOS/hook_pack_debug.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1a680084..154267db 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -59,7 +59,7 @@ jobs: - name: Run packing run: | cp ./OlivOS/hook.py ./OlivOS/hook_bak.py - cp ./OlivOS/hook_pack.py ./OlivOS/hook.py + cp ./OlivOS/hook_pack_debug.py ./OlivOS/hook.py pyinstaller ./main_debug.spec - name: Run artifact run: | @@ -137,7 +137,7 @@ jobs: - name: Run packing run: | cp ./OlivOS/hook.py ./OlivOS/hook_bak.py - cp ./OlivOS/hook_pack.py ./OlivOS/hook.py + cp ./OlivOS/hook_pack_debug.py ./OlivOS/hook.py pyinstaller ./main_debug.spec - name: Run artifact run: | @@ -176,7 +176,7 @@ jobs: - name: Run packing run: | cp ./OlivOS/hook.py ./OlivOS/hook_bak.py - cp ./OlivOS/hook_pack.py ./OlivOS/hook.py + cp ./OlivOS/hook_pack_debug.py ./OlivOS/hook.py pyinstaller ./main_debug.spec - name: Run artifact run: | @@ -244,7 +244,7 @@ jobs: - name: Run packing run: | cp ./OlivOS/hook.py ./OlivOS/hook_bak.py - cp ./OlivOS/hook_pack.py ./OlivOS/hook.py + cp ./OlivOS/hook_pack_debug.py ./OlivOS/hook.py pyinstaller ./main_debug.spec - name: Run artifact run: | @@ -322,7 +322,7 @@ jobs: - name: Run packing run: | cp ./OlivOS/hook.py ./OlivOS/hook_bak.py - cp ./OlivOS/hook_pack.py ./OlivOS/hook.py + cp ./OlivOS/hook_pack_debug.py ./OlivOS/hook.py pyinstaller ./main_debug.spec - name: Run artifact run: | @@ -361,7 +361,7 @@ jobs: - name: Run packing run: | cp ./OlivOS/hook.py ./OlivOS/hook_bak.py - cp ./OlivOS/hook_pack.py ./OlivOS/hook.py + cp ./OlivOS/hook_pack_debug.py ./OlivOS/hook.py pyinstaller ./main_debug.spec - name: Run artifact run: | @@ -390,7 +390,7 @@ jobs: - name: Run packing run: | cp ./OlivOS/hook.py ./OlivOS/hook_bak.py - cp ./OlivOS/hook_pack.py ./OlivOS/hook.py + cp ./OlivOS/hook_pack_debug.py ./OlivOS/hook.py pyinstaller ./main_mac.spec - name: Run artifact run: | diff --git a/OlivOS/hook_pack_debug.py b/OlivOS/hook_pack_debug.py new file mode 100644 index 00000000..5d4c21b9 --- /dev/null +++ b/OlivOS/hook_pack_debug.py @@ -0,0 +1,54 @@ +# -*- encoding: utf-8 -*- +''' +_______________________ ________________ +__ __ \__ /____ _/_ | / /_ __ \_ ___/ +_ / / /_ / __ / __ | / /_ / / /____ \ +/ /_/ /_ /____/ / __ |/ / / /_/ /____/ / +\____/ /_____/___/ _____/ \____/ /____/ + +@File : OlivOS/hook.py +@Author : lunzhiPenxil仑质 +@Contact : lunzhipenxil@gmail.com +@License : AGPL +@Copyright : (C) 2020-2023, OlivOS-Team +@Desc : None +''' + +import platform + +# pillow +from PIL import Image + +# sqlite +import sqlite3 + +# win +if platform.system() == 'Windows': + import win32com.client + import pythoncom + import webview + +# ext pack +# lxml +from lxml import etree + +# yaml +import yaml + +# openpyxl +import openpyxl + +# aiohttp +import aiohttp + +# qrcode +import qrcode + +# weblib +import certifi +import httpx +import prompt_toolkit +import regex +import rich + +import sys From e4a05265428f07a4aa1c2c4f723f598856273fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Tue, 18 Apr 2023 15:27:03 +0800 Subject: [PATCH 17/20] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=86=85=E7=BD=AE=E6=B5=8F=E8=A7=88=E5=99=A8=E6=89=93=E5=BC=80?= =?UTF-8?q?=E8=AE=BA=E5=9D=9B=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/__init__.py | 1 + OlivOS/bootAPI.py | 49 ++++++++++++++++++++++++++++++ OlivOS/bootDataAPI.py | 10 +++++++ OlivOS/hook.py | 1 + OlivOS/nativeWinUIAPI.py | 50 ++++++++++++++++++++----------- OlivOS/webviewUIAPI.py | 64 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 157 insertions(+), 18 deletions(-) create mode 100644 OlivOS/webviewUIAPI.py diff --git a/OlivOS/__init__.py b/OlivOS/__init__.py index 8712ec39..d7746af5 100644 --- a/OlivOS/__init__.py +++ b/OlivOS/__init__.py @@ -68,4 +68,5 @@ from . import libWQEXEModelAPI from . import libCWCBEXEModelAPI from . import nativeWinUIAPI + from . import webviewUIAPI from . import userModule diff --git a/OlivOS/bootAPI.py b/OlivOS/bootAPI.py index 1b38e713..8e3a60a4 100644 --- a/OlivOS/bootAPI.py +++ b/OlivOS/bootAPI.py @@ -687,6 +687,39 @@ def start(self): ) except Exception as e: traceback.print_exc() + elif rx_packet_data.action == 'init_type_open_webview_page': + if platform.system() == 'Windows': + if type(rx_packet_data.key) is dict \ + and 'target' in rx_packet_data.key \ + and type(rx_packet_data.key['target']) is dict \ + and 'data' in rx_packet_data.key \ + and type(rx_packet_data.key['data']) is dict \ + and 'action' in rx_packet_data.key['target'] \ + and 'name' in rx_packet_data.key['target'] \ + and 'title' in rx_packet_data.key['data'] \ + and 'url' in rx_packet_data.key['data']: + if 'init' == rx_packet_data.key['target']['action']: + for basic_conf_models_this_key in basic_conf_models: + basic_conf_models_this = basic_conf_models[basic_conf_models_this_key] + if 'webview_page' == basic_conf_models_this['type']: + if basic_conf_models_this['name'] not in Proc_dict: + model_name = '%s+%s' % ( + basic_conf_models_this['name'], + rx_packet_data.key['target']['name'] + ) + Proc_dict[model_name] = OlivOS.webviewUIAPI.page( + Proc_name=model_name, + scan_interval=basic_conf_models_this['interval'], + dead_interval=basic_conf_models_this['dead_interval'], + rx_queue=None, + tx_queue=None, + control_queue=multiprocessing_dict[basic_conf_models_this['control_queue']], + logger_proc=Proc_dict[basic_conf_models_this['logger_proc']], + title=rx_packet_data.key['data']['title'], + url=rx_packet_data.key['data']['url'] + ) + if model_name not in Proc_Proc_dict: + Proc_Proc_dict[model_name] = Proc_dict[model_name].start_unity('processing') elif rx_packet_data.action == 'call_system_event': if type(rx_packet_data.key) is dict \ and 'action' in rx_packet_data.key \ @@ -763,6 +796,22 @@ def start(self): for tmp_Proc_name in list_stop: Proc_dict.pop(tmp_Proc_name) Proc_Proc_dict.pop(tmp_Proc_name) + elif rx_packet_data.action == 'stop': + tmp_Proc_name = rx_packet_data.key + try: + if tmp_Proc_name in Proc_Proc_dict: + Proc_Proc_dict[tmp_Proc_name].terminate() + Proc_Proc_dict[tmp_Proc_name].join() + logG(1, OlivOS.L10NAPI.getTrans('OlivOS model [{0}] will stop', [ + tmp_Proc_name + ], + modelName + )) + Proc_Proc_dict.pop(tmp_Proc_name) + if tmp_Proc_name in Proc_dict: + Proc_dict.pop(tmp_Proc_name) + except Exception as e: + traceback.print_exc() elif rx_packet_data.action == 'exit_total': killMain() bootMonitor(varDict=locals()) diff --git a/OlivOS/bootDataAPI.py b/OlivOS/bootDataAPI.py index c1114881..0929a453 100644 --- a/OlivOS/bootDataAPI.py +++ b/OlivOS/bootDataAPI.py @@ -427,6 +427,16 @@ "control_queue": "OlivOS_control_queue", "debug": False }, + "OlivOS_webview_page": { + "enable": True, + "name": "OlivOS_webview_page", + "type": "webview_page", + "interval": 0.2, + "dead_interval": 1, + "logger_proc": "OlivOS_logger", + "control_queue": "OlivOS_control_queue", + "debug": False + }, "OlivOS_update_get": { "enable": True, "name": "OlivOS_update_get", diff --git a/OlivOS/hook.py b/OlivOS/hook.py index 10ef9cc0..c7e11e7c 100644 --- a/OlivOS/hook.py +++ b/OlivOS/hook.py @@ -26,3 +26,4 @@ if platform.system() == 'Windows': import win32com.client import pythoncom + import webview diff --git a/OlivOS/nativeWinUIAPI.py b/OlivOS/nativeWinUIAPI.py index 3d1f2040..325f853b 100644 --- a/OlivOS/nativeWinUIAPI.py +++ b/OlivOS/nativeWinUIAPI.py @@ -42,24 +42,6 @@ 'color_006': '#80D7FF' } -class StoppableThread(threading.Thread): - def __init__(self, *args, **kwargs): - super(StoppableThread, self).__init__(*args, **kwargs) - self._stop_event = threading.Event() - - def terminate(self): - self._stop_event.set() - - def stop(self): - self._stop_event.set() - - def join(self): - pass - - def stopped(self): - return self._stop_event.is_set() - - class dock(OlivOS.API.Proc_templet): def __init__( self, @@ -410,6 +392,7 @@ def updateShallowMenuList(self): ['插件管理', self.startPluginEditSend], ['插件菜单', self.UIData['shallow_plugin_menu_list']], ['重载插件', self.sendPluginRestart], + ['社区论坛', self.sendOpenForum], ['更新OlivOS', self.sendOlivOSUpdateGet], ['退出OlivOS', self.setOlivOSExit] ] @@ -762,6 +745,37 @@ def sendOlivOSUpdateGet(self): block=False ) + def sendOpenForum(self): + if self.UIObject['root_shallow'] is not None: + self.UIObject['root_shallow'].UIObject['shallow_root'].notify( + '正在前往社区论坛……' + ) + self.sendOpenWebviewEvent('forum_page', 'OlivOS论坛', 'https://forum.olivos.run/') + + def sendOpenWebviewEvent( + self, + name:str, + title:str, + url:str + ): + if self.Proc_info.control_queue is not None: + self.Proc_info.control_queue.put( + OlivOS.API.Control.packet( + 'init_type_open_webview_page', + { + 'target': { + 'action': 'init', + 'name': name + }, + 'data': { + 'title': title, + 'url': url + } + } + ), + block=False + ) + def startShallowSend(self): self.sendRxEvent('send', { 'target': { diff --git a/OlivOS/webviewUIAPI.py b/OlivOS/webviewUIAPI.py new file mode 100644 index 00000000..3fd0c334 --- /dev/null +++ b/OlivOS/webviewUIAPI.py @@ -0,0 +1,64 @@ +# -*- encoding: utf-8 -*- +''' +_______________________ ________________ +__ __ \__ /____ _/_ | / /_ __ \_ ___/ +_ / / /_ / __ / __ | / /_ / / /____ \ +/ /_/ /_ /____/ / __ |/ / / /_/ /____/ / +\____/ /_____/___/ _____/ \____/ /____/ + +@File : OlivOS/webviewUIAPI.py +@Author : lunzhiPenxil仑质 +@Contact : lunzhipenxil@gmail.com +@License : AGPL +@Copyright : (C) 2020-2023, OlivOS-Team +@Desc : None +''' + +import OlivOS + +import webview +import time + +class page(OlivOS.API.Proc_templet): + def __init__( + self, + Proc_name='webview_page', + scan_interval=0.001, + dead_interval=1, + rx_queue=None, + tx_queue=None, + logger_proc=None, + control_queue=None, + title='OlivOS Page', + url=None + ): + OlivOS.API.Proc_templet.__init__( + self, + Proc_name=Proc_name, + Proc_type='webview_page', + scan_interval=scan_interval, + dead_interval=dead_interval, + rx_queue=rx_queue, + tx_queue=tx_queue, + control_queue=control_queue, + logger_proc=logger_proc + ) + self.UIObject = {} + self.UIData = { + 'title': title, + 'url': url + } + + def run(self): + if self.UIData['url'] != None: + webview.create_window(self.UIData['title'], self.UIData['url']) + webview.start() + + # 发送并等待结束 + if self.Proc_info.control_queue is not None: + self.Proc_info.control_queue.put( + OlivOS.API.Control.packet('stop', self.Proc_name), + block=False + ) + else: + pass From e76051b4f15ea12fdd3c5bf4510746929e15b162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Tue, 18 Apr 2023 16:14:03 +0800 Subject: [PATCH 18/20] =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E5=86=85=E7=BD=AE=E6=B5=8F=E8=A7=88=E5=99=A8=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E6=BB=91=E5=9D=97=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/nativeWinUIAPI.py | 34 ++++++++++++++++------------------ OlivOS/webviewUIAPI.py | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/OlivOS/nativeWinUIAPI.py b/OlivOS/nativeWinUIAPI.py index 325f853b..ddc8bf8b 100644 --- a/OlivOS/nativeWinUIAPI.py +++ b/OlivOS/nativeWinUIAPI.py @@ -758,23 +758,12 @@ def sendOpenWebviewEvent( title:str, url:str ): - if self.Proc_info.control_queue is not None: - self.Proc_info.control_queue.put( - OlivOS.API.Control.packet( - 'init_type_open_webview_page', - { - 'target': { - 'action': 'init', - 'name': name - }, - 'data': { - 'title': title, - 'url': url - } - } - ), - block=False - ) + OlivOS.webviewUIAPI.sendOpenWebviewPage( + self.Proc_info.control_queue, + name, + title, + url + ) def startShallowSend(self): self.sendRxEvent('send', { @@ -1041,7 +1030,16 @@ def show_url_webbrowser(self, url): res = tkinter.messagebox.askquestion("请完成验证", "是否通过浏览器访问 \"" + url + "\" ?") try: if res == 'yes': - webbrowser.open(url) + res = tkinter.messagebox.askquestion("请完成验证", "是否使用内置浏览器?") + if res == 'yes': + OlivOS.webviewUIAPI.sendOpenWebviewPage( + control_queue=self.root.Proc_info.control_queue, + name='slider_verification_code=%s' % self.bot.hash, + title='请完成验证', + url=url + ) + else: + webbrowser.open(url) except webbrowser.Error as error_info: tkinter.messagebox.showerror("webbrowser.Error", error_info) diff --git a/OlivOS/webviewUIAPI.py b/OlivOS/webviewUIAPI.py index 3fd0c334..4bb6268f 100644 --- a/OlivOS/webviewUIAPI.py +++ b/OlivOS/webviewUIAPI.py @@ -18,6 +18,7 @@ import webview import time +import multiprocessing class page(OlivOS.API.Proc_templet): def __init__( @@ -62,3 +63,27 @@ def run(self): ) else: pass + +def sendOpenWebviewPage( + control_queue:multiprocessing.Queue, + name:str, + title:str, + url:str +): + if type(control_queue) is multiprocessing.Queue: + control_queue.put( + OlivOS.API.Control.packet( + 'init_type_open_webview_page', + { + 'target': { + 'action': 'init', + 'name': name + }, + 'data': { + 'title': title, + 'url': url + } + } + ), + block=False + ) From c77d30f9fd3e55184c967b7a7be6dcf1ccb498ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Tue, 18 Apr 2023 16:35:30 +0800 Subject: [PATCH 19/20] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=B5=8F=E8=A7=88?= =?UTF-8?q?=E5=99=A8=E4=BB=BB=E5=8A=A1=E7=94=9F=E6=88=90=E5=99=A8=E8=A2=AB?= =?UTF-8?q?=E8=BF=87=E6=BB=A4=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/webviewUIAPI.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OlivOS/webviewUIAPI.py b/OlivOS/webviewUIAPI.py index 4bb6268f..37c65801 100644 --- a/OlivOS/webviewUIAPI.py +++ b/OlivOS/webviewUIAPI.py @@ -65,12 +65,12 @@ def run(self): pass def sendOpenWebviewPage( - control_queue:multiprocessing.Queue, + control_queue, name:str, title:str, url:str ): - if type(control_queue) is multiprocessing.Queue: + if control_queue is not None: control_queue.put( OlivOS.API.Control.packet( 'init_type_open_webview_page', From cfd373480021572c235a72477f1215c1b12b042f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=91=E8=B4=A8?= Date: Wed, 19 Apr 2023 14:47:25 +0800 Subject: [PATCH 20/20] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OlivOS/nativeWinUIAPI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OlivOS/nativeWinUIAPI.py b/OlivOS/nativeWinUIAPI.py index ddc8bf8b..479e6b5d 100644 --- a/OlivOS/nativeWinUIAPI.py +++ b/OlivOS/nativeWinUIAPI.py @@ -383,8 +383,8 @@ def mainrun(self): def updateShallowMenuList(self): tmp_new = [] self.UIData['shallow_menu_list'] = [ - ['账号管理', self.startAccountEditSendFunc()], ['打开终端', self.startOlivOSTerminalUISend], + ['账号管理', self.startAccountEditSendFunc()], ['gocqhttp管理', self.UIData['shallow_gocqhttp_menu_list']], ['walleq管理', self.UIData['shallow_walleq_menu_list']], ['ComWeChat管理', self.UIData['shallow_cwcb_menu_list']],