Added console to take over the browser again after crash

This commit is contained in:
zhaoyafan 2025-02-19 02:43:30 +08:00
parent 43e68ec8c0
commit 55ea8167aa
1 changed files with 60 additions and 40 deletions

View File

@ -537,7 +537,7 @@ class Browser(InspectRequestsMixin, DriverCommonMixin, Chrome):
):
self.is_linux = sys.platform.startswith('linux')
SeleniumClear().auto()
binary, driver = BrowserPathManager().main(binary, driver)
# binary, driver = BrowserPathManager().main(binary, driver)
if self.is_linux is bool(1) and not window_size: window_size = '1920x1080'
if self.is_linux is bool(0) and headless and not window_size: window_size = '1920x1080'
# Initialization settings.
@ -669,8 +669,8 @@ class Browser(InspectRequestsMixin, DriverCommonMixin, Chrome):
self.set_window_size(*window_size.replace("\x20", '').replace('x', ',').split(','))
except Exception:
pass
else:
self.maximize_window()
# else:
# self.maximize_window()
if window_site:
try:
self.set_window_position(*window_site.replace("\x20", '').split(','))
@ -1363,7 +1363,6 @@ class BrowserManagerUserRunning:
self.user_name = user_name
self.user_data_dir = user_data_dir
self.remote_debugging_port = remote_debugging_port
self.chrome = None
self.driver = None
self.plugin = None
self.is_running_property = False
@ -1382,6 +1381,24 @@ class BrowserManagerUserRunning:
def is_running(self, value):
self.is_running_property = value
@property
def is_user_running(self):
try:
open(os.path.join(self.user_data_dir, 'lockfile'), mode='r').close()
return False
except FileNotFoundError:
return False
except PermissionError:
return True
# s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# s.settimeout(0.01)
# try:
# return s.connect_ex(('127.0.0.1', self.remote_debugging_port)) == 0
# except socket.timeout:
# return False
# finally:
# s.close()
@func_set_timeout(0.05)
def _get_window_handles(self):
return list(self.driver.window_handles)
@ -1399,13 +1416,13 @@ class BrowserManagerUserRunning:
return str(self.driver.current_url)
def update_status_running(self):
if (not self.chrome or self.chrome.poll() is not None) == 1:
if (self.is_user_running is False) == 1:
self.chrome_stopped_trigger()
else:
self.chrome_running_trigger()
def update_status_details(self):
if (not self.chrome or self.chrome.poll() is not None) == 1:
if (self.is_user_running is False) == 1:
self.chrome_stopped_trigger()
else:
self.chrome_running_trigger()
@ -1434,8 +1451,6 @@ class BrowserManagerUserRunning:
self.title = None
self.alert = None
self.window_handles = None
if (not self.chrome) == 0:
self.chrome = None
if (not self.plugin) == 0:
plugin = self.plugin
threading.Thread(target=plugin.interrupt).start()
@ -1463,9 +1478,6 @@ class BrowserManagerUserRunning:
def app_id(self):
return '%s|%s' % (self.user_id, self.user_name)
def set_chrome(self, chrome=None):
self.chrome = chrome
def set_driver(self, driver: Browser = None):
self.driver = driver
@ -1491,7 +1503,6 @@ class BrowserManager:
self.use_selenium_wire = use_selenium_wire
self.threading_lock = threading.RLock()
self.debugging_port_range = range(60000, 60256)
self.mitmproxy_port_range = range(55000, 55512)
self.data_storage = BrowserManagerDataStorage(manager_data_file)
if (not self.data_storage) == 1:
self.data_storage['browser_user'] = {}
@ -1507,26 +1518,12 @@ class BrowserManager:
exist_ports = [value['remote_debugging_port'] for key, value in self.data_storage['browser_user'].items()]
return random.choice([p for p in self.debugging_port_range if p not in exist_ports])
def _generate_random_mitmproxy_port(self):
ports_range = self.mitmproxy_port_range
port = None
for p in random.sample([i for i in ports_range], len(ports_range)):
if (not self.is_port_in_use(p)) == 1:
port = p
break
if (port is None) == 1:
raise Exception('All ports in the specified range are in use.')
return port
def _update_user_running(self):
for user_id, running in self.user_running.items():
if (not running) == 1:
continue
run = BrowserManagerUserRunning(running)
if (not run.chrome or run.chrome.poll() is not None) == 1:
run.chrome_stopped_trigger()
else:
run.chrome_running_trigger()
run.update_status_running()
def _get_user_name(self, user_id: str):
return str(self.data_storage['browser_user'][user_id]['user_name'] or '')
@ -1594,6 +1591,16 @@ class BrowserManager:
options.append('--proxy-server=%s' % (proxy_server,))
return subprocess.Popen(options, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True)
def restore_last_status(self):
for user_id, running in self.user_running.items():
if (not running) == 1:
continue
run = BrowserManagerUserRunning(running)
run.update_status_running()
if run.is_running and run.driver is None:
self.user_run(user_id)
print('Restoring user control: %s' % (user_id,), file=sys.stderr)
def load_plugins(self, plugins, is_external=0):
if (plugins is None) == 1:
return None
@ -1670,7 +1677,7 @@ class BrowserManager:
return True
def is_port_in_use(self, port: int):
if (port not in self.debugging_port_range and port not in self.mitmproxy_port_range) == 1:
if (port not in self.debugging_port_range) == 1:
return True
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(0.08)
@ -1741,7 +1748,7 @@ class BrowserManager:
finally:
self.user_operate_complete(user_id)
@func_set_timeout(0.35)
@func_set_timeout(0.45)
def user_focus_window(self, user_id: str):
if (user_id in self.user_ids()) == 0:
raise FileExistsError('User ID not exists.')
@ -1803,21 +1810,19 @@ class BrowserManager:
self.user_operate_starting(user_id)
if (user_id in self.user_ids()) == 0:
raise FileExistsError('User ID not exists.')
if (self.is_user_data_occupied(user_id)) == 1:
raise Exception('The instance may be running, please shutdown the instance first.')
user_data_dir = self._get_user_data_dir(user_id)
remote_debugging_port = self._get_user_remote_debugging_port(user_id)
mitmproxy_port = remote_debugging_port - 5000
running = BrowserManagerUserRunning(self.user_running[user_id])
running.active = 1
mitmproxy_port = self._generate_random_mitmproxy_port()
chrome = self.run_browser(user_data_dir=user_data_dir, remote_debugging_port=remote_debugging_port, proxy_server='127.0.0.1:%s' % (mitmproxy_port,) if self.use_selenium_wire else None)
running.set_chrome(chrome)
if (self.is_user_data_occupied(user_id)) == 0:
self.run_browser(user_data_dir=user_data_dir, remote_debugging_port=remote_debugging_port, proxy_server='127.0.0.1:%s' % (mitmproxy_port,) if self.use_selenium_wire else None)
driver = Browser(
driver=self.driver,
binary=self.binary,
driver_classes=self.use_selenium_wire,
window_size='%s,%s' % (self.geometry_config['browser_window_w'], self.geometry_config['browser_window_h']),
window_site='%s,%s' % (self.geometry_config['browser_window_x'], self.geometry_config['browser_window_y']),
window_size=('%s,%s' % (self.geometry_config['browser_window_w'], self.geometry_config['browser_window_h'])) if self.geometry_config else None,
window_site=('%s,%s' % (self.geometry_config['browser_window_x'], self.geometry_config['browser_window_y'])) if self.geometry_config else None,
debugger_address='127.0.0.1:%s' % (remote_debugging_port,),
backends_address='127.0.0.1:%s' % (mitmproxy_port,),
req_interceptor=self.use_selenium_wire and self.req_interceptor,
@ -1872,6 +1877,14 @@ class MainWindow(QMainWindow):
def __init__(self, runner, app_name: str, app_version: str, scale_rate: float, web_listen_host: str, web_listen_port: int):
super().__init__()
self.runner = runner
try:
if (os.path.exists(runner.app_last_exit_code) and open(runner.app_last_exit_code, mode='r').read() != '0') == 1:
QMessageBox.information(self, 'Warning', 'The application was not exited normally last time. Please wait for recovery.')
self.runner.web_server.browser_manager.restore_last_status()
except Exception:
pass
finally:
open(self.runner.app_last_exit_code, mode='w').write('')
self.scale_rate = scale_rate
self.web_listen_host = web_listen_host
self.web_listen_port = web_listen_port
@ -1945,6 +1958,7 @@ class MainWindow(QMainWindow):
def exit(self):
self.webview.deleteLater()
self.runner.handle_interrupt()
open(self.runner.app_last_exit_code, mode='w').write('0')
QApplication.quit()
def window_show(self):
@ -2244,8 +2258,9 @@ class MainRunner:
self.app_root = os.path.dirname(__file__)
appdata = os.getenv('APPDATA')
self.app_data = os.path.join(appdata, 'Galactic') if appdata else os.path.join(os.path.dirname(__file__), 'data')
self.app_last_exit_code = os.path.join(self.app_data, 'exit')
self.app_name = 'Galactic'
self.app_version = '1.0.0.1'
self.app_version = '1.0.0.2'
self.web_server_host = '127.0.0.1'
self.web_server_port = 8095
self.web_server = None
@ -2284,8 +2299,8 @@ class MainRunner:
def run(self):
os.path.exists(self.app_data) or os.makedirs(self.app_data)
if (os.environ.get('PYCHARM_HOSTED') is None) == 1:
stdout_redirector = OutputRedirector(sys.stdout, open(os.path.join(self.app_data, 'stdout.txt'), mode='w'))
stderr_redirector = OutputRedirector(sys.stderr, open(os.path.join(self.app_data, 'stderr.txt'), mode='w'))
stdout_redirector = OutputRedirector(sys.stdout, open(os.path.join(self.app_data, '%s_stdout.txt' % (time.strftime('%Y%m%d', time.localtime()),)), mode='a'))
stderr_redirector = OutputRedirector(sys.stderr, open(os.path.join(self.app_data, '%s_stderr.txt' % (time.strftime('%Y%m%d', time.localtime()),)), mode='a'))
sys.stderr = stderr_redirector
sys.stdout = stdout_redirector
sys.path.append(os.path.join(os.path.dirname(__file__), 'Packages'))
@ -2307,7 +2322,12 @@ class MainRunner:
web_listen_host=self.web_server_host,
web_listen_port=self.web_server_port
)
sys.exit(self.application.exec_())
app_exec = ''
try:
app_exec = self.application.exec_()
except Exception as e:
print(e, file=sys.stderr)
sys.exit(app_exec)
def build(self):
if (str(__file__).endswith('.py')) == 0: