pywebexec 2.2.0__py3-none-any.whl → 2.2.1__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.
@@ -264,42 +264,36 @@ paramsInput.addEventListener('focus', () => {
264
264
  }
265
265
  if (gExecutables[currentCmd] && gExecutables[currentCmd].schema && gExecutables[currentCmd].schema.properties && paramsContainer.style.display == 'none') {
266
266
  createSchemaForm($('#schemaForm'), gExecutables[currentCmd].schema, async function (errors, values) {
267
- if (errors) {
268
- console.log(errors);
269
- alert(errors[0].message);
270
- return false;
271
- } else {
272
- const commandName = commandInput.value;
273
- fitAddon.fit();
274
- terminal.clear();
275
- payload = { params: values, rows: terminal.rows, cols: terminal.cols }
276
- if ('parallel' in values) {
277
- payload['parallel'] = values['parallel'];
278
- payload['delay'] = values['delay'];
279
- delete payload['params']['parallel'];
280
- delete payload['params']['delay'];
281
- }
282
- try {
283
- const response = await fetch(`/commands/${commandName}`, {
284
- method: 'POST',
285
- headers: {
286
- 'Content-Type': 'application/json'
287
- },
288
- body: JSON.stringify(payload)
289
- });
290
-
291
- if (!response.ok) {
292
- throw new Error('Failed to launch command');
293
- }
294
-
295
- const data = await response.json();
296
- viewOutput(data.command_id);
297
- fetchCommands();
298
- commandInput.focus();
299
- commandInput.setSelectionRange(0, commandInput.value.length);
300
- } catch (error) {
301
- console.log('Error running command:', error);
267
+ const commandName = commandInput.value;
268
+ fitAddon.fit();
269
+ terminal.clear();
270
+ payload = { params: values, rows: terminal.rows, cols: terminal.cols }
271
+ if ('parallel' in values) {
272
+ payload['parallel'] = values['parallel'];
273
+ payload['delay'] = values['delay'];
274
+ delete payload['params']['parallel'];
275
+ delete payload['params']['delay'];
276
+ }
277
+ try {
278
+ const response = await fetch(`/commands/${commandName}`, {
279
+ method: 'POST',
280
+ headers: {
281
+ 'Content-Type': 'application/json'
282
+ },
283
+ body: JSON.stringify(payload)
284
+ });
285
+
286
+ if (!response.ok) {
287
+ throw new Error('Failed to launch command');
302
288
  }
289
+
290
+ const data = await response.json();
291
+ viewOutput(data.command_id);
292
+ fetchCommands();
293
+ commandInput.focus();
294
+ commandInput.setSelectionRange(0, commandInput.value.length);
295
+ } catch (error) {
296
+ console.log('Error running command:', error);
303
297
  }
304
298
  }, currentCmd);
305
299
  setHelpDivPosition();
@@ -54,12 +54,46 @@ function extractKeysAndPlaceholders(obj, formoptions, prefix = '') {
54
54
  return result;
55
55
  }
56
56
 
57
- function createSchemaForm(form, schema, onSubmit, schemaName) {
58
- if (schemaValues[schemaName]) {
59
- value = schemaValues[schemaName];
60
- } else {
61
- value = {};
57
+ // ...existing code...
58
+
59
+ function convertTextareaToArray(values, formDesc, schema) {
60
+ // Helper function to get schema type for a key path
61
+ function getSchemaType(schema, keyPath) {
62
+ const keys = keyPath.split('.');
63
+ let current = schema.properties;
64
+ for (const key of keys) {
65
+ if (!current || !current[key] || !current[key].properties) {
66
+ return current?.[key]?.type;
67
+ }
68
+ current = current[key].properties;
69
+ }
70
+ return null;
71
+ }
72
+
73
+ // Convert textarea values to arrays if schema type matches
74
+ for (let i = 0; i < formDesc.length; i++) {
75
+ if (formDesc[i].type == 'textarea') {
76
+ const schemaType = getSchemaType(schema, formDesc[i].key);
77
+ if (schemaType === 'array') {
78
+ const keys = formDesc[i].key.split('.');
79
+ let obj = values;
80
+ for (let j = 0; j < keys.length - 1; j++) {
81
+ obj = obj[keys[j]];
82
+ }
83
+ const lastKey = keys[keys.length - 1];
84
+ const val = obj[lastKey];
85
+ if (val) {
86
+ obj[lastKey] = val.trim().split(/[\s\r,]+/).filter(x => x);
87
+ }
88
+ }
89
+ }
62
90
  }
91
+ return values;
92
+ }
93
+
94
+ // ...existing code...
95
+
96
+ function createSchemaForm(form, schema, onSubmit, schemaName) {
63
97
  if (schema && schema.schema_options) {
64
98
  schema_options = schema.schema_options;
65
99
  } else {
@@ -80,6 +114,33 @@ function createSchemaForm(form, schema, onSubmit, schemaName) {
80
114
  }
81
115
  }
82
116
  formDesc = extractKeysAndPlaceholders(schema, formoptions);
117
+ if (schemaValues[schemaName]) {
118
+ value = schemaValues[schemaName];
119
+ // convert array for textarea formDesc type to string separated by newlines
120
+ // if in formDesc a key has type textarea, convert the value to string separated by newlines
121
+ // formDesc=[{key: 'db.sid', type: 'textarea'}]
122
+ // value = {db: {sid: ['AA', 'BB']}}
123
+ // convert to
124
+ // value = {db: {sid: 'AA\nBB'}}
125
+ for (let i = 0; i < formDesc.length; i++) {
126
+ if (formDesc[i].type === 'textarea') {
127
+ const keys = formDesc[i].key.split('.');
128
+ let obj = value;
129
+ for (let j = 0; j < keys.length - 1; j++) {
130
+ if (!(keys[j] in obj)) obj[keys[j]] = {};
131
+ obj = obj[keys[j]];
132
+ }
133
+ const lastKey = keys[keys.length - 1];
134
+ const val = obj[lastKey];
135
+ if (val && Array.isArray(val)) {
136
+ obj[lastKey] = val.join('\n');
137
+ }
138
+ }
139
+ }
140
+ } else {
141
+ value = {};
142
+ }
143
+
83
144
  schemaForm = form[0];
84
145
  if (onSubmit != null) {
85
146
  if (schema_options && schema_options.batch_param) {
@@ -149,9 +210,20 @@ function createSchemaForm(form, schema, onSubmit, schemaName) {
149
210
  form[0].classList.add('form-inline');
150
211
  jsform = form.jsonForm({
151
212
  schema: schema,
152
- onSubmit: onSubmit,
213
+ onSubmit: function (errors, values) {
214
+ convertTextareaToArray(values, formDesc, schema);
215
+ env = JSV.createEnvironment();
216
+ report = env.validate(values, schema);
217
+ errors = report.errors;
218
+ if (errors.length > 0) {
219
+ alert(errors[0].message);
220
+ return false;
221
+ }
222
+ onSubmit(errors, values);
223
+ },
153
224
  form: formDesc,
154
225
  value: value,
226
+ validate: false,
155
227
  // params: {
156
228
  // fieldHtmlClass: "input-small",
157
229
  // }
@@ -168,9 +240,8 @@ function createSchemaForm(form, schema, onSubmit, schemaName) {
168
240
  txt.setAttribute("spellcheck", "false");
169
241
  txt.addEventListener("input", () => adjustTxtHeight(txt));
170
242
  });
171
-
172
243
  form[0].addEventListener('input', () => {
173
- schemaValues[schemaName] = jsform.root.getFormValues();
244
+ schemaValues[schemaName] = convertTextareaToArray(jsform.root.getFormValues(), formDesc, schema);
174
245
  localStorage.setItem('schemaValues', JSON.stringify(schemaValues));
175
246
  });
176
247
 
@@ -265,7 +265,6 @@ async function viewOutput(command_id) {
265
265
  } else {
266
266
  command = `${data.command.replace(/^\.\//, '')} ${data.params.join(' ')}`;
267
267
  }
268
- console.log(command);
269
268
  setCommandStatus(data.status)
270
269
  commandInfo.innerHTML = command;
271
270
  commandInfo.setAttribute('title', command);
@@ -1,8 +1,9 @@
1
1
  let ui;
2
2
  let swaggerSchemas = {};
3
+
3
4
  function addFormInputListener(textArea, jsform){
4
5
  return function (event) {
5
- jsonString = JSON.stringify(jsform.root.getFormValues(), null, 2);
6
+ jsonString = JSON.stringify(convertTextareaToArray(jsform.root.getFormValues(), jsform.formDesc.form, jsform.formDesc.schema), null, 2);
6
7
  textArea.value = jsonString;
7
8
 
8
9
  // Find the React fiber node
@@ -107,7 +108,8 @@ window.onload = function() {
107
108
  form.id = routePathId;
108
109
  form.classList.add("schema-form");
109
110
  jsform = createSchemaForm($(form), swaggerSchemas[routePath], null, routePath);
110
- // form.addEventListener("input", formInput(node, jsform));
111
+ // form.addEventListener("input", formInput(node, jsform));
112
+ setTimeout(() => addFormInputListener(paramtext, jsform)(), 100);
111
113
  form.addEventListener("input", addFormInputListener(paramtext, jsform));
112
114
  paramtext.parentNode.insertBefore(form, paramtext.nextSibling);
113
115
  item1 = form.querySelector("input, select, textarea");
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.2.0'
21
- __version_tuple__ = version_tuple = (2, 2, 0)
20
+ __version__ = version = '2.2.1'
21
+ __version_tuple__ = version_tuple = (2, 2, 1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 2.2.0
3
+ Version: 2.2.1
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -2,7 +2,7 @@ pywebexec/__init__.py,sha256=197fHJy0UDBwTTpGCGortZRr-w2kTaD7MxqdbVmTEi0,61
2
2
  pywebexec/host_ip.py,sha256=Ud_HTflWVQ8789aoQ2RZdT1wGI-ccvrwSWGz_c7T3TI,1241
3
3
  pywebexec/pywebexec.py,sha256=R-jp9BiUMJZW7m9N9kQC6dpIueUgFVDo4n9_GFb1rOs,45734
4
4
  pywebexec/swagger.yaml,sha256=I_oLpp7Hqel8SDEEykvpmCT-Gv3ytGlziq9bvQOrtZY,7598
5
- pywebexec/version.py,sha256=wdFcRBeaWRZXknL-E8RTk9hV9M-OMto6dfJ90sc1i9A,511
5
+ pywebexec/version.py,sha256=wUUonx5HNvzUsCYrR_oek7De76IsD1eqg46c4ZbWiDg,511
6
6
  pywebexec/static/css/form.css,sha256=eApJskeJ3MCzC7_p4gXgoIbvbG5s8m4bP1O4KHHqeiA,5293
7
7
  pywebexec/static/css/markdown.css,sha256=br4-iK9wigTs54N2KHtjgZ4KLH0THVSvJo-XZAdMHiE,1970
8
8
  pywebexec/static/css/style.css,sha256=R1VOPNV2ztROKy9Fgf3tvUrtuKagY027tFJ8C866yWU,9991
@@ -33,11 +33,11 @@ pywebexec/static/images/resume.svg,sha256=99LP1Ya2JXakRCO9kW8JMuT_4a_CannF65Eiuw
33
33
  pywebexec/static/images/running.svg,sha256=fBCYwYb2O9K4N3waC2nURP25NRwZlqR4PbDZy6JQMww,610
34
34
  pywebexec/static/images/success.svg,sha256=NVwezvVMplt46ElW798vqGfrL21Mw_DWHUp_qiD_FU8,489
35
35
  pywebexec/static/images/swagger-ui.svg,sha256=FR0yeOVwe4zCYKZAjCGcT_m0Mf25NexIVaSXifIkoU0,2117
36
- pywebexec/static/js/executables.js,sha256=2ZSlsEMbfATr1EwUJMEAoS5G_wSUuWgT6AVQijawvtE,12160
36
+ pywebexec/static/js/executables.js,sha256=lF9Icb4VzbxSCTmcz-TUjvFKQ_ygmSgPq0Q_uaTRR-g,11866
37
37
  pywebexec/static/js/popup.js,sha256=O3DEWnyb5yGW9tjODYycc-ujWndyAfnJMxulaQeogtc,9700
38
- pywebexec/static/js/schemaform.js,sha256=GtIfd5YBaEr-KC1vXvZPFa5sYWRqdcjvP0Ozl7mr0YQ,6474
39
- pywebexec/static/js/script.js,sha256=sMOwgeRi59X0QyTTI58SqC4Sp_F7pK5JfozCkJMOHjs,18234
40
- pywebexec/static/js/swagger-form.js,sha256=sW7cUYJnd1ZZSMaMqaB2LCkjB1tfvSkdcAr-eW6UpZU,4430
38
+ pywebexec/static/js/schemaform.js,sha256=uYlu8P6Y1adEGefzsRhLT-gwS27TZsLwzDGs2UBgDGk,8808
39
+ pywebexec/static/js/script.js,sha256=X5TN2q1m6ZGPK72e1MWgyQWk1agOrcOWuGdwVWB9HJk,18204
40
+ pywebexec/static/js/swagger-form.js,sha256=EYXqHIE105DkXPCPi5-eYzux9nPLmJuisf-5EwFypsQ,4578
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
43
43
  pywebexec/static/js/marked/LICENSE.md,sha256=jjo_gvWaYJWPVsoI9EVkfDKkcz3HymwsRvbriYRxq5w,2942
@@ -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=9ngyldkyEdLonBjl97mbIZUlVk-jxwcHrvFzMSrveyU,1067
70
- pywebexec-2.2.0.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
71
- pywebexec-2.2.0.dist-info/METADATA,sha256=PdGpfSzOG74LxsHEY8AUmPw5l_gsGIjChSTJIAKjxIk,12810
72
- pywebexec-2.2.0.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
73
- pywebexec-2.2.0.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
74
- pywebexec-2.2.0.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
75
- pywebexec-2.2.0.dist-info/RECORD,,
70
+ pywebexec-2.2.1.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
71
+ pywebexec-2.2.1.dist-info/METADATA,sha256=UWTzS7NVz171aeuAw2z8nEdeg5ggBeKEEISktYdU8ms,12810
72
+ pywebexec-2.2.1.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
73
+ pywebexec-2.2.1.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
74
+ pywebexec-2.2.1.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
75
+ pywebexec-2.2.1.dist-info/RECORD,,