pywebexec 1.3.0__py3-none-any.whl → 1.3.2__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.
@@ -256,4 +256,13 @@ body.dimmed * {
256
256
  span {
257
257
  letter-spacing: -0.03px !important;
258
258
  }
259
+ .slider-container {
260
+ display: flex;
261
+ align-items: center;
262
+ gap: 10px;
263
+ margin-top: 10px;
264
+ }
265
+ #outputSlider {
266
+ width: 100%;
267
+ }
259
268
 
@@ -1,39 +1,46 @@
1
1
  let currentCommandId = null;
2
2
  let outputInterval = null;
3
3
  let nextOutputLink = null;
4
+ let fullOutput = '';
5
+
6
+
7
+ function initTerminal()
8
+ {
9
+ return new Terminal({
10
+ cursorBlink: false,
11
+ cursorHidden: true,
12
+ disableStdin: true,
13
+ convertEol: true,
14
+ fontFamily: 'Consolas NF, monospace, courier-new, courier',
15
+ scrollback: 999999,
16
+ theme: {
17
+ background: '#111412',
18
+ black: '#111412',
19
+ green: '#088a5b',
20
+ blue: "#2760aa",
21
+ red: '#ba1611',
22
+ yellow: "#cf8700",
23
+ magenta: "#4c3d80",
24
+ cyan: "#00a7aa",
25
+ brightBlack: "#243C4F",
26
+ brightBlue: "#5584b1",
27
+ },
28
+ rescaleOverlappingGlyphs: true,
29
+ });
30
+ }
31
+ let terminal = initTerminal()
4
32
 
5
- const terminal = new Terminal({
6
- cursorBlink: false,
7
- cursorHidden: true,
8
- disableStdin: true,
9
- convertEol: true,
10
- fontFamily: 'Consolas NF, monospace, courier-new, courier',
11
- scrollback: 999999,
12
- theme: {
13
- background: '#111412',
14
- black: '#111412',
15
- green: '#088a5b',
16
- blue: "#2760aa",
17
- red: '#ba1611',
18
- yellow: "#cf8700",
19
- magenta: "#4c3d80",
20
- cyan: "#00a7aa",
21
- brightBlack: "#243C4F",
22
- brightBlue: "#5584b1",
23
- },
24
- rescaleOverlappingGlyphs: true,
25
- });
26
33
  const fitAddon = new FitAddon.FitAddon();
27
34
  terminal.loadAddon(fitAddon);
28
35
  terminal.open(document.getElementById('output'));
29
36
  fitAddon.fit();
37
+
30
38
  function getTokenParam() {
31
39
  const urlParams = new URLSearchParams(window.location.search);
32
40
  return urlParams.get('token') ? `?token=${urlParams.get('token')}` : '';
33
41
  }
34
42
  const urlToken = getTokenParam();
35
43
 
36
-
37
44
  terminal.onSelectionChange(() => {
38
45
  const selectionText = terminal.getSelection();
39
46
  if (selectionText) {
@@ -43,7 +50,6 @@ terminal.onSelectionChange(() => {
43
50
  }
44
51
  });
45
52
 
46
-
47
53
  document.getElementById('launchForm').addEventListener('submit', async (event) => {
48
54
  event.preventDefault();
49
55
  const commandName = document.getElementById('commandName').value;
@@ -122,7 +128,8 @@ async function fetchOutput(url) {
122
128
  terminal.write(data.error);
123
129
  clearInterval(outputInterval);
124
130
  } else {
125
- terminal.write(data.output);
131
+ fullOutput += data.output;
132
+ updateTerminalOutput();
126
133
  nextOutputLink = data.links.next;
127
134
  if (data.status != 'running') {
128
135
  clearInterval(outputInterval);
@@ -134,11 +141,14 @@ async function fetchOutput(url) {
134
141
  }
135
142
 
136
143
  async function viewOutput(command_id) {
144
+ document.getElementById('outputSlider').value = 100;
137
145
  adjustOutputHeight();
138
146
  currentCommandId = command_id;
139
147
  nextOutputLink = `/command_output/${command_id}${urlToken}`;
140
148
  clearInterval(outputInterval);
141
149
  terminal.clear();
150
+ terminal.reset();
151
+ fullOutput = '';
142
152
  try {
143
153
  const response = await fetch(`/command_status/${command_id}${urlToken}`);
144
154
  if (!response.ok) {
@@ -246,7 +256,7 @@ function adjustOutputHeight() {
246
256
  const outputDiv = document.getElementById('output');
247
257
  const windowHeight = window.innerHeight;
248
258
  const outputTop = outputDiv.getBoundingClientRect().top;
249
- const maxHeight = windowHeight - outputTop - 30; // 20px for padding/margin
259
+ const maxHeight = windowHeight - outputTop - 60; // Adjusted for slider height
250
260
  outputDiv.style.height = `${maxHeight}px`;
251
261
  fitAddon.fit();
252
262
  }
@@ -274,6 +284,19 @@ function initResizer() {
274
284
  }
275
285
  }
276
286
 
287
+ function updateTerminalOutput() {
288
+ const slider = document.getElementById('outputSlider');
289
+ const percentage = slider.value;
290
+ const outputLength = Math.floor((fullOutput.length * percentage) / 100);
291
+ const limitedOutput = fullOutput.slice(0, outputLength);
292
+ terminal.clear();
293
+ terminal.reset();
294
+ terminal.write(limitedOutput);
295
+ document.getElementById('outputPercentage').innerText = `${percentage}%`;
296
+ }
297
+
298
+ document.getElementById('outputSlider').addEventListener('input', updateTerminalOutput);
299
+
277
300
  window.addEventListener('resize', adjustOutputHeight);
278
301
  window.addEventListener('load', initResizer);
279
302
 
@@ -44,6 +44,10 @@
44
44
  <div class="resizer" id="resizer"></div>
45
45
  </div>
46
46
  <div id="output" class="output"></div>
47
+ <div class="slider-container">
48
+ <input type="range" id="outputSlider" min="0" max="100" value="100">
49
+ <label for="outputSlider"><span id="outputPercentage">100%</span></label>
50
+ </div>
47
51
  <script src="/static/js/xterm/ansi_up.min.js"></script>
48
52
  <script src="/static/js/xterm/xterm.js"></script>
49
53
  <script src="/static/js/xterm/xterm-addon-fit.js"></script>
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.3.0'
16
- __version_tuple__ = version_tuple = (1, 3, 0)
15
+ __version__ = version = '1.3.2'
16
+ __version_tuple__ = version_tuple = (1, 3, 2)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -85,22 +85,23 @@ $ pywebexec -d <dir>
85
85
  * Launch commands with params/view live output/Status using browser
86
86
  * Share your terminal output using `pywebexec -d <dir> term`
87
87
 
88
- ![pywebexecnew6](https://github.com/user-attachments/assets/11415e1f-9f5f-409e-a04c-51eb062a9780)
89
88
 
90
89
  all commands output / statuses are available in the executables directory in subdirectory `.web_status`
90
+ ![pywebexecnew8](https://github.com/user-attachments/assets/b36c98e7-8209-46f9-a320-57f460255bc7)
91
91
 
92
92
  ## features
93
93
 
94
94
  * Serve executables in a directory
95
95
  * Launch commands with params from web browser or API call
96
+ * multiple share terminal output
96
97
  * Follow live output
97
98
  * Stop command
98
99
  * Relaunch command
99
100
  * HTTPS support
100
101
  * HTTPS self-signed certificate generator
101
102
  * Basic Auth
102
- * LDAP(S)
103
- * safe url token
103
+ * LDAP(S) password check/group member
104
+ * Safe url token generation
104
105
  * Can be started as a daemon (POSIX)
105
106
  * Uses gunicorn to serve http/https
106
107
  * Linux/MacOS compatible
@@ -1,7 +1,7 @@
1
1
  pywebexec/__init__.py,sha256=4spIsVaF8RJt8S58AG_wWoORRNkws9Iwqprj27C3ljM,99
2
2
  pywebexec/pywebexec.py,sha256=ljvGw-inDwsP6KQqYwwfKUeN_q9k7JwyP7PfRacnqFQ,25475
3
- pywebexec/version.py,sha256=HGwtpza1HCPtlyqElUvIyH97K44TO13CYiYVZNezQ1M,411
4
- pywebexec/static/css/style.css,sha256=nuJodEFojt_kCLPqbDBQAaBtWcRZ6uLjfI52mSf3EJA,5302
3
+ pywebexec/version.py,sha256=ik9WUFYTvRcmzFEUSqkI2H_62uw0XFdUT3mTLq8-_RY,411
4
+ pywebexec/static/css/style.css,sha256=h0IzV2hI2kpHmk4sCm6oAKlfFexfy2JTn1sEOl89ceA,5440
5
5
  pywebexec/static/css/xterm.css,sha256=gy8_LGA7Q61DUf8ElwFQzHqHMBQnbbEmpgZcbdgeSHI,5383
6
6
  pywebexec/static/images/aborted.svg,sha256=_mP43hU5QdRLFZIknBgjx-dIXrHgQG23-QV27ApXK2A,381
7
7
  pywebexec/static/images/copy.svg,sha256=d9OwtGh5GzzZHzYcDrLfNxZYLth1Q64x7bRyYxu4Px0,622
@@ -12,16 +12,16 @@ pywebexec/static/images/favicon.svg,sha256=ti80IfuDZwIvQcmJxkOeUaB1iMsiyOPmQmVO-
12
12
  pywebexec/static/images/running.gif,sha256=iYuzQGkMxrakSIwt6gPieKCImGZoSAHmU5MUNZa7cpw,25696
13
13
  pywebexec/static/images/success.svg,sha256=PJDcCSTevJh7rkfSFLtc7P0pbeh8PVQBS8DaOLQemmc,489
14
14
  pywebexec/static/js/commands.js,sha256=VdMeCop9V5KwsR2v1J_OY1xFE7tJUYgcMg_lh2VGNjs,7476
15
- pywebexec/static/js/script.js,sha256=WL8wvYjbAQpm_uMrGmuqx6rmHz9V_yMiGZPb1mU8xOU,10103
15
+ pywebexec/static/js/script.js,sha256=NCjnVd-i8zUE3qvu7UqUHBt_IcbnnUUKVGlp7XbFzic,10913
16
16
  pywebexec/static/js/xterm/LICENSE,sha256=EU1P4eXTull-_T9I80VuwnJXubB-zLzUl3xpEYj2T1M,1083
17
17
  pywebexec/static/js/xterm/ansi_up.min.js,sha256=KNGV0vEr30hNqKQimTAvGVy-icD5A1JqMQTtvYtKR2Y,13203
18
18
  pywebexec/static/js/xterm/xterm-addon-fit.js,sha256=Pprm9pZe4SadVXS5Bc8b9VnC9Ex4QlWwA0pxOH53Gck,1460
19
19
  pywebexec/static/js/xterm/xterm.js,sha256=Bzka76jZwEhVt_LlS0e0qMw7ryGa1p5qfxFyeohphBo,283371
20
20
  pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
- pywebexec/templates/index.html,sha256=LaRXHXsOR2eWkBcLIlPxGKHSLTa8JfDkDCJZWadn_1Q,2116
22
- pywebexec-1.3.0.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
23
- pywebexec-1.3.0.dist-info/METADATA,sha256=-9Gg5Bjeonp57OkAoVCq6BOTjG5EK6hoLH31q_AnkzU,7325
24
- pywebexec-1.3.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
25
- pywebexec-1.3.0.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
26
- pywebexec-1.3.0.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
27
- pywebexec-1.3.0.dist-info/RECORD,,
21
+ pywebexec/templates/index.html,sha256=DYtT555wSNhnFtzzHhPMWJireynCJNnAuTytpoORQeE,2321
22
+ pywebexec-1.3.2.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
23
+ pywebexec-1.3.2.dist-info/METADATA,sha256=RHmZ3Uk76T03J2VOLUo2pfAofuwUgw42GQIOxpX8ZKk,7397
24
+ pywebexec-1.3.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
25
+ pywebexec-1.3.2.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
26
+ pywebexec-1.3.2.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
27
+ pywebexec-1.3.2.dist-info/RECORD,,