Can delete an OTA update
This commit is contained in:
		@@ -31,6 +31,13 @@ pub fn get_ota_update(platform: OTAPlatform, version: &semver::Version) -> anyho
 | 
			
		||||
    Ok(std::fs::read(path)?)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Delete an OTA update
 | 
			
		||||
pub fn delete_update(platform: OTAPlatform, version: &semver::Version) -> anyhow::Result<()> {
 | 
			
		||||
    let path = AppConfig::get().path_ota_update(platform, version);
 | 
			
		||||
    std::fs::remove_file(path)?;
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the list of OTA software updates for a platform
 | 
			
		||||
pub fn get_ota_updates_for_platform(platform: OTAPlatform) -> anyhow::Result<Vec<OTAUpdate>> {
 | 
			
		||||
    let ota_path = AppConfig::get().ota_platform_dir(platform);
 | 
			
		||||
 
 | 
			
		||||
@@ -195,7 +195,10 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()>
 | 
			
		||||
                "/web_api/ota/{platform}/{version}",
 | 
			
		||||
                web::get().to(ota_controller::download_firmware),
 | 
			
		||||
            )
 | 
			
		||||
            // TODO : delete an OTA file
 | 
			
		||||
            .route(
 | 
			
		||||
                "/web_api/ota/{platform}/{version}",
 | 
			
		||||
                web::delete().to(ota_controller::delete_update),
 | 
			
		||||
            )
 | 
			
		||||
            .route("/web_api/ota", web::get().to(ota_controller::list_all_ota))
 | 
			
		||||
            .route(
 | 
			
		||||
                "/web_api/ota/{platform}",
 | 
			
		||||
 
 | 
			
		||||
@@ -74,6 +74,17 @@ pub async fn download_firmware(path: web::Path<SpecificOTAVersionPath>) -> HttpR
 | 
			
		||||
        .body(firmware))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Delete an uploaded firmware update
 | 
			
		||||
pub async fn delete_update(path: web::Path<SpecificOTAVersionPath>) -> HttpResult {
 | 
			
		||||
    if !ota_manager::update_exists(path.platform, &path.version)? {
 | 
			
		||||
        return Ok(HttpResponse::NotFound().json("The requested update was not found!"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ota_manager::delete_update(path.platform, &path.version)?;
 | 
			
		||||
 | 
			
		||||
    Ok(HttpResponse::Accepted().finish())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the list of all OTA updates
 | 
			
		||||
pub async fn list_all_ota() -> HttpResult {
 | 
			
		||||
    Ok(HttpResponse::Ok().json(ota_manager::get_all_ota_updates()?))
 | 
			
		||||
 
 | 
			
		||||
@@ -40,8 +40,18 @@ export class OTAAPI {
 | 
			
		||||
  /**
 | 
			
		||||
   * Get the link to download an OTA update
 | 
			
		||||
   */
 | 
			
		||||
  static DownloadOTAUpdateURL(platform: string, version: string): string {
 | 
			
		||||
    return APIClient.backendURL() + `/ota/${platform}/${version}`;
 | 
			
		||||
  static DownloadOTAUpdateURL(update: OTAUpdate): string {
 | 
			
		||||
    return APIClient.backendURL() + `/ota/${update.platform}/${update.version}`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Delete an update
 | 
			
		||||
   */
 | 
			
		||||
  static async DeleteUpdate(update: OTAUpdate): Promise<void> {
 | 
			
		||||
    await APIClient.exec({
 | 
			
		||||
      method: "DELETE",
 | 
			
		||||
      uri: `/ota/${update.platform}/${update.version}`,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
import DeleteIcon from "@mui/icons-material/Delete";
 | 
			
		||||
import DownloadIcon from "@mui/icons-material/Download";
 | 
			
		||||
import FileUploadIcon from "@mui/icons-material/FileUpload";
 | 
			
		||||
import {
 | 
			
		||||
@@ -18,6 +19,10 @@ import { UploadUpdateDialog } from "../dialogs/UploadUpdateDialog";
 | 
			
		||||
import { AsyncWidget } from "../widgets/AsyncWidget";
 | 
			
		||||
import { RouterLink } from "../widgets/RouterLink";
 | 
			
		||||
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
 | 
			
		||||
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
 | 
			
		||||
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
 | 
			
		||||
import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider";
 | 
			
		||||
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
 | 
			
		||||
 | 
			
		||||
export function OTARoute(): React.ReactElement {
 | 
			
		||||
  const [list, setList] = React.useState<string[] | undefined>();
 | 
			
		||||
@@ -84,13 +89,45 @@ function _OTARoute(p: { platforms: Array<string> }): React.ReactElement {
 | 
			
		||||
        ready={!!list}
 | 
			
		||||
        errMsg="Failed to load the list of OTA updates!"
 | 
			
		||||
        load={load}
 | 
			
		||||
        build={() => <_OTAList list={list!} />}
 | 
			
		||||
        build={() => <_OTAList list={list!} onReload={reload} />}
 | 
			
		||||
      />
 | 
			
		||||
    </SolarEnergyRouteContainer>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function _OTAList(p: { list: OTAUpdate[] }): React.ReactElement {
 | 
			
		||||
function _OTAList(p: {
 | 
			
		||||
  list: OTAUpdate[];
 | 
			
		||||
  onReload: () => void;
 | 
			
		||||
}): React.ReactElement {
 | 
			
		||||
  const alert = useAlert();
 | 
			
		||||
  const confirm = useConfirm();
 | 
			
		||||
  const loadingMessage = useLoadingMessage();
 | 
			
		||||
  const snackbar = useSnackbar();
 | 
			
		||||
 | 
			
		||||
  const deleteUpdate = async (update: OTAUpdate) => {
 | 
			
		||||
    if (
 | 
			
		||||
      !(await confirm(
 | 
			
		||||
        `Do you really want to delete the update for platform ${update.platform} version ${update.version}?`
 | 
			
		||||
      ))
 | 
			
		||||
    )
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      loadingMessage.show("Deleting update...");
 | 
			
		||||
 | 
			
		||||
      await OTAAPI.DeleteUpdate(update);
 | 
			
		||||
 | 
			
		||||
      snackbar("The update was successfully deleted!");
 | 
			
		||||
 | 
			
		||||
      p.onReload();
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.error("Failed to delete update!", e);
 | 
			
		||||
      alert(`Failed to delete the update! ${e}`);
 | 
			
		||||
    } finally {
 | 
			
		||||
      loadingMessage.hide();
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <TableContainer component={Paper}>
 | 
			
		||||
      <Table sx={{ minWidth: 650 }} aria-label="simple table">
 | 
			
		||||
@@ -110,14 +147,17 @@ function _OTAList(p: { list: OTAUpdate[] }): React.ReactElement {
 | 
			
		||||
              <TableCell align="center">{filesize(row.file_size)}</TableCell>
 | 
			
		||||
              <TableCell align="center">
 | 
			
		||||
                <Tooltip title="Download a copy of the firmware">
 | 
			
		||||
                  <RouterLink
 | 
			
		||||
                    to={OTAAPI.DownloadOTAUpdateURL(row.platform, row.version)}
 | 
			
		||||
                  >
 | 
			
		||||
                  <RouterLink to={OTAAPI.DownloadOTAUpdateURL(row)}>
 | 
			
		||||
                    <IconButton>
 | 
			
		||||
                      <DownloadIcon />
 | 
			
		||||
                    </IconButton>
 | 
			
		||||
                  </RouterLink>
 | 
			
		||||
                </Tooltip>
 | 
			
		||||
                <Tooltip title="Delete firmware update">
 | 
			
		||||
                  <IconButton onClick={() => deleteUpdate(row)}>
 | 
			
		||||
                    <DeleteIcon />
 | 
			
		||||
                  </IconButton>
 | 
			
		||||
                </Tooltip>
 | 
			
		||||
              </TableCell>
 | 
			
		||||
            </TableRow>
 | 
			
		||||
          ))}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user