mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-10-21 04:40:13 +00:00
fix(files): name single-folder downloads after the folder
The File Browser's selected-files download flow zips any selection that is not a single file and always applies the generic agent-zero-selected-<count>-<stamp>.zip archive name, so downloading one folder produced agent-zero-selected-1-<date>-<time>.zip instead of <folder>.zip. Name single-directory downloads after the folder in both the local and remote branches of prepare_files_download; true multi-selections keep the timestamped generic name. Add regression tests for both cases.
This commit is contained in:
parent
bea0c16d50
commit
17f06bfcdc
3 changed files with 42 additions and 3 deletions
|
|
@ -532,7 +532,9 @@ def prepare_files_download(paths, current_path=""):
|
|||
except BaseException:
|
||||
Path(path).unlink(missing_ok=True)
|
||||
raise
|
||||
name = posixpath.basename(paths[0]) if single else selected_archive_name(len(paths))
|
||||
name = posixpath.basename(paths[0]) if single else (
|
||||
f"{posixpath.basename(paths[0])}.zip" if len(paths) == 1 else selected_archive_name(len(paths))
|
||||
)
|
||||
temporary = True
|
||||
elif len(paths) == 1 and Path(paths[0]).is_file():
|
||||
import stat
|
||||
|
|
@ -557,7 +559,10 @@ def prepare_files_download(paths, current_path=""):
|
|||
temporary = True
|
||||
else:
|
||||
path = create_selected_zip(paths, current_path, limit, FileBrowser.max_archive_entries())
|
||||
name = selected_archive_name(len(paths))
|
||||
name = (
|
||||
f"{Path(paths[0]).name}.zip" if len(paths) == 1
|
||||
else selected_archive_name(len(paths))
|
||||
)
|
||||
temporary = True
|
||||
return {"file_source": path, "download_name": name, "max_bytes": limit, "delete_after": temporary}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
No child DOX files.
|
||||
|
||||
`read_text` owns bounded local Editor reads. `encode_upload` bounds the development RFC adapter. `prepare_files_download` owns Files routing and policy; `register_files_download` rechecks remote permission at delivery. API handlers do not select byte limits. Generic attachment/Connector downloads remain separate.
|
||||
`read_text` owns bounded local Editor reads. `encode_upload` bounds the development RFC adapter. `prepare_files_download` owns Files routing and policy; a single selected directory downloads as `<folder>.zip` while true multi-selections keep the timestamped `agent-zero-selected-<count>-<stamp>.zip` archive name. `register_files_download` rechecks remote permission at delivery. API handlers do not select byte limits. Generic attachment/Connector downloads remain separate.
|
||||
|
||||
Destructive entry operations resolve parent directories while preserving the final symlink. Delete/Rename operate on the link itself; empty/root targets are rejected in the shared helper. Local Files downloads stage a bounded snapshot and reject in-place source changes during preparation. Cancelled preparation closes late responses and their temporary descriptors.
|
||||
|
||||
|
|
|
|||
34
tests/test_download_folder_naming.py
Normal file
34
tests/test_download_folder_naming.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
from pathlib import Path
|
||||
import zipfile
|
||||
|
||||
from helpers.file_browser import prepare_files_download
|
||||
|
||||
|
||||
def test_single_folder_download_is_named_after_the_folder(tmp_path: Path) -> None:
|
||||
folder = tmp_path / "my-folder"
|
||||
folder.mkdir()
|
||||
(folder / "file.txt").write_text("content", encoding="utf-8")
|
||||
|
||||
# A single selected folder downloads as <folder>.zip, not the generic
|
||||
# agent-zero-selected-<count>-<stamp>.zip archive name.
|
||||
download = prepare_files_download([str(folder)], current_path=str(tmp_path))
|
||||
try:
|
||||
assert download["download_name"] == "my-folder.zip"
|
||||
assert zipfile.is_zipfile(download["file_source"])
|
||||
finally:
|
||||
Path(download["file_source"]).unlink(missing_ok=True)
|
||||
|
||||
|
||||
def test_multi_selection_download_keeps_generic_archive_name(tmp_path: Path) -> None:
|
||||
one = tmp_path / "one.txt"
|
||||
two = tmp_path / "two.txt"
|
||||
one.write_text("1", encoding="utf-8")
|
||||
two.write_text("2", encoding="utf-8")
|
||||
|
||||
download = prepare_files_download([str(one), str(two)], current_path=str(tmp_path))
|
||||
try:
|
||||
# True multi-selections keep the timestamped generic archive name.
|
||||
assert download["download_name"].startswith("agent-zero-selected-2-")
|
||||
assert download["download_name"].endswith(".zip")
|
||||
finally:
|
||||
Path(download["file_source"]).unlink(missing_ok=True)
|
||||
Loading…
Add table
Add a link
Reference in a new issue