pywebexec 1.6.9__tar.gz → 1.6.11__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.9/pywebexec.egg-info → pywebexec-1.6.11}/PKG-INFO +3 -2
  2. {pywebexec-1.6.9 → pywebexec-1.6.11}/README.md +2 -1
  3. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/pywebexec.py +27 -13
  4. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/version.py +2 -2
  5. {pywebexec-1.6.9 → pywebexec-1.6.11/pywebexec.egg-info}/PKG-INFO +3 -2
  6. {pywebexec-1.6.9 → pywebexec-1.6.11}/.github/workflows/python-publish.yml +0 -0
  7. {pywebexec-1.6.9 → pywebexec-1.6.11}/.gitignore +0 -0
  8. {pywebexec-1.6.9 → pywebexec-1.6.11}/LICENSE +0 -0
  9. {pywebexec-1.6.9 → pywebexec-1.6.11}/pyproject.toml +0 -0
  10. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/__init__.py +0 -0
  11. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/css/Consolas NF.ttf +0 -0
  12. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/css/style.css +0 -0
  13. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/css/xterm.css +0 -0
  14. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/aborted.svg +0 -0
  15. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/copy.svg +0 -0
  16. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/copy_ok.svg +0 -0
  17. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/down-arrow.svg +0 -0
  18. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/failed.svg +0 -0
  19. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/favicon.svg +0 -0
  20. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/font-decrease.svg +0 -0
  21. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/font-increase.svg +0 -0
  22. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/norun.svg +0 -0
  23. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/pause.svg +0 -0
  24. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/popup.svg +0 -0
  25. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/resume.svg +0 -0
  26. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/running.svg +0 -0
  27. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/images/success.svg +0 -0
  28. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/commands.js +0 -0
  29. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/popup.js +0 -0
  30. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/script.js +0 -0
  31. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/xterm/LICENSE +0 -0
  32. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/xterm/addon-canvas.js +0 -0
  33. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/xterm/addon-canvas.js.map +0 -0
  34. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/xterm/addon-fit.js +0 -0
  35. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/xterm/addon-fit.js.map +0 -0
  36. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/xterm/addon-unicode11.js +0 -0
  37. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/xterm/addon-unicode11.js.map +0 -0
  38. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/xterm/xterm.js +0 -0
  39. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/static/js/xterm/xterm.js.map +0 -0
  40. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/templates/__init__.py +0 -0
  41. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/templates/index.html +0 -0
  42. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec/templates/popup.html +0 -0
  43. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec.egg-info/SOURCES.txt +0 -0
  44. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec.egg-info/dependency_links.txt +0 -0
  45. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec.egg-info/entry_points.txt +0 -0
  46. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec.egg-info/requires.txt +0 -0
  47. {pywebexec-1.6.9 → pywebexec-1.6.11}/pywebexec.egg-info/top_level.txt +0 -0
  48. {pywebexec-1.6.9 → pywebexec-1.6.11}/setup.cfg +0 -0
@@ -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|
@@ -138,6 +138,7 @@ $ curl http://myhost:8080/command_output/<command_id> -H "Accept: text/plain"
138
138
  | POST | /run_command | command: str<br>params: array[str] | command_id: uuid<br>message: str |
139
139
  | POST | /stop_command/command_id | | message: str |
140
140
  | 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 |
141
- | GET | /command_output/command_id | offset: int | output: str<br>status: str<br>links: { next: str } |
142
141
  | 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 |
143
142
  | GET | /executables | | array of str |
143
+ | GET | /command_output/command_id | offset: int | output: str<br>status: str<br>links: { next: str } |
144
+ | 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,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():
@@ -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|
File without changes
File without changes
File without changes
File without changes