pyloid 0.22.1__py3-none-any.whl → 0.23.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pyloid/browser_window.py CHANGED
@@ -9,7 +9,18 @@ from PySide6.QtGui import (
9
9
  QKeySequence,
10
10
  QShortcut,
11
11
  )
12
- from PySide6.QtCore import Qt, QPoint, QUrl, QEvent, QFile, QEventLoop, QTimer, QObject, Signal, Slot
12
+ from PySide6.QtCore import (
13
+ Qt,
14
+ QPoint,
15
+ QUrl,
16
+ QEvent,
17
+ QFile,
18
+ QEventLoop,
19
+ QTimer,
20
+ QObject,
21
+ Signal,
22
+ Slot,
23
+ )
13
24
  from PySide6.QtWebEngineCore import (
14
25
  QWebEnginePage,
15
26
  QWebEngineSettings,
@@ -27,7 +38,13 @@ from .js_api.base import BaseAPI
27
38
  from PySide6.QtGui import QPixmap, QMovie
28
39
  from PySide6.QtWidgets import QSplashScreen, QLabel
29
40
  from typing import TYPE_CHECKING, Any
30
- from PySide6.QtWebEngineCore import QWebEngineSettings, QWebEngineDesktopMediaRequest
41
+ from PySide6.QtWebEngineCore import (
42
+ QWebEngineSettings,
43
+ QWebEngineDesktopMediaRequest,
44
+ )
45
+
46
+ from .url_interceptor import CustomUrlInterceptor
47
+ from .rpc import PyloidRPC
31
48
 
32
49
  if TYPE_CHECKING:
33
50
  from .pyloid import _Pyloid
@@ -42,10 +59,6 @@ class CustomWebPage(QWebEnginePage):
42
59
  self._desktop_media_handler = None
43
60
  self._url_handlers = {} # URL 핸들러 저장을 위한 딕셔너리 추가
44
61
 
45
- # interceptor ( all url request )
46
- # self.interceptor = CustomUrlInterceptor()
47
- # self.profile().setUrlRequestInterceptor(self.interceptor)
48
-
49
62
  def _handlePermissionRequest(self, origin: QUrl, feature: QWebEnginePage.Feature):
50
63
  # print(origin, feature)
51
64
 
@@ -83,7 +96,7 @@ class CustomWebPage(QWebEnginePage):
83
96
  window_index = windows_model.index(i)
84
97
  window_name = windows_model.data(window_index)
85
98
  print(f"Window {i}: {window_name}")
86
-
99
+
87
100
  request.selectWindow(windows_model.index(3))
88
101
 
89
102
  # # interceptor ( navigation request )
@@ -96,53 +109,47 @@ class CustomWebPage(QWebEnginePage):
96
109
  # return True
97
110
 
98
111
 
99
- # interceptor ( all url request )
100
- # class CustomUrlInterceptor(QWebEngineUrlRequestInterceptor):
101
- # def interceptRequest(self, info):
102
- # url = info.requestUrl().toString()
103
- # print(url)
104
-
105
112
  # class CustomInterceptor(QWebEngineUrlRequestInterceptor):
106
113
  # def __init__(self, index_path=None):
107
114
  # super().__init__()
108
115
  # self.index_path = get_production_path()
109
116
  # self.last_path = "/"
110
-
117
+
111
118
  # def interceptRequest(self, info):
112
119
  # url = info.requestUrl()
113
120
  # navigation_type = info.navigationType()
114
121
 
115
122
  # print("--------------------------------")
116
-
123
+
117
124
  # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeTyped:
118
125
  # print("NavigationTypeTyped")
119
-
126
+
120
127
  # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeReload:
121
128
  # print("NavigationTypeReload")
122
-
129
+
123
130
  # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeBackForward:
124
131
  # print("NavigationTypeBackForward")
125
-
132
+
126
133
  # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeLinkClicked:
127
134
  # print("NavigationTypeLinkClicked")
128
-
135
+
129
136
  # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeFormSubmitted:
130
137
  # print("NavigationTypeFormSubmitted")
131
-
138
+
132
139
  # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeTyped:
133
140
  # print("NavigationTypeTyped")
134
-
141
+
135
142
  # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeOther:
136
143
  # print("NavigationTypeOther")
137
-
144
+
138
145
  # print(navigation_type.value)
139
-
146
+
140
147
  # print(url)
141
148
  # print(url.scheme())
142
149
  # print(url.host())
143
150
  # print(url.url())
144
151
  # print(self.last_path)
145
-
152
+
146
153
  # self.last_path = url.path()
147
154
 
148
155
 
@@ -300,12 +307,24 @@ class _BrowserWindow:
300
307
  frame: bool = True,
301
308
  context_menu: bool = False,
302
309
  dev_tools: bool = False,
303
- js_apis: List[PyloidAPI] = [],
310
+ # js_apis: List[PyloidAPI] = [],
311
+ rpc: Optional[PyloidRPC] = None,
304
312
  ):
305
313
  ###########################################################################################
306
314
  self.id = str(uuid.uuid4()) # Generate unique ID
307
315
  self._window = QMainWindow()
308
316
  self.web_view = CustomWebEngineView(self)
317
+
318
+ if rpc:
319
+ self.rpc = rpc
320
+ self.rpc_url = rpc.url
321
+ else:
322
+ self.rpc = None
323
+ self.rpc_url = None
324
+
325
+ # interceptor ( all url request )
326
+ self.interceptor = CustomUrlInterceptor(rpc_url=self.rpc_url)
327
+ self.web_view.page().setUrlRequestInterceptor(self.interceptor)
309
328
 
310
329
  self._window.closeEvent = self.closeEvent # Override closeEvent method
311
330
  ###########################################################################################
@@ -318,9 +337,12 @@ class _BrowserWindow:
318
337
  self.frame = frame
319
338
  self.context_menu = context_menu
320
339
  self.dev_tools = dev_tools
321
- self.js_apis = [BaseAPI(self.id, self.app.data)]
322
- for js_api in js_apis:
323
- self.js_apis.append(js_api)
340
+
341
+ self.js_apis = [BaseAPI(self.id, self.app.data, self.app)]
342
+
343
+ # for js_api in js_apis:
344
+ # self.js_apis.append(js_api)
345
+
324
346
  self.shortcuts = {}
325
347
  self.close_on_load = True
326
348
  self.splash_screen = None
@@ -453,12 +475,11 @@ class _BrowserWindow:
453
475
  # Register additional JS APIs
454
476
  if self.js_apis:
455
477
  for js_api in self.js_apis:
456
- # Define window_id, window, and app for each JS API
457
- js_api.window_id = self.id
458
- js_api.window = self
459
- js_api.app = self.app
460
478
 
461
- self.channel.registerObject(js_api.__class__.__name__, js_api)
479
+ if js_api.__class__.__name__ == "BaseAPI":
480
+ self.channel.registerObject("__PYLOID__", js_api)
481
+ else:
482
+ self.channel.registerObject(js_api.__class__.__name__, js_api)
462
483
 
463
484
  self.web_view.page().setWebChannel(self.channel)
464
485
 
@@ -470,10 +491,10 @@ class _BrowserWindow:
470
491
 
471
492
  # Set F12 shortcut
472
493
  self.set_dev_tools(self.dev_tools)
473
-
494
+
474
495
  # 프로필 가져오기 및 인터셉터 설정
475
496
  profile = self.web_view.page().profile()
476
-
497
+
477
498
  # # 기존 인터셉터가 있다면 제거
478
499
  # if self.interceptor:
479
500
  # profile.setUrlRequestInterceptor(None)
@@ -527,13 +548,13 @@ class _BrowserWindow:
527
548
  }
528
549
  }
529
550
  };
530
- console.log('pyloid.EventAPI object initialized:', window.pyloid.EventAPI);
531
-
551
+ // console.log('pyloid.EventAPI object initialized:', window.pyloid.EventAPI);
552
+
532
553
  %s
533
554
 
534
555
  document.addEventListener('mousedown', function (e) {
535
556
  if (e.target.hasAttribute('data-pyloid-drag-region')) {
536
- window.pyloid.BaseAPI.startSystemDrag();
557
+ window.__PYLOID__.startSystemDrag();
537
558
  }
538
559
  });
539
560
 
@@ -547,12 +568,12 @@ class _BrowserWindow:
547
568
  """
548
569
  js_api_init = "\n".join(
549
570
  [
550
- f"window.pyloid['{js_api.__class__.__name__}'] = channel.objects['{js_api.__class__.__name__}'];\n"
551
- f"console.log('pyloid.{js_api.__class__.__name__} object initialized:', window.pyloid['{js_api.__class__.__name__}']);"
571
+ f"window['{js_api.__class__.__name__}'] = channel.objects['{js_api.__class__.__name__}'];\n"
572
+ # f"console.log('{js_api.__class__.__name__} object initialized:', window.pyloid['{js_api.__class__.__name__}']);"
552
573
  for js_api in self.js_apis
553
574
  ]
554
575
  )
555
- self.web_view.page().runJavaScript(js_code % (js_api_init))
576
+ self.web_view.page().runJavaScript(js_code % js_api_init)
556
577
 
557
578
  # if splash screen is set, close it when the page is loaded
558
579
  if self.close_on_load and self.splash_screen:
@@ -826,6 +847,7 @@ class _BrowserWindow:
826
847
  self.dev_tools_window = QMainWindow(self._window)
827
848
  dev_tools_view = QWebEngineView(self.dev_tools_window)
828
849
  dev_tools_view.setPage(self.web_view.page().devToolsPage())
850
+
829
851
  self.dev_tools_window.setCentralWidget(dev_tools_view)
830
852
  self.dev_tools_window.resize(800, 600)
831
853
  self.dev_tools_window.show()
@@ -1994,14 +2016,30 @@ class _BrowserWindow:
1994
2016
  class BrowserWindow(QObject):
1995
2017
  command_signal = Signal(str, str, object)
1996
2018
  result_signal = Signal(str, object)
1997
-
1998
- def __init__(self, app, title: str, width: int, height: int, x: int, y: int, frame: bool, context_menu: bool, dev_tools: bool, js_apis: List[PyloidAPI]):
2019
+
2020
+ def __init__(
2021
+ self,
2022
+ app,
2023
+ title: str,
2024
+ width: int,
2025
+ height: int,
2026
+ x: int,
2027
+ y: int,
2028
+ frame: bool,
2029
+ context_menu: bool,
2030
+ dev_tools: bool,
2031
+ rpc: Optional[PyloidRPC] = None,
2032
+ ):
1999
2033
  super().__init__()
2000
- self._window = _BrowserWindow(app, title, width, height, x, y, frame, context_menu, dev_tools, js_apis)
2034
+ self._window = _BrowserWindow(
2035
+ app, title, width, height, x, y, frame, context_menu, dev_tools, rpc
2036
+ )
2001
2037
  self.command_signal.connect(self._handle_command)
2002
-
2038
+
2003
2039
  @Slot(str, str, object)
2004
- def _handle_command(self, command_id: str, command_type: str, params: object) -> None:
2040
+ def _handle_command(
2041
+ self, command_id: str, command_type: str, params: object
2042
+ ) -> None:
2005
2043
  """
2006
2044
  Handles commands sent from multiple threads.
2007
2045
  Calls the corresponding method of _BrowserWindow based on the command type and returns the result.
@@ -2065,7 +2103,9 @@ class BrowserWindow(QObject):
2065
2103
  elif command_type == "capture":
2066
2104
  result = self._window.capture(params["save_path"])
2067
2105
  elif command_type == "add_shortcut":
2068
- result = self._window.add_shortcut(params["key_sequence"], params["callback"])
2106
+ result = self._window.add_shortcut(
2107
+ params["key_sequence"], params["callback"]
2108
+ )
2069
2109
  elif command_type == "remove_shortcut":
2070
2110
  result = self._window.remove_shortcut(params["key_sequence"])
2071
2111
  elif command_type == "get_all_shortcuts":
@@ -2093,9 +2133,13 @@ class BrowserWindow(QObject):
2093
2133
  elif command_type == "set_resizable":
2094
2134
  result = self._window.set_resizable(params["resizable"])
2095
2135
  elif command_type == "set_minimum_size":
2096
- result = self._window.set_minimum_size(params["min_width"], params["min_height"])
2136
+ result = self._window.set_minimum_size(
2137
+ params["min_width"], params["min_height"]
2138
+ )
2097
2139
  elif command_type == "set_maximum_size":
2098
- result = self._window.set_maximum_size(params["max_width"], params["max_height"])
2140
+ result = self._window.set_maximum_size(
2141
+ params["max_width"], params["max_height"]
2142
+ )
2099
2143
  elif command_type == "get_minimum_size":
2100
2144
  result = self._window.get_minimum_size()
2101
2145
  elif command_type == "get_maximum_size":
@@ -2108,7 +2152,7 @@ class BrowserWindow(QObject):
2108
2152
  params.get("close_on_load", True),
2109
2153
  params.get("stay_on_top", True),
2110
2154
  params.get("clickable", True),
2111
- params.get("position", "center")
2155
+ params.get("position", "center"),
2112
2156
  )
2113
2157
  elif command_type == "set_gif_splash_screen":
2114
2158
  result = self._window.set_gif_splash_screen(
@@ -2116,7 +2160,7 @@ class BrowserWindow(QObject):
2116
2160
  params.get("close_on_load", True),
2117
2161
  params.get("stay_on_top", True),
2118
2162
  params.get("clickable", True),
2119
- params.get("position", "center")
2163
+ params.get("position", "center"),
2120
2164
  )
2121
2165
  elif command_type == "close_splash_screen":
2122
2166
  result = self._window.close_splash_screen()
@@ -2124,35 +2168,36 @@ class BrowserWindow(QObject):
2124
2168
  return None
2125
2169
 
2126
2170
  self.result_signal.emit(command_id, result)
2127
-
2128
- def execute_command(self, command_type: str, params: object, timeout: Optional[int] = None):
2171
+
2172
+ def execute_command(
2173
+ self, command_type: str, params: object, timeout: Optional[int] = None
2174
+ ):
2129
2175
  command_id = str(uuid.uuid4())
2130
-
2176
+
2131
2177
  result_data = [None]
2132
2178
  loop = QEventLoop()
2133
-
2179
+
2134
2180
  if timeout:
2135
2181
  timer = QTimer()
2136
2182
  timer.setSingleShot(True)
2137
2183
  timer.timeout.connect(loop.quit)
2138
2184
  timer.start(timeout)
2139
-
2185
+
2140
2186
  def on_result(received_id, result):
2141
2187
  if received_id == command_id:
2142
- result_data[0] = result
2188
+ result_data[0] = result
2143
2189
  loop.quit()
2144
2190
 
2145
-
2146
2191
  self.result_signal.connect(on_result, Qt.QueuedConnection)
2147
-
2192
+
2148
2193
  self.command_signal.emit(command_id, command_type, params)
2149
-
2194
+
2150
2195
  loop.exec()
2151
-
2196
+
2152
2197
  self.result_signal.disconnect(on_result)
2153
-
2198
+
2154
2199
  return result_data[0]
2155
-
2200
+
2156
2201
  # -------------------------------------------------------------------
2157
2202
  # Execute_command wrapper functions
2158
2203
  # -------------------------------------------------------------------
@@ -2211,7 +2256,9 @@ class BrowserWindow(QObject):
2211
2256
  >>> window.load_html(html_content)
2212
2257
  >>> window.show()
2213
2258
  """
2214
- return self.execute_command("load_html", {"html_content": html_content, "base_url": base_url})
2259
+ return self.execute_command(
2260
+ "load_html", {"html_content": html_content, "base_url": base_url}
2261
+ )
2215
2262
 
2216
2263
  def set_title(self, title: str) -> None:
2217
2264
  """
@@ -2558,7 +2605,9 @@ class BrowserWindow(QObject):
2558
2605
  >>> window.add_shortcut("Ctrl+C", on_shortcut)
2559
2606
  >>> app.run()
2560
2607
  """
2561
- return self.execute_command("add_shortcut", {"key_sequence": key_sequence, "callback": callback})
2608
+ return self.execute_command(
2609
+ "add_shortcut", {"key_sequence": key_sequence, "callback": callback}
2610
+ )
2562
2611
 
2563
2612
  def remove_shortcut(self, key_sequence: str) -> None:
2564
2613
  """
@@ -2810,7 +2859,9 @@ class BrowserWindow(QObject):
2810
2859
  >>> window.set_minimum_size(400, 300)
2811
2860
  >>> app.run()
2812
2861
  """
2813
- return self.execute_command("set_minimum_size", {"min_width": min_width, "min_height": min_height})
2862
+ return self.execute_command(
2863
+ "set_minimum_size", {"min_width": min_width, "min_height": min_height}
2864
+ )
2814
2865
 
2815
2866
  def set_maximum_size(self, max_width: int, max_height: int) -> None:
2816
2867
  """
@@ -2830,7 +2881,9 @@ class BrowserWindow(QObject):
2830
2881
  >>> window.set_maximum_size(1024, 768)
2831
2882
  >>> app.run()
2832
2883
  """
2833
- return self.execute_command("set_maximum_size", {"max_width": max_width, "max_height": max_height})
2884
+ return self.execute_command(
2885
+ "set_maximum_size", {"max_width": max_width, "max_height": max_height}
2886
+ )
2834
2887
 
2835
2888
  def get_minimum_size(self) -> "Dict[str, int]":
2836
2889
  """
@@ -2889,7 +2942,14 @@ class BrowserWindow(QObject):
2889
2942
  """
2890
2943
  return self.execute_command("get_resizable", {})
2891
2944
 
2892
- def set_static_image_splash_screen(self, image_path: str, close_on_load: bool = True, stay_on_top: bool = True, clickable: bool = True, position: str = "center") -> None:
2945
+ def set_static_image_splash_screen(
2946
+ self,
2947
+ image_path: str,
2948
+ close_on_load: bool = True,
2949
+ stay_on_top: bool = True,
2950
+ clickable: bool = True,
2951
+ position: str = "center",
2952
+ ) -> None:
2893
2953
  """
2894
2954
  Sets the static image splash screen of the window.
2895
2955
 
@@ -2911,15 +2971,25 @@ class BrowserWindow(QObject):
2911
2971
  --------
2912
2972
  >>> window.set_static_image_splash_screen("./assets/loading.png", close_on_load=True, stay_on_top=True)
2913
2973
  """
2914
- return self.execute_command("set_static_image_splash_screen", {
2915
- "image_path": image_path,
2916
- "close_on_load": close_on_load,
2917
- "stay_on_top": stay_on_top,
2918
- "clickable": clickable,
2919
- "position": position
2920
- })
2974
+ return self.execute_command(
2975
+ "set_static_image_splash_screen",
2976
+ {
2977
+ "image_path": image_path,
2978
+ "close_on_load": close_on_load,
2979
+ "stay_on_top": stay_on_top,
2980
+ "clickable": clickable,
2981
+ "position": position,
2982
+ },
2983
+ )
2921
2984
 
2922
- def set_gif_splash_screen(self, gif_path: str, close_on_load: bool = True, stay_on_top: bool = True, clickable: bool = True, position: str = "center") -> None:
2985
+ def set_gif_splash_screen(
2986
+ self,
2987
+ gif_path: str,
2988
+ close_on_load: bool = True,
2989
+ stay_on_top: bool = True,
2990
+ clickable: bool = True,
2991
+ position: str = "center",
2992
+ ) -> None:
2923
2993
  """
2924
2994
  Sets the gif splash screen of the window.
2925
2995
 
@@ -2941,13 +3011,16 @@ class BrowserWindow(QObject):
2941
3011
  --------
2942
3012
  >>> window.set_gif_splash_screen("./assets/loading.gif", close_on_load=True, stay_on_top=True)
2943
3013
  """
2944
- return self.execute_command("set_gif_splash_screen", {
2945
- "gif_path": gif_path,
2946
- "close_on_load": close_on_load,
2947
- "stay_on_top": stay_on_top,
2948
- "clickable": clickable,
2949
- "position": position
2950
- })
3014
+ return self.execute_command(
3015
+ "set_gif_splash_screen",
3016
+ {
3017
+ "gif_path": gif_path,
3018
+ "close_on_load": close_on_load,
3019
+ "stay_on_top": stay_on_top,
3020
+ "clickable": clickable,
3021
+ "position": position,
3022
+ },
3023
+ )
2951
3024
 
2952
3025
  def close_splash_screen(self) -> None:
2953
3026
  """
@@ -2958,4 +3031,3 @@ class BrowserWindow(QObject):
2958
3031
  >>> window.close_splash_screen()
2959
3032
  """
2960
3033
  return self.execute_command("close_splash_screen", {})
2961
-