Can download disk images
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Pierre HUBERT 2025-05-29 10:23:26 +02:00
parent 927a51cda7
commit e7ac0198ab
4 changed files with 89 additions and 3 deletions

View File

@ -3,9 +3,10 @@ use crate::constants;
use crate::controllers::HttpResult;
use crate::utils::file_disks_utils::DiskFileInfo;
use crate::utils::files_utils;
use actix_files::NamedFile;
use actix_multipart::form::MultipartForm;
use actix_multipart::form::tempfile::TempFile;
use actix_web::{HttpResponse, web};
use actix_web::{HttpRequest, HttpResponse, web};
#[derive(Debug, MultipartForm)]
pub struct UploadDiskImageForm {
@ -73,6 +74,23 @@ pub struct DiskFilePath {
filename: String,
}
/// Download disk image
pub async fn download(p: web::Path<DiskFilePath>, req: HttpRequest) -> HttpResult {
if !files_utils::check_file_name(&p.filename) {
return Ok(HttpResponse::BadRequest().json("Invalid file name!"));
}
let file_path = AppConfig::get()
.disk_images_storage_path()
.join(&p.filename);
if !file_path.exists() {
return Ok(HttpResponse::NotFound().json("Disk image does not exists!"));
}
Ok(NamedFile::open(file_path)?.into_response(&req))
}
/// Delete a disk image
pub async fn delete(p: web::Path<DiskFilePath>) -> HttpResult {
if !files_utils::check_file_name(&p.filename) {

View File

@ -345,6 +345,10 @@ async fn main() -> std::io::Result<()> {
"/api/disk_images/list",
web::get().to(disk_images_controller::get_list),
)
.route(
"/api/disk_images/{filename}",
web::get().to(disk_images_controller::download),
)
.route(
"/api/disk_images/{filename}",
web::delete().to(disk_images_controller::delete),

View File

@ -43,6 +43,24 @@ export class DiskImageApi {
).data;
}
/**
* Download disk image file
*/
static async Download(
file: DiskImage,
progress: (p: number) => void
): Promise<Blob> {
return (
await APIClient.exec({
method: "GET",
uri: `/disk_images/${file.file_name}`,
downProgress(e) {
progress(Math.floor(100 * (e.progress / e.total)));
},
})
).data;
}
/**
* Delete disk image file
*/

View File

@ -2,7 +2,9 @@ import DeleteIcon from "@mui/icons-material/Delete";
import DownloadIcon from "@mui/icons-material/Download";
import RefreshIcon from "@mui/icons-material/Refresh";
import {
Alert,
Button,
CircularProgress,
IconButton,
LinearProgress,
Tooltip,
@ -22,6 +24,7 @@ import { DateWidget } from "../widgets/DateWidget";
import { FileInput } from "../widgets/forms/FileInput";
import { VirtWebPaper } from "../widgets/VirtWebPaper";
import { VirtWebRouteContainer } from "../widgets/VirtWebRouteContainer";
import { downloadBlob } from "../utils/FilesUtils";
export function DiskImagesRoute(): React.ReactElement {
const [list, setList] = React.useState<DiskImage[] | undefined>();
@ -159,6 +162,24 @@ function DiskImageList(p: {
const confirm = useConfirm();
const loadingMessage = useLoadingMessage();
const [dlProgress, setDlProgress] = React.useState<undefined | number>();
// Download disk image file
const downloadDiskImage = async (entry: DiskImage) => {
setDlProgress(0);
try {
const blob = await DiskImageApi.Download(entry, setDlProgress);
downloadBlob(blob, entry.file_name);
} catch (e) {
console.error(e);
alert(`Failed to download disk image file! ${e}`);
}
setDlProgress(undefined);
};
// Delete disk image
const deleteDiskImage = async (entry: DiskImage) => {
if (
@ -220,7 +241,7 @@ function DiskImageList(p: {
return (
<>
<Tooltip title="Download image">
<IconButton onClick={() => downloadIso(params.row)}>
<IconButton onClick={() => downloadDiskImage(params.row)}>
<DownloadIcon />
</IconButton>
</Tooltip>
@ -236,6 +257,31 @@ function DiskImageList(p: {
];
return (
<DataGrid getRowId={(c) => c.file_name} rows={p.list} columns={columns} />
<>
{/* Download notification */}
{dlProgress !== undefined && (
<Alert severity="info">
<div
style={{
display: "flex",
flexDirection: "row",
alignItems: "center",
overflow: "hidden",
}}
>
<Typography variant="body1">
Downloading... {dlProgress}%
</Typography>
<CircularProgress
variant="determinate"
size={"1.5rem"}
style={{ marginLeft: "10px" }}
value={dlProgress}
/>
</div>
</Alert>
)}
<DataGrid getRowId={(c) => c.file_name} rows={p.list} columns={columns} />
</>
);
}