pywebexec 1.3.1__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.1'
16
- __version_tuple__ = version_tuple = (1, 3, 1)
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.1
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
@@ -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=cOVPCvD2h2G_2KB6G3ddreYkIQfAnS6WqgAkF_qgGOQ,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.1.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
23
- pywebexec-1.3.1.dist-info/METADATA,sha256=lO1a0YsGGQR_yxguJZ5M-lSSETyT4MD8g7nLy_e0cQU,7397
24
- pywebexec-1.3.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
25
- pywebexec-1.3.1.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
26
- pywebexec-1.3.1.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
27
- pywebexec-1.3.1.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,,