Function optimization, use new browser window activation solution
This commit is contained in:
parent
ed496a08c2
commit
45e6a627bb
123
Galactic.py
123
Galactic.py
|
@ -18,6 +18,9 @@ import hashlib
|
||||||
import asyncio
|
import asyncio
|
||||||
import tempfile
|
import tempfile
|
||||||
import platform
|
import platform
|
||||||
|
import win32gui
|
||||||
|
import win32process
|
||||||
|
import win32con
|
||||||
import requests
|
import requests
|
||||||
import requests.adapters
|
import requests.adapters
|
||||||
import importlib.util
|
import importlib.util
|
||||||
|
@ -771,6 +774,51 @@ class Browser(InspectRequestsMixin, DriverCommonMixin, Chrome):
|
||||||
except Exception:
|
except Exception:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
@property
|
||||||
|
def window_titles(self):
|
||||||
|
"""
|
||||||
|
Return to title list.
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
try:
|
||||||
|
targets = self.execute_cdp_cmd('Target.getTargets', {})
|
||||||
|
for target in targets['targetInfos']:
|
||||||
|
if (target['type'] == 'page') == 1:
|
||||||
|
result.append(target['title'])
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return result[::-1]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def window_urls(self):
|
||||||
|
"""
|
||||||
|
Return to url list.
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
try:
|
||||||
|
targets = self.execute_cdp_cmd('Target.getTargets', {})
|
||||||
|
for target in targets['targetInfos']:
|
||||||
|
if (target['type'] == 'page') == 1:
|
||||||
|
result.append(target['url'])
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return result[::-1]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def window_handles(self):
|
||||||
|
"""
|
||||||
|
Return to window handle list.
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
try:
|
||||||
|
targets = self.execute_cdp_cmd('Target.getTargets', {})
|
||||||
|
for target in targets['targetInfos']:
|
||||||
|
if (target['type'] == 'page') == 1:
|
||||||
|
result.append(target['targetId'])
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return result[::-1]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def window_inner_size(self) -> tuple:
|
def window_inner_size(self) -> tuple:
|
||||||
"""
|
"""
|
||||||
|
@ -842,7 +890,6 @@ class Browser(InspectRequestsMixin, DriverCommonMixin, Chrome):
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@calculate_execution_time
|
|
||||||
def quit_backend(self):
|
def quit_backend(self):
|
||||||
"""
|
"""
|
||||||
Exit the browser backend.
|
Exit the browser backend.
|
||||||
|
@ -1004,6 +1051,14 @@ class Browser(InspectRequestsMixin, DriverCommonMixin, Chrome):
|
||||||
self.switch_to.default_content()
|
self.switch_to.default_content()
|
||||||
self.wait(0.2)
|
self.wait(0.2)
|
||||||
|
|
||||||
|
def tab_active(self):
|
||||||
|
"""
|
||||||
|
Activate current tab.
|
||||||
|
"""
|
||||||
|
self.switch_to.window(self.current_window_handle)
|
||||||
|
self.wait(0.2)
|
||||||
|
self._update_cdp_command()
|
||||||
|
|
||||||
def tab_create(self, url: str = None):
|
def tab_create(self, url: str = None):
|
||||||
"""
|
"""
|
||||||
Create a new tab and open the URL.
|
Create a new tab and open the URL.
|
||||||
|
@ -1651,18 +1706,35 @@ class BrowserManager:
|
||||||
continue
|
continue
|
||||||
running.update_status_running()
|
running.update_status_running()
|
||||||
|
|
||||||
|
def _get_user_process_id(self, user_id: str):
|
||||||
|
try:
|
||||||
|
return int(self.data_storage['browser_user'][user_id]['process_id'])
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
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 '')
|
try:
|
||||||
|
return str(self.data_storage['browser_user'][user_id]['user_name'])
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
def _get_user_data_dir(self, user_id: str):
|
def _get_user_data_dir(self, user_id: str):
|
||||||
|
try:
|
||||||
return os.path.join(self.browser_data_home, self.data_storage['browser_user'][user_id]['user_data_dir'])
|
return os.path.join(self.browser_data_home, self.data_storage['browser_user'][user_id]['user_data_dir'])
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
def _get_user_remote_debugging_port(self, user_id: str):
|
def _get_user_remote_debugging_port(self, user_id: str):
|
||||||
|
try:
|
||||||
return int(self.data_storage['browser_user'][user_id]['remote_debugging_port'])
|
return int(self.data_storage['browser_user'][user_id]['remote_debugging_port'])
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
def _get_user_app_id(self, user_id: str):
|
def _get_user_app_id(self, user_id: str):
|
||||||
user_name = self.data_storage['browser_user'][user_id]['user_name']
|
try:
|
||||||
return user_name or user_id
|
return self.data_storage['browser_user'][user_id]['user_name'] or user_id
|
||||||
|
except KeyError:
|
||||||
|
return user_id
|
||||||
|
|
||||||
def _initialize_user_running(self, user_id: str):
|
def _initialize_user_running(self, user_id: str):
|
||||||
return BrowserManagerUserRunning(
|
return BrowserManagerUserRunning(
|
||||||
|
@ -1698,6 +1770,23 @@ class BrowserManager:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e, file=sys.stderr)
|
print(e, file=sys.stderr)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_chrome_hwnd(pid: int):
|
||||||
|
if pid:
|
||||||
|
def callback(hwnd, hwnds):
|
||||||
|
if win32gui.IsWindowVisible(hwnd) and win32gui.GetParent(hwnd) == 0:
|
||||||
|
_, found_pid = win32process.GetWindowThreadProcessId(hwnd)
|
||||||
|
if found_pid == pid and 'Chrome_' in win32gui.GetClassName(hwnd):
|
||||||
|
ws = win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE)
|
||||||
|
if (ws & win32con.WS_EX_TOOLWINDOW) == 0 and (ws & win32con.WS_EX_PALETTEWINDOW) == 0:
|
||||||
|
hwnds.append(hwnd)
|
||||||
|
return False
|
||||||
|
hwnds = []
|
||||||
|
win32gui.EnumWindows(callback, hwnds)
|
||||||
|
return hwnds[0] if hwnds else None
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def run_browser(self, user_data_dir: str, remote_debugging_port: int, proxy_server: str = None):
|
def run_browser(self, user_data_dir: str, remote_debugging_port: int, proxy_server: str = None):
|
||||||
options = [
|
options = [
|
||||||
self.binary,
|
self.binary,
|
||||||
|
@ -1714,7 +1803,7 @@ class BrowserManager:
|
||||||
options.append('--remote-debugging-port=%s' % (remote_debugging_port,))
|
options.append('--remote-debugging-port=%s' % (remote_debugging_port,))
|
||||||
if proxy_server:
|
if proxy_server:
|
||||||
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=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def clear_dirs(dirs):
|
def clear_dirs(dirs):
|
||||||
|
@ -1933,7 +2022,6 @@ class BrowserManager:
|
||||||
self.user_operate_complete(user_id)
|
self.user_operate_complete(user_id)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@func_set_timeout(0.55)
|
|
||||||
@calculate_execution_time
|
@calculate_execution_time
|
||||||
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:
|
||||||
|
@ -1941,12 +2029,20 @@ class BrowserManager:
|
||||||
if (user_id in self.user_ids_online()) == 0:
|
if (user_id in self.user_ids_online()) == 0:
|
||||||
raise FileExistsError('User ID is not running.')
|
raise FileExistsError('User ID is not running.')
|
||||||
try:
|
try:
|
||||||
self.user_running[user_id].driver.minimize_window()
|
chrome_hwnd = self.get_chrome_hwnd(self._get_user_process_id(user_id))
|
||||||
self.user_running[user_id].driver.set_window_rect(
|
if chrome_hwnd:
|
||||||
|
for _ in range(1 + int(bool(win32gui.IsIconic(chrome_hwnd)))):
|
||||||
|
win32gui.ShowWindow(chrome_hwnd, win32con.SW_RESTORE)
|
||||||
|
win32gui.ShowWindow(chrome_hwnd, win32con.SW_RESTORE)
|
||||||
|
win32gui.SetForegroundWindow(chrome_hwnd)
|
||||||
|
win32gui.SetWindowPos(
|
||||||
|
chrome_hwnd,
|
||||||
|
win32con.HWND_NOTOPMOST,
|
||||||
self.geometry_config['browser_window_x'],
|
self.geometry_config['browser_window_x'],
|
||||||
self.geometry_config['browser_window_y'],
|
self.geometry_config['browser_window_y'],
|
||||||
self.geometry_config['browser_window_w'],
|
self.geometry_config['browser_window_w'],
|
||||||
self.geometry_config['browser_window_h']
|
self.geometry_config['browser_window_h'],
|
||||||
|
win32con.SWP_NOZORDER
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
@ -2013,7 +2109,10 @@ class BrowserManager:
|
||||||
running = BrowserManagerUserRunning(self.user_running[user_id])
|
running = BrowserManagerUserRunning(self.user_running[user_id])
|
||||||
running.active = 1
|
running.active = 1
|
||||||
if (self.is_user_data_occupied(user_id)) == 0:
|
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)
|
browser_process = 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.data_storage['browser_user'][user_id]['process_id'] = browser_process.pid
|
||||||
|
self.data_storage.save()
|
||||||
|
print('The browser starts, and the process ID is %s.' % (browser_process.pid,), file=sys.stderr)
|
||||||
driver = Browser(
|
driver = Browser(
|
||||||
driver=self.driver,
|
driver=self.driver,
|
||||||
binary=self.binary,
|
binary=self.binary,
|
||||||
|
@ -2446,8 +2545,6 @@ class WebServer:
|
||||||
try:
|
try:
|
||||||
self.browser_manager.user_focus_window(data.data['user_id'])
|
self.browser_manager.user_focus_window(data.data['user_id'])
|
||||||
return self.message(0)
|
return self.message(0)
|
||||||
except FunctionTimedOut:
|
|
||||||
return self.message(0)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return self.message(1, '%s' % (e,))
|
return self.message(1, '%s' % (e,))
|
||||||
|
|
||||||
|
@ -2536,7 +2633,7 @@ class MainRunner:
|
||||||
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_running_file = os.path.join(self.app_data, 'running')
|
self.app_running_file = os.path.join(self.app_data, 'running')
|
||||||
self.app_name = 'Galactic'
|
self.app_name = 'Galactic'
|
||||||
self.app_version = '1.0.0.3'
|
self.app_version = '1.0.0.4'
|
||||||
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
|
||||||
|
|
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue