Added console to take over the browser again after crash
This commit is contained in:
parent
43e68ec8c0
commit
55ea8167aa
100
Galactic.py
100
Galactic.py
|
@ -537,7 +537,7 @@ class Browser(InspectRequestsMixin, DriverCommonMixin, Chrome):
|
||||||
):
|
):
|
||||||
self.is_linux = sys.platform.startswith('linux')
|
self.is_linux = sys.platform.startswith('linux')
|
||||||
SeleniumClear().auto()
|
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(1) and not window_size: window_size = '1920x1080'
|
||||||
if self.is_linux is bool(0) and headless 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.
|
# Initialization settings.
|
||||||
|
@ -669,8 +669,8 @@ class Browser(InspectRequestsMixin, DriverCommonMixin, Chrome):
|
||||||
self.set_window_size(*window_size.replace("\x20", '').replace('x', ',').split(','))
|
self.set_window_size(*window_size.replace("\x20", '').replace('x', ',').split(','))
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
else:
|
# else:
|
||||||
self.maximize_window()
|
# self.maximize_window()
|
||||||
if window_site:
|
if window_site:
|
||||||
try:
|
try:
|
||||||
self.set_window_position(*window_site.replace("\x20", '').split(','))
|
self.set_window_position(*window_site.replace("\x20", '').split(','))
|
||||||
|
@ -1363,7 +1363,6 @@ class BrowserManagerUserRunning:
|
||||||
self.user_name = user_name
|
self.user_name = user_name
|
||||||
self.user_data_dir = user_data_dir
|
self.user_data_dir = user_data_dir
|
||||||
self.remote_debugging_port = remote_debugging_port
|
self.remote_debugging_port = remote_debugging_port
|
||||||
self.chrome = None
|
|
||||||
self.driver = None
|
self.driver = None
|
||||||
self.plugin = None
|
self.plugin = None
|
||||||
self.is_running_property = False
|
self.is_running_property = False
|
||||||
|
@ -1382,6 +1381,24 @@ class BrowserManagerUserRunning:
|
||||||
def is_running(self, value):
|
def is_running(self, value):
|
||||||
self.is_running_property = 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)
|
@func_set_timeout(0.05)
|
||||||
def _get_window_handles(self):
|
def _get_window_handles(self):
|
||||||
return list(self.driver.window_handles)
|
return list(self.driver.window_handles)
|
||||||
|
@ -1399,13 +1416,13 @@ class BrowserManagerUserRunning:
|
||||||
return str(self.driver.current_url)
|
return str(self.driver.current_url)
|
||||||
|
|
||||||
def update_status_running(self):
|
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()
|
self.chrome_stopped_trigger()
|
||||||
else:
|
else:
|
||||||
self.chrome_running_trigger()
|
self.chrome_running_trigger()
|
||||||
|
|
||||||
def update_status_details(self):
|
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()
|
self.chrome_stopped_trigger()
|
||||||
else:
|
else:
|
||||||
self.chrome_running_trigger()
|
self.chrome_running_trigger()
|
||||||
|
@ -1434,8 +1451,6 @@ class BrowserManagerUserRunning:
|
||||||
self.title = None
|
self.title = None
|
||||||
self.alert = None
|
self.alert = None
|
||||||
self.window_handles = None
|
self.window_handles = None
|
||||||
if (not self.chrome) == 0:
|
|
||||||
self.chrome = None
|
|
||||||
if (not self.plugin) == 0:
|
if (not self.plugin) == 0:
|
||||||
plugin = self.plugin
|
plugin = self.plugin
|
||||||
threading.Thread(target=plugin.interrupt).start()
|
threading.Thread(target=plugin.interrupt).start()
|
||||||
|
@ -1463,9 +1478,6 @@ class BrowserManagerUserRunning:
|
||||||
def app_id(self):
|
def app_id(self):
|
||||||
return '%s|%s' % (self.user_id, self.user_name)
|
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):
|
def set_driver(self, driver: Browser = None):
|
||||||
self.driver = driver
|
self.driver = driver
|
||||||
|
|
||||||
|
@ -1491,7 +1503,6 @@ class BrowserManager:
|
||||||
self.use_selenium_wire = use_selenium_wire
|
self.use_selenium_wire = use_selenium_wire
|
||||||
self.threading_lock = threading.RLock()
|
self.threading_lock = threading.RLock()
|
||||||
self.debugging_port_range = range(60000, 60256)
|
self.debugging_port_range = range(60000, 60256)
|
||||||
self.mitmproxy_port_range = range(55000, 55512)
|
|
||||||
self.data_storage = BrowserManagerDataStorage(manager_data_file)
|
self.data_storage = BrowserManagerDataStorage(manager_data_file)
|
||||||
if (not self.data_storage) == 1:
|
if (not self.data_storage) == 1:
|
||||||
self.data_storage['browser_user'] = {}
|
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()]
|
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])
|
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):
|
def _update_user_running(self):
|
||||||
for user_id, running in self.user_running.items():
|
for user_id, running in self.user_running.items():
|
||||||
if (not running) == 1:
|
if (not running) == 1:
|
||||||
continue
|
continue
|
||||||
run = BrowserManagerUserRunning(running)
|
run = BrowserManagerUserRunning(running)
|
||||||
if (not run.chrome or run.chrome.poll() is not None) == 1:
|
run.update_status_running()
|
||||||
run.chrome_stopped_trigger()
|
|
||||||
else:
|
|
||||||
run.chrome_running_trigger()
|
|
||||||
|
|
||||||
def _get_user_name(self, user_id: str):
|
def _get_user_name(self, user_id: str):
|
||||||
return str(self.data_storage['browser_user'][user_id]['user_name'] or '')
|
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,))
|
options.append('--proxy-server=%s' % (proxy_server,))
|
||||||
return subprocess.Popen(options, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True)
|
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):
|
def load_plugins(self, plugins, is_external=0):
|
||||||
if (plugins is None) == 1:
|
if (plugins is None) == 1:
|
||||||
return None
|
return None
|
||||||
|
@ -1670,7 +1677,7 @@ class BrowserManager:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def is_port_in_use(self, port: int):
|
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
|
return True
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
s.settimeout(0.08)
|
s.settimeout(0.08)
|
||||||
|
@ -1741,7 +1748,7 @@ class BrowserManager:
|
||||||
finally:
|
finally:
|
||||||
self.user_operate_complete(user_id)
|
self.user_operate_complete(user_id)
|
||||||
|
|
||||||
@func_set_timeout(0.35)
|
@func_set_timeout(0.45)
|
||||||
def user_focus_window(self, user_id: str):
|
def user_focus_window(self, user_id: str):
|
||||||
if (user_id in self.user_ids()) == 0:
|
if (user_id in self.user_ids()) == 0:
|
||||||
raise FileExistsError('User ID not exists.')
|
raise FileExistsError('User ID not exists.')
|
||||||
|
@ -1803,21 +1810,19 @@ class BrowserManager:
|
||||||
self.user_operate_starting(user_id)
|
self.user_operate_starting(user_id)
|
||||||
if (user_id in self.user_ids()) == 0:
|
if (user_id in self.user_ids()) == 0:
|
||||||
raise FileExistsError('User ID not exists.')
|
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)
|
user_data_dir = self._get_user_data_dir(user_id)
|
||||||
remote_debugging_port = self._get_user_remote_debugging_port(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 = BrowserManagerUserRunning(self.user_running[user_id])
|
||||||
running.active = 1
|
running.active = 1
|
||||||
mitmproxy_port = self._generate_random_mitmproxy_port()
|
if (self.is_user_data_occupied(user_id)) == 0:
|
||||||
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)
|
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)
|
|
||||||
driver = Browser(
|
driver = Browser(
|
||||||
driver=self.driver,
|
driver=self.driver,
|
||||||
binary=self.binary,
|
binary=self.binary,
|
||||||
driver_classes=self.use_selenium_wire,
|
driver_classes=self.use_selenium_wire,
|
||||||
window_size='%s,%s' % (self.geometry_config['browser_window_w'], self.geometry_config['browser_window_h']),
|
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']),
|
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,),
|
debugger_address='127.0.0.1:%s' % (remote_debugging_port,),
|
||||||
backends_address='127.0.0.1:%s' % (mitmproxy_port,),
|
backends_address='127.0.0.1:%s' % (mitmproxy_port,),
|
||||||
req_interceptor=self.use_selenium_wire and self.req_interceptor,
|
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):
|
def __init__(self, runner, app_name: str, app_version: str, scale_rate: float, web_listen_host: str, web_listen_port: int):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.runner = runner
|
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.scale_rate = scale_rate
|
||||||
self.web_listen_host = web_listen_host
|
self.web_listen_host = web_listen_host
|
||||||
self.web_listen_port = web_listen_port
|
self.web_listen_port = web_listen_port
|
||||||
|
@ -1945,6 +1958,7 @@ class MainWindow(QMainWindow):
|
||||||
def exit(self):
|
def exit(self):
|
||||||
self.webview.deleteLater()
|
self.webview.deleteLater()
|
||||||
self.runner.handle_interrupt()
|
self.runner.handle_interrupt()
|
||||||
|
open(self.runner.app_last_exit_code, mode='w').write('0')
|
||||||
QApplication.quit()
|
QApplication.quit()
|
||||||
|
|
||||||
def window_show(self):
|
def window_show(self):
|
||||||
|
@ -2244,8 +2258,9 @@ class MainRunner:
|
||||||
self.app_root = os.path.dirname(__file__)
|
self.app_root = os.path.dirname(__file__)
|
||||||
appdata = os.getenv('APPDATA')
|
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_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_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_host = '127.0.0.1'
|
||||||
self.web_server_port = 8095
|
self.web_server_port = 8095
|
||||||
self.web_server = None
|
self.web_server = None
|
||||||
|
@ -2284,8 +2299,8 @@ class MainRunner:
|
||||||
def run(self):
|
def run(self):
|
||||||
os.path.exists(self.app_data) or os.makedirs(self.app_data)
|
os.path.exists(self.app_data) or os.makedirs(self.app_data)
|
||||||
if (os.environ.get('PYCHARM_HOSTED') is None) == 1:
|
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'))
|
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, 'stderr.txt'), mode='w'))
|
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.stderr = stderr_redirector
|
||||||
sys.stdout = stdout_redirector
|
sys.stdout = stdout_redirector
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), 'Packages'))
|
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_host=self.web_server_host,
|
||||||
web_listen_port=self.web_server_port
|
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):
|
def build(self):
|
||||||
if (str(__file__).endswith('.py')) == 0:
|
if (str(__file__).endswith('.py')) == 0:
|
||||||
|
|
Loading…
Reference in New Issue