pywebexec 2.2.0__py3-none-any.whl → 2.2.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.
- pywebexec/static/css/form.css +13 -0
- pywebexec/static/js/executables.js +29 -35
- pywebexec/static/js/schemaform.js +81 -8
- pywebexec/static/js/script.js +0 -1
- pywebexec/static/js/swagger-form.js +4 -2
- pywebexec/version.py +2 -2
- {pywebexec-2.2.0.dist-info → pywebexec-2.2.2.dist-info}/METADATA +3 -2
- {pywebexec-2.2.0.dist-info → pywebexec-2.2.2.dist-info}/RECORD +12 -12
- {pywebexec-2.2.0.dist-info → pywebexec-2.2.2.dist-info}/WHEEL +1 -1
- {pywebexec-2.2.0.dist-info → pywebexec-2.2.2.dist-info}/entry_points.txt +0 -0
- {pywebexec-2.2.0.dist-info → pywebexec-2.2.2.dist-info/licenses}/LICENSE +0 -0
- {pywebexec-2.2.0.dist-info → pywebexec-2.2.2.dist-info}/top_level.txt +0 -0
pywebexec/static/css/form.css
CHANGED
@@ -211,6 +211,19 @@
|
|
211
211
|
box-shadow: unset;
|
212
212
|
outline: 0;
|
213
213
|
}
|
214
|
+
.controls > .checkbox input {
|
215
|
+
top: 5px;
|
216
|
+
}
|
217
|
+
.checkbox {
|
218
|
+
label {
|
219
|
+
font-weight: normal;
|
220
|
+
}
|
221
|
+
input {
|
222
|
+
top: 1px;
|
223
|
+
display: unset;
|
224
|
+
margin-right: 4px;
|
225
|
+
}
|
226
|
+
}
|
214
227
|
}
|
215
228
|
|
216
229
|
.swagger-ui textarea {
|
@@ -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
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
payload
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
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,48 @@ function extractKeysAndPlaceholders(obj, formoptions, prefix = '') {
|
|
54
54
|
return result;
|
55
55
|
}
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
+
} else {
|
88
|
+
delete obj[lastKey];
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
62
92
|
}
|
93
|
+
return values;
|
94
|
+
}
|
95
|
+
|
96
|
+
// ...existing code...
|
97
|
+
|
98
|
+
function createSchemaForm(form, schema, onSubmit, schemaName) {
|
63
99
|
if (schema && schema.schema_options) {
|
64
100
|
schema_options = schema.schema_options;
|
65
101
|
} else {
|
@@ -80,6 +116,33 @@ function createSchemaForm(form, schema, onSubmit, schemaName) {
|
|
80
116
|
}
|
81
117
|
}
|
82
118
|
formDesc = extractKeysAndPlaceholders(schema, formoptions);
|
119
|
+
if (schemaValues[schemaName]) {
|
120
|
+
value = schemaValues[schemaName];
|
121
|
+
// convert array for textarea formDesc type to string separated by newlines
|
122
|
+
// if in formDesc a key has type textarea, convert the value to string separated by newlines
|
123
|
+
// formDesc=[{key: 'db.sid', type: 'textarea'}]
|
124
|
+
// value = {db: {sid: ['AA', 'BB']}}
|
125
|
+
// convert to
|
126
|
+
// value = {db: {sid: 'AA\nBB'}}
|
127
|
+
for (let i = 0; i < formDesc.length; i++) {
|
128
|
+
if (formDesc[i].type === 'textarea') {
|
129
|
+
const keys = formDesc[i].key.split('.');
|
130
|
+
let obj = value;
|
131
|
+
for (let j = 0; j < keys.length - 1; j++) {
|
132
|
+
if (!(keys[j] in obj)) obj[keys[j]] = {};
|
133
|
+
obj = obj[keys[j]];
|
134
|
+
}
|
135
|
+
const lastKey = keys[keys.length - 1];
|
136
|
+
const val = obj[lastKey];
|
137
|
+
if (val && Array.isArray(val)) {
|
138
|
+
obj[lastKey] = val.join('\n');
|
139
|
+
}
|
140
|
+
}
|
141
|
+
}
|
142
|
+
} else {
|
143
|
+
value = {};
|
144
|
+
}
|
145
|
+
|
83
146
|
schemaForm = form[0];
|
84
147
|
if (onSubmit != null) {
|
85
148
|
if (schema_options && schema_options.batch_param) {
|
@@ -149,9 +212,20 @@ function createSchemaForm(form, schema, onSubmit, schemaName) {
|
|
149
212
|
form[0].classList.add('form-inline');
|
150
213
|
jsform = form.jsonForm({
|
151
214
|
schema: schema,
|
152
|
-
onSubmit:
|
215
|
+
onSubmit: function (errors, values) {
|
216
|
+
convertTextareaToArray(values, formDesc, schema);
|
217
|
+
env = JSV.createEnvironment();
|
218
|
+
report = env.validate(values, schema);
|
219
|
+
errors = report.errors;
|
220
|
+
if (errors.length > 0) {
|
221
|
+
alert(errors[0].message);
|
222
|
+
return false;
|
223
|
+
}
|
224
|
+
onSubmit(errors, values);
|
225
|
+
},
|
153
226
|
form: formDesc,
|
154
227
|
value: value,
|
228
|
+
validate: false,
|
155
229
|
// params: {
|
156
230
|
// fieldHtmlClass: "input-small",
|
157
231
|
// }
|
@@ -168,9 +242,8 @@ function createSchemaForm(form, schema, onSubmit, schemaName) {
|
|
168
242
|
txt.setAttribute("spellcheck", "false");
|
169
243
|
txt.addEventListener("input", () => adjustTxtHeight(txt));
|
170
244
|
});
|
171
|
-
|
172
245
|
form[0].addEventListener('input', () => {
|
173
|
-
schemaValues[schemaName] = jsform.root.getFormValues();
|
246
|
+
schemaValues[schemaName] = convertTextareaToArray(jsform.root.getFormValues(), formDesc, schema);
|
174
247
|
localStorage.setItem('schemaValues', JSON.stringify(schemaValues));
|
175
248
|
});
|
176
249
|
|
pywebexec/static/js/script.js
CHANGED
@@ -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
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: pywebexec
|
3
|
-
Version: 2.2.
|
3
|
+
Version: 2.2.2
|
4
4
|
Summary: Simple Python HTTP Exec Server
|
5
5
|
Home-page: https://github.com/joknarf/pywebexec
|
6
6
|
Author: Franck Jouvanceau
|
@@ -62,6 +62,7 @@ Requires-Dist: ldap3>=2.9.1
|
|
62
62
|
Requires-Dist: pyte>=0.8.1
|
63
63
|
Requires-Dist: PyYAML>=6.0.1
|
64
64
|
Requires-Dist: run-para>=1.0.2
|
65
|
+
Dynamic: license-file
|
65
66
|
|
66
67
|
[](https://pypi.org/project/pywebexec/)
|
67
68
|

|
@@ -2,8 +2,8 @@ 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=
|
6
|
-
pywebexec/static/css/form.css,sha256=
|
5
|
+
pywebexec/version.py,sha256=YDBduKhVnvbZfZTbXbsjQMbxTwgIIXIZ646Mj9YV074,511
|
6
|
+
pywebexec/static/css/form.css,sha256=HnQ4A7QSQu1lC6P8h4hGpUMtOXujNg8SR1_qteu7oDk,5487
|
7
7
|
pywebexec/static/css/markdown.css,sha256=br4-iK9wigTs54N2KHtjgZ4KLH0THVSvJo-XZAdMHiE,1970
|
8
8
|
pywebexec/static/css/style.css,sha256=R1VOPNV2ztROKy9Fgf3tvUrtuKagY027tFJ8C866yWU,9991
|
9
9
|
pywebexec/static/css/swagger-ui.css,sha256=xhXN8fnUaIACGHuPIEIr9-qmyYr6Zx0k2wv4Qy7Bg1Y,154985
|
@@ -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=
|
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=
|
39
|
-
pywebexec/static/js/script.js,sha256=
|
40
|
-
pywebexec/static/js/swagger-form.js,sha256=
|
38
|
+
pywebexec/static/js/schemaform.js,sha256=NLMAnS2GpyhGp286HUBqQXJAAQaqFMtJ03rGVrh8JaM,8856
|
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.
|
71
|
-
pywebexec-2.2.
|
72
|
-
pywebexec-2.2.
|
73
|
-
pywebexec-2.2.
|
74
|
-
pywebexec-2.2.
|
75
|
-
pywebexec-2.2.
|
70
|
+
pywebexec-2.2.2.dist-info/licenses/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
|
71
|
+
pywebexec-2.2.2.dist-info/METADATA,sha256=6wl5EJ2M1Oww4Pn6Pu5wRAIqf0cHv6DixTl4jv5ICf4,12832
|
72
|
+
pywebexec-2.2.2.dist-info/WHEEL,sha256=tTnHoFhvKQHCh4jz3yCn0WPTYIy7wXx3CJtJ7SJGV7c,91
|
73
|
+
pywebexec-2.2.2.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
|
74
|
+
pywebexec-2.2.2.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
|
75
|
+
pywebexec-2.2.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|