更新了前端界面:
Browse files在进度条下方新增了 <div id="downloadResult"></div>,用于显示下载完成后的链接。
在脚本中取消自动点击,并在下载完成时生成一个可点击的下载链接,提示 “下载完成:点击此处下载 文件名”。
现在下载完成后,页面上会出现漂亮的链接,点击即可获取 TXT/ZIP 文件。
server.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
from fastapi import FastAPI, HTTPException
|
| 2 |
-
from fastapi.responses import FileResponse, HTMLResponse
|
| 3 |
import os, shutil, glob
|
| 4 |
import tempfile
|
| 5 |
import re
|
|
@@ -15,18 +15,62 @@ app = FastAPI(
|
|
| 15 |
def root():
|
| 16 |
return """
|
| 17 |
<!DOCTYPE html>
|
| 18 |
-
<html lang
|
| 19 |
<head>
|
| 20 |
-
<meta charset
|
| 21 |
<title>番茄小说下载器</title>
|
| 22 |
</head>
|
| 23 |
<body>
|
| 24 |
<h1>番茄小说下载器</h1>
|
| 25 |
-
<
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
<
|
| 29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
</body>
|
| 31 |
</html>
|
| 32 |
"""
|
|
|
|
| 1 |
from fastapi import FastAPI, HTTPException
|
| 2 |
+
from fastapi.responses import FileResponse, HTMLResponse, StreamingResponse
|
| 3 |
import os, shutil, glob
|
| 4 |
import tempfile
|
| 5 |
import re
|
|
|
|
| 15 |
def root():
|
| 16 |
return """
|
| 17 |
<!DOCTYPE html>
|
| 18 |
+
<html lang=\"zh-CN\">
|
| 19 |
<head>
|
| 20 |
+
<meta charset=\"UTF-8\">
|
| 21 |
<title>番茄小说下载器</title>
|
| 22 |
</head>
|
| 23 |
<body>
|
| 24 |
<h1>番茄小说下载器</h1>
|
| 25 |
+
<label for=\"book_ids\">小说ID列表(逗号或空格分隔):</label><br/>
|
| 26 |
+
<textarea id=\"book_ids\" rows=\"4\" cols=\"50\"></textarea><br/>
|
| 27 |
+
<button id=\"downloadBtn\">下载</button>
|
| 28 |
+
<div id=\"progress\" style=\"display:none;margin-top:10px;\">\n <progress id=\"progBar\" value=\"0\" max=\"100\"></progress>\n <span id=\"progText\">0%</span>\n </div>\n <div id=\"downloadResult\" style=\"margin-top:10px;\"></div>
|
| 29 |
+
<script>
|
| 30 |
+
document.getElementById('downloadBtn').addEventListener('click', function(){
|
| 31 |
+
const book_ids = document.getElementById('book_ids').value;
|
| 32 |
+
if (!book_ids) return;
|
| 33 |
+
document.getElementById('progress').style.display = 'block';
|
| 34 |
+
fetch(`/download?book_ids=${encodeURIComponent(book_ids)}`).then(response=>{
|
| 35 |
+
const total = response.headers.get('Content-Length');
|
| 36 |
+
const reader = response.body.getReader();
|
| 37 |
+
let received = 0;
|
| 38 |
+
const chunks = [];
|
| 39 |
+
function read() {
|
| 40 |
+
return reader.read().then(({done, value})=>{
|
| 41 |
+
if (done) {
|
| 42 |
+
const blob = new Blob(chunks, {type: response.headers.get('Content-Type')});
|
| 43 |
+
const url = URL.createObjectURL(blob);
|
| 44 |
+
const cd = response.headers.get('Content-Disposition');
|
| 45 |
+
let filename = 'download';
|
| 46 |
+
if (cd) {
|
| 47 |
+
const match = cd.match(/filename="?(.+)"?/);
|
| 48 |
+
if (match) filename = match[1];
|
| 49 |
+
}
|
| 50 |
+
// 生成下载链接并展示
|
| 51 |
+
const link = document.createElement('a');
|
| 52 |
+
link.href = url;
|
| 53 |
+
link.download = filename;
|
| 54 |
+
link.innerText = `下载完成:点击此处下载 ${filename}`;
|
| 55 |
+
link.style.display = 'block';
|
| 56 |
+
link.style.marginTop = '10px';
|
| 57 |
+
document.getElementById('downloadResult').appendChild(link);
|
| 58 |
+
return;
|
| 59 |
+
}
|
| 60 |
+
chunks.push(value);
|
| 61 |
+
received += value.length;
|
| 62 |
+
if (total) {
|
| 63 |
+
const percent = Math.round(received / total * 100);
|
| 64 |
+
document.getElementById('progBar').value = percent;
|
| 65 |
+
document.getElementById('progText').innerText = percent + '%';
|
| 66 |
+
}
|
| 67 |
+
return read();
|
| 68 |
+
});
|
| 69 |
+
}
|
| 70 |
+
read();
|
| 71 |
+
});
|
| 72 |
+
});
|
| 73 |
+
</script>
|
| 74 |
</body>
|
| 75 |
</html>
|
| 76 |
"""
|