pycoze 0.1.264__py3-none-any.whl → 0.1.266__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.
- pycoze/api/__init__.py +3 -1
- pycoze/api/lib/tab_cls.py +103 -0
- pycoze/api/lib/view.py +242 -0
- pycoze/api/lib/window_cls.py +7 -7
- {pycoze-0.1.264.dist-info → pycoze-0.1.266.dist-info}/METADATA +1 -1
- {pycoze-0.1.264.dist-info → pycoze-0.1.266.dist-info}/RECORD +9 -7
- {pycoze-0.1.264.dist-info → pycoze-0.1.266.dist-info}/LICENSE +0 -0
- {pycoze-0.1.264.dist-info → pycoze-0.1.266.dist-info}/WHEEL +0 -0
- {pycoze-0.1.264.dist-info → pycoze-0.1.266.dist-info}/top_level.txt +0 -0
pycoze/api/__init__.py
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
from .lib.window_cls import WindowCls
|
2
|
+
from .lib.tab_cls import TabCls
|
2
3
|
|
3
4
|
class Api:
|
4
5
|
def __init__(self) -> None:
|
5
6
|
self.window = WindowCls()
|
7
|
+
self.tab = TabCls()
|
6
8
|
|
7
|
-
|
9
|
+
api = Api()
|
8
10
|
|
9
11
|
# from ps_view import ViewCls, WebsiteViewCls, FileViewCls, DirectoryViewCls, WorkflowCls
|
@@ -0,0 +1,103 @@
|
|
1
|
+
import os
|
2
|
+
from uuid import uuid4
|
3
|
+
from view import ViewCls, WebsiteViewCls, FileViewCls, DirectoryViewCls, WorkflowCls
|
4
|
+
import time
|
5
|
+
from typing import Union
|
6
|
+
from pycoze import utils
|
7
|
+
|
8
|
+
|
9
|
+
socket = utils.socket
|
10
|
+
|
11
|
+
class TabCls:
|
12
|
+
|
13
|
+
def open_path(self, item_path: str) -> FileViewCls | DirectoryViewCls:
|
14
|
+
if not os.path.isabs(item_path):
|
15
|
+
item_path = os.path.abspath(item_path)
|
16
|
+
if os.path.isdir(item_path):
|
17
|
+
return self.open_dir(item_path)
|
18
|
+
else:
|
19
|
+
return self.open_file(item_path)
|
20
|
+
|
21
|
+
def open_file(self, item_path: str) -> Union[FileViewCls, WebsiteViewCls, WorkflowCls]:
|
22
|
+
if not os.path.isabs(item_path):
|
23
|
+
item_path = os.path.abspath(item_path)
|
24
|
+
location = ["FileOrDir", item_path]
|
25
|
+
socket.post("add-tab", {"location": location, "name": os.path.basename(item_path)})
|
26
|
+
lower_suffix = item_path.lower().split(".")[-1]
|
27
|
+
if lower_suffix == 'workflow':
|
28
|
+
return WorkflowCls(location)
|
29
|
+
if len(location) > 1 and (location[0] == "Website" or location[1].endswith(".website") or location[1].endswith(".html") or location[1].endswith(".ipynb")):
|
30
|
+
return WebsiteViewCls(location)
|
31
|
+
return FileViewCls(location)
|
32
|
+
|
33
|
+
def open_dir(self, item_path: str) -> DirectoryViewCls:
|
34
|
+
if not os.path.isabs(item_path):
|
35
|
+
item_path = os.path.abspath(item_path)
|
36
|
+
location = ["FileOrDir", item_path]
|
37
|
+
socket.post("add-tab", {"location": location, "name": os.path.basename(item_path)})
|
38
|
+
return DirectoryViewCls(location)
|
39
|
+
|
40
|
+
def open_website(self, url: str, uid:str=None) -> WebsiteViewCls:
|
41
|
+
if uid is None:
|
42
|
+
uid = str(uuid4())
|
43
|
+
location = ["Website", url, uid]
|
44
|
+
socket.post("add-tab", {"location": location, "name": url})
|
45
|
+
return WebsiteViewCls(location)
|
46
|
+
|
47
|
+
def get_active(self) -> ViewCls:
|
48
|
+
result = socket.post_and_recv_result("get-active-tab", {})
|
49
|
+
return self._result_to_view(result)
|
50
|
+
|
51
|
+
def _result_to_view(self, result: list[str]) -> ViewCls:
|
52
|
+
if result[0] == "Website":
|
53
|
+
return WebsiteViewCls(result)
|
54
|
+
elif result[0] == "FileOrDir":
|
55
|
+
if os.path.isdir(result[1]):
|
56
|
+
return DirectoryViewCls(result)
|
57
|
+
else:
|
58
|
+
if result[1].lower().split(".")[-1] == 'workflow':
|
59
|
+
return WorkflowCls(result)
|
60
|
+
return FileViewCls(result)
|
61
|
+
return ViewCls(result)
|
62
|
+
|
63
|
+
def wait_for_tab_open(self, location: list[str] | ViewCls):
|
64
|
+
times = 0
|
65
|
+
while not self.is_tab_open(location):
|
66
|
+
time.sleep(0.01)
|
67
|
+
times += 1
|
68
|
+
if times > 1000:
|
69
|
+
raise Exception("Tab open timeout")
|
70
|
+
|
71
|
+
def get_all(self) -> list[ViewCls]:
|
72
|
+
results = socket.post_and_recv_result("get-all-tabs", {})
|
73
|
+
return [self._result_to_view(result) for result in results]
|
74
|
+
|
75
|
+
def close_tab(self, location: list[str] | ViewCls):
|
76
|
+
if isinstance(location, ViewCls):
|
77
|
+
location = location.location
|
78
|
+
self.wait_for_tab_open(location)
|
79
|
+
socket.post("close-tab", {"location": location})
|
80
|
+
|
81
|
+
def switch_tab(self, location: list[str] | ViewCls):
|
82
|
+
if isinstance(location, ViewCls):
|
83
|
+
location = location.location
|
84
|
+
self.wait_for_tab_open(location)
|
85
|
+
socket.post("switchTab", {"location": location})
|
86
|
+
|
87
|
+
def is_tab_open(self, location: list[str] | ViewCls):
|
88
|
+
if isinstance(location, ViewCls):
|
89
|
+
location = location.location
|
90
|
+
result = socket.post_and_recv_result("is-tab-open", {"location": location})
|
91
|
+
return result
|
92
|
+
|
93
|
+
def pin_tab(self, location: list[str] | ViewCls):
|
94
|
+
if isinstance(location, ViewCls):
|
95
|
+
location = location.location
|
96
|
+
self.wait_for_tab_open(location)
|
97
|
+
socket.post("pin-tab", {"location": location})
|
98
|
+
|
99
|
+
def unpin_tab(self, location: list[str] | ViewCls):
|
100
|
+
if isinstance(location, ViewCls):
|
101
|
+
location = location.location
|
102
|
+
self.wait_for_tab_open(location)
|
103
|
+
socket.post("unpin-tab", {"location": location})
|
pycoze/api/lib/view.py
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
import time
|
2
|
+
from typing import Union
|
3
|
+
from pycoze import utils
|
4
|
+
|
5
|
+
|
6
|
+
socket = utils.socket
|
7
|
+
|
8
|
+
class ViewCls:
|
9
|
+
|
10
|
+
def __init__(self, location: list[str], nodeIds: list[str] = []):
|
11
|
+
self.location = location
|
12
|
+
self.nodeIds = nodeIds
|
13
|
+
self.is_in_workflow = len(nodeIds) > 0
|
14
|
+
self.is_tab = len(nodeIds) == 0
|
15
|
+
|
16
|
+
def __getitem__(self, key):
|
17
|
+
return self.location[key]
|
18
|
+
|
19
|
+
def wait_for_tab_open(self):
|
20
|
+
times = 0
|
21
|
+
while not self.is_tab_open():
|
22
|
+
time.sleep(0.01)
|
23
|
+
times += 1
|
24
|
+
if times > 1000:
|
25
|
+
raise Exception("Tab open timeout")
|
26
|
+
|
27
|
+
def close_tab(self):
|
28
|
+
assert self.is_tab
|
29
|
+
self.wait_for_tab_open()
|
30
|
+
socket.post("close-tab", {"location": self.location})
|
31
|
+
|
32
|
+
def set_activate(self):
|
33
|
+
assert self.is_tab
|
34
|
+
self.wait_for_tab_open()
|
35
|
+
socket.post("switchTab", {"location": self.location})
|
36
|
+
|
37
|
+
def is_tab_open(self):
|
38
|
+
assert self.is_tab
|
39
|
+
result = socket.post_and_recv_result("is-tab-open", {"location": self.location})
|
40
|
+
return result
|
41
|
+
|
42
|
+
def pin_tab(self):
|
43
|
+
assert self.is_tab
|
44
|
+
self.wait_for_tab_open()
|
45
|
+
socket.post("pin-tab", {"location": self.location})
|
46
|
+
|
47
|
+
def unpin_tab(self):
|
48
|
+
assert self.is_tab
|
49
|
+
self.wait_for_tab_open()
|
50
|
+
socket.post("unpin-tab", {"location": self.location})
|
51
|
+
|
52
|
+
|
53
|
+
class WebsiteViewCls(ViewCls):
|
54
|
+
def execute_javaScript(self, js_code: str):
|
55
|
+
result = socket.post_and_recv_result("webview.executeJavaScript", {"location": self.location, "code": js_code})
|
56
|
+
if not result["ok"]:
|
57
|
+
raise Exception(result["value"])
|
58
|
+
return result["value"] if "value" in result else None
|
59
|
+
|
60
|
+
def capture_page(self, rect=None):
|
61
|
+
result = socket.post_and_recv_result("webview.capturePage", {"location": self.location, "rect": rect})
|
62
|
+
if not result["ok"]:
|
63
|
+
raise Exception(result["value"])
|
64
|
+
return result["value"]
|
65
|
+
|
66
|
+
def get_webview_height(self):
|
67
|
+
result = socket.post_and_recv_result("get-webview-height", {"location": self.location})
|
68
|
+
if not result["ok"]:
|
69
|
+
raise Exception(result["value"])
|
70
|
+
return result["value"]
|
71
|
+
|
72
|
+
def set_webview_height(self, height: int):
|
73
|
+
result = socket.post_and_recv_result("set-webview-height", {"location": self.location, "height": height})
|
74
|
+
if not result["ok"]:
|
75
|
+
raise Exception(result["value"])
|
76
|
+
return result["value"]
|
77
|
+
|
78
|
+
def set_webview_allow_new_window(self, allow: bool):
|
79
|
+
result = socket.post_and_recv_result("set-webview-allow-new-window", {"location": self.location, "allow": allow})
|
80
|
+
if not result["ok"]:
|
81
|
+
raise Exception(result["value"])
|
82
|
+
return result["value"]
|
83
|
+
|
84
|
+
class FileViewCls(ViewCls):
|
85
|
+
|
86
|
+
def get_file_path(self):
|
87
|
+
return self.location[1]
|
88
|
+
|
89
|
+
|
90
|
+
class DirectoryViewCls(FileViewCls):
|
91
|
+
|
92
|
+
def get_dir_path(self):
|
93
|
+
return self.location[1]
|
94
|
+
|
95
|
+
|
96
|
+
class WorkflowCls(FileViewCls):
|
97
|
+
|
98
|
+
def layout_arrangement(self):
|
99
|
+
# NetworkX layout arrangement,直接用python的布局即可,虽然没有输入输出port的,但是用节点坐标,再缩放几倍一般情况就可以了
|
100
|
+
pass
|
101
|
+
|
102
|
+
def run(self, wait_for_end=False):
|
103
|
+
result = socket.post_and_recv_result("workflow-run", {"location": self.location, "wait_for_end": wait_for_end})
|
104
|
+
if not result["ok"]:
|
105
|
+
raise Exception(result["value"])
|
106
|
+
return result["value"] # task_id
|
107
|
+
|
108
|
+
def stop(self):
|
109
|
+
result = socket.post_and_recv_result("workflow-stop", {"location": self.location})
|
110
|
+
if not result["ok"]:
|
111
|
+
raise Exception(result["value"])
|
112
|
+
|
113
|
+
def get_state(self):
|
114
|
+
result = socket.post_and_recv_result("workflow-get-state", {"location": self.location})
|
115
|
+
if not result["ok"]:
|
116
|
+
raise Exception(result["value"])
|
117
|
+
return result["value"]
|
118
|
+
|
119
|
+
def get_nodes(self):
|
120
|
+
result = socket.post_and_recv_result("workflow-get-graph-nodes", {"location": self.location})
|
121
|
+
if not result["ok"]:
|
122
|
+
raise Exception(result["value"])
|
123
|
+
return result["value"]
|
124
|
+
|
125
|
+
def get_edges(self):
|
126
|
+
result = socket.post_and_recv_result("workflow-get-graph-edges", {"location": self.location})
|
127
|
+
return result["value"]
|
128
|
+
|
129
|
+
def add_text_node(self, text: str, position='center'):
|
130
|
+
result = socket.post_and_recv_result("workflow-add-text-node", {
|
131
|
+
"location": self.location,
|
132
|
+
"text": text,
|
133
|
+
"position": position
|
134
|
+
})
|
135
|
+
if not result["ok"]:
|
136
|
+
raise Exception(result["value"])
|
137
|
+
time.sleep(0.01)
|
138
|
+
return result["value"] # node
|
139
|
+
|
140
|
+
def add_markdown_node(self, text: str, position='center'):
|
141
|
+
result = socket.post_and_recv_result("workflow-add-markdown-node", {
|
142
|
+
"location": self.location,
|
143
|
+
"text": text,
|
144
|
+
"position": position
|
145
|
+
})
|
146
|
+
if not result["ok"]:
|
147
|
+
raise Exception(result["value"])
|
148
|
+
time.sleep(0.01)
|
149
|
+
return result["value"] # node
|
150
|
+
|
151
|
+
def add_file_node(self, file_path: str, position='center'):
|
152
|
+
is_step = False
|
153
|
+
if file_path.lower().endswith(".py"):
|
154
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
155
|
+
content = f.read()
|
156
|
+
if "ps_workflow" in content:
|
157
|
+
is_step = True
|
158
|
+
if is_step:
|
159
|
+
return self.add_step_file_node(file_path, position)
|
160
|
+
result = socket.post_and_recv_result("workflow-add-file-node", {
|
161
|
+
"location": self.location,
|
162
|
+
"file_path": file_path,
|
163
|
+
"position": position
|
164
|
+
})
|
165
|
+
if not result["ok"]:
|
166
|
+
raise Exception(result["value"])
|
167
|
+
time.sleep(0.01)
|
168
|
+
return result["value"] # node
|
169
|
+
|
170
|
+
def add_step_file_node(self, file_path: str, position='center'):
|
171
|
+
result = socket.post_and_recv_result("workflow-add-step-file-node", {
|
172
|
+
"location": self.location,
|
173
|
+
"file_path": file_path,
|
174
|
+
"position": position
|
175
|
+
})
|
176
|
+
if not result["ok"]:
|
177
|
+
raise Exception(result["value"])
|
178
|
+
time.sleep(0.01)
|
179
|
+
return result["value"] # node
|
180
|
+
|
181
|
+
def add_edge(self, from_node_id: str, from_port_id: str, to_node_id: str, to_port_id: str):
|
182
|
+
result = socket.post_and_recv_result(
|
183
|
+
"workflow-add-edge", {
|
184
|
+
"location": self.location,
|
185
|
+
"source": {
|
186
|
+
"cell": from_node_id,
|
187
|
+
"port": from_port_id
|
188
|
+
},
|
189
|
+
"target": {
|
190
|
+
"cell": to_node_id,
|
191
|
+
"port": to_port_id
|
192
|
+
}
|
193
|
+
})
|
194
|
+
if not result["ok"]:
|
195
|
+
raise Exception(result["value"])
|
196
|
+
time.sleep(0.01)
|
197
|
+
return result["value"] # edge
|
198
|
+
|
199
|
+
def get_node_info(self, node: Union[str, object]):
|
200
|
+
if isinstance(node, object):
|
201
|
+
node_id = node["id"]
|
202
|
+
result = socket.post_and_recv_result("workflow-get-node-info", {"location": self.location, "node_id": node_id})
|
203
|
+
if not result["ok"]:
|
204
|
+
raise Exception(result["value"])
|
205
|
+
return result["value"]
|
206
|
+
|
207
|
+
def get_node_state(self, node: Union[str, object]):
|
208
|
+
if isinstance(node, object):
|
209
|
+
node_id = node["id"]
|
210
|
+
result = socket.post_and_recv_result("workflow-get-node-state", {"location": self.location, "node_id": node_id})
|
211
|
+
if not result["ok"]:
|
212
|
+
raise Exception(result["value"])
|
213
|
+
return result["value"]
|
214
|
+
|
215
|
+
def get_node_log(self, node: Union[str, object]):
|
216
|
+
if isinstance(node, object):
|
217
|
+
node_id = node["id"]
|
218
|
+
result = socket.post_and_recv_result("workflow-get-node-log", {"location": self.location, "node_id": node_id})
|
219
|
+
if not result["ok"]:
|
220
|
+
raise Exception(result["value"])
|
221
|
+
return result["value"]
|
222
|
+
|
223
|
+
def get_node_input_data(self, node: Union[str, object], port:str):
|
224
|
+
if isinstance(node, object):
|
225
|
+
node_id = node["id"]
|
226
|
+
result = socket.post_and_recv_result("workflow-get-node-input-data", {"location": self.location, "node_id": node_id, "port":port})
|
227
|
+
if not result["ok"]:
|
228
|
+
raise Exception(result["value"])
|
229
|
+
return result["value"]
|
230
|
+
|
231
|
+
def get_node_output_data(self, node: Union[str, object], port:str):
|
232
|
+
if isinstance(node, object):
|
233
|
+
node_id = node["id"]
|
234
|
+
result = socket.post_and_recv_result("workflow-get-node-output-data", {"location": self.location, "node_id": node_id, "port":port})
|
235
|
+
if not result["ok"]:
|
236
|
+
raise Exception(result["value"])
|
237
|
+
return result["value"]
|
238
|
+
|
239
|
+
def parse_node_data(self, data: Union[dict|list]):
|
240
|
+
if isinstance(data, list):
|
241
|
+
return [parse_data(d) for d in data]
|
242
|
+
return parse_data(data)
|
pycoze/api/lib/window_cls.py
CHANGED
@@ -8,11 +8,7 @@ socket = utils.socket
|
|
8
8
|
|
9
9
|
class WindowCls:
|
10
10
|
|
11
|
-
def
|
12
|
-
result = socket.post_and_recv_result("get-selected-text", {})
|
13
|
-
return result
|
14
|
-
|
15
|
-
def append_msg(self, message: str, type: str = 'info'):
|
11
|
+
def message(self, message: str, type: str = 'info'):
|
16
12
|
assert type in ['info', 'warning', 'success', 'error'], 'type must be info, warning, success or error'
|
17
13
|
if not isinstance(message, str):
|
18
14
|
message = repr(message)
|
@@ -24,6 +20,10 @@ class WindowCls:
|
|
24
20
|
def maximize(self):
|
25
21
|
socket.post("maximize", {})
|
26
22
|
|
23
|
+
def get_slected_text(self) -> str:
|
24
|
+
result = socket.post_and_recv_result("get-selected-text", {})
|
25
|
+
return result
|
26
|
+
|
27
27
|
def open_file_with_system(self, file_path, wait: bool):
|
28
28
|
process_fn = subprocess.run if wait else subprocess.Popen
|
29
29
|
if sys.platform.startswith('linux'):
|
@@ -35,9 +35,9 @@ class WindowCls:
|
|
35
35
|
else:
|
36
36
|
raise OSError('Unsupported operating system')
|
37
37
|
|
38
|
-
def open_program(self,
|
38
|
+
def open_program(self, program_path, wait: bool):
|
39
39
|
process_fn = subprocess.run if wait else subprocess.Popen
|
40
|
-
process_fn([
|
40
|
+
process_fn([program_path])
|
41
41
|
|
42
42
|
def execute_javaScript(self, js_code: str):
|
43
43
|
result = socket.post_and_recv_result("executeJavaScript", {"code": js_code})
|
@@ -5,9 +5,11 @@ pycoze/ai/llm/__init__.py,sha256=5_AnOrzXI2V6ZZsLUWW1v5ATRWmJy53JLN9jfSZQXCg,249
|
|
5
5
|
pycoze/ai/llm/chat.py,sha256=izriC7nCp5qeJRqcUVQBVqTHiH6MJS77ROzGBJufdNI,5133
|
6
6
|
pycoze/ai/llm/text_to_image_prompt.py,sha256=0bx2C_YRvjAo7iphHGp1-pmGKsKqwur7dM0t3SiA8kA,3398
|
7
7
|
pycoze/ai/llm/think.py,sha256=sUgTBdGzcZtL3r-Wx8M3lDuVUmDVz8g3qC0VU8uiKAI,5143
|
8
|
-
pycoze/api/__init__.py,sha256=
|
8
|
+
pycoze/api/__init__.py,sha256=q34K7gjDIyRPwsRaTMwfvZXops_15yYp7WD7tXwfp8A,279
|
9
9
|
pycoze/api/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
-
pycoze/api/lib/
|
10
|
+
pycoze/api/lib/tab_cls.py,sha256=bMNF5e-fAjKRF3ZwXXyVReqnXuE4GJEZOi3Ni7Xruyk,4202
|
11
|
+
pycoze/api/lib/view.py,sha256=WrDcI5Du38BpSv1u4TXZ3idToe7VAtDM3Zrjd7BNfVc,8850
|
12
|
+
pycoze/api/lib/window_cls.py,sha256=Yezy-SR_EwVtUjrgXnHRC69WGgXVaXeJHjaxn09Ophg,1737
|
11
13
|
pycoze/bot/__init__.py,sha256=JxnRoCCqx_LFyVb3pLu0qYCsH8ZLuAaMXAtvVUuCHuE,78
|
12
14
|
pycoze/bot/agent_chat.py,sha256=ARXXsIVCTpmBojz2C4BR69nB0QhM6gkEngL3iq34JPo,4178
|
13
15
|
pycoze/bot/bot.py,sha256=_qmUTZ09FmRLifHrW5stDZWGVK6yuMEMBC3fmeYJnqk,844
|
@@ -33,8 +35,8 @@ pycoze/utils/arg.py,sha256=jop1tBfe5hYkHW1NSpCeaZBEznkgguBscj_7M2dWfrs,503
|
|
33
35
|
pycoze/utils/env.py,sha256=5pWlXfM1F5ZU9hhv1rHlDEanjEW5wf0nbyez9bNRqqA,559
|
34
36
|
pycoze/utils/socket.py,sha256=yyYgx7G40x58sV466OQH0vj3i55xgR3uMDEjbQMbGks,2413
|
35
37
|
pycoze/utils/text_or_file.py,sha256=gpxZVWt2DW6YiEg_MnMuwg36VNf3TX383QD_1oZNB0Y,551
|
36
|
-
pycoze-0.1.
|
37
|
-
pycoze-0.1.
|
38
|
-
pycoze-0.1.
|
39
|
-
pycoze-0.1.
|
40
|
-
pycoze-0.1.
|
38
|
+
pycoze-0.1.266.dist-info/LICENSE,sha256=QStd_Qsd0-kAam_-sOesCIp_uKrGWeoKwt9M49NVkNU,1090
|
39
|
+
pycoze-0.1.266.dist-info/METADATA,sha256=iOKp4KKH2GscWVx3ljJaxwGwawNRaD9GQvFczQ56Cik,699
|
40
|
+
pycoze-0.1.266.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
41
|
+
pycoze-0.1.266.dist-info/top_level.txt,sha256=76dPeDhKvOCleL3ZC5gl1-y4vdS1tT_U1hxWVAn7sFo,7
|
42
|
+
pycoze-0.1.266.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|