pywebexec 2.3.4__py3-none-any.whl → 2.3.5__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.
pywebexec/pywebexec.py CHANGED
@@ -921,6 +921,8 @@ def run_dynamic_command(cmd):
921
921
  if value:
922
922
  params += f"{prefix} "
923
923
  continue
924
+ if prefix and not value: # skip empty params with prefix
925
+ continue
924
926
  if isinstance(value, dict) or convert_values.get(param, None) == "json":
925
927
  value = shlex.quote(json.dumps(value, indent=2, sort_keys=False))
926
928
  elif convert_values.get(param, None) == "quote":
@@ -123,6 +123,7 @@
123
123
  margin-top: 0px;
124
124
  margin-bottom: 1px;
125
125
  padding: 0;
126
+ padding-right: 10px;
126
127
  }
127
128
  input[type="checkbox"] {
128
129
  display: block;
@@ -148,6 +149,21 @@
148
149
  .controls input[type="text"] {
149
150
  width: 110px;;
150
151
  }
152
+
153
+ .controls > div:not([id]) { /* for checkboxes */
154
+ scrollbar-width: thin;
155
+ scrollbar-gutter: stable;
156
+ overflow-y: auto;
157
+ max-height: 100px;
158
+ border: solid 1px #ccc;
159
+ border-radius: 5px;
160
+ padding: 5px 2px;
161
+ }
162
+ .controls > div.range {
163
+ overflow-y: hidden;
164
+ padding: 0px 5px;
165
+ }
166
+
151
167
  input[type="number"] {
152
168
  max-width: 120px;
153
169
  text-align: right;
@@ -201,9 +217,13 @@
201
217
  ._jsonform-array-deletelast {
202
218
  display: none;
203
219
  }
204
- ._jsonform-array-buttons {
220
+ ul ~ ._jsonform-array-buttons {
205
221
  display: block;
206
222
  width: 100%;
223
+ }
224
+ ._jsonform-array-buttons {
225
+ /* display: block; */
226
+ /* width: 100%; */
207
227
  text-align: right;
208
228
  }
209
229
  i[title="Delete current"] {
@@ -237,6 +257,34 @@
237
257
  background-color: #f2dede;
238
258
  border-color: #ebccd1;
239
259
  }
260
+ #reset-form:hover {
261
+ background-color: #e8e8e8;
262
+ border-color: #adadad;
263
+ }
264
+ #reset-form {
265
+ position: relative;
266
+ margin-bottom: 10px;
267
+ height: 24px;
268
+ top: 20px;
269
+ background-color: #f5f5f5;
270
+ border-color: #ccc;
271
+ height: 24px;
272
+ color: #333;
273
+ padding: 3px 13px;
274
+ }
275
+ fieldset {
276
+ border: 1px solid #ccc;
277
+ border-radius: 5px;
278
+ padding-top: 9px;
279
+ width: 100%;
280
+ label {
281
+ padding-right: 5px;
282
+ }
283
+ }
284
+ fieldset > div {
285
+ /* display: block ruby; */
286
+ padding-bottom: 5px;
287
+ }
240
288
  }
241
289
 
242
290
  .swagger-ui textarea {
@@ -53,7 +53,34 @@ function extractKeysAndPlaceholders(obj, formoptions, prefix = '') {
53
53
  return result;
54
54
  }
55
55
 
56
- // ...existing code...
56
+
57
+ // Convert objects to JSON strings where schema type is object without properties
58
+ function convertObjectsToJsonStrings(obj, schema, prefix = '') {
59
+ // Helper function to get schema type and check for properties
60
+ function getSchemaTypeForKey(schema, keyPath) {
61
+ const keys = keyPath.split('.');
62
+ let current = schema.properties;
63
+ for (const key of keys) {
64
+ if (!current || !current[key]) return null;
65
+ current = current[key];
66
+ }
67
+ return current;
68
+ }
69
+
70
+ for (const key in obj) {
71
+ const keyPath = prefix ? `${prefix}.${key}` : key;
72
+ const schemaType = getSchemaTypeForKey(schema, keyPath);
73
+
74
+ if (schemaType && schemaType.type === 'object' && !schemaType.properties) {
75
+ if (typeof obj[key] === 'object' && obj[key] !== null) {
76
+ obj[key] = JSON.stringify(obj[key], null, 2);
77
+ }
78
+ } else if (typeof obj[key] === 'object' && obj[key] !== null) {
79
+ convertObjectsToJsonStrings(obj[key], schema, keyPath);
80
+ }
81
+ }
82
+ }
83
+
57
84
 
58
85
  function convertTextareaToArray(values, formDesc, schema) {
59
86
  // Helper function to get schema type for a key path
@@ -107,6 +134,7 @@ function validateSchemaForm(form, formDesc, schema, values, schemaName) {
107
134
  err.style.display = 'none';
108
135
  return true;
109
136
  }
137
+
110
138
  function createSchemaForm($form, schema, onSubmit, schemaName) {
111
139
  if (schema && schema.schema_options) {
112
140
  schema_options = schema.schema_options;
@@ -151,6 +179,7 @@ function createSchemaForm($form, schema, onSubmit, schemaName) {
151
179
  }
152
180
  }
153
181
  }
182
+ convertObjectsToJsonStrings(value, schema);
154
183
  } else {
155
184
  value = {};
156
185
  }
@@ -205,8 +234,27 @@ function createSchemaForm($form, schema, onSubmit, schemaName) {
205
234
  }
206
235
  }
207
236
  formDesc.push({
208
- type: 'submit',
209
- title: 'Run',
237
+ type: 'actions',
238
+ items: [
239
+ {
240
+ type: 'submit',
241
+ title: 'Run',
242
+ id: 'run-form',
243
+ },
244
+ {
245
+ type: 'button',
246
+ title: 'Reset',
247
+ id: 'reset-form',
248
+ onClick: function (evt) {
249
+ console.log('reset');
250
+ evt.preventDefault();
251
+ evt.stopPropagation();
252
+ evt.stopImmediatePropagation();
253
+ schemaValues[schemaName] = {};
254
+ createSchemaForm($form, schema, onSubmit, schemaName);
255
+ },
256
+ },
257
+ ],
210
258
  });
211
259
  } else {
212
260
  if (schema_params_options && schema_params_options.batch_param) {
@@ -308,5 +356,3 @@ async function getPostParametersSchema() {
308
356
  let schemaForm;
309
357
  // let inputHandlers = [];
310
358
  let schemaValues = JSON.parse(localStorage.getItem('schemaValues')) || {};
311
-
312
-
@@ -222,10 +222,20 @@ async function fetchOutput(url) {
222
222
  fullOutput = fullOutput.slice(-maxSize);
223
223
 
224
224
  if (data.status != 'running') {
225
- const htmlContent = extractHtml(fullOutput);
226
- if (htmlContent) {
227
- document.getElementById('output').innerHTML = htmlContent;
228
- document.getElementById('output').classList.add('outputhtml');
225
+ if (data.status === 'success') {
226
+ const htmlContent = extractHtml(fullOutput);
227
+ if (htmlContent) {
228
+ document.getElementById('output').innerHTML = htmlContent;
229
+ document.getElementById('output').classList.add('outputhtml');
230
+ } else {
231
+ if (slider.value == 1000)
232
+ terminal.write(data.output);
233
+ else {
234
+ percentage = Math.round((outputLength * 1000)/fullOutput.length);
235
+ slider.value = percentage;
236
+ outputPercentage.innerText = `${Math.floor(percentage/10)}%`;
237
+ }
238
+ }
229
239
  } else {
230
240
  if (slider.value == 1000)
231
241
  terminal.write(data.output);
@@ -303,14 +313,18 @@ async function viewOutput(command_id) {
303
313
  const outputResponse = await fetch(nextOutputLink);
304
314
  const outputData = await outputResponse.json();
305
315
  const output = outputData.output;
306
- const htmlContent = extractHtml(output);
307
- if (htmlContent) {
308
- document.getElementById('output').innerHTML = htmlContent;
309
- document.getElementById('output').classList.add('outputhtml');
316
+ document.getElementById('output').classList.remove('outputhtml');
317
+ document.getElementById('output').innerHTML = '';
318
+ document.getElementById('output').appendChild(terminal.element);
319
+ if (data.status === 'success') {
320
+ const htmlContent = extractHtml(output);
321
+ if (htmlContent) {
322
+ document.getElementById('output').innerHTML = htmlContent;
323
+ document.getElementById('output').classList.add('outputhtml');
324
+ } else {
325
+ terminal.write(output);
326
+ }
310
327
  } else {
311
- document.getElementById('output').classList.remove('outputhtml');
312
- document.getElementById('output').innerHTML = '';
313
- document.getElementById('output').appendChild(terminal.element);
314
328
  terminal.write(output);
315
329
  }
316
330
  toggleButton.style.display = 'none';
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.4'
21
- __version_tuple__ = version_tuple = (2, 3, 4)
20
+ __version__ = version = '2.3.5'
21
+ __version_tuple__ = version_tuple = (2, 3, 5)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pywebexec
3
- Version: 2.3.4
3
+ Version: 2.3.5
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -1,9 +1,9 @@
1
1
  pywebexec/__init__.py,sha256=197fHJy0UDBwTTpGCGortZRr-w2kTaD7MxqdbVmTEi0,61
2
2
  pywebexec/host_ip.py,sha256=oiCMlo2o3AkkgXDarUSx8T3FWXKI0vk1-EPnx5FGBd8,1332
3
- pywebexec/pywebexec.py,sha256=LD917ZeDVnOSMuLWPkl9JT1baaDvZ_e0Yk7RTs5yBfk,48273
3
+ pywebexec/pywebexec.py,sha256=1M5CtxKr5YkEMBhuVSrwnMNcVRuf7iQf-uxF4Lf0ouQ,48375
4
4
  pywebexec/swagger.yaml,sha256=I_oLpp7Hqel8SDEEykvpmCT-Gv3ytGlziq9bvQOrtZY,7598
5
- pywebexec/version.py,sha256=uwWN-nUjSdzfl2KBdAxl_KFIRtDM-6vnPwbujKx_J2g,511
6
- pywebexec/static/css/form.css,sha256=XC_0ES5yMHYz0S2OHR0RAboQN7fBUmg5ZIq8Qm5rHP0,5806
5
+ pywebexec/version.py,sha256=yuw-MeUgld_ZQvHY-ySzAKeJ1b7eRT6gVg14nwqZJYY,511
6
+ pywebexec/static/css/form.css,sha256=vfB0wEHETHWR3vyjkjm3M84CV3vh82yUxAsN8I3UwKg,6757
7
7
  pywebexec/static/css/markdown.css,sha256=br4-iK9wigTs54N2KHtjgZ4KLH0THVSvJo-XZAdMHiE,1970
8
8
  pywebexec/static/css/style.css,sha256=9P46lB-YLCYWRKIG58h_6Goj49ImAMxcWibh_uyrmDo,10308
9
9
  pywebexec/static/css/swagger-ui.css,sha256=xhXN8fnUaIACGHuPIEIr9-qmyYr6Zx0k2wv4Qy7Bg1Y,154985
@@ -35,8 +35,8 @@ pywebexec/static/images/success.svg,sha256=NVwezvVMplt46ElW798vqGfrL21Mw_DWHUp_q
35
35
  pywebexec/static/images/swagger-ui.svg,sha256=FR0yeOVwe4zCYKZAjCGcT_m0Mf25NexIVaSXifIkoU0,2117
36
36
  pywebexec/static/js/executables.js,sha256=cTgCFHr_F9bFCirtfG_uR32vOY3vNUr4Ih3Wglj5lFc,11988
37
37
  pywebexec/static/js/popup.js,sha256=IaKmk2U2hEn-Nv6krf_PPW6LaG8NcpCkJKb7lUX0qZo,11457
38
- pywebexec/static/js/schemaform.js,sha256=NlFXFKJI53izxPXct3a5XiB1RhWGt0_EIp6o1HfsryU,9624
39
- pywebexec/static/js/script.js,sha256=Baj26fNeBV1_dFV3nqa75Y_B534M6D_3VALRxp6qeNo,20155
38
+ pywebexec/static/js/schemaform.js,sha256=57FeWNWJT1zW9sG3ujZEOG7vLoiHif5ROQZori2QNMg,11131
39
+ pywebexec/static/js/script.js,sha256=TI3TSylgBxh_a6QvYWlg4CyJ6LMPxnhFl8WRtRDGD0Y,20810
40
40
  pywebexec/static/js/swagger-form.js,sha256=CLcSHMhk5P4-_2MIRBoJLgEnIj_9keDDSzUugXHZjio,4565
41
41
  pywebexec/static/js/js-yaml/LICENSE,sha256=oHvCRGi5ZUznalR9R6LbKC0HcztxXbTHOpi9Y5YflVA,1084
42
42
  pywebexec/static/js/js-yaml/js-yaml.min.js,sha256=Rdw90D3AegZwWiwpibjH9wkBPwS9U4bjJ51ORH8H69c,39430
@@ -67,9 +67,9 @@ pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
67
67
  pywebexec/templates/index.html,sha256=w18O2plH_yS8bqlPsu5hwFFmCj9H2hWLSV8B6ADcSwU,3900
68
68
  pywebexec/templates/popup.html,sha256=3kpMccKD_OLLhJ4Y9KRw6Ny8wQWjVaRrUfV9y5-bDiQ,1580
69
69
  pywebexec/templates/swagger_ui.html,sha256=MAPr-z96VERAecDvX37V8q2Nxph-O0fNDBul1x2w9SI,1147
70
- pywebexec-2.3.4.dist-info/licenses/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
71
- pywebexec-2.3.4.dist-info/METADATA,sha256=h0SQW-btDQIC76B1kbUZc2M-PRX7wnQOyKWcHj1hf4Q,13015
72
- pywebexec-2.3.4.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
73
- pywebexec-2.3.4.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
74
- pywebexec-2.3.4.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
75
- pywebexec-2.3.4.dist-info/RECORD,,
70
+ pywebexec-2.3.5.dist-info/licenses/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
71
+ pywebexec-2.3.5.dist-info/METADATA,sha256=ip0nBVVxyEqlIrNJwuV0BCWPKYpjZcRAAZRCOan5tuk,13015
72
+ pywebexec-2.3.5.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
73
+ pywebexec-2.3.5.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
74
+ pywebexec-2.3.5.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
75
+ pywebexec-2.3.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.0.2)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5