unisi 0.2.8__py3-none-any.whl → 0.2.9__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 +2 -2
- unisi/autotest.py +1 -0
- unisi/common.py +3 -0
- unisi/containers.py +27 -27
- unisi/dbunits.py +1 -0
- unisi/graphs.py +1 -0
- unisi/kdb.py +1 -0
- unisi/llmrag.py +1 -0
- unisi/multimon.py +1 -0
- unisi/proxy.py +1 -0
- unisi/reloader.py +1 -0
- unisi/server.py +61 -0
- unisi/tables.py +1 -0
- unisi/units.py +35 -5
- unisi/users.py +19 -78
- unisi/utils.py +5 -2
- unisi/voicecom.py +194 -72
- unisi/web/css/{748.d3c09c5d.css → 450.f5cbf6d1.css} +1 -1
- unisi/web/index.html +1 -1
- unisi/web/js/450.ea87a6d5.js +1 -0
- unisi/web/js/app.7317dfbe.js +1 -0
- {unisi-0.2.8.dist-info → unisi-0.2.9.dist-info}/METADATA +2 -4
- {unisi-0.2.8.dist-info → unisi-0.2.9.dist-info}/RECORD +26 -26
- {unisi-0.2.8.dist-info → unisi-0.2.9.dist-info}/WHEEL +1 -1
- unisi/web/js/748.213707d6.js +0 -1
- unisi/web/js/app.8df2e0ff.js +0 -1
- {unisi-0.2.8.dist-info → unisi-0.2.9.dist-info}/entry_points.txt +0 -0
- {unisi-0.2.8.dist-info → unisi-0.2.9.dist-info}/licenses/LICENSE +0 -0
unisi/__init__.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
from .utils import *
|
2
2
|
from .units import *
|
3
|
-
from .users import User
|
4
|
-
from .server import start
|
3
|
+
from .users import User
|
4
|
+
from .server import start, handle, context_user, context_screen
|
5
5
|
from .tables import *
|
6
6
|
from .containers import *
|
7
7
|
from .proxy import *
|
unisi/autotest.py
CHANGED
unisi/common.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# Copyright © 2024 UNISI Tech. All rights reserved.
|
1
2
|
import jsonpickle, inspect, asyncio
|
2
3
|
|
3
4
|
UpdateScreen = True
|
@@ -64,6 +65,8 @@ def set_defaults(self, param_defaults : dict):
|
|
64
65
|
setattr(self, param, value)
|
65
66
|
|
66
67
|
def pretty4(name):
|
68
|
+
if name.startswith('_'):
|
69
|
+
name = name[1:]
|
67
70
|
pretty_name = name.replace('_',' ')
|
68
71
|
return pretty_name[0].upper() + pretty_name[1:]
|
69
72
|
|
unisi/containers.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# Copyright © 2024 UNISI Tech. All rights reserved.
|
1
2
|
from .units import *
|
2
3
|
from .common import pretty4, flatten, delete_unit
|
3
4
|
from numbers import Number
|
@@ -50,8 +51,7 @@ class Block(Unit):
|
|
50
51
|
user = Unishare.context_user()
|
51
52
|
if hasattr(self,'closable'):
|
52
53
|
def close(*_):
|
53
|
-
delete_unit(user.screen.blocks, self.name)
|
54
|
-
return Redesign
|
54
|
+
delete_unit(user.screen.blocks, self.name)
|
55
55
|
self.close = close
|
56
56
|
|
57
57
|
self.set_reactivity(user)
|
@@ -95,26 +95,26 @@ class ParamBlock(Block):
|
|
95
95
|
|
96
96
|
for param, val in params.items():
|
97
97
|
pretty_name = pretty4(param)
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
98
|
+
match val:
|
99
|
+
case True | False:
|
100
|
+
el = Switch(pretty_name, val)
|
101
|
+
case str() | int() | float():
|
102
|
+
el = Edit(pretty_name, val)
|
103
|
+
case tuple() | list():
|
104
|
+
if len(val) != 2:
|
105
|
+
raise ValueError('Composite value has to contain the current value and options value!')
|
106
|
+
options = val[1]
|
107
|
+
if not isinstance(options, list | tuple | dict):
|
108
|
+
raise ValueError('Options value (the second parameter) has to be a list or tuple!')
|
109
|
+
if len(options) == 3 and all(map(lambda e: isinstance(e, Number), options)):
|
110
|
+
el = Range(pretty_name, val[0], options = options)
|
111
|
+
elif isinstance(options, list | tuple):
|
112
|
+
el = Select(pretty_name, val[0], options = options, type = 'select')
|
113
|
+
else:
|
114
|
+
el = Tree(pretty_name, val[0], options = options)
|
115
|
+
case _:
|
116
|
+
raise ValueError(f'The {param} value {val} is not supported. Look at ParamBlock documentation!')
|
117
|
+
|
118
118
|
self.name2elem[param] = el
|
119
119
|
|
120
120
|
if cnt % row == 0:
|
@@ -136,9 +136,9 @@ class Dialog:
|
|
136
136
|
self.icon = icon
|
137
137
|
self.value = [[], *content] if content else []
|
138
138
|
|
139
|
-
class Screen:
|
140
|
-
def __init__(self, name
|
141
|
-
self.
|
142
|
-
self.
|
143
|
-
self.type = 'screen'
|
139
|
+
class Screen(Unit):
|
140
|
+
def __init__(self, name):
|
141
|
+
self._mark_changed = None
|
142
|
+
self.name = name
|
143
|
+
self.type = 'screen'
|
144
144
|
|
unisi/dbunits.py
CHANGED
unisi/graphs.py
CHANGED
unisi/kdb.py
CHANGED
unisi/llmrag.py
CHANGED
unisi/multimon.py
CHANGED
unisi/proxy.py
CHANGED
unisi/reloader.py
CHANGED
unisi/server.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# Copyright © 2024 UNISI Tech. All rights reserved.
|
1
2
|
from aiohttp import web, WSMsgType
|
2
3
|
from .users import *
|
3
4
|
from pathlib import Path
|
@@ -6,9 +7,69 @@ from .autotest import recorder, run_tests
|
|
6
7
|
from .common import *
|
7
8
|
from.llmrag import setup_llmrag
|
8
9
|
from .dbunits import dbupdates
|
10
|
+
from .kdb import Database
|
9
11
|
from config import port, upload_dir
|
10
12
|
import traceback, json
|
11
13
|
|
14
|
+
def context_user():
|
15
|
+
return context_object(User)
|
16
|
+
|
17
|
+
def context_screen():
|
18
|
+
user = context_user()
|
19
|
+
return user.screen if user else None
|
20
|
+
|
21
|
+
def message_logger(str, type = 'error'):
|
22
|
+
user = context_user()
|
23
|
+
user.log(str, type)
|
24
|
+
|
25
|
+
Unishare.context_user = context_user
|
26
|
+
Unishare.message_logger = message_logger
|
27
|
+
User.type = User
|
28
|
+
|
29
|
+
if config.db_dir:
|
30
|
+
Unishare.db = Database(config.db_dir, message_logger)
|
31
|
+
|
32
|
+
def make_user(request):
|
33
|
+
session = f'{request.remote}-{User.count}'
|
34
|
+
if requested_connect := request.query_string if config.share else None:
|
35
|
+
user = Unishare.sessions.get(requested_connect, None)
|
36
|
+
if not user:
|
37
|
+
error = f'Session id "{requested_connect}" is unknown. Connection refused!'
|
38
|
+
with logging_lock:
|
39
|
+
logging.error(error)
|
40
|
+
return None, Error(error)
|
41
|
+
user = User.type(session, user)
|
42
|
+
ok = user.screens
|
43
|
+
elif config.mirror and User.count:
|
44
|
+
user = User.type(session, User.last_user)
|
45
|
+
ok = user.screens
|
46
|
+
elif not User.count:
|
47
|
+
user = User.last_user
|
48
|
+
user.session = session
|
49
|
+
user.monitor(session)
|
50
|
+
ok = True
|
51
|
+
else:
|
52
|
+
user = User.type(session)
|
53
|
+
ok = user.load()
|
54
|
+
|
55
|
+
User.count += 1
|
56
|
+
Unishare.sessions[session] = user
|
57
|
+
return user, ok
|
58
|
+
|
59
|
+
def handle(elem, event):
|
60
|
+
def h(fn):
|
61
|
+
key = elem, event
|
62
|
+
handler_map = User.last_user.__handlers__
|
63
|
+
func = handler_map.get(key, None)
|
64
|
+
if func:
|
65
|
+
handler_map[key] = compose_handlers(func, fn)
|
66
|
+
else:
|
67
|
+
handler_map[key] = fn
|
68
|
+
return fn
|
69
|
+
return h
|
70
|
+
|
71
|
+
Unishare.handle = handle
|
72
|
+
|
12
73
|
async def post_handler(request):
|
13
74
|
reader = await request.multipart()
|
14
75
|
field = await reader.next()
|
unisi/tables.py
CHANGED
unisi/units.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# Copyright © 2024 UNISI Tech. All rights reserved.
|
1
2
|
from .common import *
|
2
3
|
from .llmrag import get_property
|
3
4
|
|
@@ -22,13 +23,26 @@ class ChangedProxy:
|
|
22
23
|
elif not callable(value) and not isinstance(value, atomics):
|
23
24
|
return ChangedProxy(value, self)
|
24
25
|
return value
|
26
|
+
|
27
|
+
def __setattr__(self, name, value):
|
28
|
+
if name in ('_obj', '_unit'):
|
29
|
+
super().__setattr__(name, value)
|
30
|
+
else:
|
31
|
+
self._obj.__setattr__(name, value)
|
32
|
+
self._unit._mark_changed()
|
25
33
|
|
26
34
|
def __setitem__(self, key, value):
|
27
35
|
self._obj[key] = value
|
28
36
|
self._unit._mark_changed ()
|
29
37
|
|
30
38
|
def __getitem__(self, key):
|
31
|
-
|
39
|
+
value = self._obj[key]
|
40
|
+
if not callable(value) and not isinstance(value, atomics):
|
41
|
+
value = ChangedProxy(value, self._unit)
|
42
|
+
return value
|
43
|
+
|
44
|
+
def __eq__(self, other):
|
45
|
+
return self._obj.__eq__(other._obj) if isinstance(other, ChangedProxy) else self._obj.__eq__(other)
|
32
46
|
|
33
47
|
def __delitem__(self, key):
|
34
48
|
del self._obj[key]
|
@@ -42,6 +56,16 @@ class ChangedProxy:
|
|
42
56
|
return len(self._obj)
|
43
57
|
except TypeError:
|
44
58
|
return 0
|
59
|
+
|
60
|
+
def __hash__(self):
|
61
|
+
return hash(self._obj)
|
62
|
+
|
63
|
+
def __iadd__(self, other):
|
64
|
+
if isinstance(self._obj, list):
|
65
|
+
self.extend(other)
|
66
|
+
return self # Important: __iadd__ must return self
|
67
|
+
|
68
|
+
raise TypeError(f"Unsupported operand type for += with '{type(self._obj).__name__}'")
|
45
69
|
|
46
70
|
def __getstate__(self):
|
47
71
|
return self._obj
|
@@ -81,9 +105,7 @@ class Unit:
|
|
81
105
|
|
82
106
|
def __setattr__(self, name, value):
|
83
107
|
#it is correct condition order
|
84
|
-
if name != "
|
85
|
-
if name != "__dict__" and not isinstance(value, atomics) and not callable(value):
|
86
|
-
value = ChangedProxy(value, self)
|
108
|
+
if name[0] != "_" and self._mark_changed:
|
87
109
|
self._mark_changed(name, value)
|
88
110
|
super().__setattr__(name, value)
|
89
111
|
|
@@ -103,7 +125,13 @@ class Unit:
|
|
103
125
|
def delattr(self, attr):
|
104
126
|
if hasattr(self, attr):
|
105
127
|
delattr(self, attr)
|
106
|
-
|
128
|
+
|
129
|
+
def __eq__(self, other):
|
130
|
+
return super().__eq__(other._obj) if isinstance(other, ChangedProxy) else super().__eq__(other)
|
131
|
+
|
132
|
+
def __hash__(self):
|
133
|
+
return super().__hash__()
|
134
|
+
|
107
135
|
@property
|
108
136
|
def compact_view(self) -> str:
|
109
137
|
"""reduce for external (llm) using if required"""
|
@@ -153,6 +181,7 @@ def smart_complete(lst, min_input_length = 0, max_output_length = 20):
|
|
153
181
|
class Edit(Unit):
|
154
182
|
def __init__(self, name, *args, **kwargs):
|
155
183
|
super().__init__(name, *args, **kwargs)
|
184
|
+
self.x = -1
|
156
185
|
has_value = hasattr(self,'value')
|
157
186
|
if 'type' not in kwargs:
|
158
187
|
if has_value:
|
@@ -263,6 +292,7 @@ class Tree(Unit):
|
|
263
292
|
class TextArea(Unit):
|
264
293
|
def __init__(self,name, *args, **kwargs):
|
265
294
|
super().__init__(name, *args, **kwargs)
|
295
|
+
self.x = -1
|
266
296
|
self.type = 'text'
|
267
297
|
|
268
298
|
|
unisi/users.py
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
+
# Copyright © 2024 UNISI Tech. All rights reserved.
|
1
2
|
from .utils import *
|
2
3
|
from .units import *
|
3
4
|
from .common import *
|
4
5
|
from .voicecom import VoiceCom
|
5
6
|
from .containers import Dialog, Screen
|
6
7
|
from .multimon import notify_monitor, logging_lock, run_external_process
|
7
|
-
from .kdb import Database
|
8
8
|
from .dbunits import dbshare, dbupdates
|
9
9
|
import sys, asyncio, logging, importlib
|
10
10
|
|
@@ -79,7 +79,7 @@ class User:
|
|
79
79
|
module.user = self
|
80
80
|
|
81
81
|
spec.loader.exec_module(module)
|
82
|
-
screen = Screen(getattr(module, 'name', ''))
|
82
|
+
screen = Screen(getattr(module, 'name', ''))
|
83
83
|
#set system vars
|
84
84
|
for var, val in screen.defaults.items():
|
85
85
|
setattr(screen, var, getattr(module, var, val))
|
@@ -89,22 +89,23 @@ class User:
|
|
89
89
|
screen.toolbar += User.toolbar
|
90
90
|
else:
|
91
91
|
screen.toolbar = User.toolbar
|
92
|
-
|
92
|
+
screen.set_reactivity(self)
|
93
|
+
module.screen = screen#ChangedProxy(screen, screen)
|
93
94
|
return module
|
94
95
|
|
95
96
|
async def delete(self):
|
96
97
|
uss = Unishare.sessions
|
97
98
|
if uss and uss.get(self.session):
|
98
|
-
del uss[self.session]
|
99
|
-
|
99
|
+
del uss[self.session]
|
100
100
|
if self.reflections: #reflections is common array
|
101
101
|
if len(self.reflections) == 2:
|
102
102
|
self.reflections.clear() #1 element in user.reflections has no sense
|
103
103
|
else:
|
104
104
|
self.reflections.remove(self)
|
105
|
-
|
106
105
|
if notify_monitor:
|
107
106
|
await notify_monitor('-', self.session, self.last_message)
|
107
|
+
if config.share:
|
108
|
+
self.log(f'User is disconnected, session: {self.session}', type = 'info')
|
108
109
|
|
109
110
|
def set_clean(self):
|
110
111
|
#remove user modules from sys
|
@@ -145,7 +146,7 @@ class User:
|
|
145
146
|
def screen(self):
|
146
147
|
return self.screen_module.screen
|
147
148
|
|
148
|
-
def set_screen(self,name):
|
149
|
+
def set_screen(self,name):
|
149
150
|
return asyncio.run(self.process(ArgObject(block = 'root', element = None, value = name)))
|
150
151
|
|
151
152
|
async def result4message(self, message):
|
@@ -217,10 +218,10 @@ class User:
|
|
217
218
|
return ['toolbar', e.name]
|
218
219
|
|
219
220
|
def prepare_result(self, raw):
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
raw =
|
221
|
+
reload_screen = self.screen in self.changed_units
|
222
|
+
if reload_screen or raw is True or raw == Redesign:
|
223
|
+
self.screen.reload = reload_screen or raw == Redesign
|
224
|
+
raw = self.screen
|
224
225
|
else:
|
225
226
|
match raw:
|
226
227
|
case None:
|
@@ -261,17 +262,16 @@ class User:
|
|
261
262
|
error = f'Unknown screen name: {message.value}'
|
262
263
|
self.log(error)
|
263
264
|
return Error(error)
|
264
|
-
elif message.voice_type:
|
265
|
-
created = False
|
265
|
+
elif message.voice_type:
|
266
266
|
if not self.voice:
|
267
|
-
self.voice = VoiceCom(self)
|
268
|
-
created = True
|
267
|
+
self.voice = VoiceCom(self)
|
269
268
|
if message.event == 'listen':
|
270
|
-
|
269
|
+
if message.value:
|
270
|
+
self.voice.start()
|
271
|
+
else:
|
272
|
+
self.voice.stop()
|
271
273
|
else:
|
272
|
-
self.voice.
|
273
|
-
if created:
|
274
|
-
return Redesign
|
274
|
+
self.voice.process_word(message.value)
|
275
275
|
else:
|
276
276
|
elem = self.find_element(message)
|
277
277
|
if elem:
|
@@ -358,62 +358,3 @@ class User:
|
|
358
358
|
sync_calls.append(user.send(update4user))
|
359
359
|
dbupdates.clear()
|
360
360
|
await asyncio.gather(*sync_calls)
|
361
|
-
|
362
|
-
def context_user():
|
363
|
-
return context_object(User)
|
364
|
-
|
365
|
-
def context_screen():
|
366
|
-
user = context_user()
|
367
|
-
return user.screen if user else None
|
368
|
-
|
369
|
-
def message_logger(str, type = 'error'):
|
370
|
-
user = context_user()
|
371
|
-
user.log(str, type)
|
372
|
-
|
373
|
-
Unishare.context_user = context_user
|
374
|
-
Unishare.message_logger = message_logger
|
375
|
-
User.type = User
|
376
|
-
|
377
|
-
if config.db_dir:
|
378
|
-
Unishare.db = Database(config.db_dir, message_logger)
|
379
|
-
|
380
|
-
def make_user(request):
|
381
|
-
session = f'{request.remote}-{User.count}'
|
382
|
-
if requested_connect := request.query_string if config.share else None:
|
383
|
-
user = Unishare.sessions.get(requested_connect, None)
|
384
|
-
if not user:
|
385
|
-
error = f'Session id "{requested_connect}" is unknown. Connection refused!'
|
386
|
-
with logging_lock:
|
387
|
-
logging.error(error)
|
388
|
-
return None, Error(error)
|
389
|
-
user = User.type(session, user)
|
390
|
-
ok = user.screens
|
391
|
-
elif config.mirror and User.count:
|
392
|
-
user = User.type(session, User.last_user)
|
393
|
-
ok = user.screens
|
394
|
-
elif not User.count:
|
395
|
-
user = User.last_user
|
396
|
-
user.session = session
|
397
|
-
user.monitor(session)
|
398
|
-
ok = True
|
399
|
-
else:
|
400
|
-
user = User.type(session)
|
401
|
-
ok = user.load()
|
402
|
-
|
403
|
-
User.count += 1
|
404
|
-
Unishare.sessions[session] = user
|
405
|
-
return user, ok
|
406
|
-
|
407
|
-
def handle(elem, event):
|
408
|
-
def h(fn):
|
409
|
-
key = elem, event
|
410
|
-
handler_map = User.last_user.__handlers__
|
411
|
-
func = handler_map.get(key, None)
|
412
|
-
if func:
|
413
|
-
handler_map[key] = compose_handlers(func, fn)
|
414
|
-
else:
|
415
|
-
handler_map[key] = fn
|
416
|
-
return fn
|
417
|
-
return h
|
418
|
-
|
419
|
-
Unishare.handle = handle
|
unisi/utils.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# Copyright © 2024 UNISI Tech. All rights reserved.
|
1
2
|
import os, platform, requests, logging
|
2
3
|
from .common import set_defaults
|
3
4
|
from .containers import Screen
|
@@ -41,7 +42,8 @@ set_defaults(config, dict(
|
|
41
42
|
froze_time= None,
|
42
43
|
monitor_tick = 0.005,
|
43
44
|
pool = None,
|
44
|
-
db_dir = None
|
45
|
+
db_dir = None,
|
46
|
+
lang = 'en-US'
|
45
47
|
))
|
46
48
|
|
47
49
|
Screen.defaults = dict(
|
@@ -51,7 +53,8 @@ Screen.defaults = dict(
|
|
51
53
|
header = config.appname,
|
52
54
|
toolbar = [],
|
53
55
|
order = 0,
|
54
|
-
reload = config.hot_reload
|
56
|
+
reload = config.hot_reload,
|
57
|
+
lang = config.lang
|
55
58
|
)
|
56
59
|
|
57
60
|
if config.froze_time == 0:
|