unisi 0.1.7__py3-none-any.whl → 0.1.8__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.
- unisi/__init__.py +0 -1
- unisi/users.py +1 -1
- {unisi-0.1.7.dist-info → unisi-0.1.8.dist-info}/METADATA +7 -9
- {unisi-0.1.7.dist-info → unisi-0.1.8.dist-info}/RECORD +6 -7
- unisi/proxy.py +0 -202
- {unisi-0.1.7.dist-info → unisi-0.1.8.dist-info}/WHEEL +0 -0
- {unisi-0.1.7.dist-info → unisi-0.1.8.dist-info}/licenses/LICENSE +0 -0
unisi/__init__.py
CHANGED
unisi/users.py
CHANGED
@@ -194,7 +194,7 @@ class User:
|
|
194
194
|
if elem:
|
195
195
|
return self.process_element(elem, message)
|
196
196
|
|
197
|
-
error = f'Element {message.block}>>{message.element} does not
|
197
|
+
error = f'Element {message.block}>>{message.element} does not exist!'
|
198
198
|
self.log(error)
|
199
199
|
return Error(error)
|
200
200
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: unisi
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.8
|
4
4
|
Summary: UNified System Interface, GUI and proxy
|
5
5
|
Author-Email: UNISI Tech <g.dernovoy@gmail.com>
|
6
6
|
License: Apache-2.0
|
@@ -30,8 +30,6 @@ UNISI technology provides a unified system interface and advanced program functi
|
|
30
30
|
- Integral autotesting
|
31
31
|
- Protocol schema auto validation
|
32
32
|
- Shared sessions
|
33
|
-
- Voice interaction (not released yet)
|
34
|
-
- Remote GUI interaction and pipelining (not released yet)
|
35
33
|
|
36
34
|
### Installing ###
|
37
35
|
```
|
@@ -39,7 +37,7 @@ pip install unisi
|
|
39
37
|
```
|
40
38
|
|
41
39
|
### Programming ###
|
42
|
-
This repo explains how to work with Unisi using Python and the tiny but optimal framework for that. Unisi web version is included in this library. Supports Python 3.
|
40
|
+
This repo explains how to work with Unisi using Python and the tiny but optimal framework for that. Unisi web version is included in this library. Supports Python 3.10 and up.
|
43
41
|
|
44
42
|
|
45
43
|
### High level - Screen ###
|
@@ -336,12 +334,12 @@ Graph supports an interactive graph.
|
|
336
334
|
```
|
337
335
|
graph = Graph('X graph', graph_value, graph_selection,
|
338
336
|
nodes = [
|
339
|
-
{ 'id' : 'node1', '
|
340
|
-
{ 'id' : 'node2', '
|
341
|
-
{ 'id' : 'node3', '
|
337
|
+
{ 'id' : 'node1', 'name': "Node 1" },
|
338
|
+
{ 'id' : 'node2', 'name': "Node 2" },
|
339
|
+
{ 'id' : 'node3', 'name': "Node 3" }
|
342
340
|
], edges = [
|
343
|
-
{ 'id' : 'edge1', 'source': "node1", 'target': "node2", '
|
344
|
-
{ 'id' :'edge2' , 'source': "node2", 'target': "node3" , '
|
341
|
+
{ 'id' : 'edge1', 'source': "node1", 'target': "node2", 'name' : 'extending' },
|
342
|
+
{ 'id' :'edge2' , 'source': "node2", 'target': "node3" , 'name' : 'extending'}
|
345
343
|
])
|
346
344
|
```
|
347
345
|
where graph_value is a dictionary like {'nodes' : ["node1"], 'edges' : ['edge3']}, where enumerations are selected nodes and edges.
|
@@ -1,7 +1,7 @@
|
|
1
|
-
unisi-0.1.
|
2
|
-
unisi-0.1.
|
3
|
-
unisi-0.1.
|
4
|
-
unisi/__init__.py,sha256=
|
1
|
+
unisi-0.1.8.dist-info/METADATA,sha256=rBUW89zbtC9urbRQ1mzUAcdU786z5oJyYT1QCHMx860,17684
|
2
|
+
unisi-0.1.8.dist-info/WHEEL,sha256=N2J68yzZqJh3mI_Wg92rwhw0rtJDFpZj9bwQIMJgaVg,90
|
3
|
+
unisi-0.1.8.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
4
|
+
unisi/__init__.py,sha256=z7fP6b-R1l4VZmc0tFXz4-Uay5y1kSzMm3xbWl5Zh-g,154
|
5
5
|
unisi/autotest.py,sha256=mkvfUuxO7co9QcninjBSS9u-zJSva9H_51k3m6sd3rw,9485
|
6
6
|
unisi/common.py,sha256=jsZpOkZIQdfPZjrTIoO1OLiZfQ_spEpMCX3td269RR0,635
|
7
7
|
unisi/containers.py,sha256=Me28aZkhchWJA5OExtXoFzl2u5bc6p0m2Cww7CfKIbA,4200
|
@@ -11,11 +11,10 @@ unisi/jsoncomparison/compare.py,sha256=qPDaxd9n0GgiNd2SgrcRWvRDoXGg7NStViP9PHk2t
|
|
11
11
|
unisi/jsoncomparison/config.py,sha256=LbdLJE1KIebFq_tX7zcERhPvopKhnzcTqMCnS3jN124,381
|
12
12
|
unisi/jsoncomparison/errors.py,sha256=wqphE1Xn7K6n16uvUhDC45m2BxbsMUhIF2olPbhqf4o,1192
|
13
13
|
unisi/jsoncomparison/ignore.py,sha256=xfF0a_BBEyGdZBoq-ovpCpawgcX8SRwwp7IrGnu1c2w,2634
|
14
|
-
unisi/proxy.py,sha256=sMnGEs480wiic91AGH9hrDAisc0gDUEKKHX_nC3v3_E,7559
|
15
14
|
unisi/reloader.py,sha256=B0f9GU452epFvdih8sH7_NiIJrXnC5i27uw2imGQxMg,6585
|
16
15
|
unisi/server.py,sha256=5oax_OGWGPNm1smQM_8EpCb1jKia2s7IBnIfjIr1Z2w,4583
|
17
16
|
unisi/tables.py,sha256=v7Fio5iIN7u1t7cE4Yvl4ewn7jTmmNPyWigoKW1Mj8U,4239
|
18
|
-
unisi/users.py,sha256=
|
17
|
+
unisi/users.py,sha256=JD4AD0WyuJQK31juWURqHwbeHF-016nifGQBZutHSPI,9818
|
19
18
|
unisi/utils.py,sha256=6iDXECQE_44v8m6fvte_PXM0Ku6ZV-8LkAqMcNSMYdk,2975
|
20
19
|
unisi/web/css/847.64dbc68c.css,sha256=ckeNz4l2QkIp60LdV_-cEXf9orp0ZVklEbrQfjkAG5M,2691
|
21
20
|
unisi/web/css/app.31d6cfe0.css,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -39,4 +38,4 @@ unisi/web/js/430.591e9a73.js,sha256=7S1CJTwGdE2EKXzeFRcaYuTrn0QteoVI03Hykz8qh3s,
|
|
39
38
|
unisi/web/js/847.c4ea8fe3.js,sha256=el_JqiK9zS97V_UDUjlkbwIM8NQ4Y0Yt2WMMRoNm3UM,56531
|
40
39
|
unisi/web/js/app.8224dd96.js,sha256=aKvusY5mySDAmto_L53gUEV2njTSU6JZKWGe_TXtlK8,5923
|
41
40
|
unisi/web/js/vendor.d6797c01.js,sha256=2aKM3Lfxc0pHSirrcUReL1LcvDYWnfeBj2c67XsSELk,1279477
|
42
|
-
unisi-0.1.
|
41
|
+
unisi-0.1.8.dist-info/RECORD,,
|
unisi/proxy.py
DELETED
@@ -1,202 +0,0 @@
|
|
1
|
-
from websocket import create_connection
|
2
|
-
from enum import IntFlag
|
3
|
-
import json, requests, os
|
4
|
-
from .common import *
|
5
|
-
|
6
|
-
class Event(IntFlag):
|
7
|
-
none = 0
|
8
|
-
update = 1
|
9
|
-
invalid = 2
|
10
|
-
message = 4
|
11
|
-
update_message = 6
|
12
|
-
progress = 12
|
13
|
-
update_progress = 13
|
14
|
-
unknown = 16
|
15
|
-
unknown_update = 17
|
16
|
-
dialog = 32
|
17
|
-
screen = 65
|
18
|
-
complete = 128
|
19
|
-
append = 256
|
20
|
-
|
21
|
-
ws_header = 'ws://'
|
22
|
-
wss_header = 'wss://'
|
23
|
-
ws_path = 'ws'
|
24
|
-
|
25
|
-
message_types = ['error','warning','info']
|
26
|
-
|
27
|
-
class Proxy:
|
28
|
-
"""UNISI proxy"""
|
29
|
-
def __init__(self, host_port, timeout = 7, ssl = False):
|
30
|
-
addr_port = f'{wss_header if ssl else ws_header}{host_port}'
|
31
|
-
addr_port = f'{addr_port}{"" if addr_port.endswith("/") else "/"}{ws_path}'
|
32
|
-
self.host_port = f'{"https" if ssl else "http"}://{host_port}'
|
33
|
-
self.conn = create_connection(addr_port, timeout = timeout)
|
34
|
-
self.screen = None
|
35
|
-
self.screens = {}
|
36
|
-
self.dialog = None
|
37
|
-
self.event = None
|
38
|
-
self.request(None)
|
39
|
-
|
40
|
-
def close(self):
|
41
|
-
self.conn.close()
|
42
|
-
|
43
|
-
@property
|
44
|
-
def screen_menu(self):
|
45
|
-
return [name_icon[0] for name_icon in self.screen['menu']] if self.screen else []
|
46
|
-
|
47
|
-
@property
|
48
|
-
def commands(self):
|
49
|
-
"""return command objects"""
|
50
|
-
return self.elements(types=['command'])
|
51
|
-
|
52
|
-
def element(self, name, block_name = None):
|
53
|
-
"""return the element only if 1 element has such name"""
|
54
|
-
result = None
|
55
|
-
name2block = self.screen['name2block']
|
56
|
-
for block in [name2block[block_name]] if block_name else name2block.values():
|
57
|
-
for el in flatten(block['value']):
|
58
|
-
if el['name'] == name:
|
59
|
-
if not result:
|
60
|
-
result = el
|
61
|
-
else:
|
62
|
-
return None
|
63
|
-
return result
|
64
|
-
|
65
|
-
def elements(self, block = None, types = None):
|
66
|
-
"""get elements with filtering types and blocks"""
|
67
|
-
if block:
|
68
|
-
return [el for el in flatten(block['value']) if not types or el['type'] in types]
|
69
|
-
answer = []
|
70
|
-
for block in self.screen['name2block'].values():
|
71
|
-
answer.extend([el for el in flatten(block['value']) if not types or el['type'] in types])
|
72
|
-
return answer
|
73
|
-
|
74
|
-
def block_name(self, element):
|
75
|
-
is_name = isinstance(element, str)
|
76
|
-
for block in self.screen['name2block'].values():
|
77
|
-
for el in flatten(block['value']):
|
78
|
-
if el['name'] == element if is_name else el == element:
|
79
|
-
return block['name']
|
80
|
-
|
81
|
-
def upload(self, fpath):
|
82
|
-
"""upload file to the server and get its server path"""
|
83
|
-
file = open(fpath, "rb")
|
84
|
-
response = requests.post(self.host_port, files = {os.path.basename(fpath): file})
|
85
|
-
return getattr(response, 'text', '')
|
86
|
-
|
87
|
-
def command(self, command, value = None):
|
88
|
-
return self.interact(self.make_message(command, value))
|
89
|
-
|
90
|
-
def command_upload(self, command, fpath):
|
91
|
-
"""upload file to the server and call command"""
|
92
|
-
spath = self.upload(fpath)
|
93
|
-
return self.command(command, spath) if spath else Event.invalid
|
94
|
-
|
95
|
-
def make_message(self, element, value = None, event = 'changed'):
|
96
|
-
if isinstance(element, str):
|
97
|
-
element = self.element(element)
|
98
|
-
if event != 'changed' and event not in element:
|
99
|
-
return None
|
100
|
-
return ArgObject(block = self.block_name(element), element = element['name'],
|
101
|
-
event = event, value = value)
|
102
|
-
|
103
|
-
def interact(self, message, progress_callback = None):
|
104
|
-
"""progress_callback is def (proxy:Proxy)"""
|
105
|
-
while self.request(message) & Event.progress:
|
106
|
-
if progress_callback:
|
107
|
-
progress_callback(self)
|
108
|
-
message = None
|
109
|
-
return self.event
|
110
|
-
|
111
|
-
def request(self, message):
|
112
|
-
"""send message or message list, get responce, return the responce type"""
|
113
|
-
if message:
|
114
|
-
self.conn.send(toJson(message))
|
115
|
-
responce = self.conn.recv()
|
116
|
-
message = json.loads(responce)
|
117
|
-
return self.process(message)
|
118
|
-
|
119
|
-
def set_value(self, element, new_value):
|
120
|
-
if isinstance(element, str):
|
121
|
-
element = self.element(element)
|
122
|
-
element['value'] = new_value
|
123
|
-
ms = self.make_message(element, new_value)
|
124
|
-
return self.interact(ms) if ms else Event.invalid
|
125
|
-
|
126
|
-
def set_screen(self, name):
|
127
|
-
screen = self.screens.get(name)
|
128
|
-
if not screen:
|
129
|
-
if name in self.screen_menu:
|
130
|
-
mtype = self.request(ArgObject(block = 'root', element = None, value = name))
|
131
|
-
return mtype == Event.screen
|
132
|
-
else:
|
133
|
-
return False
|
134
|
-
return True
|
135
|
-
|
136
|
-
@property
|
137
|
-
def dialog_commands(self):
|
138
|
-
return self.dialog['commands'] if self.dialog else []
|
139
|
-
|
140
|
-
def dialog_responce(self, command: str | None):
|
141
|
-
if not self.dialog:
|
142
|
-
self.event = Event.invalid
|
143
|
-
return self.event
|
144
|
-
return self.interact(ArgObject(block = self.dialog['name'], value = command))
|
145
|
-
|
146
|
-
def process(self, message):
|
147
|
-
self.message = message
|
148
|
-
if not message:
|
149
|
-
self.event = Event.none
|
150
|
-
self.mtype = None
|
151
|
-
else:
|
152
|
-
mtype = message.get('type')
|
153
|
-
self.mtype = mtype
|
154
|
-
if mtype == 'screen':
|
155
|
-
self.screen = message
|
156
|
-
self.screens[self.screen['name']] = message
|
157
|
-
name2block = {block['name']: block for block in flatten(message['blocks'])}
|
158
|
-
name2block['toolbar'] = {'name': 'toolbar', 'value': message['toolbar']}
|
159
|
-
message['name2block'] = name2block
|
160
|
-
self.event = Event.screen
|
161
|
-
elif mtype == 'dialog':
|
162
|
-
self.dialog = message
|
163
|
-
self.event = Event.dialog
|
164
|
-
elif mtype == 'complete':
|
165
|
-
return Event.complete
|
166
|
-
elif mtype == 'append':
|
167
|
-
self.event = Event.append
|
168
|
-
elif mtype == 'update':
|
169
|
-
self.update(message)
|
170
|
-
self.event = Event.update
|
171
|
-
else:
|
172
|
-
updates = message.get('updates')
|
173
|
-
if updates:
|
174
|
-
self.update(message)
|
175
|
-
if type in message_types:
|
176
|
-
self.event = Event.update_message if updates else Event.message
|
177
|
-
if type == 'progress':
|
178
|
-
self.event = Event.update_progress if updates else Event.progress
|
179
|
-
else:
|
180
|
-
self.event = Event.unknown_update if updates else Event.unknown
|
181
|
-
return self.event
|
182
|
-
|
183
|
-
def update(self, message):
|
184
|
-
"""update screen from the message"""
|
185
|
-
result = Event.update
|
186
|
-
updates = message.updates
|
187
|
-
for update in updates:
|
188
|
-
path = update['path']
|
189
|
-
name2block = self.screen['name2block']
|
190
|
-
if len(path) == 1: #block
|
191
|
-
name2block[block] = update['data']
|
192
|
-
else:
|
193
|
-
block, element = path
|
194
|
-
for el in flatten(name2block[block]['value']):
|
195
|
-
if el['name'] == element:
|
196
|
-
el.__dict__ = update['data'].__dict__
|
197
|
-
break
|
198
|
-
else:
|
199
|
-
result = Event.unknown_update
|
200
|
-
return result
|
201
|
-
|
202
|
-
|
File without changes
|
File without changes
|