pywebexec 1.7.6__py3-none-any.whl → 1.7.9__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 +12 -12
- pywebexec/static/js/popup.js +1 -0
- pywebexec/static/js/script.js +9 -2
- pywebexec/version.py +2 -2
- {pywebexec-1.7.6.dist-info → pywebexec-1.7.9.dist-info}/METADATA +2 -2
- {pywebexec-1.7.6.dist-info → pywebexec-1.7.9.dist-info}/RECORD +10 -10
- {pywebexec-1.7.6.dist-info → pywebexec-1.7.9.dist-info}/LICENSE +0 -0
- {pywebexec-1.7.6.dist-info → pywebexec-1.7.9.dist-info}/WHEEL +0 -0
- {pywebexec-1.7.6.dist-info → pywebexec-1.7.9.dist-info}/entry_points.txt +0 -0
- {pywebexec-1.7.6.dist-info → pywebexec-1.7.9.dist-info}/top_level.txt +0 -0
pywebexec/pywebexec.py
CHANGED
@@ -492,33 +492,31 @@ def script(output_file):
|
|
492
492
|
p.interact()
|
493
493
|
|
494
494
|
|
495
|
-
def run_command(fromip, user, command, params, command_id):
|
495
|
+
def run_command(fromip, user, command, params, command_id, rows, cols):
|
496
496
|
# app.logger.info(f'{fromip} run_command {command_id} {user}: {command} {params}')
|
497
497
|
log_info(fromip, user, f'run_command {command_id}: {command_str(command, params)}')
|
498
|
-
start_time = datetime.now().isoformat()
|
498
|
+
start_time = datetime.now(timezone.utc).isoformat()
|
499
499
|
update_command_status(command_id, {
|
500
500
|
'status': 'running',
|
501
501
|
'command': command,
|
502
502
|
'params': params,
|
503
503
|
'start_time': start_time,
|
504
504
|
'user': user,
|
505
|
-
'cols':
|
506
|
-
'rows':
|
505
|
+
'cols': cols,
|
506
|
+
'rows': rows,
|
507
507
|
})
|
508
508
|
output_file_path = get_output_file_path(command_id)
|
509
509
|
try:
|
510
510
|
with open(output_file_path, 'wb') as fd:
|
511
|
-
p = pexpect.spawn(command, params, ignore_sighup=True, timeout=None, dimensions=(
|
511
|
+
p = pexpect.spawn(command, params, ignore_sighup=True, timeout=None, dimensions=(rows, cols))
|
512
512
|
update_command_status(command_id, {
|
513
|
-
'status': 'running',
|
514
513
|
'pid': p.pid,
|
515
|
-
'user': user
|
516
514
|
})
|
517
515
|
p.logfile = fd
|
518
516
|
p.expect(pexpect.EOF)
|
519
517
|
fd.flush()
|
520
518
|
status = p.wait()
|
521
|
-
end_time = datetime.now().isoformat()
|
519
|
+
end_time = datetime.now(timezone.utc).isoformat()
|
522
520
|
# Update the status based on the result
|
523
521
|
if status is None:
|
524
522
|
exit_code = -15
|
@@ -549,7 +547,7 @@ def run_command(fromip, user, command, params, command_id):
|
|
549
547
|
log_info(fromip, user, f'run_command {command_id}: {command_str(command, params)}: exit code {exit_code}')
|
550
548
|
|
551
549
|
except Exception as e:
|
552
|
-
end_time = datetime.now().isoformat()
|
550
|
+
end_time = datetime.now(timezone.utc).isoformat()
|
553
551
|
update_command_status(command_id, {
|
554
552
|
'status': 'failed',
|
555
553
|
'end_time': end_time,
|
@@ -617,7 +615,7 @@ def check_processes():
|
|
617
615
|
status = read_command_status(command_id)
|
618
616
|
if status.get('status') == 'running' and 'pid' in status:
|
619
617
|
if not is_process_alive(status['pid']):
|
620
|
-
end_time = datetime.now().isoformat()
|
618
|
+
end_time = datetime.now(timezone.utc).isoformat()
|
621
619
|
update_command_status(command_id, {
|
622
620
|
'status': 'aborted',
|
623
621
|
'end_time': end_time,
|
@@ -643,7 +641,7 @@ def stop_command(command_id):
|
|
643
641
|
return jsonify({'error': 'Invalid command_id or command not running'}), 400
|
644
642
|
|
645
643
|
pid = status['pid']
|
646
|
-
end_time = datetime.now().isoformat()
|
644
|
+
end_time = datetime.now(timezone.utc).isoformat()
|
647
645
|
try:
|
648
646
|
#update_command_status(command_id, 'aborted', end_time=end_time, exit_code=-15)
|
649
647
|
os.killpg(os.getpgid(pid), 15) # Send SIGTERM to the process group
|
@@ -725,6 +723,8 @@ def run_command_endpoint():
|
|
725
723
|
data = request.json
|
726
724
|
command = data.get('command')
|
727
725
|
params = data.get('params', [])
|
726
|
+
rows = data.get('rows', tty_rows)
|
727
|
+
cols = data.get('cols', tty_cols)
|
728
728
|
|
729
729
|
if not command:
|
730
730
|
return jsonify({'error': 'command is required'}), 400
|
@@ -753,7 +753,7 @@ def run_command_endpoint():
|
|
753
753
|
})
|
754
754
|
|
755
755
|
# Run the command in a separate thread
|
756
|
-
thread = threading.Thread(target=run_command, args=(request.remote_addr, user, command_path, params, command_id))
|
756
|
+
thread = threading.Thread(target=run_command, args=(request.remote_addr, user, command_path, params, command_id, rows, cols))
|
757
757
|
thread.start()
|
758
758
|
|
759
759
|
return jsonify({'message': 'Command is running', 'command_id': command_id})
|
pywebexec/static/js/popup.js
CHANGED
pywebexec/static/js/script.js
CHANGED
@@ -128,13 +128,15 @@ document.getElementById('launchForm').addEventListener('submit', async (event) =
|
|
128
128
|
event.preventDefault();
|
129
129
|
const commandName = document.getElementById('commandName').value;
|
130
130
|
const params = document.getElementById('params').value.split(' ');
|
131
|
+
fitAddon.fit();
|
132
|
+
terminal.clear();
|
131
133
|
try {
|
132
134
|
const response = await fetch(`/run_command${urlToken}`, {
|
133
135
|
method: 'POST',
|
134
136
|
headers: {
|
135
137
|
'Content-Type': 'application/json'
|
136
138
|
},
|
137
|
-
body: JSON.stringify({ command: commandName, params: params })
|
139
|
+
body: JSON.stringify({ command: commandName, params: params, rows: terminal.rows, cols: terminal.cols })
|
138
140
|
});
|
139
141
|
if (!response.ok) {
|
140
142
|
throw new Error('Failed to launch command');
|
@@ -314,6 +316,8 @@ async function relaunchCommand(command_id, event) {
|
|
314
316
|
alert(data.error);
|
315
317
|
return;
|
316
318
|
}
|
319
|
+
fitAddon.fit();
|
320
|
+
terminal.clear();
|
317
321
|
const relaunchResponse = await fetch(`/run_command${urlToken}`, {
|
318
322
|
method: 'POST',
|
319
323
|
headers: {
|
@@ -321,7 +325,9 @@ async function relaunchCommand(command_id, event) {
|
|
321
325
|
},
|
322
326
|
body: JSON.stringify({
|
323
327
|
command: data.command,
|
324
|
-
params: data.params
|
328
|
+
params: data.params,
|
329
|
+
rows: terminal.rows,
|
330
|
+
cols: terminal.cols,
|
325
331
|
})
|
326
332
|
});
|
327
333
|
if (!relaunchResponse.ok) {
|
@@ -480,6 +486,7 @@ function toggleFit() {
|
|
480
486
|
toggleFitButton.setAttribute('title', 'terminal fit window');
|
481
487
|
}
|
482
488
|
autoFit();
|
489
|
+
viewOutput(currentCommandId);
|
483
490
|
}
|
484
491
|
|
485
492
|
toggleButton.addEventListener('click', toggleFetchOutput);
|
pywebexec/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: pywebexec
|
3
|
-
Version: 1.7.
|
3
|
+
Version: 1.7.9
|
4
4
|
Summary: Simple Python HTTP Exec Server
|
5
5
|
Home-page: https://github.com/joknarf/pywebexec
|
6
6
|
Author: Franck Jouvanceau
|
@@ -199,7 +199,7 @@ $ curl http://myhost:8080/command_output/<command_id> -H "Accept: text/plain"
|
|
199
199
|
|
200
200
|
| method | route | params/payload | returns
|
201
201
|
|-----------|-----------------------------|--------------------|---------------------|
|
202
|
-
| POST | /run_command | command: str<br>params: array[str] | command_id: uuid<br>message: str |
|
202
|
+
| POST | /run_command | command: str<br>params: array[str]<br>rows: int<br>cols: int | command_id: uuid<br>message: str |
|
203
203
|
| POST | /stop_command/command_id | | message: str |
|
204
204
|
| GET | /command_status/command_id | | command_id: uuid<br>command: str<br>params: array[str]<br>start_time: isotime<br>end_time: isotime<br>status: str<br>exit_code: int<br>last_output_line: str |
|
205
205
|
| GET | /commands | | array of<br>command_id: uuid<br>command: str<br>start_time: isotime<br>end_time: isotime<br>status: str<br>exit_code: int<br>last_output_line: str |
|
@@ -1,6 +1,6 @@
|
|
1
1
|
pywebexec/__init__.py,sha256=4spIsVaF8RJt8S58AG_wWoORRNkws9Iwqprj27C3ljM,99
|
2
|
-
pywebexec/pywebexec.py,sha256=
|
3
|
-
pywebexec/version.py,sha256=
|
2
|
+
pywebexec/pywebexec.py,sha256=MmpHK2SscvIPj1gmV9AcJXYfeaL-at5BDgLhKIxzZBc,33604
|
3
|
+
pywebexec/version.py,sha256=ODwgXLJxyAG069GuB0hTip534M1pf6WoBdbcnmuVFy0,411
|
4
4
|
pywebexec/static/css/Consolas NF.ttf,sha256=DJEOzF0eqZ-kxu3Gs_VE8X0NJqiobBzmxWDGpdgGRxI,1313900
|
5
5
|
pywebexec/static/css/style.css,sha256=3s7QgbCh4wb7kfZ7Pjo-B6o3lDIBogZ-3j6AfaPdpzU,8209
|
6
6
|
pywebexec/static/css/xterm.css,sha256=uo5phWaUiJgcz0DAzv46uoByLLbJLeetYosL1xf68rY,5559
|
@@ -21,8 +21,8 @@ pywebexec/static/images/resume.svg,sha256=99LP1Ya2JXakRCO9kW8JMuT_4a_CannF65Eiuw
|
|
21
21
|
pywebexec/static/images/running.svg,sha256=fBCYwYb2O9K4N3waC2nURP25NRwZlqR4PbDZy6JQMww,610
|
22
22
|
pywebexec/static/images/success.svg,sha256=NVwezvVMplt46ElW798vqGfrL21Mw_DWHUp_qiD_FU8,489
|
23
23
|
pywebexec/static/js/commands.js,sha256=h2fkd9qpypLBxvhEEbay23nwuqUwcKJA0vHugcyL8pU,7961
|
24
|
-
pywebexec/static/js/popup.js,sha256=
|
25
|
-
pywebexec/static/js/script.js,sha256=
|
24
|
+
pywebexec/static/js/popup.js,sha256=_2GzUizJ-sdZFWG7SZwbYJTPbu4EvVq7D5Q_UE8nepA,9452
|
25
|
+
pywebexec/static/js/script.js,sha256=m4qjZt0voE-FObq3GRvlYgQWSx9ApInJRtgtf3uCGqE,18530
|
26
26
|
pywebexec/static/js/xterm/LICENSE,sha256=EU1P4eXTull-_T9I80VuwnJXubB-zLzUl3xpEYj2T1M,1083
|
27
27
|
pywebexec/static/js/xterm/addon-canvas.js,sha256=ez6QTVvsmLVNJmdJlM-ZQ5bErwlxAQ_9DUmDIptl2TM,94607
|
28
28
|
pywebexec/static/js/xterm/addon-canvas.js.map,sha256=ECBA4B-BqUpdFeRzlsEWLSQnudnhLP-yPQJ8_hKquMo,379537
|
@@ -35,9 +35,9 @@ pywebexec/static/js/xterm/xterm.js.map,sha256=Y7O2Pb-fIS7Z8AC1D5s04_aiW_Jf1f4mCf
|
|
35
35
|
pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
36
|
pywebexec/templates/index.html,sha256=CcLN3v_42lnj4juiTntDTiGHJ8-zQnmB9oqpSK_0kks,2981
|
37
37
|
pywebexec/templates/popup.html,sha256=f5m4u8WKpkevL2mQamGqo4_y-rSuLOXGuNsezuUbniY,1508
|
38
|
-
pywebexec-1.7.
|
39
|
-
pywebexec-1.7.
|
40
|
-
pywebexec-1.7.
|
41
|
-
pywebexec-1.7.
|
42
|
-
pywebexec-1.7.
|
43
|
-
pywebexec-1.7.
|
38
|
+
pywebexec-1.7.9.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
|
39
|
+
pywebexec-1.7.9.dist-info/METADATA,sha256=ktA3IaI3-tmiO6niFlh1iOHQTGaVLuW7T9byfexDhpM,8148
|
40
|
+
pywebexec-1.7.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
41
|
+
pywebexec-1.7.9.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
|
42
|
+
pywebexec-1.7.9.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
|
43
|
+
pywebexec-1.7.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|