diff --git a/Galactic.py b/Galactic.py index 638c699..1f0a06c 100644 --- a/Galactic.py +++ b/Galactic.py @@ -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: