pywebexec 2.3.13__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,21 +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
- data = p.fileobj.recv(10485760)
556
- if not data:
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)
559
+ fd.write(data.encode())
560
+ if not p.isalive():
557
561
  break
558
- fd.write(data)
559
562
  except (EOFError, WinptyError):
560
563
  break
561
- status = p.exitstatus
562
- p.close()
564
+ status = p.get_exitstatus()
565
+ del p
563
566
  else:
564
567
  # On Unix, use pexpect
565
568
  with open(output_file_path, 'wb') as fd:
@@ -575,29 +578,29 @@ def run_command(fromip, user, command, params, command_id, rows, cols):
575
578
  end_time = datetime.now(timezone.utc).isoformat()
576
579
  # Update the status based on the result
577
580
  if status is None:
578
- exit_code = -15
581
+ status = -15
582
+ if status in [15, -15] :
579
583
  update_command_status(command_id, {
580
584
  'status': 'aborted',
581
585
  'end_time': end_time,
582
- 'exit_code': exit_code,
586
+ 'exit_code': status,
583
587
  })
584
588
  log_info(fromip, user, f'run_command {command_id}: {command_str(command, params)}: command aborted')
585
589
  else:
586
- exit_code = status
587
- if exit_code == 0:
590
+ if status == 0:
588
591
  update_command_status(command_id, {
589
592
  'status': 'success',
590
593
  'end_time': end_time,
591
- 'exit_code': exit_code,
594
+ 'exit_code': status,
592
595
  })
593
596
  log_info(fromip, user, f'run_command {command_id}: {command_str(command, params)}: completed successfully')
594
597
  else:
595
598
  update_command_status(command_id, {
596
599
  'status': 'failed',
597
600
  'end_time': end_time,
598
- 'exit_code': exit_code,
601
+ 'exit_code': status,
599
602
  })
600
- 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}')
601
604
 
602
605
  except Exception as e:
603
606
  end_time = datetime.now(timezone.utc).isoformat()
@@ -609,8 +612,8 @@ def run_command(fromip, user, command, params, command_id, rows, cols):
609
612
  with open(get_output_file_path(command_id), 'a') as output_file:
610
613
  output_file.write(str(e))
611
614
  app.logger.error(fromip, user, f'Error running command {command_id}: {e}')
612
- exit_code = 1
613
- return exit_code
615
+ status = 1
616
+ return status
614
617
 
615
618
  def command_str(command, params):
616
619
  try:
@@ -735,9 +738,9 @@ def stop_command(command_id):
735
738
  end_time = datetime.now(timezone.utc).isoformat()
736
739
  try:
737
740
  try:
738
- os.killpg(os.getpgid(pid), signal.SIGTERM) # Send SIGTERM to the process group
741
+ os.killpg(os.getpgid(pid), signal.SIGTERM)
739
742
  except:
740
- os.kill(pid, signal.SIGINT) # Send SIGTERM to the process
743
+ os.kill(pid, signal.SIGTERM)
741
744
  except Exception as e:
742
745
  update_command_status(command_id, {
743
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.13'
21
- __version_tuple__ = version_tuple = (2, 3, 13)
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.13
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=iQsFNCjh_vWOVSPQuSJVHnNecYoM3i_o_fTIdcPLNEc,48241
3
+ pywebexec/pywebexec.py,sha256=NT4f7Xd4qMkAgjgwguqKKbUkOTCqT7ArRYlsW57Pfwg,48477
4
4
  pywebexec/swagger.yaml,sha256=I_oLpp7Hqel8SDEEykvpmCT-Gv3ytGlziq9bvQOrtZY,7598
5
- pywebexec/version.py,sha256=g7JB3-xSQEFZqMm5-StvX0lwySFF3upByJIPluxkg7Y,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.13.dist-info/licenses/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
71
- pywebexec-2.3.13.dist-info/METADATA,sha256=wkQVPjtyJ3gvD-TRYBbkUr9506YH2jO2qUl5dxNxqak,13016
72
- pywebexec-2.3.13.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
73
- pywebexec-2.3.13.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
74
- pywebexec-2.3.13.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
75
- pywebexec-2.3.13.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,,