pywebexec 1.4.12__py3-none-any.whl → 1.4.14__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 +33 -19
- pywebexec/static/css/style.css +3 -5
- pywebexec/static/js/script.js +1 -3
- pywebexec/version.py +2 -2
- {pywebexec-1.4.12.dist-info → pywebexec-1.4.14.dist-info}/METADATA +9 -3
- {pywebexec-1.4.12.dist-info → pywebexec-1.4.14.dist-info}/RECORD +10 -10
- {pywebexec-1.4.12.dist-info → pywebexec-1.4.14.dist-info}/LICENSE +0 -0
- {pywebexec-1.4.12.dist-info → pywebexec-1.4.14.dist-info}/WHEEL +0 -0
- {pywebexec-1.4.12.dist-info → pywebexec-1.4.14.dist-info}/entry_points.txt +0 -0
- {pywebexec-1.4.12.dist-info → pywebexec-1.4.14.dist-info}/top_level.txt +0 -0
pywebexec/pywebexec.py
CHANGED
@@ -44,7 +44,7 @@ app.config['LDAP_BIND_PASSWORD'] = os.environ.get('PYWEBEXEC_LDAP_BIND_PASSWORD'
|
|
44
44
|
# Directory to store the command status and output
|
45
45
|
CWD = os.getcwd()
|
46
46
|
COMMAND_STATUS_DIR = '.web_status'
|
47
|
-
CONFDIR = os.path.expanduser("~/")
|
47
|
+
CONFDIR = os.path.expanduser("~/").rstrip('/')
|
48
48
|
if os.path.isdir(f"{CONFDIR}/.config"):
|
49
49
|
CONFDIR += '/.config'
|
50
50
|
CONFDIR += "/.pywebexec"
|
@@ -223,7 +223,7 @@ def start_gunicorn(daemonized=False, baselog=None):
|
|
223
223
|
if daemonized:
|
224
224
|
if daemon_d('status', pidfilepath=baselog, silent=True):
|
225
225
|
print(f"Error: pywebexec already running on {args.listen}:{args.port}", file=sys.stderr)
|
226
|
-
|
226
|
+
return 1
|
227
227
|
|
228
228
|
if sys.stdout.isatty():
|
229
229
|
errorlog = "-"
|
@@ -244,6 +244,7 @@ def start_gunicorn(daemonized=False, baselog=None):
|
|
244
244
|
'pidfile': pidfile,
|
245
245
|
}
|
246
246
|
PyWebExec(app, options=options).run()
|
247
|
+
return 0
|
247
248
|
|
248
249
|
def daemon_d(action, pidfilepath, silent=False, hostname=None, args=None):
|
249
250
|
"""start/stop daemon"""
|
@@ -285,10 +286,9 @@ def daemon_d(action, pidfilepath, silent=False, hostname=None, args=None):
|
|
285
286
|
except Exception as e:
|
286
287
|
print(e)
|
287
288
|
|
288
|
-
def start_term():
|
289
|
+
def start_term(command_id):
|
289
290
|
os.environ["PYWEBEXEC"] = " (shared)"
|
290
291
|
os.chdir(CWD)
|
291
|
-
command_id = str(uuid.uuid4())
|
292
292
|
start_time = datetime.now().isoformat()
|
293
293
|
user = pwd.getpwuid(os.getuid())[0]
|
294
294
|
update_command_status(command_id, 'running', command="term", params=[user,os.ttyname(sys.stdout.fileno())], start_time=start_time, user=user)
|
@@ -296,10 +296,25 @@ def start_term():
|
|
296
296
|
res = script(output_file_path)
|
297
297
|
end_time = datetime.now().isoformat()
|
298
298
|
update_command_status(command_id, status="success", end_time=end_time, exit_code=res)
|
299
|
-
return
|
299
|
+
return command_id
|
300
|
+
|
301
|
+
|
302
|
+
def print_urls(command_id=None):
|
303
|
+
protocol = 'https' if args.cert else 'http'
|
304
|
+
url_params = ""
|
305
|
+
token = os.environ.get("PYWEBEXEC_TOKEN")
|
306
|
+
if token:
|
307
|
+
url_params = f"?token={token}"
|
308
|
+
if command_id:
|
309
|
+
print(f"{protocol}://{hostname}:{args.port}/popup/{command_id}{url_params}")
|
310
|
+
print(f"{protocol}://{ip}:{args.port}/popup/{command_id}{url_params}")
|
311
|
+
else:
|
312
|
+
print(f"{protocol}://{hostname}:{args.port}{url_params}")
|
313
|
+
print(f"{protocol}://{ip}:{args.port}{url_params}")
|
314
|
+
|
300
315
|
|
301
316
|
def parseargs():
|
302
|
-
global app, args, COMMAND_STATUS_DIR
|
317
|
+
global app, args, COMMAND_STATUS_DIR, hostname, ip
|
303
318
|
|
304
319
|
parser = argparse.ArgumentParser(description='Run the command execution server.')
|
305
320
|
parser.add_argument('-u', '--user', help='Username for basic auth')
|
@@ -311,7 +326,7 @@ def parseargs():
|
|
311
326
|
"-p", "--port", type=int, default=8080, help="HTTP server listen port"
|
312
327
|
)
|
313
328
|
parser.add_argument(
|
314
|
-
"-d", "--dir", type=str,
|
329
|
+
"-d", "--dir", type=str, help=f"Serve target directory. default {CONFDIR}"
|
315
330
|
)
|
316
331
|
parser.add_argument(
|
317
332
|
"-t",
|
@@ -328,6 +343,9 @@ def parseargs():
|
|
328
343
|
choices=["start","stop","restart","status","shareterm", "term"])
|
329
344
|
|
330
345
|
args = parser.parse_args()
|
346
|
+
if not os.path.exists(CONFDIR):
|
347
|
+
os.mkdir(CONFDIR, mode=0o700)
|
348
|
+
args.dir = args.dir or CONFDIR
|
331
349
|
if os.path.isdir(args.dir):
|
332
350
|
try:
|
333
351
|
os.chdir(args.dir)
|
@@ -338,20 +356,17 @@ def parseargs():
|
|
338
356
|
print(f"Error: {args.dir} not found", file=sys.stderr)
|
339
357
|
sys.exit(1)
|
340
358
|
if not os.path.exists(COMMAND_STATUS_DIR):
|
341
|
-
os.
|
342
|
-
if not os.path.exists(CONFDIR):
|
343
|
-
os.mkdir(CONFDIR, mode=0o700)
|
359
|
+
os.mkdir(COMMAND_STATUS_DIR, mode=0o700)
|
344
360
|
if args.action == "term":
|
345
361
|
COMMAND_STATUS_DIR = f"{os.getcwd()}/{COMMAND_STATUS_DIR}"
|
346
|
-
|
362
|
+
start_term(str(uuid.uuid4()))
|
363
|
+
sys.exit(0)
|
347
364
|
(hostname, ip) = resolve(gethostname()) if args.listen == '0.0.0.0' else resolve(args.listen)
|
348
|
-
url_params = ""
|
349
365
|
|
350
366
|
if args.tokenurl:
|
351
367
|
token = os.environ.get("PYWEBEXEC_TOKEN", token_urlsafe())
|
352
368
|
os.environ["PYWEBEXEC_TOKEN"] = token
|
353
369
|
app.config["TOKEN_URL"] = token
|
354
|
-
url_params = f"?token={token}"
|
355
370
|
|
356
371
|
if args.gencert:
|
357
372
|
args.cert = args.cert or f"{CONFDIR}/pywebexec.crt"
|
@@ -376,10 +391,7 @@ def parseargs():
|
|
376
391
|
|
377
392
|
if args.action != 'stop':
|
378
393
|
print("Starting server:")
|
379
|
-
|
380
|
-
print(f"{protocol}://{hostname}:{args.port}{url_params}")
|
381
|
-
print(f"{protocol}://{ip}:{args.port}{url_params}")
|
382
|
-
|
394
|
+
print_urls()
|
383
395
|
return args
|
384
396
|
|
385
397
|
def get_status_file_path(command_id):
|
@@ -703,7 +715,9 @@ def main():
|
|
703
715
|
COMMAND_STATUS_DIR = f"{os.getcwd()}/{COMMAND_STATUS_DIR}"
|
704
716
|
with open(basef + ".log", "ab+") as log:
|
705
717
|
pywebexec = subprocess.Popen([sys.executable] + sys.argv[:-1], stdout=log, stderr=log)
|
706
|
-
|
718
|
+
command_id = str(uuid.uuid4())
|
719
|
+
print_urls(command_id)
|
720
|
+
res = start_term(command_id)
|
707
721
|
time.sleep(1)
|
708
722
|
pywebexec.terminate()
|
709
723
|
sys.exit()
|
@@ -719,5 +733,5 @@ def main():
|
|
719
733
|
|
720
734
|
|
721
735
|
if __name__ == '__main__':
|
722
|
-
main()
|
736
|
+
sys.exit(main())
|
723
737
|
# app.run(host='0.0.0.0', port=5000)
|
pywebexec/static/css/style.css
CHANGED
@@ -267,14 +267,12 @@ span {
|
|
267
267
|
width: 100%;
|
268
268
|
}
|
269
269
|
.popup-button {
|
270
|
-
background:
|
271
|
-
|
270
|
+
background-color: transparent;
|
271
|
+
background-image: url("/static/images/popup.svg");
|
272
272
|
cursor: pointer;
|
273
|
+
border: none;
|
273
274
|
padding: 0;
|
274
|
-
margin-left: 5px;
|
275
275
|
vertical-align: middle;
|
276
|
-
}
|
277
|
-
.popup-button img {
|
278
276
|
width: 16px;
|
279
277
|
height: 16px;
|
280
278
|
}
|
pywebexec/static/js/script.js
CHANGED
@@ -111,9 +111,7 @@ async function fetchCommands() {
|
|
111
111
|
${command.command.startsWith('term') ? '' : command.status === 'running' ? `<button onclick="stopCommand('${command.command_id}', event)">Stop</button>` : `<button onclick="relaunchCommand('${command.command_id}', event)">Run</button>`}
|
112
112
|
</td>
|
113
113
|
<td class="monospace outcol">
|
114
|
-
<button class="popup-button" onclick="openPopup('${command.command_id}', event)">
|
115
|
-
<img src="/static/images/popup.svg" alt="Popup">
|
116
|
-
</button>
|
114
|
+
<button class="popup-button" onclick="openPopup('${command.command_id}', event)"></button>
|
117
115
|
${command.last_output_line || ''}
|
118
116
|
</td>
|
119
117
|
`;
|
pywebexec/version.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: pywebexec
|
3
|
-
Version: 1.4.
|
3
|
+
Version: 1.4.14
|
4
4
|
Summary: Simple Python HTTP Exec Server
|
5
5
|
Home-page: https://github.com/joknarf/pywebexec
|
6
6
|
Author: Franck Jouvanceau
|
@@ -76,8 +76,14 @@ $ pip install pywebexec
|
|
76
76
|
|
77
77
|
## Quick start
|
78
78
|
|
79
|
-
*
|
80
|
-
|
79
|
+
* share terminal
|
80
|
+
```shell
|
81
|
+
$ pywebexec shareterm
|
82
|
+
```
|
83
|
+
|
84
|
+
* serve executables
|
85
|
+
* put in a directory the scripts/commands/links to commands you want to expose
|
86
|
+
* start http server serving current directory executables listening on 0.0.0.0 port 8080
|
81
87
|
```shell
|
82
88
|
$ pywebexec -d <dir>
|
83
89
|
```
|
@@ -1,8 +1,8 @@
|
|
1
1
|
pywebexec/__init__.py,sha256=4spIsVaF8RJt8S58AG_wWoORRNkws9Iwqprj27C3ljM,99
|
2
|
-
pywebexec/pywebexec.py,sha256
|
3
|
-
pywebexec/version.py,sha256=
|
2
|
+
pywebexec/pywebexec.py,sha256=-wnb1KGTGKHRZUipcvZMwb8yQkidkhs_J_jMR6f84o4,27419
|
3
|
+
pywebexec/version.py,sha256=LXsHxD5FW3f8CmcjK3voP4WqE9lpQQNN_tpUuI6VMfI,413
|
4
4
|
pywebexec/static/css/Consolas NF.ttf,sha256=DJEOzF0eqZ-kxu3Gs_VE8X0NJqiobBzmxWDGpdgGRxI,1313900
|
5
|
-
pywebexec/static/css/style.css,sha256=
|
5
|
+
pywebexec/static/css/style.css,sha256=cGJHPFj23SQ_bFpesfUaFA3VFxhXtpRUOL_zzx3x_X8,5726
|
6
6
|
pywebexec/static/css/xterm.css,sha256=gy8_LGA7Q61DUf8ElwFQzHqHMBQnbbEmpgZcbdgeSHI,5383
|
7
7
|
pywebexec/static/images/aborted.svg,sha256=_mP43hU5QdRLFZIknBgjx-dIXrHgQG23-QV27ApXK2A,381
|
8
8
|
pywebexec/static/images/copy.svg,sha256=d9OwtGh5GzzZHzYcDrLfNxZYLth1Q64x7bRyYxu4Px0,622
|
@@ -15,7 +15,7 @@ pywebexec/static/images/running.gif,sha256=iYuzQGkMxrakSIwt6gPieKCImGZoSAHmU5MUN
|
|
15
15
|
pywebexec/static/images/success.svg,sha256=PJDcCSTevJh7rkfSFLtc7P0pbeh8PVQBS8DaOLQemmc,489
|
16
16
|
pywebexec/static/js/commands.js,sha256=8JDb3Q55EJOYf2Q9Uy6qEuqAnn1oGjM0RndgQ4aOjqo,7725
|
17
17
|
pywebexec/static/js/popup.js,sha256=i7BPBh6oS0Q6H528DwP6KwJ8CKh7ULwm1rLHSbyvDhk,4656
|
18
|
-
pywebexec/static/js/script.js,sha256=
|
18
|
+
pywebexec/static/js/script.js,sha256=x3YJn61YOpV5bSum3nrV7MRP7lMAAWv1-mhWBJen2nE,12161
|
19
19
|
pywebexec/static/js/xterm/LICENSE,sha256=EU1P4eXTull-_T9I80VuwnJXubB-zLzUl3xpEYj2T1M,1083
|
20
20
|
pywebexec/static/js/xterm/ansi_up.min.js,sha256=KNGV0vEr30hNqKQimTAvGVy-icD5A1JqMQTtvYtKR2Y,13203
|
21
21
|
pywebexec/static/js/xterm/xterm-addon-fit.js,sha256=Pprm9pZe4SadVXS5Bc8b9VnC9Ex4QlWwA0pxOH53Gck,1460
|
@@ -23,9 +23,9 @@ pywebexec/static/js/xterm/xterm.js,sha256=Bzka76jZwEhVt_LlS0e0qMw7ryGa1p5qfxFyeo
|
|
23
23
|
pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
24
|
pywebexec/templates/index.html,sha256=DYtT555wSNhnFtzzHhPMWJireynCJNnAuTytpoORQeE,2321
|
25
25
|
pywebexec/templates/popup.html,sha256=T6_tAOUoA58sA1oxB5pb8i42RenoMdCsH8T86Gccb6Q,945
|
26
|
-
pywebexec-1.4.
|
27
|
-
pywebexec-1.4.
|
28
|
-
pywebexec-1.4.
|
29
|
-
pywebexec-1.4.
|
30
|
-
pywebexec-1.4.
|
31
|
-
pywebexec-1.4.
|
26
|
+
pywebexec-1.4.14.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
|
27
|
+
pywebexec-1.4.14.dist-info/METADATA,sha256=70sAlcFCe8Lx83npHf3snGV36Ez3OPtfVISxo9IrfaE,7801
|
28
|
+
pywebexec-1.4.14.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
29
|
+
pywebexec-1.4.14.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
|
30
|
+
pywebexec-1.4.14.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
|
31
|
+
pywebexec-1.4.14.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|