pywebexec 1.6.17__tar.gz → 1.7.1__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 (48) hide show
  1. {pywebexec-1.6.17/pywebexec.egg-info → pywebexec-1.7.1}/PKG-INFO +1 -1
  2. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/pywebexec.py +32 -18
  3. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/script.js +1 -1
  4. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/version.py +2 -2
  5. {pywebexec-1.6.17 → pywebexec-1.7.1/pywebexec.egg-info}/PKG-INFO +1 -1
  6. {pywebexec-1.6.17 → pywebexec-1.7.1}/.github/workflows/python-publish.yml +0 -0
  7. {pywebexec-1.6.17 → pywebexec-1.7.1}/.gitignore +0 -0
  8. {pywebexec-1.6.17 → pywebexec-1.7.1}/LICENSE +0 -0
  9. {pywebexec-1.6.17 → pywebexec-1.7.1}/README.md +0 -0
  10. {pywebexec-1.6.17 → pywebexec-1.7.1}/pyproject.toml +0 -0
  11. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/__init__.py +0 -0
  12. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/css/Consolas NF.ttf +0 -0
  13. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/css/style.css +0 -0
  14. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/css/xterm.css +0 -0
  15. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/aborted.svg +0 -0
  16. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/copy.svg +0 -0
  17. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/copy_ok.svg +0 -0
  18. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/down-arrow.svg +0 -0
  19. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/failed.svg +0 -0
  20. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/favicon.svg +0 -0
  21. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/font-decrease.svg +0 -0
  22. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/font-increase.svg +0 -0
  23. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/norun.svg +0 -0
  24. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/pause.svg +0 -0
  25. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/popup.svg +0 -0
  26. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/resume.svg +0 -0
  27. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/running.svg +0 -0
  28. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/images/success.svg +0 -0
  29. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/commands.js +0 -0
  30. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/popup.js +0 -0
  31. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/xterm/LICENSE +0 -0
  32. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/xterm/addon-canvas.js +0 -0
  33. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/xterm/addon-canvas.js.map +0 -0
  34. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/xterm/addon-fit.js +0 -0
  35. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/xterm/addon-fit.js.map +0 -0
  36. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/xterm/addon-unicode11.js +0 -0
  37. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/xterm/addon-unicode11.js.map +0 -0
  38. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/xterm/xterm.js +0 -0
  39. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/static/js/xterm/xterm.js.map +0 -0
  40. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/templates/__init__.py +0 -0
  41. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/templates/index.html +0 -0
  42. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec/templates/popup.html +0 -0
  43. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec.egg-info/SOURCES.txt +0 -0
  44. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec.egg-info/dependency_links.txt +0 -0
  45. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec.egg-info/entry_points.txt +0 -0
  46. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec.egg-info/requires.txt +0 -0
  47. {pywebexec-1.6.17 → pywebexec-1.7.1}/pywebexec.egg-info/top_level.txt +0 -0
  48. {pywebexec-1.6.17 → pywebexec-1.7.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 1.6.17
3
+ Version: 1.7.1
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -58,7 +58,7 @@ CONFDIR += "/.pywebexec"
58
58
  term_command_id = str(uuid.uuid4())
59
59
 
60
60
  # In-memory cache for command statuses
61
- command_status_cache = {}
61
+ status_cache = {}
62
62
 
63
63
  def generate_random_password(length=12):
64
64
  characters = string.ascii_letters + string.digits + string.punctuation
@@ -162,7 +162,6 @@ def generate_selfsigned_cert(hostname, ip_addresses=None, key=None):
162
162
  return cert_pem, key_pem
163
163
 
164
164
 
165
-
166
165
  class PyWebExec(Application):
167
166
 
168
167
  def __init__(self, app, options=None):
@@ -242,7 +241,8 @@ def start_gunicorn(daemonized=False, baselog=None):
242
241
  accesslog = None #"-"
243
242
  options = {
244
243
  'bind': '%s:%s' % (args.listen, args.port),
245
- 'workers': 4,
244
+ 'workers': 1,
245
+ 'threads': 4,
246
246
  'timeout': 600,
247
247
  'certfile': args.cert,
248
248
  'keyfile': args.key,
@@ -429,6 +429,9 @@ def get_status_file_path(command_id):
429
429
  def get_output_file_path(command_id):
430
430
  return os.path.join(COMMAND_STATUS_DIR, f'{command_id}_output.txt')
431
431
 
432
+ def get_done_file_path(command_id):
433
+ return os.path.join(COMMAND_STATUS_DIR, f'{command_id}.done')
434
+
432
435
  def update_command_status(command_id, updates):
433
436
  status_file_path = get_status_file_path(command_id)
434
437
  status = read_command_status(command_id) or {}
@@ -437,28 +440,32 @@ def update_command_status(command_id, updates):
437
440
  output_file_path = get_output_file_path(command_id)
438
441
  if os.path.exists(output_file_path):
439
442
  status['last_output_line'] = get_last_line(output_file_path, status.get('cols'), status.get('rows'))
440
- command_status_cache[command_id] = status
443
+ status_cache[command_id] = status
441
444
  with open(status_file_path, 'w') as f:
442
445
  json.dump(status, f)
443
-
446
+ if status.get('status') != 'running':
447
+ open(get_done_file_path(command_id), 'a').close()
448
+
449
+
444
450
  def read_command_status(command_id):
445
451
  # Return cached status if available
446
- if command_id in command_status_cache:
447
- return command_status_cache[command_id]
448
-
452
+ status_data = {}
453
+ if command_id in status_cache:
454
+ status_data = status_cache[command_id]
455
+ status = status_data.get('status')
456
+ if status and status != "running":
457
+ return status_data
458
+ if command_id in status_cache and not os.path.exists(get_done_file_path(command_id)):
459
+ return status_data
449
460
  status_file_path = get_status_file_path(command_id)
450
461
  if not os.path.exists(status_file_path):
451
462
  return None
452
463
  with open(status_file_path, 'r') as f:
453
464
  try:
454
- status_data = json.load(f)
465
+ status_data.update(json.load(f))
455
466
  except json.JSONDecodeError:
456
467
  return None
457
-
458
- # Cache the status if it is not "running"
459
- if status_data['status'] != 'running':
460
- command_status_cache[command_id] = status_data
461
-
468
+ status_cache[command_id] = status_data
462
469
  return status_data
463
470
 
464
471
  def sigwinch_passthrough(sig, data):
@@ -562,6 +569,7 @@ def command_str(command, params):
562
569
 
563
570
 
564
571
  def read_commands():
572
+ global status_cache
565
573
  commands = []
566
574
  for filename in os.listdir(COMMAND_STATUS_DIR):
567
575
  if filename.endswith('.json'):
@@ -569,11 +577,17 @@ def read_commands():
569
577
  status = read_command_status(command_id)
570
578
  if status:
571
579
  command = command_str(status.get('command', '-'), status.get('params', []))
572
- last_line = status.get('last_output_line')
573
- if status.get('status') == 'running':
580
+ if status.get('status') == 'running' and status.get('last_update',0)<datetime.now().timestamp()-5:
574
581
  output_file_path = get_output_file_path(command_id)
575
582
  if os.path.exists(output_file_path):
576
- last_line = get_last_line(output_file_path, status.get('cols'), status.get('rows'))
583
+ size = os.path.getsize(output_file_path)
584
+ if size != status.get('size'):
585
+ status.update({
586
+ 'size': size,
587
+ 'last_update': datetime.now().timestamp(),
588
+ 'last_output_line': get_last_line(output_file_path, status.get('cols'), status.get('rows')),
589
+ })
590
+ status_cache[command_id] = status
577
591
  commands.append({
578
592
  'command_id': command_id,
579
593
  'status': status.get('status'),
@@ -581,7 +595,7 @@ def read_commands():
581
595
  'end_time': status.get('end_time', 'N/A'),
582
596
  'command': command,
583
597
  'exit_code': status.get('exit_code', 'N/A'),
584
- 'last_output_line': last_line,
598
+ 'last_output_line': status.get('last_output_line'),
585
599
  })
586
600
  return commands
587
601
 
@@ -120,7 +120,7 @@ document.getElementById('launchForm').addEventListener('submit', async (event) =
120
120
  throw new Error('Failed to launch command');
121
121
  }
122
122
  const data = await response.json();
123
- await new Promise(r => setTimeout(r, 300));
123
+ //await new Promise(r => setTimeout(r, 300));// not ok
124
124
  fetchCommands();
125
125
  viewOutput(data.command_id);
126
126
  commandInput.focus()
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.6.17'
16
- __version_tuple__ = version_tuple = (1, 6, 17)
15
+ __version__ = version = '1.7.1'
16
+ __version_tuple__ = version_tuple = (1, 7, 1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 1.6.17
3
+ Version: 1.7.1
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
File without changes
File without changes
File without changes
File without changes
File without changes