pywebexec 1.4.10__tar.gz → 1.4.12__tar.gz

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.
Files changed (38) hide show
  1. {pywebexec-1.4.10/pywebexec.egg-info → pywebexec-1.4.12}/PKG-INFO +13 -1
  2. {pywebexec-1.4.10 → pywebexec-1.4.12}/README.md +12 -0
  3. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/pywebexec.py +43 -20
  4. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/js/popup.js +2 -0
  5. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/templates/popup.html +3 -0
  6. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/version.py +2 -2
  7. {pywebexec-1.4.10 → pywebexec-1.4.12/pywebexec.egg-info}/PKG-INFO +13 -1
  8. {pywebexec-1.4.10 → pywebexec-1.4.12}/.github/workflows/python-publish.yml +0 -0
  9. {pywebexec-1.4.10 → pywebexec-1.4.12}/.gitignore +0 -0
  10. {pywebexec-1.4.10 → pywebexec-1.4.12}/LICENSE +0 -0
  11. {pywebexec-1.4.10 → pywebexec-1.4.12}/pyproject.toml +0 -0
  12. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/__init__.py +0 -0
  13. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/css/Consolas NF.ttf +0 -0
  14. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/css/style.css +0 -0
  15. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/css/xterm.css +0 -0
  16. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/images/aborted.svg +0 -0
  17. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/images/copy.svg +0 -0
  18. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/images/copy_ok.svg +0 -0
  19. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/images/down-arrow.svg +0 -0
  20. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/images/failed.svg +0 -0
  21. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/images/favicon.svg +0 -0
  22. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/images/popup.svg +0 -0
  23. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/images/running.gif +0 -0
  24. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/images/success.svg +0 -0
  25. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/js/commands.js +0 -0
  26. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/js/script.js +0 -0
  27. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/js/xterm/LICENSE +0 -0
  28. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/js/xterm/ansi_up.min.js +0 -0
  29. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/js/xterm/xterm-addon-fit.js +0 -0
  30. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/static/js/xterm/xterm.js +0 -0
  31. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/templates/__init__.py +0 -0
  32. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec/templates/index.html +0 -0
  33. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec.egg-info/SOURCES.txt +0 -0
  34. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec.egg-info/dependency_links.txt +0 -0
  35. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec.egg-info/entry_points.txt +0 -0
  36. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec.egg-info/requires.txt +0 -0
  37. {pywebexec-1.4.10 → pywebexec-1.4.12}/pywebexec.egg-info/top_level.txt +0 -0
  38. {pywebexec-1.4.10 → pywebexec-1.4.12}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 1.4.10
3
+ Version: 1.4.12
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -113,6 +113,18 @@ $ pywebexec --dir ~/myscripts --listen 0.0.0.0 --port 8080 --title myscripts
113
113
  $ pywebexec -d ~/myscripts -l 0.0.0.0 -p 8080 -t myscripts
114
114
  ```
115
115
 
116
+ ## Sharing terminals
117
+
118
+ * start server and share tty in one command
119
+ ```shell
120
+ $ pywebexec -d ~/webshare shareterm
121
+ ```
122
+ * share tty with an already pywebexec server started
123
+ ```shell
124
+ $ pywebexec -d ~/webshare term
125
+ ```
126
+ if another user need to share his terminal, he need to have write permission on `<dir>/.web_status` directory.
127
+
116
128
  ## Safe url token
117
129
 
118
130
  * generate safe url, use the url to access the server
@@ -51,6 +51,18 @@ $ pywebexec --dir ~/myscripts --listen 0.0.0.0 --port 8080 --title myscripts
51
51
  $ pywebexec -d ~/myscripts -l 0.0.0.0 -p 8080 -t myscripts
52
52
  ```
53
53
 
54
+ ## Sharing terminals
55
+
56
+ * start server and share tty in one command
57
+ ```shell
58
+ $ pywebexec -d ~/webshare shareterm
59
+ ```
60
+ * share tty with an already pywebexec server started
61
+ ```shell
62
+ $ pywebexec -d ~/webshare term
63
+ ```
64
+ if another user need to share his terminal, he need to have write permission on `<dir>/.web_status` directory.
65
+
54
66
  ## Safe url token
55
67
 
56
68
  * generate safe url, use the url to access the server
@@ -9,6 +9,7 @@ import argparse
9
9
  import random
10
10
  import string
11
11
  from datetime import datetime, timezone, timedelta
12
+ import time
12
13
  import shlex
13
14
  from gunicorn.app.base import Application
14
15
  import ipaddress
@@ -22,6 +23,7 @@ import signal
22
23
  import fcntl
23
24
  import termios
24
25
  import struct
26
+ import subprocess
25
27
 
26
28
 
27
29
  if os.environ.get('PYWEBEXEC_LDAP_SERVER'):
@@ -40,6 +42,7 @@ app.config['LDAP_BIND_DN'] = os.environ.get('PYWEBEXEC_LDAP_BIND_DN')
40
42
  app.config['LDAP_BIND_PASSWORD'] = os.environ.get('PYWEBEXEC_LDAP_BIND_PASSWORD')
41
43
 
42
44
  # Directory to store the command status and output
45
+ CWD = os.getcwd()
43
46
  COMMAND_STATUS_DIR = '.web_status'
44
47
  CONFDIR = os.path.expanduser("~/")
45
48
  if os.path.isdir(f"{CONFDIR}/.config"):
@@ -216,17 +219,19 @@ def get_last_non_empty_line_of_file(file_path):
216
219
 
217
220
 
218
221
  def start_gunicorn(daemonized=False, baselog=None):
222
+ pidfile = f"{baselog}.pid"
219
223
  if daemonized:
220
- errorlog = f"{baselog}.log"
221
- accesslog = None # f"{baselog}.access.log"
222
- pidfile = f"{baselog}.pid"
223
224
  if daemon_d('status', pidfilepath=baselog, silent=True):
224
225
  print(f"Error: pywebexec already running on {args.listen}:{args.port}", file=sys.stderr)
225
226
  sys.exit(1)
226
- else:
227
+
228
+ if sys.stdout.isatty():
227
229
  errorlog = "-"
228
230
  accesslog = None #"-"
229
- pidfile = None
231
+ else:
232
+ errorlog = f"{baselog}.log"
233
+ accesslog = None # f"{baselog}.access.log"
234
+
230
235
  options = {
231
236
  'bind': '%s:%s' % (args.listen, args.port),
232
237
  'workers': 4,
@@ -280,6 +285,19 @@ def daemon_d(action, pidfilepath, silent=False, hostname=None, args=None):
280
285
  except Exception as e:
281
286
  print(e)
282
287
 
288
+ def start_term():
289
+ os.environ["PYWEBEXEC"] = " (shared)"
290
+ os.chdir(CWD)
291
+ command_id = str(uuid.uuid4())
292
+ start_time = datetime.now().isoformat()
293
+ user = pwd.getpwuid(os.getuid())[0]
294
+ update_command_status(command_id, 'running', command="term", params=[user,os.ttyname(sys.stdout.fileno())], start_time=start_time, user=user)
295
+ output_file_path = get_output_file_path(command_id)
296
+ res = script(output_file_path)
297
+ end_time = datetime.now().isoformat()
298
+ update_command_status(command_id, status="success", end_time=end_time, exit_code=res)
299
+ return res
300
+
283
301
  def parseargs():
284
302
  global app, args, COMMAND_STATUS_DIR
285
303
 
@@ -306,10 +324,10 @@ def parseargs():
306
324
  parser.add_argument("-k", "--key", type=str, help="Path to https certificate key")
307
325
  parser.add_argument("-g", "--gencert", action="store_true", help="https server self signed cert")
308
326
  parser.add_argument("-T", "--tokenurl", action="store_true", help="generate safe url to access")
309
- parser.add_argument("action", nargs="?", help="daemon action start/stop/restart/status/term", choices=["start","stop","restart","status","term"])
327
+ parser.add_argument("action", nargs="?", help="daemon action start/stop/restart/status/shareterm/term",
328
+ choices=["start","stop","restart","status","shareterm", "term"])
310
329
 
311
330
  args = parser.parse_args()
312
- cwd = os.getcwd()
313
331
  if os.path.isdir(args.dir):
314
332
  try:
315
333
  os.chdir(args.dir)
@@ -325,21 +343,13 @@ def parseargs():
325
343
  os.mkdir(CONFDIR, mode=0o700)
326
344
  if args.action == "term":
327
345
  COMMAND_STATUS_DIR = f"{os.getcwd()}/{COMMAND_STATUS_DIR}"
328
- os.chdir(cwd)
329
- command_id = str(uuid.uuid4())
330
- start_time = datetime.now().isoformat()
331
- user = pwd.getpwuid(os.getuid())[0]
332
- update_command_status(command_id, 'running', command="term", params=[user,os.ttyname(sys.stdout.fileno())], start_time=start_time, user=user)
333
- output_file_path = get_output_file_path(command_id)
334
- res = script(output_file_path)
335
- end_time = datetime.now().isoformat()
336
- update_command_status(command_id, status="success", end_time=end_time, exit_code=res)
337
- sys.exit(res)
346
+ sys.exit(start_term())
338
347
  (hostname, ip) = resolve(gethostname()) if args.listen == '0.0.0.0' else resolve(args.listen)
339
348
  url_params = ""
340
349
 
341
350
  if args.tokenurl:
342
- token = token_urlsafe()
351
+ token = os.environ.get("PYWEBEXEC_TOKEN", token_urlsafe())
352
+ os.environ["PYWEBEXEC_TOKEN"] = token
343
353
  app.config["TOKEN_URL"] = token
344
354
  url_params = f"?token={token}"
345
355
 
@@ -446,7 +456,6 @@ def script(output_file):
446
456
  sigwinch_passthrough(None, None)
447
457
  signal.signal(signal.SIGWINCH, sigwinch_passthrough)
448
458
  p.interact()
449
-
450
459
 
451
460
 
452
461
  def run_command(command, params, command_id, user):
@@ -688,12 +697,26 @@ def popup(command_id):
688
697
  return render_template('popup.html', command_id=command_id)
689
698
 
690
699
  def main():
700
+ global COMMAND_STATUS_DIR
691
701
  basef = f"{CONFDIR}/pywebexec_{args.listen}:{args.port}"
702
+ if args.action == "shareterm":
703
+ COMMAND_STATUS_DIR = f"{os.getcwd()}/{COMMAND_STATUS_DIR}"
704
+ with open(basef + ".log", "ab+") as log:
705
+ pywebexec = subprocess.Popen([sys.executable] + sys.argv[:-1], stdout=log, stderr=log)
706
+ start_term()
707
+ time.sleep(1)
708
+ pywebexec.terminate()
709
+ sys.exit()
710
+
711
+ if args.action == "restart":
712
+ daemon_d('stop', pidfilepath=basef)
713
+ args.action = "start"
692
714
  if args.action == "start":
693
715
  return start_gunicorn(daemonized=True, baselog=basef)
694
716
  if args.action:
695
717
  return daemon_d(args.action, pidfilepath=basef)
696
- return start_gunicorn()
718
+ return start_gunicorn(baselog=basef)
719
+
697
720
 
698
721
  if __name__ == '__main__':
699
722
  main()
@@ -47,6 +47,7 @@ async function fetchOutput(url) {
47
47
  try {
48
48
  const response = await fetch(url);
49
49
  if (!response.ok) {
50
+ document.getElementById('dimmer').style.display = 'none';
50
51
  return;
51
52
  }
52
53
  const data = await response.json();
@@ -72,6 +73,7 @@ async function fetchOutput(url) {
72
73
  }
73
74
  }
74
75
  } catch (error) {
76
+ document.getElementById('dimmer').style.display = 'block';
75
77
  console.log('Error fetching output:', error);
76
78
  }
77
79
  }
@@ -8,6 +8,9 @@
8
8
  <link rel="stylesheet" href="/static/css/xterm.css">
9
9
  </head>
10
10
  <body>
11
+ <div id="dimmer" class="dimmer">
12
+ <div class="dimmer-text">Server not available</div>
13
+ </div>
11
14
  <div id="output" class="output"></div>
12
15
  <div class="slider-container">
13
16
  <input type="range" id="outputSlider" min="0" max="100" value="100">
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.4.10'
16
- __version_tuple__ = version_tuple = (1, 4, 10)
15
+ __version__ = version = '1.4.12'
16
+ __version_tuple__ = version_tuple = (1, 4, 12)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 1.4.10
3
+ Version: 1.4.12
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -113,6 +113,18 @@ $ pywebexec --dir ~/myscripts --listen 0.0.0.0 --port 8080 --title myscripts
113
113
  $ pywebexec -d ~/myscripts -l 0.0.0.0 -p 8080 -t myscripts
114
114
  ```
115
115
 
116
+ ## Sharing terminals
117
+
118
+ * start server and share tty in one command
119
+ ```shell
120
+ $ pywebexec -d ~/webshare shareterm
121
+ ```
122
+ * share tty with an already pywebexec server started
123
+ ```shell
124
+ $ pywebexec -d ~/webshare term
125
+ ```
126
+ if another user need to share his terminal, he need to have write permission on `<dir>/.web_status` directory.
127
+
116
128
  ## Safe url token
117
129
 
118
130
  * generate safe url, use the url to access the server
File without changes
File without changes
File without changes
File without changes