pywebexec 2.3.9__py3-none-any.whl → 2.3.11__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.
@@ -44,7 +44,7 @@
44
44
  }
45
45
  .btn-primary {
46
46
  position: relative;
47
- margin-bottom: 10px;
47
+ margin-bottom: 20px;
48
48
  height: 24px;
49
49
  top: 20px;
50
50
  color: #fff;
@@ -224,13 +224,17 @@
224
224
  }
225
225
  ul ~ ._jsonform-array-buttons {
226
226
  display: block;
227
+ }
228
+ li > fieldset {
227
229
  width: 100%;
230
+ margin-bottom: 3px;
228
231
  }
229
232
  ._jsonform-array-buttons {
230
- /* display: block; */
231
- /* width: 100%; */
232
233
  text-align: right;
233
234
  }
235
+ ul._jsonform-array-ul > li > div.form-group {
236
+ width: 100%;
237
+ }
234
238
  i[title="Delete current"] {
235
239
  top: 5px;
236
240
  }
@@ -253,7 +257,7 @@
253
257
  }
254
258
  .alert {
255
259
  padding: 5px 10px;
256
- margin-bottom: 2px;
260
+ margin-top: 10px;
257
261
  border: 1px solid transparent;
258
262
  border-radius: 15px;
259
263
  font-size: 14px;
@@ -292,10 +296,12 @@
292
296
  border: 1px solid #ccc;
293
297
  border-radius: 5px;
294
298
  padding-top: 9px;
299
+ height: fit-content;
295
300
  /* width: 100%; */
296
301
  label {
297
302
  padding-right: 5px;
298
303
  }
304
+
299
305
  }
300
306
  fieldset > div {
301
307
  /* display: block ruby; */
@@ -11,7 +11,7 @@ function adjustInputWidth(input) {
11
11
  if (input.scrollWidth > 0) {
12
12
  input.style.width = `${input.scrollWidth + delta}px`;
13
13
  } else {
14
- input.style.width = `${input.value.length * 11 + delta}px`;
14
+ input.style.width = `${input.value.length * 10 + 20}px`;
15
15
  }
16
16
 
17
17
  }
@@ -144,35 +144,30 @@ function validateSchemaForm(form, formDesc, schema, values, schemaName) {
144
144
  }
145
145
 
146
146
  function createSchemaForm($form, schema, onSubmit, schemaName) {
147
+ schema_options = undefined;
148
+ schema_params_options = undefined;
147
149
  if (schema && schema.schema_options) {
148
150
  schema_options = schema.schema_options;
149
- } else {
150
- schema_options = {};
151
151
  }
152
152
  if (schema && schema.properties && schema.properties.params && schema.properties.params.schema_options) {
153
153
  schema_params_options = schema.properties.params.schema_options;
154
- } else {
155
- schema_params_options = {};
156
154
  }
157
155
 
158
156
  formkeys = {};
159
157
  formoptions = {};
160
158
  if (schema_options) {
161
- formkeys = schema.schema_options.form || {};
162
- formoptions = schema.schema_options.formoptions || {};
163
- } else {
164
- if (schema_params_options) {
165
- let fkeys = schema_params_options.form || {};
166
- let foptions = schema_params_options.formoptions || {};
167
- for (let key in fkeys) {
168
- formkeys[`params.${key}`] = fkeys[key];
169
- }
170
- for (let key in foptions) {
171
- formoptions[`params.${key}`] = foptions[key];
172
- }
159
+ formkeys = schema_options.form || {}
160
+ formoptions = schema_options.formoptions || {};
161
+ } else if (schema_params_options) {
162
+ let fkeys = schema_params_options.form || {};
163
+ let foptions = schema_params_options.formoptions || {};
164
+ for (let key in fkeys) {
165
+ formkeys[`params.${key}`] = fkeys[key];
166
+ }
167
+ for (let key in foptions) {
168
+ formoptions[`params.${key}`] = foptions[key];
173
169
  }
174
170
  }
175
-
176
171
  formDesc = extractKeysAndPlaceholders(schema, formkeys, formoptions);
177
172
  if (schemaValues[schemaName]) {
178
173
  value = schemaValues[schemaName];
@@ -251,7 +246,7 @@ function createSchemaForm($form, schema, onSubmit, schemaName) {
251
246
  }
252
247
  }
253
248
  }
254
- if (formoptions) {
249
+ if (Object.keys(formoptions).length) {
255
250
  items = [];
256
251
  for (let key in formoptions) {
257
252
  items.push({
@@ -307,6 +302,22 @@ function createSchemaForm($form, schema, onSubmit, schemaName) {
307
302
  }
308
303
  }
309
304
  }
305
+ if (formoptions) {
306
+ items = [];
307
+ for (let key in formoptions) {
308
+ items.push({
309
+ key: key,
310
+ ... formoptions[key],
311
+ });
312
+ }
313
+ formDesc.push({
314
+ type: 'fieldset',
315
+ title: 'Options',
316
+ fieldHtmlClass: 'fieldsetoptions',
317
+ expandable: true,
318
+ items: items,
319
+ });
320
+ }
310
321
  }
311
322
  // schemaForm.classList.add('form-inline');
312
323
  jsform = $form.jsonForm({
pywebexec/version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '2.3.9'
21
- __version_tuple__ = version_tuple = (2, 3, 9)
20
+ __version__ = version = '2.3.11'
21
+ __version_tuple__ = version_tuple = (2, 3, 11)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pywebexec
3
- Version: 2.3.9
3
+ Version: 2.3.11
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -1,11 +1,9 @@
1
1
  pywebexec/__init__.py,sha256=197fHJy0UDBwTTpGCGortZRr-w2kTaD7MxqdbVmTEi0,61
2
- pywebexec/cmdscript.py,sha256=TCYfWTPYn5LEWiMPm0zc9iyHm2AV4uH5E-gOL3hGoDc,6182
3
- pywebexec/cmdscript.py.ok,sha256=nWB11LXjQahCUwJ8jK0XuU1ekoMyN9Zu_FaOdVTpOwk,2859
4
2
  pywebexec/host_ip.py,sha256=oiCMlo2o3AkkgXDarUSx8T3FWXKI0vk1-EPnx5FGBd8,1332
5
3
  pywebexec/pywebexec.py,sha256=1M5CtxKr5YkEMBhuVSrwnMNcVRuf7iQf-uxF4Lf0ouQ,48375
6
4
  pywebexec/swagger.yaml,sha256=I_oLpp7Hqel8SDEEykvpmCT-Gv3ytGlziq9bvQOrtZY,7598
7
- pywebexec/version.py,sha256=xD7sq7tXCC-QKVs2SPi2bsTgQhH6dVLkP6dvZaxMKcA,511
8
- pywebexec/static/css/form.css,sha256=jScx_gUwW0RyrYZJsn6z6vBsBAAgV-zva63folDPNtA,7160
5
+ pywebexec/version.py,sha256=a5XAzJslSZuuV5AcA8qIp59T1qgt9ZCq0ijQ9uRPsf8,513
6
+ pywebexec/static/css/form.css,sha256=riFFi02xtUXusTTZOU3RSZykutJWMFfK65-eR5RbhY8,7252
9
7
  pywebexec/static/css/markdown.css,sha256=br4-iK9wigTs54N2KHtjgZ4KLH0THVSvJo-XZAdMHiE,1970
10
8
  pywebexec/static/css/style.css,sha256=pUmylXwbFIoXrdaJRVOUohlKIhOIilapH97NyIlgGV4,10343
11
9
  pywebexec/static/css/swagger-ui.css,sha256=xhXN8fnUaIACGHuPIEIr9-qmyYr6Zx0k2wv4Qy7Bg1Y,154985
@@ -37,7 +35,7 @@ pywebexec/static/images/success.svg,sha256=NVwezvVMplt46ElW798vqGfrL21Mw_DWHUp_q
37
35
  pywebexec/static/images/swagger-ui.svg,sha256=FR0yeOVwe4zCYKZAjCGcT_m0Mf25NexIVaSXifIkoU0,2117
38
36
  pywebexec/static/js/executables.js,sha256=cTgCFHr_F9bFCirtfG_uR32vOY3vNUr4Ih3Wglj5lFc,11988
39
37
  pywebexec/static/js/popup.js,sha256=IaKmk2U2hEn-Nv6krf_PPW6LaG8NcpCkJKb7lUX0qZo,11457
40
- pywebexec/static/js/schemaform.js,sha256=oo4G8XqtL-iDCuq_HULgmYx5YOwY-c9166Wi7C1iAWQ,11919
38
+ pywebexec/static/js/schemaform.js,sha256=OdHhwhSRi-ps_LiQX14vAeyNlnKgzKw3fXUl9nzoT6c,12231
41
39
  pywebexec/static/js/script.js,sha256=TI3TSylgBxh_a6QvYWlg4CyJ6LMPxnhFl8WRtRDGD0Y,20810
42
40
  pywebexec/static/js/swagger-form.js,sha256=CLcSHMhk5P4-_2MIRBoJLgEnIj_9keDDSzUugXHZjio,4565
43
41
  pywebexec/static/js/js-yaml/LICENSE,sha256=oHvCRGi5ZUznalR9R6LbKC0HcztxXbTHOpi9Y5YflVA,1084
@@ -69,9 +67,9 @@ pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
69
67
  pywebexec/templates/index.html,sha256=w18O2plH_yS8bqlPsu5hwFFmCj9H2hWLSV8B6ADcSwU,3900
70
68
  pywebexec/templates/popup.html,sha256=3kpMccKD_OLLhJ4Y9KRw6Ny8wQWjVaRrUfV9y5-bDiQ,1580
71
69
  pywebexec/templates/swagger_ui.html,sha256=MAPr-z96VERAecDvX37V8q2Nxph-O0fNDBul1x2w9SI,1147
72
- pywebexec-2.3.9.dist-info/licenses/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
73
- pywebexec-2.3.9.dist-info/METADATA,sha256=mapKSx2-T9t0PuRG5sCWF0yaGGLzg081Q8FD75-5hDQ,13015
74
- pywebexec-2.3.9.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
75
- pywebexec-2.3.9.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
76
- pywebexec-2.3.9.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
77
- pywebexec-2.3.9.dist-info/RECORD,,
70
+ pywebexec-2.3.11.dist-info/licenses/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
71
+ pywebexec-2.3.11.dist-info/METADATA,sha256=p4PmUdP846ada5-3UH44cvT5sEUfT1NeKPVoDHaGTVM,13016
72
+ pywebexec-2.3.11.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
73
+ pywebexec-2.3.11.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
74
+ pywebexec-2.3.11.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
75
+ pywebexec-2.3.11.dist-info/RECORD,,
pywebexec/cmdscript.py DELETED
@@ -1,150 +0,0 @@
1
- import os
2
- import sys
3
- import msvcrt
4
- import shutil
5
- import time
6
- import signal
7
- from datetime import datetime
8
- from winpty import PTY, WinptyError
9
-
10
- class CmdInteractive:
11
- def __init__(self, logfile=None):
12
- self.logfile = logfile
13
- cols, rows = shutil.get_terminal_size()
14
- self.pty = PTY(cols, rows)
15
- # Set up Ctrl+C handling
16
- signal.signal(signal.SIGINT, self._handle_sigint)
17
- self.pid = self.pty.spawn('cmd.exe')
18
- if not self.pid:
19
- raise RuntimeError("Failed to spawn cmd.exe")
20
- self.command_buffer = []
21
- self.history = []
22
- self.history_index = 0
23
- self.cursor_pos = 0 # Track cursor position in command buffer
24
-
25
- def _handle_sigint(self, signum, frame):
26
- """Handle Ctrl+C by forwarding it to the child process"""
27
- try:
28
- self.pty.write('\x03')
29
- except:
30
- pass
31
-
32
- def log(self, text, direction='>>'):
33
- if self.logfile:
34
- timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
35
- with open(self.logfile, 'a', encoding='utf-8') as f:
36
- f.write(f'{timestamp} {direction} {text}')
37
-
38
- def handle_special_key(self, char):
39
- """Handle special key sequences"""
40
- if char == b'\xe0': # Extended key
41
- key = msvcrt.getch()
42
- if key == b'H': # Up arrow
43
- if self.history and self.history_index > 0:
44
- self.history_index -= 1
45
- cmd = self.history[self.history_index]
46
- self._replace_line(cmd)
47
- elif key == b'P': # Down arrow
48
- if self.history_index < len(self.history) - 1:
49
- self.history_index += 1
50
- cmd = self.history[self.history_index]
51
- self._replace_line(cmd)
52
- elif key == b'K': # Left arrow
53
- if self.cursor_pos > 0:
54
- self.cursor_pos -= 1
55
- self.pty.write('\x1b[D')
56
- elif key == b'M': # Right arrow
57
- if self.cursor_pos < len(self.command_buffer):
58
- self.cursor_pos += 1
59
- self.pty.write('\x1b[C')
60
- return True
61
- return False
62
-
63
- def _replace_line(self, new_text):
64
- """Replace current line with new text"""
65
- # Clear current line
66
- self.pty.write('\r' + ' ' * len(self.command_buffer) + '\r')
67
- # Write new line
68
- self.command_buffer = list(new_text)
69
- self.cursor_pos = len(self.command_buffer)
70
- self.pty.write(''.join(self.command_buffer))
71
-
72
- def interact(self):
73
- try:
74
- while True:
75
- try:
76
- try:
77
- output = self.pty.read()
78
- if output:
79
- if isinstance(output, str):
80
- output = output.encode('utf-8')
81
- sys.stdout.buffer.write(output)
82
- sys.stdout.buffer.flush()
83
- self.log(output.decode('utf-8', errors='replace'), '>>')
84
- except (EOFError, WinptyError):
85
- break
86
-
87
- if msvcrt.kbhit():
88
- char = msvcrt.getch()
89
- if self.handle_special_key(char):
90
- continue
91
-
92
- if char == b'\r': # Enter
93
- self.pty.write('\r\n')
94
- if self.command_buffer:
95
- cmd = ''.join(self.command_buffer)
96
- self.history.append(cmd)
97
- self.history_index = len(self.history)
98
- self.command_buffer = []
99
- self.cursor_pos = 0
100
- elif char == b'\x08': # Backspace
101
- if self.cursor_pos > 0:
102
- # Remove character at cursor position
103
- self.command_buffer.pop(self.cursor_pos - 1)
104
- self.cursor_pos -= 1
105
- # Rewrite the line from cursor position
106
- remain = ''.join(self.command_buffer[self.cursor_pos:])
107
- self.pty.write('\x08' + remain + ' ')
108
- # Move cursor back to position
109
- if remain:
110
- self.pty.write('\x1b[' + str(len(remain)) + 'D')
111
- elif char == b'\x03': # Ctrl+C
112
- self.pty.write('\x03')
113
- self.command_buffer = []
114
- self.cursor_pos = 0
115
- continue
116
- else:
117
- # Insert character at cursor position
118
- if isinstance(char, bytes):
119
- char = char.decode('cp437', errors='replace')
120
- self.command_buffer.insert(self.cursor_pos, char)
121
- self.cursor_pos += 1
122
- # Write new char and remaining text
123
- remain = ''.join(self.command_buffer[self.cursor_pos-1:])
124
- self.pty.write(remain)
125
- # Move cursor back if needed
126
- if self.cursor_pos < len(self.command_buffer):
127
- self.pty.write('\x1b[' + str(len(remain)-1) + 'D')
128
- self.log(char, '<<')
129
-
130
- except (IOError, OSError) as e:
131
- if "handle is closed" in str(e):
132
- break
133
- raise
134
-
135
- except KeyboardInterrupt:
136
- pass
137
- finally:
138
- self.close()
139
-
140
- def close(self):
141
- if hasattr(self, 'pty'):
142
- del self.pty
143
-
144
- if __name__ == '__main__':
145
- log_file = 'cmd_session.log'
146
- try:
147
- cmd = CmdInteractive(log_file)
148
- cmd.interact()
149
- except ImportError:
150
- print("Please install pywinpty: pip install pywinpty")
pywebexec/cmdscript.py.ok DELETED
@@ -1,85 +0,0 @@
1
- import os
2
- import sys
3
- import msvcrt
4
- import shutil
5
- import time
6
- import signal
7
- from datetime import datetime
8
- from winpty import PTY, WinptyError
9
-
10
- class CmdInteractive:
11
- def __init__(self, logfile=None):
12
- self.logfile = logfile
13
- cols, rows = shutil.get_terminal_size()
14
- self.pty = PTY(cols, rows)
15
- # Set up Ctrl+C handling
16
- signal.signal(signal.SIGINT, self._handle_sigint)
17
- self.pid = self.pty.spawn('cmd.exe')
18
- if not self.pid:
19
- raise RuntimeError("Failed to spawn cmd.exe")
20
-
21
- def _handle_sigint(self, signum, frame):
22
- """Handle Ctrl+C by forwarding it to the child process"""
23
- try:
24
- self.pty.write('\x03')
25
- except:
26
- pass
27
-
28
- def log(self, text, direction='>>'):
29
- if self.logfile:
30
- timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
31
- with open(self.logfile, 'a', encoding='utf-8') as f:
32
- f.write(f'{timestamp} {direction} {text}')
33
-
34
- def interact(self):
35
- try:
36
- while True:
37
- try:
38
- try:
39
- output = self.pty.read()
40
- if output:
41
- if isinstance(output, str):
42
- output = output.encode('utf-8')
43
- sys.stdout.buffer.write(output)
44
- sys.stdout.buffer.flush()
45
- self.log(output.decode('utf-8', errors='replace'), '>>')
46
- except (EOFError, WinptyError):
47
- break
48
-
49
- if msvcrt.kbhit():
50
- char = msvcrt.getch()
51
- if char == b'\x03': # Ctrl+C
52
- # Forward Ctrl+C to child process
53
- self.pty.write('\x03')
54
- continue
55
- if char == b'\x1d': # Ctrl+]
56
- break
57
- if isinstance(char, bytes):
58
- char = char.decode('cp437', errors='replace')
59
- try:
60
- self.pty.write(char)
61
- self.log(char, '<<')
62
- except (EOFError, WinptyError):
63
- break
64
-
65
- except (IOError, OSError) as e:
66
- if "handle is closed" in str(e):
67
- break
68
- raise
69
-
70
- except KeyboardInterrupt:
71
- pass
72
- finally:
73
- self.close()
74
-
75
- def close(self):
76
- if hasattr(self, 'pty'):
77
- del self.pty
78
-
79
- if __name__ == '__main__':
80
- log_file = 'cmd_session.log'
81
- try:
82
- cmd = CmdInteractive(log_file)
83
- cmd.interact()
84
- except ImportError:
85
- print("Please install pywinpty: pip install pywinpty")