pywebexec 1.6.9__py3-none-any.whl → 1.6.11__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
@@ -1,5 +1,5 @@
1
1
  import sys
2
- from flask import Flask, request, jsonify, render_template, session, redirect, url_for
2
+ from flask import Flask, request, jsonify, render_template, session, redirect, url_for, Response, stream_with_context
3
3
  from flask_httpauth import HTTPBasicAuth
4
4
  import threading
5
5
  import os
@@ -330,11 +330,13 @@ def print_urls(command_id=None):
330
330
  if token:
331
331
  url_params = f"?token={token}"
332
332
  if command_id:
333
- print(f"{protocol}://{hostname}:{args.port}/dopopup/{command_id}{url_params}", flush=True)
334
- print(f"{protocol}://{ip}:{args.port}/dopopup/{command_id}{url_params}", flush=True)
333
+ print(f"web popup: {protocol}://{hostname}:{args.port}/dopopup/{command_id}{url_params}", flush=True)
334
+ print(f"web popup: {protocol}://{ip}:{args.port}/dopopup/{command_id}{url_params}", flush=True)
335
+ print(f"raw output: {protocol}://{hostname}:{args.port}/command_output_raw/{command_id}{url_params}", flush=True)
336
+ print(f"raw output: {protocol}://{ip}:{args.port}/command_output_raw/{command_id}{url_params}", flush=True)
335
337
  else:
336
- print(f"{protocol}://{hostname}:{args.port}{url_params}", flush=True)
337
- print(f"{protocol}://{ip}:{args.port}{url_params}", flush=True)
338
+ print(f"web commands: {protocol}://{hostname}:{args.port}{url_params}", flush=True)
339
+ print(f"web commands: {protocol}://{ip}:{args.port}{url_params}", flush=True)
338
340
 
339
341
 
340
342
  def is_port_in_use(address, port):
@@ -798,14 +800,26 @@ def get_command_output(command_id):
798
800
  @app.route('/command_output_raw/<command_id>', methods=['GET'])
799
801
  def get_command_output_raw(command_id):
800
802
  offset = int(request.args.get('offset', 0))
801
- maxsize = int(request.args.get('maxsize', 10485760))
802
- output_file_path = get_output_file_path(command_id)
803
- if os.path.exists(output_file_path):
804
- with open(output_file_path, 'rb') as output_file:
805
- output_file.seek(offset)
806
- output = output_file.read(maxsize)
807
- return output, 200, {'Content-Type': 'text/plain'}
808
- return jsonify({'error': 'Invalid command_id'}), 404
803
+ @stream_with_context
804
+ def generate(offset):
805
+ try:
806
+ output_file_path = get_output_file_path(command_id)
807
+ if os.path.exists(output_file_path):
808
+ with open(output_file_path, 'rb') as output_file:
809
+ while True:
810
+ while True:
811
+ chunk = output_file.read(1024)
812
+ if not chunk:
813
+ time.sleep(0.5)
814
+ break
815
+ yield chunk
816
+ status = read_command_status(command_id)
817
+ if not status or status['status'] != 'running':
818
+ yield f"\nEnd of command {command_id} {status.get('status', '')} exit: {status.get('exit_code')}\n"
819
+ break
820
+ except GeneratorExit:
821
+ return
822
+ return Response(generate(offset), content_type='text/plain')
809
823
 
810
824
  @app.route('/executables', methods=['GET'])
811
825
  def list_executables():
pywebexec/version.py CHANGED
@@ -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.9'
16
- __version_tuple__ = version_tuple = (1, 6, 9)
15
+ __version__ = version = '1.6.11'
16
+ __version_tuple__ = version_tuple = (1, 6, 11)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 1.6.9
3
+ Version: 1.6.11
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -200,6 +200,7 @@ $ curl http://myhost:8080/command_output/<command_id> -H "Accept: text/plain"
200
200
  | POST | /run_command | command: str<br>params: array[str] | command_id: uuid<br>message: str |
201
201
  | POST | /stop_command/command_id | | message: str |
202
202
  | GET | /command_status/command_id | | command_id: uuid<br>command: str<br>params: array[str]<br>start_time: isotime<br>end_time: isotime<br>status: str<br>exit_code: int<br>last_output_line: str |
203
- | GET | /command_output/command_id | offset: int | output: str<br>status: str<br>links: { next: str } |
204
203
  | GET | /commands | | array of<br>command_id: uuid<br>command: str<br>start_time: isotime<br>end_time: isotime<br>status: str<br>exit_code: int<br>last_output_line: str |
205
204
  | GET | /executables | | array of str |
205
+ | GET | /command_output/command_id | offset: int | output: str<br>status: str<br>links: { next: str } |
206
+ | GET | /command_output_raw/command_id | offset: int | output: stream raw output until end of command<br>curl -N -s http://srv/command_output_raw/command_id|
@@ -1,6 +1,6 @@
1
1
  pywebexec/__init__.py,sha256=4spIsVaF8RJt8S58AG_wWoORRNkws9Iwqprj27C3ljM,99
2
- pywebexec/pywebexec.py,sha256=L47T3dB78GvW2CD09kRFncjaNjLxJ_NqB4VvOftSodo,31719
3
- pywebexec/version.py,sha256=H4tpGbuK5q1tqtuUh1Nr2Buwsz8VycRrcpqeBxyquBg,411
2
+ pywebexec/pywebexec.py,sha256=CLHDHDkgsftj8VWKp6ofnUgM8oQf8rvCvROlnljP4ow,32577
3
+ pywebexec/version.py,sha256=fbMgF3ll0MwJN-g_yFfiW2LYnfAEawaw32LMtGtBPy8,413
4
4
  pywebexec/static/css/Consolas NF.ttf,sha256=DJEOzF0eqZ-kxu3Gs_VE8X0NJqiobBzmxWDGpdgGRxI,1313900
5
5
  pywebexec/static/css/style.css,sha256=MJHUBpjWL4sLxM7a7DxypmPKaFJQbmA_ESNXsbLviNI,8201
6
6
  pywebexec/static/css/xterm.css,sha256=uo5phWaUiJgcz0DAzv46uoByLLbJLeetYosL1xf68rY,5559
@@ -33,9 +33,9 @@ pywebexec/static/js/xterm/xterm.js.map,sha256=Y7O2Pb-fIS7Z8AC1D5s04_aiW_Jf1f4mCf
33
33
  pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  pywebexec/templates/index.html,sha256=5h8kLyzAhbvUDU9sEwrGIvD6FxAMcDZLXlN-ldlO8KU,2880
35
35
  pywebexec/templates/popup.html,sha256=3ZqQcE9mYs-RXv0Lfb24zntOlvR137ZYI9mtCZNVAo0,1407
36
- pywebexec-1.6.9.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
37
- pywebexec-1.6.9.dist-info/METADATA,sha256=ECfHWHQFub3yEsBHe32T47A2mpHgqXTs0bX10WAmdOs,7801
38
- pywebexec-1.6.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
39
- pywebexec-1.6.9.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
40
- pywebexec-1.6.9.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
41
- pywebexec-1.6.9.dist-info/RECORD,,
36
+ pywebexec-1.6.11.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
37
+ pywebexec-1.6.11.dist-info/METADATA,sha256=Do6KMuv1dJL4UjCD-ypdImK1RMOxiGRBnDC0u6uNPoM,7974
38
+ pywebexec-1.6.11.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
39
+ pywebexec-1.6.11.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
40
+ pywebexec-1.6.11.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
41
+ pywebexec-1.6.11.dist-info/RECORD,,