transfer: download 保存路径是目录时自动拼服务端文件名 (修复 IsADirectoryError); 测试 58 项
This commit is contained in:
@@ -231,6 +231,14 @@ class TestListDownload(TransferTestBase):
|
||||
self.assertEqual(got.read_bytes(), b"hello")
|
||||
got.unlink()
|
||||
|
||||
def test_download_to_dir(self):
|
||||
# dest 是目录 -> 自动拼服务端文件名
|
||||
dest_dir = self.tmp / "dl"
|
||||
dest_dir.mkdir()
|
||||
got = self.client.download("F-1", dest_dir)
|
||||
self.assertEqual(got, dest_dir / "报告.pdf")
|
||||
self.assertEqual(got.read_bytes(), b"hello")
|
||||
|
||||
def test_download_unknown_404(self):
|
||||
with self.assertRaises(TransferError):
|
||||
self.client.download("NOPE")
|
||||
|
||||
+11
-8
@@ -119,19 +119,22 @@ class TransferClient:
|
||||
return payload.get("files", [])
|
||||
|
||||
def download(self, file_id: str, dest: Path | None = None) -> Path:
|
||||
"""GET /api/files/{id}: 流式下载, 实时进度。dest 缺省用服务端文件名。"""
|
||||
"""GET /api/files/{id}: 流式下载, 实时进度。dest 缺省用服务端文件名; 是目录则拼文件名。"""
|
||||
req = urlrequest.Request(self.base_url + f"/api/files/{file_id}", method="GET")
|
||||
try:
|
||||
with urlrequest.urlopen(req, timeout=self.timeout) as resp:
|
||||
# 从 Content-Disposition 取文件名 (filename*=utf-8''... 或 filename=...)
|
||||
cd = resp.headers.get("Content-Disposition") or ""
|
||||
name = "download.bin"
|
||||
if "filename*=utf-8''" in cd:
|
||||
name = urlparse.unquote(cd.split("filename*=utf-8''")[1].split(";")[0])
|
||||
elif "filename=" in cd:
|
||||
name = cd.split("filename=")[1].split(";")[0].strip('"')
|
||||
if dest is None:
|
||||
# 从 Content-Disposition 取文件名 (filename*=utf-8''... 或 filename=...)
|
||||
cd = resp.headers.get("Content-Disposition") or ""
|
||||
name = "download.bin"
|
||||
if "filename*=utf-8''" in cd:
|
||||
name = urlparse.unquote(cd.split("filename*=utf-8''")[1].split(";")[0])
|
||||
elif "filename=" in cd:
|
||||
name = cd.split("filename=")[1].split(";")[0].strip('"')
|
||||
dest = Path(name)
|
||||
elif dest.is_dir():
|
||||
dest = dest / name
|
||||
assert dest is not None
|
||||
total = int(resp.headers.get("Content-Length") or 0)
|
||||
done = 0
|
||||
with open(dest, "wb") as f:
|
||||
|
||||
Reference in New Issue
Block a user