pywebexec 1.7.1__py3-none-any.whl → 1.7.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.
- pywebexec/pywebexec.py +15 -15
- pywebexec/static/css/style.css +15 -10
- pywebexec/static/images/fit-tty.svg +1 -0
- pywebexec/static/images/fit-win.svg +1 -0
- pywebexec/static/js/popup.js +41 -7
- pywebexec/static/js/script.js +41 -5
- pywebexec/templates/index.html +1 -0
- pywebexec/templates/popup.html +1 -0
- pywebexec/version.py +2 -2
- {pywebexec-1.7.1.dist-info → pywebexec-1.7.2.dist-info}/METADATA +1 -1
- {pywebexec-1.7.1.dist-info → pywebexec-1.7.2.dist-info}/RECORD +15 -13
- {pywebexec-1.7.1.dist-info → pywebexec-1.7.2.dist-info}/LICENSE +0 -0
- {pywebexec-1.7.1.dist-info → pywebexec-1.7.2.dist-info}/WHEEL +0 -0
- {pywebexec-1.7.1.dist-info → pywebexec-1.7.2.dist-info}/entry_points.txt +0 -0
- {pywebexec-1.7.1.dist-info → pywebexec-1.7.2.dist-info}/top_level.txt +0 -0
pywebexec/pywebexec.py
CHANGED
@@ -56,6 +56,8 @@ if os.path.isdir(f"{CONFDIR}/.config"):
|
|
56
56
|
CONFDIR += '/.config'
|
57
57
|
CONFDIR += "/.pywebexec"
|
58
58
|
term_command_id = str(uuid.uuid4())
|
59
|
+
tty_cols = 125
|
60
|
+
tty_rows = 30
|
59
61
|
|
60
62
|
# In-memory cache for command statuses
|
61
63
|
status_cache = {}
|
@@ -181,6 +183,8 @@ class PyWebExec(Application):
|
|
181
183
|
return self.application
|
182
184
|
#38;2;66;59;165m
|
183
185
|
ANSI_ESCAPE = re.compile(br'(?:\x1B[@-Z\\-_]|\x1B([(]B|>)|(?:\x1B\[|\x9B)[0-?]*[ -/]*[@-~]|\x1B\[([0-9]{1,2};){0,4}[0-9]{1,3}[m|K]|\x1B\[[0-9;]*[mGKHF]|[\x00-\x1F\x7F])')
|
186
|
+
ANSI_ESCAPE = re.compile(br'(?:\x1B[@-Z\\-_]|\x1B([(]B|>)|(?:\x1B\[|\x9B)[0-?]*[ -/]*[@-~]|\x1B\[([0-9]{1,2};){0,4}[0-9]{1,3}[m|K]|\x1B\[[0-9;]*[mGKHF])')
|
187
|
+
ANSI_ESCAPE = re.compile(br'(\x1B\[([0-9]{1,2};){0,4}[0-9]{1,3}[m|K]|\x1B\[[0-9;]*[mGKHF])')
|
184
188
|
|
185
189
|
def strip_ansi_control_chars(text):
|
186
190
|
"""Remove ANSI and control characters from the text."""
|
@@ -202,12 +206,10 @@ def get_visible_output(line, cols, rows):
|
|
202
206
|
stream = pyte.ByteStream(screen)
|
203
207
|
stream.feed(line)
|
204
208
|
visible_line = ""
|
205
|
-
|
206
|
-
|
207
|
-
visible_line = screen.display[row].strip(" ")
|
209
|
+
for visible_line in reversed(screen.display):
|
210
|
+
visible_line = visible_line.strip(" ")
|
208
211
|
if visible_line:
|
209
212
|
return visible_line
|
210
|
-
row -= 1
|
211
213
|
except:
|
212
214
|
return ""
|
213
215
|
return ""
|
@@ -215,8 +217,8 @@ def get_visible_output(line, cols, rows):
|
|
215
217
|
|
216
218
|
def get_last_line(file_path, cols=None, rows=None, maxsize=2048):
|
217
219
|
"""Retrieve last non empty line after vt100 interpretation"""
|
218
|
-
cols = cols or
|
219
|
-
rows = rows or
|
220
|
+
cols = cols or tty_cols
|
221
|
+
rows = rows or tty_rows
|
220
222
|
with open(file_path, 'rb') as fd:
|
221
223
|
try:
|
222
224
|
fd.seek(-maxsize, os.SEEK_END)
|
@@ -429,9 +431,6 @@ def get_status_file_path(command_id):
|
|
429
431
|
def get_output_file_path(command_id):
|
430
432
|
return os.path.join(COMMAND_STATUS_DIR, f'{command_id}_output.txt')
|
431
433
|
|
432
|
-
def get_done_file_path(command_id):
|
433
|
-
return os.path.join(COMMAND_STATUS_DIR, f'{command_id}.done')
|
434
|
-
|
435
434
|
def update_command_status(command_id, updates):
|
436
435
|
status_file_path = get_status_file_path(command_id)
|
437
436
|
status = read_command_status(command_id) or {}
|
@@ -443,8 +442,6 @@ def update_command_status(command_id, updates):
|
|
443
442
|
status_cache[command_id] = status
|
444
443
|
with open(status_file_path, 'w') as f:
|
445
444
|
json.dump(status, f)
|
446
|
-
if status.get('status') != 'running':
|
447
|
-
open(get_done_file_path(command_id), 'a').close()
|
448
445
|
|
449
446
|
|
450
447
|
def read_command_status(command_id):
|
@@ -455,7 +452,7 @@ def read_command_status(command_id):
|
|
455
452
|
status = status_data.get('status')
|
456
453
|
if status and status != "running":
|
457
454
|
return status_data
|
458
|
-
if command_id in status_cache and
|
455
|
+
if command_id in status_cache and status_cache.get('last_read',0)>datetime.now().timestamp()-0.5:
|
459
456
|
return status_data
|
460
457
|
status_file_path = get_status_file_path(command_id)
|
461
458
|
if not os.path.exists(status_file_path):
|
@@ -465,6 +462,7 @@ def read_command_status(command_id):
|
|
465
462
|
status_data.update(json.load(f))
|
466
463
|
except json.JSONDecodeError:
|
467
464
|
return None
|
465
|
+
status_data['last_read'] = datetime.now().timestamp()
|
468
466
|
status_cache[command_id] = status_data
|
469
467
|
return status_data
|
470
468
|
|
@@ -501,18 +499,19 @@ def run_command(fromip, user, command, params, command_id):
|
|
501
499
|
'command': command,
|
502
500
|
'params': params,
|
503
501
|
'start_time': start_time,
|
504
|
-
'user': user
|
502
|
+
'user': user,
|
503
|
+
'cols': tty_cols,
|
504
|
+
'rows': tty_rows,
|
505
505
|
})
|
506
506
|
output_file_path = get_output_file_path(command_id)
|
507
507
|
try:
|
508
508
|
with open(output_file_path, 'wb') as fd:
|
509
|
-
p = pexpect.spawn(command, params, ignore_sighup=True, timeout=None)
|
509
|
+
p = pexpect.spawn(command, params, ignore_sighup=True, timeout=None, dimensions=(tty_rows, tty_cols))
|
510
510
|
update_command_status(command_id, {
|
511
511
|
'status': 'running',
|
512
512
|
'pid': p.pid,
|
513
513
|
'user': user
|
514
514
|
})
|
515
|
-
p.setwinsize(24, 125)
|
516
515
|
p.logfile = fd
|
517
516
|
p.expect(pexpect.EOF)
|
518
517
|
fd.flush()
|
@@ -798,6 +797,7 @@ def get_command_output(command_id):
|
|
798
797
|
'output': output[-maxsize:],
|
799
798
|
'status': status_data.get("status"),
|
800
799
|
'cols': status_data.get("cols"),
|
800
|
+
'rows': status_data.get("rows"),
|
801
801
|
'links': {
|
802
802
|
'next': f'{request.url_root}command_output/{command_id}?offset={new_offset}&maxsize={maxsize}{token_param}'
|
803
803
|
}
|
pywebexec/static/css/style.css
CHANGED
@@ -48,7 +48,6 @@ select { /* Safari bug */
|
|
48
48
|
min-width: 150px;
|
49
49
|
}
|
50
50
|
.output {
|
51
|
-
white-space: pre-wrap;
|
52
51
|
background: #111;
|
53
52
|
padding: 10px;
|
54
53
|
border: 1px solid #ccc;
|
@@ -329,20 +328,18 @@ span {
|
|
329
328
|
|
330
329
|
.pause {
|
331
330
|
background-image: url("/static/images/pause.svg");
|
332
|
-
/*background-size: contain;*/
|
333
|
-
background-repeat: no-repeat;
|
334
|
-
background-position: center;
|
335
|
-
background-size: 24px 24px;
|
336
331
|
}
|
337
332
|
.resume {
|
338
333
|
background-image: url("/static/images/resume.svg");
|
339
|
-
/*background-size: contain;*/
|
340
|
-
background-repeat: no-repeat;
|
341
|
-
background-position: center;
|
342
|
-
background-size: 24px 24px;
|
343
334
|
}
|
344
335
|
|
345
|
-
.
|
336
|
+
.fit-window {
|
337
|
+
background-image: url("/static/images/fit-win.svg");
|
338
|
+
}
|
339
|
+
.fit-tty {
|
340
|
+
background-image: url("/static/images/fit-tty.svg");
|
341
|
+
}
|
342
|
+
.pause-resume-button, .fit-button {
|
346
343
|
background-color: transparent;
|
347
344
|
border: none;
|
348
345
|
/*padding: 0;*/
|
@@ -350,6 +347,10 @@ span {
|
|
350
347
|
height: 24px;
|
351
348
|
cursor: pointer;
|
352
349
|
flex-shrink: 0;
|
350
|
+
background-repeat: no-repeat;
|
351
|
+
background-position: center;
|
352
|
+
background-size: 24px 24px;
|
353
|
+
|
353
354
|
}
|
354
355
|
|
355
356
|
|
@@ -389,4 +390,8 @@ span {
|
|
389
390
|
border-radius: 17px;
|
390
391
|
min-width: 17px;
|
391
392
|
text-align: center;
|
393
|
+
}
|
394
|
+
|
395
|
+
.xterm-accessibility {
|
396
|
+
display: none;
|
392
397
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg height="200px" width="200px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-42.63 -42.63 558.91 558.91" xml:space="preserve" fill="#000000"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <circle style="fill:#404040;" cx="236.827" cy="236.827" r="236.827"></circle> <g> <path style="fill:#FFFFFF;" d="M421.487,220.971c-32.306,0-64.612,0-96.919,0c10.033-10.033,20.07-20.067,30.104-30.1 c12.782-12.778-7.128-32.538-19.939-19.726c-17.999,17.995-35.993,35.99-53.992,53.984c-5.422,5.419-5.277,14.453,0.105,19.835 c17.999,17.999,35.993,35.993,53.992,53.992c12.782,12.782,32.542-7.128,19.726-19.939c-9.996-9.996-19.992-19.992-29.988-29.988 c32.235,0,64.47,0,96.705,0C439.396,249.026,439.557,220.971,421.487,220.971z"></path> <path style="fill:#FFFFFF;" d="M193.011,225.021c-17.999-17.999-35.993-35.99-53.992-53.984 c-12.782-12.782-32.542,7.128-19.726,19.939c10,10,19.999,19.995,29.995,29.995c-32.239,0-64.474,0-96.713,0 c-18.111,0-18.272,28.054-0.202,28.054c32.302,0,64.601,0,96.904,0c-10.03,10.033-20.063,20.059-30.092,30.092 c-12.782,12.782,7.128,32.542,19.939,19.726c17.999-17.999,35.993-35.993,53.992-53.992 C198.541,239.434,198.396,230.399,193.011,225.021z"></path> <circle style="fill:#FFFFFF;" cx="236.827" cy="236.79" r="24.098"></circle> </g> </g></svg>
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg height="200px" width="200px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-42.63 -42.63 558.91 558.91" xml:space="preserve" fill="#000000"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <circle style="fill:#404040;" cx="236.827" cy="236.827" r="236.827"></circle> <g> <path style="fill:#FFFFFF;" d="M431.251,225.029c-17.999-17.999-35.993-36.001-53.992-53.996 c-12.778-12.782-32.542,7.128-19.726,19.939c9.996,10,19.992,19.995,29.991,29.995c-32.235,0-64.474,0-96.709,0 c-18.111,0-18.272,28.054-0.202,28.054c32.306,0,64.612,0,96.919,0c-10.033,10.033-20.07,20.067-30.104,30.1 c-12.782,12.778,7.128,32.538,19.939,19.726c17.999-17.995,35.993-35.99,53.992-53.984 C436.782,239.437,436.633,230.406,431.251,225.029z"></path> <path style="fill:#FFFFFF;" d="M183.247,220.964c-32.302,0-64.605,0-96.907,0c10.033-10.033,20.063-20.067,30.096-30.1 c12.782-12.782-7.128-32.542-19.939-19.726c-17.999,17.999-35.993,35.997-53.992,53.996c-5.422,5.422-5.277,14.453,0.105,19.835 c17.999,17.999,35.993,35.99,53.992,53.984c12.782,12.782,32.542-7.128,19.726-19.939c-10-10-19.999-19.996-29.995-29.995 c32.239,0,64.474,0,96.713,0C201.155,249.018,201.316,220.964,183.247,220.964z"></path> <circle style="fill:#FFFFFF;" cx="236.827" cy="236.79" r="24.098"></circle> </g> </g></svg>
|
pywebexec/static/js/popup.js
CHANGED
@@ -75,8 +75,30 @@ let fullOutput = '';
|
|
75
75
|
let outputLength = 0;
|
76
76
|
let slider = null;
|
77
77
|
let isPaused = false;
|
78
|
+
let cols = 0;
|
79
|
+
let rows = 0;
|
80
|
+
let fitWindow = false;
|
81
|
+
|
78
82
|
const toggleButton = document.getElementById('toggleFetch');
|
79
83
|
const pausedMessage = document.getElementById('pausedMessage');
|
84
|
+
const toggleFitButton = document.getElementById('toggleFit');
|
85
|
+
|
86
|
+
function autoFit(scroll=true) {
|
87
|
+
// Scroll output div to bottom
|
88
|
+
const outputDiv = document.getElementById('output');
|
89
|
+
outputDiv.scrollTop = terminal.element.clientHeight - outputDiv.clientHeight + 20;
|
90
|
+
if (cols && !fitWindow) {
|
91
|
+
let fit = fitAddon.proposeDimensions();
|
92
|
+
if (fit.rows < rows) {
|
93
|
+
terminal.resize(cols, rows);
|
94
|
+
} else {
|
95
|
+
terminal.resize(cols, fit.rows);
|
96
|
+
}
|
97
|
+
} else {
|
98
|
+
fitAddon.fit();
|
99
|
+
}
|
100
|
+
if (scroll) terminal.scrollToBottom();
|
101
|
+
}
|
80
102
|
|
81
103
|
function getTokenParam() {
|
82
104
|
const urlParams = new URLSearchParams(window.location.search);
|
@@ -104,8 +126,10 @@ async function fetchOutput(url) {
|
|
104
126
|
clearInterval(outputInterval);
|
105
127
|
} else {
|
106
128
|
if (data.cols) {
|
107
|
-
|
108
|
-
|
129
|
+
cols = data.cols;
|
130
|
+
rows = data.rows;
|
131
|
+
autoFit(false);
|
132
|
+
}
|
109
133
|
percentage = slider.value;
|
110
134
|
fullOutput += data.output;
|
111
135
|
if (fullOutput.length > maxSize)
|
@@ -178,8 +202,7 @@ function adjustOutputHeight() {
|
|
178
202
|
const outputTop = outputDiv.getBoundingClientRect().top;
|
179
203
|
const maxHeight = windowHeight - outputTop - 60; // Adjusted for slider height
|
180
204
|
outputDiv.style.height = `${maxHeight}px`;
|
181
|
-
|
182
|
-
sliderUpdateOutput();
|
205
|
+
autoFit();
|
183
206
|
}
|
184
207
|
|
185
208
|
function sliderUpdateOutput() {
|
@@ -214,9 +237,20 @@ function toggleFetchOutput() {
|
|
214
237
|
}
|
215
238
|
isPaused = !isPaused;
|
216
239
|
}
|
240
|
+
function toggleFit() {
|
241
|
+
fitWindow = ! fitWindow;
|
242
|
+
if (fitWindow) {
|
243
|
+
toggleFitButton.classList.add('fit-tty');
|
244
|
+
toggleFitButton.setAttribute('title', 'terminal fit tty');
|
245
|
+
} else {
|
246
|
+
toggleFitButton.classList.remove('fit-tty');
|
247
|
+
toggleFitButton.setAttribute('title', 'terminal fit window');
|
248
|
+
}
|
249
|
+
autoFit();
|
250
|
+
}
|
217
251
|
|
218
252
|
toggleButton.addEventListener('click', toggleFetchOutput);
|
219
|
-
|
253
|
+
toggleFitButton.addEventListener('click', toggleFit);
|
220
254
|
window.addEventListener('resize', adjustOutputHeight);
|
221
255
|
window.addEventListener('load', () => {
|
222
256
|
slider = document.getElementById('outputSlider');
|
@@ -229,11 +263,11 @@ window.addEventListener('load', () => {
|
|
229
263
|
document.getElementById('decreaseFontSize').addEventListener('click', () => {
|
230
264
|
fontSize = Math.max(8, fontSize - 1);
|
231
265
|
terminal.options.fontSize = fontSize;
|
232
|
-
|
266
|
+
autoFit();
|
233
267
|
});
|
234
268
|
|
235
269
|
document.getElementById('increaseFontSize').addEventListener('click', () => {
|
236
270
|
fontSize = Math.min(32, fontSize + 1);
|
237
271
|
terminal.options.fontSize = fontSize;
|
238
|
-
|
272
|
+
autoFit();
|
239
273
|
});
|
pywebexec/static/js/script.js
CHANGED
@@ -11,6 +11,9 @@ let fontSize = 14;
|
|
11
11
|
let isPaused = false;
|
12
12
|
let showRunningOnly = false;
|
13
13
|
let hiddenCommandIds = [];
|
14
|
+
let fitWindow = false;
|
15
|
+
let cols = 0;
|
16
|
+
let rows = 0;
|
14
17
|
|
15
18
|
function initTerminal()
|
16
19
|
{
|
@@ -97,6 +100,23 @@ terminal.onSelectionChange(() => {
|
|
97
100
|
}
|
98
101
|
});
|
99
102
|
|
103
|
+
function autoFit(scroll=true) {
|
104
|
+
// Scroll output div to bottom
|
105
|
+
const outputDiv = document.getElementById('output');
|
106
|
+
outputDiv.scrollTop = terminal.element.clientHeight - outputDiv.clientHeight + 20;
|
107
|
+
if (cols && !fitWindow) {
|
108
|
+
let fit = fitAddon.proposeDimensions();
|
109
|
+
if (fit.rows < rows) {
|
110
|
+
terminal.resize(cols, rows);
|
111
|
+
} else {
|
112
|
+
terminal.resize(cols, fit.rows);
|
113
|
+
}
|
114
|
+
} else {
|
115
|
+
fitAddon.fit();
|
116
|
+
}
|
117
|
+
if (scroll) terminal.scrollToBottom();
|
118
|
+
}
|
119
|
+
|
100
120
|
function getTokenParam() {
|
101
121
|
const urlParams = new URLSearchParams(window.location.search);
|
102
122
|
return urlParams.get('token') ? `?token=${urlParams.get('token')}` : '';
|
@@ -201,8 +221,10 @@ async function fetchOutput(url) {
|
|
201
221
|
clearInterval(outputInterval);
|
202
222
|
} else {
|
203
223
|
if (data.cols) {
|
204
|
-
|
205
|
-
|
224
|
+
cols = data.cols;
|
225
|
+
rows = data.rows;
|
226
|
+
autoFit(scroll=false);
|
227
|
+
}
|
206
228
|
fullOutput += data.output;
|
207
229
|
if (fullOutput.length > maxSize)
|
208
230
|
fullOutput = fullOutput.slice(-maxSize);
|
@@ -370,7 +392,7 @@ function adjustOutputHeight() {
|
|
370
392
|
const outputTop = outputDiv.getBoundingClientRect().top;
|
371
393
|
const maxHeight = windowHeight - outputTop - 60; // Adjusted for slider height
|
372
394
|
outputDiv.style.height = `${maxHeight}px`;
|
373
|
-
|
395
|
+
autoFit();
|
374
396
|
}
|
375
397
|
|
376
398
|
function initResizer() {
|
@@ -412,17 +434,19 @@ slider.addEventListener('input', sliderUpdateOutput);
|
|
412
434
|
document.getElementById('decreaseFontSize').addEventListener('click', () => {
|
413
435
|
fontSize = Math.max(8, fontSize - 1);
|
414
436
|
terminal.options.fontSize = fontSize;
|
415
|
-
|
437
|
+
autoFit();
|
416
438
|
});
|
417
439
|
|
418
440
|
document.getElementById('increaseFontSize').addEventListener('click', () => {
|
419
441
|
fontSize = Math.min(32, fontSize + 1);
|
420
442
|
terminal.options.fontSize = fontSize;
|
421
|
-
|
443
|
+
autoFit();
|
422
444
|
});
|
423
445
|
|
424
446
|
const toggleButton = document.getElementById('toggleFetch');
|
425
447
|
const pausedMessage = document.getElementById('pausedMessage');
|
448
|
+
const toggleFitButton = document.getElementById('toggleFit');
|
449
|
+
|
426
450
|
|
427
451
|
function toggleFetchOutput() {
|
428
452
|
if (isPaused) {
|
@@ -446,8 +470,20 @@ function toggleFetchOutput() {
|
|
446
470
|
}
|
447
471
|
isPaused = !isPaused;
|
448
472
|
}
|
473
|
+
function toggleFit() {
|
474
|
+
fitWindow = ! fitWindow;
|
475
|
+
if (fitWindow) {
|
476
|
+
toggleFitButton.classList.add('fit-tty');
|
477
|
+
toggleFitButton.setAttribute('title', 'terminal fit tty');
|
478
|
+
} else {
|
479
|
+
toggleFitButton.classList.remove('fit-tty');
|
480
|
+
toggleFitButton.setAttribute('title', 'terminal fit window');
|
481
|
+
}
|
482
|
+
autoFit();
|
483
|
+
}
|
449
484
|
|
450
485
|
toggleButton.addEventListener('click', toggleFetchOutput);
|
486
|
+
toggleFitButton.addEventListener('click', toggleFit);
|
451
487
|
|
452
488
|
document.getElementById('thStatus').addEventListener('click', () => {
|
453
489
|
showRunningOnly = !showRunningOnly;
|
pywebexec/templates/index.html
CHANGED
@@ -52,6 +52,7 @@
|
|
52
52
|
<button id="toggleFetch" class="pause-resume-button pause"></button>
|
53
53
|
<button id="decreaseFontSize" class="font-size-button font-decrease"></button>
|
54
54
|
<button id="increaseFontSize" class="font-size-button font-increase"></button>
|
55
|
+
<button id="toggleFit" class="fit-button fit-window" title="terminal fit window"></button>
|
55
56
|
</div>
|
56
57
|
<script src="/static/js/xterm/xterm.js"></script>
|
57
58
|
<script src="/static/js/xterm/addon-canvas.js"></script>
|
pywebexec/templates/popup.html
CHANGED
@@ -20,6 +20,7 @@
|
|
20
20
|
<button id="toggleFetch" class="pause-resume-button pause"></button>
|
21
21
|
<button id="decreaseFontSize" class="font-size-button font-decrease"></button>
|
22
22
|
<button id="increaseFontSize" class="font-size-button font-increase"></button>
|
23
|
+
<button id="toggleFit" class="fit-button fit-window" title="terminal fit window"></button>
|
23
24
|
</div>
|
24
25
|
<script src="/static/js/xterm/xterm.js"></script>
|
25
26
|
<script src="/static/js/xterm/addon-canvas.js"></script>
|
pywebexec/version.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
pywebexec/__init__.py,sha256=4spIsVaF8RJt8S58AG_wWoORRNkws9Iwqprj27C3ljM,99
|
2
|
-
pywebexec/pywebexec.py,sha256=
|
3
|
-
pywebexec/version.py,sha256=
|
2
|
+
pywebexec/pywebexec.py,sha256=gJsI7kob3IyB6DVoWWSyEHOcxpWlsZz-b7jQUyePA-A,33555
|
3
|
+
pywebexec/version.py,sha256=Qj1rYkRQ0hSV6NX03bgvPhjsn6HWrQ8maBXi446C5ZM,411
|
4
4
|
pywebexec/static/css/Consolas NF.ttf,sha256=DJEOzF0eqZ-kxu3Gs_VE8X0NJqiobBzmxWDGpdgGRxI,1313900
|
5
|
-
pywebexec/static/css/style.css,sha256=
|
5
|
+
pywebexec/static/css/style.css,sha256=3s7QgbCh4wb7kfZ7Pjo-B6o3lDIBogZ-3j6AfaPdpzU,8209
|
6
6
|
pywebexec/static/css/xterm.css,sha256=uo5phWaUiJgcz0DAzv46uoByLLbJLeetYosL1xf68rY,5559
|
7
7
|
pywebexec/static/images/aborted.svg,sha256=2nuvSwGBIZGWtlM1DrBO3qiSq1reDbcZDAj9rJXBnjY,380
|
8
8
|
pywebexec/static/images/copy.svg,sha256=d9OwtGh5GzzZHzYcDrLfNxZYLth1Q64x7bRyYxu4Px0,622
|
@@ -10,6 +10,8 @@ pywebexec/static/images/copy_ok.svg,sha256=mEqUVUhSq8xaJK2msQkxRawnz_KwlCZ-tok8Q
|
|
10
10
|
pywebexec/static/images/down-arrow.svg,sha256=4TclEmntMvKk_F_ADXgTpGtviYo826EDmmZiGE7HQBI,121
|
11
11
|
pywebexec/static/images/failed.svg,sha256=rSTBWOtiz7slGDobeU_vaLaMM8CoPeul_tQgWVBcodo,1438
|
12
12
|
pywebexec/static/images/favicon.svg,sha256=9gSN5Oak1zTWhTCyutlupPBKUxcbdoVt7dvhk8xvEug,1224
|
13
|
+
pywebexec/static/images/fit-tty.svg,sha256=gyRB9cqvXFSUOzpBq_Cr0Hv8nIpfr5ca74uUXjkLR-A,1438
|
14
|
+
pywebexec/static/images/fit-win.svg,sha256=_JNK-ew7mc8QIFG2D2TPNm0W2wN2d3Oa6d2d8iwbCFQ,1435
|
13
15
|
pywebexec/static/images/font-decrease.svg,sha256=89TJXQpfZ-XDJ2qC0c7cbLH-tWC-4AJQr_VOgsp06Gg,1782
|
14
16
|
pywebexec/static/images/font-increase.svg,sha256=u-EBxUzmOhKx4UH96fb4gLZ0l6Jkew1HLhcSqz7Z1ak,1869
|
15
17
|
pywebexec/static/images/norun.svg,sha256=_9PyQklBOfUwFak1gVrm-76tYM825urAFhj-zMBec20,555
|
@@ -19,8 +21,8 @@ pywebexec/static/images/resume.svg,sha256=99LP1Ya2JXakRCO9kW8JMuT_4a_CannF65Eiuw
|
|
19
21
|
pywebexec/static/images/running.svg,sha256=fBCYwYb2O9K4N3waC2nURP25NRwZlqR4PbDZy6JQMww,610
|
20
22
|
pywebexec/static/images/success.svg,sha256=NVwezvVMplt46ElW798vqGfrL21Mw_DWHUp_qiD_FU8,489
|
21
23
|
pywebexec/static/js/commands.js,sha256=h2fkd9qpypLBxvhEEbay23nwuqUwcKJA0vHugcyL8pU,7961
|
22
|
-
pywebexec/static/js/popup.js,sha256=
|
23
|
-
pywebexec/static/js/script.js,sha256=
|
24
|
+
pywebexec/static/js/popup.js,sha256=UPKtjPLIR5KaAV2i1iWUGwcCTX1tT3vnOIMc8VKQqag,9311
|
25
|
+
pywebexec/static/js/script.js,sha256=W5NfzFYdyfQpALx_bjeppQFVWxvZGMoVTTq0VOnITxw,18147
|
24
26
|
pywebexec/static/js/xterm/LICENSE,sha256=EU1P4eXTull-_T9I80VuwnJXubB-zLzUl3xpEYj2T1M,1083
|
25
27
|
pywebexec/static/js/xterm/addon-canvas.js,sha256=ez6QTVvsmLVNJmdJlM-ZQ5bErwlxAQ_9DUmDIptl2TM,94607
|
26
28
|
pywebexec/static/js/xterm/addon-canvas.js.map,sha256=ECBA4B-BqUpdFeRzlsEWLSQnudnhLP-yPQJ8_hKquMo,379537
|
@@ -31,11 +33,11 @@ pywebexec/static/js/xterm/addon-unicode11.js.map,sha256=paDj5KKtTIUGedQn2x7CaUTD
|
|
31
33
|
pywebexec/static/js/xterm/xterm.js,sha256=H5kaw7Syg-v5bmCuI6AKUnZd06Lkb6b92p8aqwMvdJU,289441
|
32
34
|
pywebexec/static/js/xterm/xterm.js.map,sha256=Y7O2Pb-fIS7Z8AC1D5s04_aiW_Jf1f4mCfN0U_OI6Zw,1118392
|
33
35
|
pywebexec/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
|
-
pywebexec/templates/index.html,sha256=
|
35
|
-
pywebexec/templates/popup.html,sha256=
|
36
|
-
pywebexec-1.7.
|
37
|
-
pywebexec-1.7.
|
38
|
-
pywebexec-1.7.
|
39
|
-
pywebexec-1.7.
|
40
|
-
pywebexec-1.7.
|
41
|
-
pywebexec-1.7.
|
36
|
+
pywebexec/templates/index.html,sha256=2fEN8cggHBEd8-RamDFpnekVJtIbRembFSw0-1YEptc,2979
|
37
|
+
pywebexec/templates/popup.html,sha256=GT2jY7oOxpCaBaRl924QJWdFBmfSOP952T13d37R_pY,1506
|
38
|
+
pywebexec-1.7.2.dist-info/LICENSE,sha256=gRJf0JPT_wsZJsUGlWPTS8Vypfl9vQ1qjp6sNbKykuA,1064
|
39
|
+
pywebexec-1.7.2.dist-info/METADATA,sha256=NudV7MvLxsTsIZzpTjzNuLJNijAmoK0C9o5VDIg0oRI,8000
|
40
|
+
pywebexec-1.7.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
41
|
+
pywebexec-1.7.2.dist-info/entry_points.txt,sha256=l52GBkPCXRkmlHfEyoVauyfBdg8o-CAtC8qQpOIjJK0,55
|
42
|
+
pywebexec-1.7.2.dist-info/top_level.txt,sha256=vHoHyzngrfGdm_nM7Xn_5iLmaCrf10XO1EhldgNLEQ8,10
|
43
|
+
pywebexec-1.7.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|