Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import com.portalmedia.embarc.gui.Main;
import com.portalmedia.embarc.gui.helper.CleanInputPathHelper;
import com.portalmedia.embarc.gui.helper.DPXFileListHelper;
import com.portalmedia.embarc.gui.model.DPXFileInformationViewModel;
import com.portalmedia.embarc.system.DiskSpaceChecker;
import com.portalmedia.embarc.system.UserPreferencesService;

import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon;
Expand Down Expand Up @@ -185,6 +189,15 @@ public void changed(ObservableValue<? extends Boolean> observable, Boolean oldVa
final String tmpWriteFilesPath = saveAsCb.isSelected() ? writeFilesPath.getText() : "";
final String tmpReportPath = reportCb.isSelected() ? reportPath.getText() : "";

// Check for available disk space when saving to a separate directory
if (saveAsCb.isSelected() && !tmpWriteFilesPath.isEmpty()) {
List<DPXFileInformationViewModel> fileList = DPXFileListHelper.getAllFilesToWrite(writeEditedCb.isSelected());
if (!DiskSpaceChecker.checkDiskSpaceForDPX(tmpWriteFilesPath, fileList)) {
// User chose not to proceed due to insufficient disk space
return;
}
}

final WriteFilesDialog d = new WriteFilesDialog(tmpWriteFilesPath, tmpReportPath,
writeEditedCb.isSelected());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@

import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.portalmedia.embarc.gui.Main;
import com.portalmedia.embarc.gui.helper.MXFFileList;
import com.portalmedia.embarc.parser.FileInformation;
import com.portalmedia.embarc.parser.mxf.MXFMetadata;
import com.portalmedia.embarc.system.DiskSpaceChecker;
import com.portalmedia.embarc.gui.helper.CleanInputPathHelper;
import com.portalmedia.embarc.system.UserPreferencesService;

Expand Down Expand Up @@ -147,6 +152,25 @@ public void changed(ObservableValue<? extends Boolean> observable, Boolean oldVa

final String tmpWriteFilesPath = saveAsCb.isSelected() ? writeFilesPath.getText() : "";

// Check for available disk space when saving to a separate directory
if (saveAsCb.isSelected() && !tmpWriteFilesPath.isEmpty()) {
List<FileInformation<MXFMetadata>> fileList;
if (writeEditedCb.isSelected()) {
// Filter to only get edited files
fileList = MXFFileList.getList().stream()
.filter(file -> file.isEdited() && file.getFileShouldBeWritten())
.collect(java.util.stream.Collectors.toList());
} else {
// Get all files
fileList = MXFFileList.getList();
}

if (!DiskSpaceChecker.checkDiskSpaceForMXF(tmpWriteFilesPath, fileList)) {
// User chose not to proceed due to insufficient disk space
return;
}
}

WriteFilesDialogMXF d;
try {
d = new WriteFilesDialogMXF(tmpWriteFilesPath, writeEditedCb.isSelected());
Expand Down
168 changes: 168 additions & 0 deletions src/main/com/portalmedia/embarc/system/DiskSpaceChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package com.portalmedia.embarc.system;

import java.io.File;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.portalmedia.embarc.gui.Main;
import com.portalmedia.embarc.gui.model.DPXFileInformationViewModel;
import com.portalmedia.embarc.parser.FileInformation;
import com.portalmedia.embarc.parser.mxf.MXFMetadata;

import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;

/**
* Utility class to check available disk space before writing files
*
* @author PortalMedia
* @version 1.0
* @since 2025-05-11
*/
public class DiskSpaceChecker {
private static final Logger LOGGER = Logger.getLogger(DiskSpaceChecker.class.getName());

/**
* Checks if there is enough disk space available in the target directory for DPX files
*
* @param targetDir The directory where files will be written
* @param fileList List of DPX files to be written
* @return true if user confirms to proceed or if there's enough space, false otherwise
*/
public static boolean checkDiskSpaceForDPX(String targetDir, List<DPXFileInformationViewModel> fileList) {
if (targetDir == null || targetDir.isEmpty() || fileList == null || fileList.isEmpty()) {
return true;
}

File directory = new File(targetDir);
if (!directory.exists()) {
// Create directory if it doesn't exist
if (!directory.mkdirs()) {
LOGGER.log(Level.WARNING, "Failed to create directory: " + targetDir);
return true; // Continue anyway as this will be handled during file writing
}
}

// Calculate total size of files to be written
long totalSize = 0;
for (DPXFileInformationViewModel file : fileList) {
try {
String filePath = file.getProp("path");
if (filePath != null && !filePath.isEmpty()) {
File sourceFile = new File(filePath);
if (sourceFile.exists()) {
totalSize += sourceFile.length();
}
}
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error calculating file size", e);
}
}

// Get available space in target directory
long availableSpace = directory.getFreeSpace();

// If available space is less than total size, show confirmation dialog
if (availableSpace < totalSize) {
LOGGER.log(Level.SEVERE, "Available space is less than total size");
return showConfirmationDialog(totalSize, availableSpace);
}

return true;
}

/**
* Checks if there is enough disk space available in the target directory for MXF files
*
* @param targetDir The directory where files will be written
* @param fileList List of MXF files to be written
* @return true if user confirms to proceed or if there's enough space, false otherwise
*/
public static boolean checkDiskSpaceForMXF(String targetDir, List<FileInformation<MXFMetadata>> fileList) {
if (targetDir == null || targetDir.isEmpty() || fileList == null || fileList.isEmpty()) {
return true;
}

File directory = new File(targetDir);
if (!directory.exists()) {
// Create directory if it doesn't exist
if (!directory.mkdirs()) {
LOGGER.log(Level.WARNING, "Failed to create directory: " + targetDir);
return true; // Continue anyway as this will be handled during file writing
}
}

// Calculate total size of files to be written
long totalSize = 0;
for (FileInformation<MXFMetadata> file : fileList) {
try {
totalSize += file.getFileData().getFileSize();
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Error calculating file size", e);
}
}

// Get available space in target directory
long availableSpace = directory.getFreeSpace();

// If available space is less than total size, show confirmation dialog
if (availableSpace < totalSize) {
return showConfirmationDialog(totalSize, availableSpace);
}

return true;
}

/**
* Shows a confirmation dialog to the user when there's not enough disk space
*
* @param requiredSpace The amount of space required for the files
* @param availableSpace The amount of space available on the disk
* @return true if user confirms to proceed, false otherwise
*/
private static boolean showConfirmationDialog(long requiredSpace, long availableSpace) {
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("Disk Space Warning");
alert.setHeaderText("Insufficient Disk Space");

String formattedRequired = formatSize(requiredSpace);
String formattedAvailable = formatSize(availableSpace);

alert.setContentText("embARC is about to write " + formattedRequired + " of data, but only " +
formattedAvailable + " is available on the target drive. Do you want to continue?");

ButtonType buttonTypeYes = new ButtonType("Yes", ButtonData.YES);
ButtonType buttonTypeNo = new ButtonType("No", ButtonData.NO);

alert.getButtonTypes().setAll(buttonTypeYes, buttonTypeNo);
alert.initOwner(Main.getPrimaryStage());

Optional<ButtonType> result = alert.showAndWait();
return result.isPresent() && result.get() == buttonTypeYes;
}

/**
* Formats a size in bytes to a human-readable string (KB, MB, GB, TB)
*
* @param size Size in bytes
* @return Formatted string
*/
private static String formatSize(long size) {
if (size <= 0) return "0 B";

final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" };
int digitGroups = (int) (Math.log10(size) / Math.log10(1024));

if (digitGroups >= units.length) {
digitGroups = units.length - 1;
}

DecimalFormat df = new DecimalFormat("#,##0.##");
return df.format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
}
}