pywebexec 0.0.3__py3-none-any.whl → 0.0.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 +23 -22
- pywebexec/templates/index.html +5 -2
- pywebexec/version.py +2 -2
- {pywebexec-0.0.3.dist-info → pywebexec-0.0.5.dist-info}/METADATA +4 -3
- {pywebexec-0.0.3.dist-info → pywebexec-0.0.5.dist-info}/RECORD +9 -9
- {pywebexec-0.0.3.dist-info → pywebexec-0.0.5.dist-info}/LICENSE +0 -0
- {pywebexec-0.0.3.dist-info → pywebexec-0.0.5.dist-info}/WHEEL +0 -0
- {pywebexec-0.0.3.dist-info → pywebexec-0.0.5.dist-info}/entry_points.txt +0 -0
- {pywebexec-0.0.3.dist-info → pywebexec-0.0.5.dist-info}/top_level.txt +0 -0
pywebexec/pywebexec.py
CHANGED
|
@@ -99,7 +99,7 @@ def get_status_file_path(script_id):
|
|
|
99
99
|
def get_output_file_path(script_id):
|
|
100
100
|
return os.path.join(SCRIPT_STATUS_DIR, f'{script_id}_output.txt')
|
|
101
101
|
|
|
102
|
-
def update_script_status(script_id, status, script_name=None, params=None, start_time=None, end_time=None, exit_code=None):
|
|
102
|
+
def update_script_status(script_id, status, script_name=None, params=None, start_time=None, end_time=None, exit_code=None, pid=None):
|
|
103
103
|
status_file_path = get_status_file_path(script_id)
|
|
104
104
|
status_data = read_script_status(script_id) or {}
|
|
105
105
|
status_data['status'] = status
|
|
@@ -113,6 +113,8 @@ def update_script_status(script_id, status, script_name=None, params=None, start
|
|
|
113
113
|
status_data['end_time'] = end_time
|
|
114
114
|
if exit_code is not None:
|
|
115
115
|
status_data['exit_code'] = exit_code
|
|
116
|
+
if pid is not None:
|
|
117
|
+
status_data['pid'] = pid
|
|
116
118
|
with open(status_file_path, 'w') as f:
|
|
117
119
|
json.dump(status_data, f)
|
|
118
120
|
|
|
@@ -134,6 +136,7 @@ def run_script(script_name, params, script_id):
|
|
|
134
136
|
with open(output_file_path, 'w') as output_file:
|
|
135
137
|
# Run the script with parameters and redirect stdout and stderr to the file
|
|
136
138
|
process = subprocess.Popen([script_name] + params, stdout=output_file, stderr=output_file, text=True)
|
|
139
|
+
update_script_status(script_id, 'running', pid=process.pid)
|
|
137
140
|
processes[script_id] = process
|
|
138
141
|
process.wait()
|
|
139
142
|
processes.pop(script_id, None)
|
|
@@ -193,25 +196,26 @@ def run_script_endpoint():
|
|
|
193
196
|
@app.route('/stop_script/<script_id>', methods=['POST'])
|
|
194
197
|
@auth_required
|
|
195
198
|
def stop_script(script_id):
|
|
196
|
-
|
|
199
|
+
status = read_script_status(script_id)
|
|
200
|
+
if not status or 'pid' not in status:
|
|
201
|
+
return jsonify({'error': 'Invalid script_id or script not running'}), 400
|
|
202
|
+
|
|
203
|
+
pid = status['pid']
|
|
197
204
|
end_time = datetime.now().isoformat()
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return jsonify({'error': 'Failed to terminate script'}), 500
|
|
213
|
-
update_script_status(script_id, 'failed', end_time=end_time, exit_code=1)
|
|
214
|
-
return jsonify({'error': 'Invalid script_id or script not running'}), 400
|
|
205
|
+
try:
|
|
206
|
+
os.kill(pid, 15) # Send SIGTERM
|
|
207
|
+
update_script_status(script_id, 'aborted', end_time=end_time, exit_code=-15)
|
|
208
|
+
return jsonify({'message': 'Script aborted'})
|
|
209
|
+
except Exception as e:
|
|
210
|
+
status_data = read_script_status(script_id) or {}
|
|
211
|
+
status_data['status'] = 'failed'
|
|
212
|
+
status_data['end_time'] = end_time
|
|
213
|
+
status_data['exit_code'] = 1
|
|
214
|
+
with open(get_status_file_path(script_id), 'w') as f:
|
|
215
|
+
json.dump(status_data, f)
|
|
216
|
+
with open(get_output_file_path(script_id), 'a') as output_file:
|
|
217
|
+
output_file.write(str(e))
|
|
218
|
+
return jsonify({'error': 'Failed to terminate script'}), 500
|
|
215
219
|
|
|
216
220
|
@app.route('/script_status/<script_id>', methods=['GET'])
|
|
217
221
|
@auth_required
|
|
@@ -276,9 +280,6 @@ def list_executables():
|
|
|
276
280
|
def verify_password(username, password):
|
|
277
281
|
return username == app.config['USER'] and password == app.config['PASSWORD']
|
|
278
282
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
283
|
if __name__ == '__main__':
|
|
283
284
|
start_gunicorn()
|
|
284
285
|
#app.run(host='0.0.0.0', port=5000)
|
pywebexec/templates/index.html
CHANGED
|
@@ -79,7 +79,9 @@
|
|
|
79
79
|
.copy_clip_ok, .copy_clip_ok:hover {
|
|
80
80
|
background-image: url("/static/images/copy_ok.svg");
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
input {
|
|
83
|
+
width: 50%
|
|
84
|
+
}
|
|
83
85
|
</style>
|
|
84
86
|
</head>
|
|
85
87
|
<body>
|
|
@@ -126,6 +128,7 @@
|
|
|
126
128
|
});
|
|
127
129
|
const data = await response.json();
|
|
128
130
|
fetchScripts();
|
|
131
|
+
viewOutput(data.script_id)
|
|
129
132
|
});
|
|
130
133
|
|
|
131
134
|
async function fetchScripts() {
|
|
@@ -214,8 +217,8 @@
|
|
|
214
217
|
})
|
|
215
218
|
});
|
|
216
219
|
const relaunchData = await relaunchResponse.json();
|
|
217
|
-
alert(relaunchData.message);
|
|
218
220
|
fetchScripts();
|
|
221
|
+
viewOutput(relaunchData.script_id)
|
|
219
222
|
}
|
|
220
223
|
|
|
221
224
|
async function stopScript(script_id) {
|
pywebexec/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pywebexec
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.5
|
|
4
4
|
Summary: Simple Python HTTP Exec Server
|
|
5
5
|
Home-page: https://github.com/joknarf/pywebexec
|
|
6
6
|
Author: Franck Jouvanceau
|
|
@@ -78,12 +78,13 @@ $ pip install pywebexec
|
|
|
78
78
|
$ pywebexec
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
* Launch commands with params/view live output/Status using browser
|
|
81
|
+
* Launch commands with params/view live output/Status using browser
|
|
82
|
+

|
|
82
83
|
|
|
83
84
|
## features
|
|
84
85
|
|
|
85
86
|
* Serve executables in current directory
|
|
86
|
-
* Launch commands with params from web browser
|
|
87
|
+
* Launch commands with params from web browser or API call
|
|
87
88
|
* Follow live output
|
|
88
89
|
* Stop command
|
|
89
90
|
* Relaunch command
|
|
@@ -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=85QTsituZUVcoHL_BswWWVHa-7Xey5-bPrVTUZPBG-E,10284
|
|
3
|
+
pywebexec/version.py,sha256=EJB7__SNK9kQS_SWZB_U4DHJ3P8ftF6etZEihTYnuXE,411
|
|
4
4
|
pywebexec/static/images/aborted.svg,sha256=_mP43hU5QdRLFZIknBgjx-dIXrHgQG23-QV27ApXK2A,381
|
|
5
5
|
pywebexec/static/images/copy.svg,sha256=d9OwtGh5GzzZHzYcDrLfNxZYLth1Q64x7bRyYxu4Px0,622
|
|
6
6
|
pywebexec/static/images/copy_ok.svg,sha256=mEqUVUhSq8xaJK2msQkxRawnz_KwlCZ-tok8QS6hJ3g,451
|
|
@@ -8,10 +8,10 @@ pywebexec/static/images/failed.svg,sha256=ADZ7IKrUyOXtqpivnz3VcH0-Wru-I5MOi3OJAk
|
|
|
8
8
|
pywebexec/static/images/running.svg,sha256=vBpiG6ClNUNCArkwsyqK7O-qhIKJX1NI7MSjclNSp_8,1537
|
|
9
9
|
pywebexec/static/images/success.svg,sha256=PJDcCSTevJh7rkfSFLtc7P0pbeh8PVQBS8DaOLQemmc,489
|
|
10
10
|
pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
pywebexec/templates/index.html,sha256=
|
|
12
|
-
pywebexec-0.0.
|
|
13
|
-
pywebexec-0.0.
|
|
14
|
-
pywebexec-0.0.
|
|
15
|
-
pywebexec-0.0.
|
|
16
|
-
pywebexec-0.0.
|
|
17
|
-
pywebexec-0.0.
|
|
11
|
+
pywebexec/templates/index.html,sha256=bBMilfYfG3J-084apqGihEXoq2q0anYK4IYu55CuXYc,9906
|
|
12
|
+
pywebexec-0.0.5.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
|
|
13
|
+
pywebexec-0.0.5.dist-info/METADATA,sha256=zSG5LIPZIRiEQbG2srw0BkJCN9OrO9rXq-_enaD3rbE,4698
|
|
14
|
+
pywebexec-0.0.5.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
|
|
15
|
+
pywebexec-0.0.5.dist-info/entry_points.txt,sha256=-6--c27U7RARJe0BiW5CkTuKljf6pRtnDzE0wfmD9TM,65
|
|
16
|
+
pywebexec-0.0.5.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
|
|
17
|
+
pywebexec-0.0.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|