unisi 0.3.1__py3-none-any.whl → 0.3.2__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/server.py CHANGED
@@ -50,15 +50,14 @@ def make_user(request):
50
50
  ok = True
51
51
  else:
52
52
  user = User.type(session)
53
- ok = user.load()
54
-
53
+ ok = user.load()
55
54
  User.count += 1
56
55
  Unishare.sessions[session] = user
57
56
  return user, ok
58
57
 
59
- def handle(elem, event):
58
+ def handle(unit, event):
60
59
  def h(fn):
61
- key = elem, event
60
+ key = unit, event
62
61
  handler_map = User.last_user.handlers
63
62
  func = handler_map.get(key, None)
64
63
  if func:
@@ -89,7 +88,6 @@ async def static_serve(request):
89
88
  file_path = Path(f"{webpath}{rpath}" )
90
89
  if request.path == '/':
91
90
  file_path /= 'index.html'
92
-
93
91
  if not file_path.exists():
94
92
  file_path = None
95
93
  #unmask win path
@@ -113,7 +111,6 @@ async def websocket_handler(request):
113
111
  if type(res) != str:
114
112
  res = toJson(user.prepare_result(res))
115
113
  await ws.send_str(res)
116
-
117
114
  user.send = send
118
115
  await send(True if status else empty_app)
119
116
  try:
@@ -146,7 +143,6 @@ async def websocket_handler(request):
146
143
  except BaseException as e:
147
144
  if not isinstance(e, ConnectionResetError):
148
145
  user.log(traceback.format_exc())
149
-
150
146
  await user.delete()
151
147
  return ws
152
148
 
unisi/voicecom.py CHANGED
@@ -17,11 +17,15 @@ def find_most_similar_sequence(input_string, string_list):
17
17
  best_match = string
18
18
  return best_match, highest_ratio
19
19
 
20
- def word_to_number(sn):
20
+ def word_to_number(word: str):
21
+ sn = word.replace(',', '')
21
22
  try:
22
- return w2n.word_to_num(sn)
23
+ return float(sn)
23
24
  except:
24
- return None
25
+ try:
26
+ return w2n.word_to_num(sn)
27
+ except:
28
+ return None
25
29
 
26
30
  command_synonyms = dict( #-> words
27
31
  value = ['is', 'equals'],
@@ -47,9 +51,7 @@ modes = dict( #-> actions
47
51
  word2command = {}
48
52
  for command, syns in command_synonyms.items():
49
53
  for syn in syns:
50
- word2command[syn] = command
51
- if command in root_commands:
52
- root_commands.append(syn)
54
+ word2command[syn] = command
53
55
 
54
56
  word2command.update({command: command for command in root_commands})
55
57
  for mode, commands in modes.items():
@@ -137,15 +139,13 @@ class VoiceCom:
137
139
 
138
140
  def commands4mode(self, mode):
139
141
  if commands :=self.cached_commands.get(mode, None):
140
- return commands
142
+ self.commands = commands
141
143
  syn_commands = []
142
- commands = modes.get(mode, [])
144
+ commands = modes.get(mode, []) + root_commands
143
145
  for command in commands:
144
146
  if command in command_synonyms:
145
- syn_commands.extend(command_synonyms[command])
146
- if syn_commands:
147
- commands.extend(syn_commands)
148
- commands.extend(root_commands)
147
+ syn_commands.extend(command_synonyms[command])
148
+ commands.extend(syn_commands)
149
149
  commands.sort()
150
150
  self.cached_commands[mode] = commands
151
151
  self.commands = commands
@@ -188,17 +188,13 @@ class VoiceCom:
188
188
  match self.mode:
189
189
  case 'number'|'text':
190
190
  #double repeat command word cause execution
191
- if self.mode == 'number' and not command:
191
+ if self.mode == 'number':
192
192
  num = word_to_number(word)
193
- if num is not None:
194
- self.previous_unit_value_x = self.unit.value, self.unit.x
195
- if self.unit.x == -1:
196
- self.unit.value = num
197
- elif num >= 0 and num <= 9:
198
- snum = str(num)
199
- svalue = str(self.unit.value)
200
- self.unit.value = float(svalue[:self.unit.x] + snum + svalue[self.unit.x:])
201
- self.unit.x += 1
193
+ if command:
194
+ self.run_command(command)
195
+ elif num is not None:
196
+ self.previous_unit_value_x = self.unit.value, self.unit.x
197
+ self.unit.value = num
202
198
  else:
203
199
  self.message.value = 'Not a number'
204
200
  elif self.mode == 'text':
@@ -222,6 +218,8 @@ class VoiceCom:
222
218
  case 'select':
223
219
  if command == 'ok' and self.context:
224
220
  self.activate_unit(self.name2unit[self.context])
221
+ elif command:
222
+ self.run_command(command)
225
223
  else:
226
224
  unit_name, similarity = self.buffer_suits_name(word)
227
225
  if similarity >= 0.8:
@@ -254,10 +252,7 @@ class VoiceCom:
254
252
  self.message.value = ''
255
253
  match command:
256
254
  case 'select':
257
- self.mode = 'select'
258
- self.buffer = []
259
- self.commands = root_commands
260
- self.message.value = VoiceCom.standart_message
255
+ self.reset()
261
256
  case 'screen':
262
257
  self.context_options = [getattr(s, 'name')for s in self.user.screens
263
258
  if hasattr(s, 'name') and s.name != self.user.screen.name]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unisi
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Unified System Interface, GUI and Remote API
5
5
  Author-Email: UNISI Tech <g.dernovoy@gmail.com>
6
6
  License: Apache-2.0
@@ -43,6 +43,7 @@ UNISI technology provides a unified system interface and advanced program functi
43
43
  - Monitoring and profiling
44
44
  - Database interactions
45
45
  - LLM-RAG interactions
46
+ - Voice interaction
46
47
 
47
48
  ### Installing ###
48
49
  ```
@@ -57,7 +58,7 @@ This document serves as a comprehensive guide on utilizing Unisi with Python, al
57
58
  ### High level - Screen ###
58
59
  The program directory has to contain a screens folder which contains all screens which Unisi has to show.
59
60
 
60
- Screen example tests/screens/main.py
61
+ Screen example tests/blocks/main.py
61
62
  ```
62
63
  name = "Main"
63
64
  blocks = [block]
@@ -85,7 +86,7 @@ block = Block('X Block',
85
86
  | toolbar | Optional | list | Unit elements to show in the screen toolbar |
86
87
  | order | Optional | int | order in the program menu |
87
88
  | icon | Optional | str | MD icon of screen to show in the screen menu |
88
- | prepare | Optional | def prepare() | Syncronizes GUI elements one to another and with the program/system data. It is called before screen appearing if defined. |
89
+ | prepare | Optional | def prepare() | Syncronizes Unit/GUI elements one to another and with the program/system data. It is called before screen appearing if defined. |
89
90
 
90
91
 
91
92
  ### Server start ###
@@ -171,7 +172,7 @@ Examples of such block tests/blocks/tblock.py:
171
172
  from unisi import *
172
173
  ..
173
174
  concept_block = Block('Concept block',
174
- [ #some gui elements
175
+ [ #some Units
175
176
  Button('Run',run_proccess),
176
177
  Edit('Working folder','run_folder')
177
178
  ], result_table)
@@ -194,7 +195,7 @@ blocks = [ [b1,b2], [b3, [b4, b5]]]
194
195
  ![image](https://github.com/user-attachments/assets/16ab9909-08b3-429e-9205-9b388b10aba7)
195
196
 
196
197
  ### ParamBlock ###
197
- ParamBlock(name, *gui_elements, row = 3, **parameters)
198
+ ParamBlock(name, *units, row = 3, **parameters)
198
199
 
199
200
  ParamBlock creates blocks with Unit elements formed from parameters. Parameters can be string, bool, number and optional types. Example:
200
201
  ```
@@ -263,7 +264,7 @@ Text('Some field')
263
264
  complete handler is optional function which accepts the current edit value and returns a string list for autocomplete.
264
265
 
265
266
  ```
266
- def get_complete_list(gui_element, current_value):
267
+ def get_complete_list(unit, current_value):
267
268
  return [s for s in vocab if current_value in s]
268
269
 
269
270
  Edit('Edit me', 'value', complete = get_complete_list) #value has to be string or number
@@ -402,7 +403,7 @@ Info(info_message, *UnitforUpdades)
402
403
  Warning(warning_message, *UnitforUpdades)
403
404
  Error(error_message, *UnitforUpdades)
404
405
  ```
405
- They are returned by handlers and cause appearing on the top screen colored rectangle window for 3 second. UnitforUpdades is optional Unit enumeration for updating on GUI client side.
406
+ They are returned by handlers and cause appearing on the top screen colored rectangle window for 3 second. UnitforUpdades is optional Unit enumeration for updating on client side (GUI).
406
407
 
407
408
  For long time processes it is possible to create Progress window. It is just call user.progress in any async handler.
408
409
  Open window
@@ -513,6 +514,24 @@ Table options multimode = True and value define relation type 1 -> 1 if equals N
513
514
  UNISI is compatible with any database that implements the Database and Dbtable methods. Internally UNISI operates using the Kuzu graph database.
514
515
  For using the functionality db_dir in config.py has to be defined as a path to the database directory.
515
516
 
517
+ ### Voice interaction. ###
518
+ This functionality allows users to interact with a user interface using voice commands instead of fingers or a mouse. It facilitates voice interaction with a graphical user interface composed of various Units. It recognizes spoken words, interprets them as commands or element selections, and performs corresponding actions. The system supports various modes of interaction, including text input, number input, element selection, screen navigation, and command execution. The user speaks commands or element names. The module recognizes words and updates the Mate block, which exposes the state of the module and what it expects to listen.
519
+
520
+ #### Modes. ####
521
+ Select Mode (Default): The user can select an interactive element or switch to another mode (e.g., "screen" to change a current screen).
522
+ Text Mode: Activated when a text input element is selected. The user can dictate text, and use commands like "left," "right," "backspace," "delete," "space," "undo," and "clean."
523
+
524
+
525
+ Number Mode: Activated when a number input element is selected. The user can dictate numbers or use number-related commands.
526
+
527
+ Screen Mode: Allows the user to switch the current screen.
528
+
529
+ Command Mode: Activated when a command element is selected (e.g., a button). The user can execute the command using words like "push," "execute," or "run." Synonyms like "ok" and "okay" are also recognized.
530
+
531
+ Graph Mode: Supports graph element manipulation (nodes and edges). Currently documented but no specifics are provided on how to use it.
532
+
533
+ Table Mode: Supports table navigation and editing with commands like "page", "row", "column", "left", "right", "up", "down", "backspace", and "delete." Currently documented but no specifics are provided on how to use it.
534
+
516
535
 
517
536
  Examples are in tests folder.
518
537
 
@@ -1,7 +1,7 @@
1
- unisi-0.3.1.dist-info/METADATA,sha256=FJmY_iY8-U6nYVJ42Uiiz4F0FdefXXmGhSWAV8GAJBQ,24306
2
- unisi-0.3.1.dist-info/WHEEL,sha256=pM0IBB6ZwH3nkEPhtcp50KvKNX-07jYtnb1g1m6Z4Co,90
3
- unisi-0.3.1.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
- unisi-0.3.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
1
+ unisi-0.3.2.dist-info/METADATA,sha256=i8IJvdK52wrM7IBA1-ge8Zp397Z9PZo0WJhYey_vLbE,26062
2
+ unisi-0.3.2.dist-info/WHEEL,sha256=pM0IBB6ZwH3nkEPhtcp50KvKNX-07jYtnb1g1m6Z4Co,90
3
+ unisi-0.3.2.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
+ unisi-0.3.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
5
5
  unisi/__init__.py,sha256=JVioDSebhtmoYTldT6ChEayuRTHOgYsAflcxcBYWBTY,279
6
6
  unisi/autotest.py,sha256=qYKwSPEPUEio6koUSu1tc71pDkX-doCQJlyRppaXCtY,8709
7
7
  unisi/common.py,sha256=gaMz7PpFqz-JpiQnc9sx3HgS4UWnVzv_Xf8XAKve8q8,5386
@@ -18,12 +18,12 @@ unisi/llmrag.py,sha256=Wh9pQ8kBMlersKxbEDlZ3XeY2grH0_Rfg8I3E2W87hI,3481
18
18
  unisi/multimon.py,sha256=YKwCuvMsMfdgOGkJoqiqh_9wywXMeo9bUhHmbAIUeSE,4060
19
19
  unisi/proxy.py,sha256=QMHSSFJtmVZIexIMAsuFNlF5JpnYNG90rkTM3PYJhY4,7750
20
20
  unisi/reloader.py,sha256=5zWglaaU1zcXXNrSeyJMZW47fiHnjxbJ-CbDGREPyNk,6638
21
- unisi/server.py,sha256=W_vuWRV42metdh8u0Kf6BglnwGdm-Sgm2FktQDlbo5Y,6144
21
+ unisi/server.py,sha256=c62F_XYnj9afhxyeNkSAqVt2zsroz6GlZRtQrbZdEHA,6140
22
22
  unisi/tables.py,sha256=yF6Y2dczZoSD3fo7K14pyo3vP6A0U8dt-u4xY0SS8HU,13848
23
23
  unisi/units.py,sha256=rhZJtbZhje5C0Kc4sS1juMehcg5orOmQYpEe8KOVpzY,11004
24
24
  unisi/users.py,sha256=l7KazUJiby_jTKekS2tqT0TZNzZc6cOazGDzD-W3yHA,16040
25
25
  unisi/utils.py,sha256=NHoRMItaMleHg2UEp96_zzvrtGaZHcLNUZqmKkEwiHQ,2474
26
- unisi/voicecom.py,sha256=_F4V4HZkridNNyQN-mov3W9wIZu278Pxd0bD3oRvRFI,14189
26
+ unisi/voicecom.py,sha256=5LGuHyaAlXY8f3KHqtLtOloJ3Dtkp-rIvW0FgPacHvs,13857
27
27
  unisi/web/css/364.9c989936.css,sha256=nvhfMM7I0j4Xyec9QWuXjiwY_rw8IZzxC1M0bzBwEak,3264
28
28
  unisi/web/css/app.31d6cfe0.css,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  unisi/web/css/vendor.f7e3cefe.css,sha256=0cbvPPBV-_jv7jBIC9glq8c1QgCowWt_TxoBalHGdAs,220668
@@ -46,4 +46,4 @@ unisi/web/js/609.35dc13d3.js,sha256=v3eqMeVE666_qkm_FGKzKkZWvg8WlVjRVYJCjTqTUFE,
46
46
  unisi/web/js/935.cc0c012c.js,sha256=FzVIRBr4vyQgW38ROCoh929gtzuXqM73Cf77vejfDWk,6561
47
47
  unisi/web/js/app.99853ae7.js,sha256=DUtNxnatRpjh2Utx8Y-d81mVQYQFOcLnX6M3GdQbg8o,6150
48
48
  unisi/web/js/vendor.1bb14e9d.js,sha256=7q80jaZcms7UhWSqHAk2pXSx67cYQJGlsp-6DBXBZuU,1253597
49
- unisi-0.3.1.dist-info/RECORD,,
49
+ unisi-0.3.2.dist-info/RECORD,,
File without changes