py-web-ssh 0.1.3__tar.gz → 0.1.4__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.
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/PKG-INFO +1 -1
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/pyproject.toml +1 -1
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/__init__.py +1 -1
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/static/app.js +26 -3
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/static/index.html +33 -31
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/LICENSE +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/README.md +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/app.py +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/auth.py +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/client_session.py +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/files.py +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/history.py +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/models.py +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/session.py +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/ssh_client.py +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/static/logs.html +0 -0
- {py_web_ssh-0.1.3 → py_web_ssh-0.1.4}/webssh/static/styles.css +0 -0
|
@@ -164,15 +164,31 @@ document.querySelector("#upload-form").addEventListener("submit", async (event)
|
|
|
164
164
|
setStatus(response.ok ? "上传完成" : "上传失败");
|
|
165
165
|
});
|
|
166
166
|
|
|
167
|
-
document.querySelector("#download-form").addEventListener("submit", (event) => {
|
|
167
|
+
document.querySelector("#download-form").addEventListener("submit", async (event) => {
|
|
168
168
|
event.preventDefault();
|
|
169
169
|
const remotePath = valueOf("#download-path");
|
|
170
170
|
if (!activeSessionId || !remotePath) {
|
|
171
171
|
appendLogLine("下载需要会话 UUID 和远端路径。");
|
|
172
172
|
return;
|
|
173
173
|
}
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
setStatus("下载中...");
|
|
175
|
+
const response = await fetch(
|
|
176
|
+
`/api/sessions/${activeSessionId}/files/download?remote_path=${encodeURIComponent(remotePath)}`,
|
|
177
|
+
);
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
appendLogLine(`下载失败: ${await response.text()}`);
|
|
180
|
+
setStatus("下载失败");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const blob = await response.blob();
|
|
184
|
+
const link = document.createElement("a");
|
|
185
|
+
link.href = URL.createObjectURL(blob);
|
|
186
|
+
link.download = filenameFromResponse(response, remotePath);
|
|
187
|
+
document.body.appendChild(link);
|
|
188
|
+
link.click();
|
|
189
|
+
link.remove();
|
|
190
|
+
URL.revokeObjectURL(link.href);
|
|
191
|
+
setStatus("下载完成");
|
|
176
192
|
});
|
|
177
193
|
|
|
178
194
|
document.querySelectorAll(".tab").forEach((button) => {
|
|
@@ -367,6 +383,13 @@ function checked(selector) {
|
|
|
367
383
|
return document.querySelector(selector).checked;
|
|
368
384
|
}
|
|
369
385
|
|
|
386
|
+
function filenameFromResponse(response, fallbackPath) {
|
|
387
|
+
const disposition = response.headers.get("Content-Disposition") || "";
|
|
388
|
+
const match = disposition.match(/filename="([^"]+)"/);
|
|
389
|
+
if (match) return match[1];
|
|
390
|
+
return fallbackPath.split("/").filter(Boolean).pop() || "download.bin";
|
|
391
|
+
}
|
|
392
|
+
|
|
370
393
|
function bytesToBase64(bytes) {
|
|
371
394
|
let binary = "";
|
|
372
395
|
const size = 0x8000;
|
|
@@ -30,46 +30,48 @@
|
|
|
30
30
|
<button class="panel-toggle" type="button" aria-expanded="false" aria-controls="connect-panel">
|
|
31
31
|
连接
|
|
32
32
|
</button>
|
|
33
|
-
<
|
|
33
|
+
<div id="connect-panel" class="stack panel-body" hidden>
|
|
34
34
|
<div class="section-tabs" aria-label="连接栏目">
|
|
35
35
|
<button class="section-tab active" type="button">连接</button>
|
|
36
36
|
<button class="section-tab" type="button" data-open-panel="session-panel">会话</button>
|
|
37
37
|
<button class="section-tab" type="button" data-open-panel="files-panel">文件</button>
|
|
38
38
|
</div>
|
|
39
|
-
<
|
|
40
|
-
目标服务器
|
|
41
|
-
<input id="host" name="host" required autocomplete="off" placeholder="192.168.1.10" />
|
|
42
|
-
</label>
|
|
43
|
-
<div class="grid-2">
|
|
39
|
+
<form id="connect-form" class="stack">
|
|
44
40
|
<label>
|
|
45
|
-
|
|
46
|
-
<input id="
|
|
41
|
+
目标服务器
|
|
42
|
+
<input id="host" name="host" required autocomplete="off" placeholder="192.168.1.10" />
|
|
47
43
|
</label>
|
|
44
|
+
<div class="grid-2">
|
|
45
|
+
<label>
|
|
46
|
+
端口
|
|
47
|
+
<input id="port" name="port" type="number" min="1" max="65535" value="22" required />
|
|
48
|
+
</label>
|
|
49
|
+
<label>
|
|
50
|
+
用户名
|
|
51
|
+
<input id="username" name="username" required autocomplete="username" />
|
|
52
|
+
</label>
|
|
53
|
+
</div>
|
|
48
54
|
<label>
|
|
49
|
-
|
|
50
|
-
<input id="
|
|
55
|
+
口令
|
|
56
|
+
<input id="password" name="password" type="password" autocomplete="current-password" />
|
|
51
57
|
</label>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<label><input id="strict-host-key" type="checkbox" /> known_hosts 校验</label>
|
|
70
|
-
</div>
|
|
71
|
-
<button class="primary" type="submit">连接</button>
|
|
72
|
-
</form>
|
|
58
|
+
<label>
|
|
59
|
+
私钥文件
|
|
60
|
+
<input id="private-key-file" name="private-key-file" type="file" />
|
|
61
|
+
</label>
|
|
62
|
+
<label>
|
|
63
|
+
私钥口令
|
|
64
|
+
<input id="private-key-passphrase" name="private-key-passphrase" type="password" />
|
|
65
|
+
</label>
|
|
66
|
+
<div class="checks">
|
|
67
|
+
<label><input id="legacy-algorithms" type="checkbox" checked /> legacy 算法</label>
|
|
68
|
+
<label><input id="allow-agent" type="checkbox" /> SSH agent</label>
|
|
69
|
+
<label><input id="look-for-keys" type="checkbox" /> 服务端本机密钥</label>
|
|
70
|
+
<label><input id="strict-host-key" type="checkbox" /> known_hosts 校验</label>
|
|
71
|
+
</div>
|
|
72
|
+
<button class="primary" type="submit">连接</button>
|
|
73
|
+
</form>
|
|
74
|
+
</div>
|
|
73
75
|
</section>
|
|
74
76
|
|
|
75
77
|
<section class="panel collapsible-panel">
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|