pywebexec 2.3.12__py3-none-any.whl → 2.3.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 CHANGED
@@ -22,7 +22,7 @@ if platform.system() != 'Windows':
22
22
  import termios
23
23
  else:
24
24
  from waitress import serve
25
- from winpty import PtyProcess, WinptyError
25
+ from winpty import PTY, WinptyError
26
26
  import ipaddress
27
27
  from socket import socket, AF_INET, SOCK_STREAM
28
28
  import ssl
@@ -513,7 +513,6 @@ def script(output_file):
513
513
  signal.signal(signal.SIGWINCH, sigwinch_passthrough)
514
514
  p.interact()
515
515
 
516
-
517
516
  def run_command(fromip, user, command, params, command_id, rows, cols):
518
517
  log_info(fromip, user, f'run_command {command_id}: {command_str(command, params)}')
519
518
  start_time = datetime.now(timezone.utc).isoformat()
@@ -545,24 +544,25 @@ def run_command(fromip, user, command, params, command_id, rows, cols):
545
544
  elif platform.system() == 'Windows':
546
545
  # On Windows, use winpty
547
546
  with open(output_file_path, 'wb', buffering=0) as fd:
548
- p = PtyProcess.spawn([sys.executable, "-u", command, *params], dimensions=(rows, cols))
549
- pid = p.pid
547
+ p = PTY(cols, rows)
548
+ p.spawn(subprocess.list2cmdline([sys.executable, "-u", command, *params]))
550
549
  update_command_status(command_id, {
551
- 'pid': pid,
550
+ 'pid': p.pid,
552
551
  })
553
552
  while True:
554
553
  try:
555
- if not p.isalive():
556
- time.sleep(1)
557
- data = p.read(10485760)
554
+ # sleep less than 0.1s to get full output after command ends
555
+ # pty won't be readable 0.1s after command ends
556
+ time.sleep(0.09)
557
+ # cannot use blocking read as it will block forever if no output at end of commandgit d
558
+ data = p.read(10485760, blocking=False)
558
559
  fd.write(data.encode())
559
560
  if not p.isalive():
560
561
  break
561
- time.sleep(0.1)
562
562
  except (EOFError, WinptyError):
563
563
  break
564
- status = p.exitstatus
565
- p.close()
564
+ status = p.get_exitstatus()
565
+ del p
566
566
  else:
567
567
  # On Unix, use pexpect
568
568
  with open(output_file_path, 'wb') as fd:
@@ -578,29 +578,29 @@ def run_command(fromip, user, command, params, command_id, rows, cols):
578
578
  end_time = datetime.now(timezone.utc).isoformat()
579
579
  # Update the status based on the result
580
580
  if status is None:
581
- exit_code = -15
581
+ status = -15
582
+ if status in [15, -15] :
582
583
  update_command_status(command_id, {
583
584
  'status': 'aborted',
584
585
  'end_time': end_time,
585
- 'exit_code': exit_code,
586
+ 'exit_code': status,
586
587
  })
587
588
  log_info(fromip, user, f'run_command {command_id}: {command_str(command, params)}: command aborted')
588
589
  else:
589
- exit_code = status
590
- if exit_code == 0:
590
+ if status == 0:
591
591
  update_command_status(command_id, {
592
592
  'status': 'success',
593
593
  'end_time': end_time,
594
- 'exit_code': exit_code,
594
+ 'exit_code': status,
595
595
  })
596
596
  log_info(fromip, user, f'run_command {command_id}: {command_str(command, params)}: completed successfully')
597
597
  else:
598
598
  update_command_status(command_id, {
599
599
  'status': 'failed',
600
600
  'end_time': end_time,
601
- 'exit_code': exit_code,
601
+ 'exit_code': status,
602
602
  })
603
- log_info(fromip, user, f'run_command {command_id}: {command_str(command, params)}: exit code {exit_code}')
603
+ log_info(fromip, user, f'run_command {command_id}: {command_str(command, params)}: exit code {status}')
604
604
 
605
605
  except Exception as e:
606
606
  end_time = datetime.now(timezone.utc).isoformat()
@@ -612,8 +612,8 @@ def run_command(fromip, user, command, params, command_id, rows, cols):
612
612
  with open(get_output_file_path(command_id), 'a') as output_file:
613
613
  output_file.write(str(e))
614
614
  app.logger.error(fromip, user, f'Error running command {command_id}: {e}')
615
- exit_code = 1
616
- return exit_code
615
+ status = 1
616
+ return status
617
617
 
618
618
  def command_str(command, params):
619
619
  try:
@@ -738,9 +738,9 @@ def stop_command(command_id):
738
738
  end_time = datetime.now(timezone.utc).isoformat()
739
739
  try:
740
740
  try:
741
- os.killpg(os.getpgid(pid), signal.SIGTERM) # Send SIGTERM to the process group
741
+ os.killpg(os.getpgid(pid), signal.SIGTERM)
742
742
  except:
743
- os.kill(pid, signal.SIGINT) # Send SIGTERM to the process
743
+ os.kill(pid, signal.SIGTERM)
744
744
  except Exception as e:
745
745
  update_command_status(command_id, {
746
746
  'status': 'aborted',
pywebexec/version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '2.3.12'
21
- __version_tuple__ = version_tuple = (2, 3, 12)
20
+ __version__ = version = '2.3.14'
21
+ __version_tuple__ = version_tuple = (2, 3, 14)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pywebexec
3
- Version: 2.3.12
3
+ Version: 2.3.14
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -1,8 +1,8 @@
1
1
  pywebexec/__init__.py,sha256=197fHJy0UDBwTTpGCGortZRr-w2kTaD7MxqdbVmTEi0,61
2
2
  pywebexec/host_ip.py,sha256=oiCMlo2o3AkkgXDarUSx8T3FWXKI0vk1-EPnx5FGBd8,1332
3
- pywebexec/pywebexec.py,sha256=1M5CtxKr5YkEMBhuVSrwnMNcVRuf7iQf-uxF4Lf0ouQ,48375
3
+ pywebexec/pywebexec.py,sha256=NT4f7Xd4qMkAgjgwguqKKbUkOTCqT7ArRYlsW57Pfwg,48477
4
4
  pywebexec/swagger.yaml,sha256=I_oLpp7Hqel8SDEEykvpmCT-Gv3ytGlziq9bvQOrtZY,7598
5
- pywebexec/version.py,sha256=joxpi5tVTL5LL2B2j6lZDiCaftcd7q6F9z-wABndm5Q,513
5
+ pywebexec/version.py,sha256=Aelhd_nWH-KFOx_jUKbvGukd7h0Q1WZNZKS7Tu4SHi0,513
6
6
  pywebexec/static/css/form.css,sha256=riFFi02xtUXusTTZOU3RSZykutJWMFfK65-eR5RbhY8,7252
7
7
  pywebexec/static/css/markdown.css,sha256=br4-iK9wigTs54N2KHtjgZ4KLH0THVSvJo-XZAdMHiE,1970
8
8
  pywebexec/static/css/style.css,sha256=pUmylXwbFIoXrdaJRVOUohlKIhOIilapH97NyIlgGV4,10343
@@ -67,9 +67,9 @@ pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
67
67
  pywebexec/templates/index.html,sha256=w18O2plH_yS8bqlPsu5hwFFmCj9H2hWLSV8B6ADcSwU,3900
68
68
  pywebexec/templates/popup.html,sha256=3kpMccKD_OLLhJ4Y9KRw6Ny8wQWjVaRrUfV9y5-bDiQ,1580
69
69
  pywebexec/templates/swagger_ui.html,sha256=MAPr-z96VERAecDvX37V8q2Nxph-O0fNDBul1x2w9SI,1147
70
- pywebexec-2.3.12.dist-info/licenses/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
71
- pywebexec-2.3.12.dist-info/METADATA,sha256=aWLzt0bcF4EmtZwXhY5T9giS0WkJFDY-6BiZYFeaGX0,13016
72
- pywebexec-2.3.12.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
73
- pywebexec-2.3.12.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
74
- pywebexec-2.3.12.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
75
- pywebexec-2.3.12.dist-info/RECORD,,
70
+ pywebexec-2.3.14.dist-info/licenses/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
71
+ pywebexec-2.3.14.dist-info/METADATA,sha256=8PDed7Qx0Rfvb3OExe836rpjUEZDoGgTcqQFHhhpvWA,13016
72
+ pywebexec-2.3.14.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
73
+ pywebexec-2.3.14.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
74
+ pywebexec-2.3.14.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
75
+ pywebexec-2.3.14.dist-info/RECORD,,