pyloid 0.22.0.dev6__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 +156 -84
- pyloid/js_api/base.py +234 -8
- pyloid/js_api/window_api.py +9 -52
- pyloid/pyloid.py +596 -100
- pyloid/rpc.py +339 -0
- pyloid/store.py +172 -0
- pyloid/url_interceptor.py +24 -0
- {pyloid-0.22.0.dev6.dist-info → pyloid-0.23.0.dist-info}/METADATA +4 -1
- {pyloid-0.22.0.dev6.dist-info → pyloid-0.23.0.dist-info}/RECORD +11 -8
- {pyloid-0.22.0.dev6.dist-info → pyloid-0.23.0.dist-info}/LICENSE +0 -0
- {pyloid-0.22.0.dev6.dist-info → pyloid-0.23.0.dist-info}/WHEEL +0 -0
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
|
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
|
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
|
-
|
322
|
-
|
323
|
-
|
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
|
-
|
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.
|
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
|
551
|
-
f"console.log('
|
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 %
|
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__(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
2915
|
-
"
|
2916
|
-
|
2917
|
-
|
2918
|
-
|
2919
|
-
|
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(
|
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(
|
2945
|
-
"
|
2946
|
-
|
2947
|
-
|
2948
|
-
|
2949
|
-
|
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
|
-
|