diff --git a/photon-client/src/views/SettingsViews/General.vue b/photon-client/src/views/SettingsViews/General.vue index 46635d59b..6a98d2cae 100644 --- a/photon-client/src/views/SettingsViews/General.vue +++ b/photon-client/src/views/SettingsViews/General.vue @@ -115,7 +115,7 @@ { - this.snackbar = { - color: "success", - text: "Settings imported successfully! Program will now exit...", - }; + }).catch(err => { + if (err.response) { + this.snackbar = { + color: "error", + text: "Error while uploading settings file! Could not process provided file.", + }; + } else if (err.request) { + this.snackbar = { + color: "error", + text: "Error while uploading settings file! No respond to upload attempt.", + }; + } else { + this.snackbar = { + color: "error", + text: "Error while uploading settings file!", + }; + } this.snack = true; }); }, diff --git a/photon-server/src/main/java/org/photonvision/common/configuration/ConfigManager.java b/photon-server/src/main/java/org/photonvision/common/configuration/ConfigManager.java index cd56da46d..00b2d6c62 100644 --- a/photon-server/src/main/java/org/photonvision/common/configuration/ConfigManager.java +++ b/photon-server/src/main/java/org/photonvision/common/configuration/ConfigManager.java @@ -40,6 +40,10 @@ public class ConfigManager { private static final Logger logger = new Logger(ConfigManager.class, LogGroup.General); private static ConfigManager INSTANCE; + public static final String HW_CFG_FNAME = "hardwareConfig.json"; + public static final String HW_SET_FNAME = "hardwareSettings.json"; + public static final String NET_SET_FNAME = "networkSettings.json"; + private PhotonConfiguration config; private final File hardwareConfigFile; private final File hardwareSettingsFile; @@ -82,11 +86,11 @@ public class ConfigManager { ConfigManager(Path configDirectoryFile) { this.configDirectoryFile = new File(configDirectoryFile.toUri()); this.hardwareConfigFile = - new File(Path.of(configDirectoryFile.toString(), "hardwareConfig.json").toUri()); + new File(Path.of(configDirectoryFile.toString(), HW_CFG_FNAME).toUri()); this.hardwareSettingsFile = - new File(Path.of(configDirectoryFile.toString(), "hardwareSettings.json").toUri()); + new File(Path.of(configDirectoryFile.toString(), HW_SET_FNAME).toUri()); this.networkConfigFile = - new File(Path.of(configDirectoryFile.toString(), "networkSettings.json").toUri()); + new File(Path.of(configDirectoryFile.toString(), NET_SET_FNAME).toUri()); this.camerasFolder = new File(Path.of(configDirectoryFile.toString(), "cameras").toUri()); TimedTaskManager.getInstance().addTask("ConfigManager", this::checkSaveAndWrite, 1000); @@ -364,6 +368,33 @@ public class ConfigManager { return imgFilePath.toPath(); } + public Path getHardwareConfigFile() { + return this.hardwareConfigFile.toPath(); + } + + public Path getHardwareSettingsFile() { + return this.hardwareSettingsFile.toPath(); + } + + public Path getNetworkConfigFile() { + return this.networkConfigFile.toPath(); + } + + public void saveUploadedHardwareConfig(Path uploadPath) { + FileUtils.deleteFile(this.getHardwareConfigFile()); + FileUtils.copyFile(uploadPath, this.getHardwareConfigFile()); + } + + public void saveUploadedHardwareSettings(Path uploadPath) { + FileUtils.deleteFile(this.getHardwareSettingsFile()); + FileUtils.copyFile(uploadPath, this.getHardwareSettingsFile()); + } + + public void saveUploadedNetworkConfig(Path uploadPath) { + FileUtils.deleteFile(this.getNetworkConfigFile()); + FileUtils.copyFile(uploadPath, this.getNetworkConfigFile()); + } + public void requestSave() { logger.trace("Requesting save..."); saveRequestTimestamp = System.currentTimeMillis(); diff --git a/photon-server/src/main/java/org/photonvision/common/util/file/FileUtils.java b/photon-server/src/main/java/org/photonvision/common/util/file/FileUtils.java index 69e373f7f..56fa53eb7 100644 --- a/photon-server/src/main/java/org/photonvision/common/util/file/FileUtils.java +++ b/photon-server/src/main/java/org/photonvision/common/util/file/FileUtils.java @@ -58,6 +58,22 @@ public class FileUtils { } } + public static void deleteFile(Path path) { + try { + Files.delete(path); + } catch (IOException e) { + logger.error("Exception deleting file " + path + "!", e); + } + } + + public static void copyFile(Path src, Path dst) { + try { + Files.copy(src, dst); + } catch (IOException e) { + logger.error("Exception copying file " + src + " to " + dst + "!", e); + } + } + public static void setFilePerms(Path path) throws IOException { if (!Platform.CurrentPlatform.isWindows()) { File thisFile = path.toFile(); diff --git a/photon-server/src/main/java/org/photonvision/server/RequestHandler.java b/photon-server/src/main/java/org/photonvision/server/RequestHandler.java index 251cdc76e..2109e63ef 100644 --- a/photon-server/src/main/java/org/photonvision/server/RequestHandler.java +++ b/photon-server/src/main/java/org/photonvision/server/RequestHandler.java @@ -49,22 +49,58 @@ public class RequestHandler { public static void onSettingUpload(Context ctx) { var file = ctx.uploadedFile("zipData"); if (file != null) { - var tempZipPath = + + // Copy the file from the client to a temporary location + var tempFilePath = new File(Path.of(System.getProperty("java.io.tmpdir"), file.getFilename()).toString()); - tempZipPath.getParentFile().mkdirs(); + tempFilePath.getParentFile().mkdirs(); try { - FileUtils.copyInputStreamToFile(file.getContent(), tempZipPath); + FileUtils.copyInputStreamToFile(file.getContent(), tempFilePath); } catch (IOException e) { - logger.error("Exception uploading settings file!"); + logger.error("Exception while uploading settings file to temp folder!"); e.printStackTrace(); + return; } - ConfigManager.saveUploadedSettingsZip(tempZipPath); + + // Process the file by its extension + if (file.getExtension().contains("zip")) { + // .zip files are assumed to be full packages of configuration files + logger.debug("Processing uploaded settings zip " + file.getFilename()); + ConfigManager.saveUploadedSettingsZip(tempFilePath); + + } else if (file.getFilename().equals(ConfigManager.HW_CFG_FNAME)) { + // Filenames matching the hardware config .json file are assumed to be + // hardware config .json's + logger.debug("Processing uploaded hardware config " + file.getFilename()); + ConfigManager.getInstance().saveUploadedHardwareConfig(tempFilePath.toPath()); + + } else if (file.getFilename().equals(ConfigManager.HW_SET_FNAME)) { + // Filenames matching the hardware settings .json file are assumed to be + // hardware settings.json's + logger.debug("Processing uploaded hardware settings" + file.getFilename()); + ConfigManager.getInstance().saveUploadedHardwareSettings(tempFilePath.toPath()); + + } else if (file.getFilename().equals(ConfigManager.NET_SET_FNAME)) { + // Filenames matching the network config .json file are assumed to be + // network config .json's + logger.debug("Processing uploaded network config " + file.getFilename()); + ConfigManager.getInstance().saveUploadedNetworkConfig(tempFilePath.toPath()); + + } else { + logger.error( + "Couldn't apply provided settings file - did not recognize " + + file.getFilename() + + " as a supported file."); + ctx.status(500); + return; + } + ctx.status(200); logger.info("Settings uploaded, going down for restart."); - restartProgram(ctx); + } else { - logger.error("Couldn't read uploaded settings ZIP! Ignoring."); + logger.error("Couldn't read uploaded file! Ignoring."); ctx.status(500); } }