diff --git a/config.properties b/config.properties index 0850f98..ed53fba 100644 --- a/config.properties +++ b/config.properties @@ -1,4 +1,4 @@ -#Mon Dec 16 15:02:10 WIB 2024 +#Tue Dec 17 09:22:55 WIB 2024 AudioPhase1=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase1.mp3 AudioPhase2=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase2.mp3 AudioPhase3=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase3.mp3 @@ -11,7 +11,7 @@ CameraConfigLeft90={"Brightness"\:0.0,"Contrast"\:32.0,"Saturation"\:64.0,"Hue"\ CameraConfigRight45={"Brightness"\:0.0,"Contrast"\:32.0,"Saturation"\:64.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:157.0,"Sharpness"\:3.0,"Gamma"\:100.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true} CameraConfigRight90={"Brightness"\:0.0,"Contrast"\:32.0,"Saturation"\:64.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:157.0,"Sharpness"\:3.0,"Gamma"\:100.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true} CameraLeft45=OBSBOT Meet 2 StreamCamera -CameraLeft90=OBSBOT Meet 2 StreamCamera +CameraLeft90=ACER QHD User Facing CameraRight45=OBSBOT Meet 2 StreamCamera CameraRight90=OBSBOT Meet 2 StreamCamera FTPHost=192.168.10.2 diff --git a/database.db b/database.db index 30c9d3f..e12762c 100644 Binary files a/database.db and b/database.db differ diff --git a/src/main/java/FTP/FtpMonitorData.java b/src/main/java/FTP/FtpMonitorData.java new file mode 100644 index 0000000..fa9dafa --- /dev/null +++ b/src/main/java/FTP/FtpMonitorData.java @@ -0,0 +1,19 @@ +package FTP; + +import id.co.gtc.erhacam.UploadProgress; + +public class FtpMonitorData { + public String information; + public String filename; + public UploadProgress progress; + public long total; + public long current; + + public FtpMonitorData(String information, String filename, UploadProgress progress, long total, long current) { + this.information = information; + this.filename = filename; + this.progress = progress; + this.total = total; + this.current = current; + } +} diff --git a/src/main/java/id/co/gtc/erhacam/CaptureView.java b/src/main/java/id/co/gtc/erhacam/CaptureView.java index a651ca1..531562f 100644 --- a/src/main/java/id/co/gtc/erhacam/CaptureView.java +++ b/src/main/java/id/co/gtc/erhacam/CaptureView.java @@ -9,26 +9,28 @@ import Database.PhotoReviewClass; import Database.Sqlite; import FTP.FTPUpload; import FTP.FTPUploadEvent; +import FTP.FtpMonitorData; import javafx.application.Platform; + import javafx.beans.InvalidationListener; -import javafx.beans.Observable; -import javafx.beans.value.ChangeListener; -import javafx.beans.value.ObservableValue; import javafx.concurrent.Task; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; -import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.Button; import javafx.scene.control.TextArea; import javafx.scene.layout.AnchorPane; import javafx.stage.DirectoryChooser; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; import javafx.scene.control.Alert.AlertType; import org.bytedeco.javacv.OpenCVFrameGrabber; @@ -65,6 +67,7 @@ public class CaptureView { private List cams; + private final AtomicBoolean[] have_face = new AtomicBoolean[5]; @FXML private void ChangeDirectory(){ @@ -103,12 +106,17 @@ public class CaptureView { @SuppressWarnings("resource") @FXML private void TakePhotos(){ + boolean has_face = Arrays.stream(have_face).anyMatch(AtomicBoolean::get); + if (!has_face){ + audioPlayer.PlayFile(audio_posisikan_muka, ps); + return; + } Size thumbsize = new Size(160,120); String directory = directorypath.getText(); String prefix = RemoveSpaces(prefixfile.getText()) ; if (ValidDirectory(directory)){ if (ValidString(prefix)){ - audioPlayer.PlayFile(audio_posisi_diam, ps); + //audioPlayer.PlayFile(audio_posisi_diam, ps); PhotoReviewClass prc = new PhotoReviewClass(); prc.setPrefix(prefix); @@ -208,9 +216,30 @@ public class CaptureView { String[] files = prc.files(); if (files!=null && files.length>0){ InsertSQL(prc); + progressanchor.getChildren().clear(); prefixfile.setText(""); - new Thread(()-> UploadToFTP(files)).start(); + new Thread(()-> { + try{ + InetAddress target = InetAddress.getByName(config.getFTPHost()); + int port = toInt(config.getFTPPort()); + if (target.isReachable(2000)){ + Socket socket = new Socket(); + InetSocketAddress isa = new InetSocketAddress(target, port); + socket.connect(isa,2000); + socket.close(); + // sampai sini berarti FTP Host reachable + UploadToFTP(files); + } else throw new Exception("FTP Host not reachable"); + } catch (Exception e){ + Logger.error("Error UploadToFTP: "+e.getMessage()); + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle("Error"); + alert.setHeaderText("Upload to FTP Failed"); + alert.setContentText("Error: "+e.getMessage()); + alert.showAndWait(); + } + }).start(); } else { Alert Alert = new Alert(AlertType.ERROR); Alert.setTitle("Error"); @@ -412,6 +441,7 @@ public class CaptureView { private void SetupCameraWithController(Cameradetail image, String cameraname, int devicenumber){ if (image!=null){ + String title = switch(image.getCameraConfigEnum()){ case CameraConfigCenter -> "03"; case CameraConfigLeft45 -> "02"; @@ -419,6 +449,15 @@ public class CaptureView { case CameraConfigRight45 -> "04"; case CameraConfigRight90 -> "05"; }; + + final AtomicBoolean _have_face = switch (image.getCameraConfigEnum()){ + case CameraConfigCenter -> have_face[2]; + case CameraConfigLeft45 -> have_face[1]; + case CameraConfigLeft90 -> have_face[0]; + case CameraConfigRight45 -> have_face[3]; + case CameraConfigRight90 -> have_face[4]; + }; + Platform.runLater(()-> image.setCameraTitle(title)); if (devicenumber!=-1){ OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(devicenumber); @@ -460,11 +499,12 @@ public class CaptureView { + LiveCamEvent lce = new LiveCamEvent() { @Override public void onDetectedQRCode(String qrCode) { Platform.runLater(()->prefixfile.setText(RemoveSpaces(qrCode))); - if (ValidString(qrCode)) audioPlayer.PlayFile(audio_posisikan_muka, ps); + //if (ValidString(qrCode)) audioPlayer.PlayFile(audio_posisikan_muka, ps); } @Override @@ -472,7 +512,8 @@ public class CaptureView { Platform.runLater(()-> { String ss = hasface ? String.format("Camera Started, %dx%d@%d, Face Detected", width, height, image.getLiveFPS()) : String.format("Camera Started, %dx%d@%d", width, height, image.getLiveFPS()); image.setCameraStatus(ss); - //String qr = prefixfile.getText(); + _have_face.set(hasface); + //if (ValidString(qr) && hasface) audioPlayer.PlayFile(audio_posisikan_muka, ps); }); } @@ -496,6 +537,7 @@ public class CaptureView { private void LoadCameraDetail(AnchorPane cam, int camid, CameraConfigEnum cc){ try{ + have_face[camid-1] = new AtomicBoolean(false); FXMLLoader loader = new FXMLLoader(getClass().getResource("cameradetail.fxml")); AnchorPane child = loader.load(); @@ -561,6 +603,7 @@ public class CaptureView { final double uploadprogressheight = 50; Map progressmap = new HashMap<>(); + // Load uploadprogress.fxml for each file for (String filetoupload : files){ Task loadtask = new Task<>() { @Override @@ -579,100 +622,127 @@ public class CaptureView { return pane; } }; + // kalau berhasil, add ke progressanchor loadtask.setOnSucceeded(e-> progressanchor.getChildren().add(loadtask.getValue())); + // kalau gagal, log error loadtask.setOnFailed(e-> Logger.error("Error LoadTask: {}",e.getSource().getMessage())); new Thread(loadtask).start(); } - FTPUpload ftp = new FTPUpload(config.getFTPHost(), toInt(config.getFTPPort()), config.getFTPUser(), config.getFTPPass(), config.getFTPPath()); - ftp.UploadFile(new FTPUploadEvent() { - @Override - public void onUploadSuccess(String file) { - Logger.info("Upload Success: {}" ,file); - UploadProgress up = progressmap.get(GetFileName(file)); - if (up!=null){ - Platform.runLater(()->{ - up.SetStatus("Success"); - up.SetProgress(1,1); - }); - } + + InvalidationListener progressanchorlistener = observable -> { + // kalau sudah selesai load semua, mulai upload + Logger.info("Progress Anchor Children Size: {}", progressanchor.getChildren().size()); + if (progressanchor.getChildren().size()==files.length){ + Task monitorFTP = new Task<>() { + @Override + protected FtpMonitorData call() throws Exception { + FTPUpload ftp = new FTPUpload(config.getFTPHost(), toInt(config.getFTPPort()), config.getFTPUser(), config.getFTPPass(), config.getFTPPath()); + ftp.UploadFile(new FTPUploadEvent() { + @Override + public void onUploadSuccess(String file) { + Logger.info("Upload Success: {}" ,file); + String filename = GetFileName(file); + UploadProgress up = progressmap.get(filename); + if (up!=null){ + updateValue(new FtpMonitorData("Success", filename, up, 1, 1)); +// Platform.runLater(()->{ +// up.SetStatus("Success"); +// up.SetProgress(1,1); +// }); + + } + } + + @Override + public void onUploadFailed(String file) { + Logger.info("Upload Failed: {}",file); + String filename = GetFileName(file); + UploadProgress up = progressmap.get(filename); + if (up!=null){ + updateValue(new FtpMonitorData("Failed", filename, up, 1, 0)); +// Platform.runLater(()->{ +// up.SetStatus("Failed"); +// up.SetProgress(0,1); +// }); + + } + } + + @Override + public void onUploadProgress(String file, long bytes, long total) { + String filename = GetFileName(file); + UploadProgress up = progressmap.get(filename); + if (up!=null){ + updateValue(new FtpMonitorData("Uploading", filename, up, total, bytes)); +// Platform.runLater(()->up.SetProgress(bytes, total)); + } + } + + @Override + public void onUploadStarted(String file) { + Logger.info("Upload Started: {}",file); + String filename = GetFileName(file); + UploadProgress up = progressmap.get(filename); + if (up!=null){ + updateValue(new FtpMonitorData("Started", filename, up, 0, 0)); +// Platform.runLater(()->{ +// up.SetStatus("Started"); +// up.SetProgress(0,0); +// }); + } + + } + + @Override + public void uploadLog(String msg) { + Logger.info("Upload Log: {}",msg); + } + + @Override + public void onUploadFinished(int total, int success, int failed, String[] files) { + Logger.info("Upload Finished, Total: {}, Success: {}, Failed: {}", total, success, failed); + Platform.runLater(()->{ + audioPlayer.PlayFile(audio_ke_ruangtunggu, ps); + Alert Alert = new Alert(AlertType.INFORMATION); + Alert.setTitle("Upload Finished"); + Alert.setHeaderText("Upload Finished"); + Alert.setContentText("Total: "+total+"\nSuccess: "+success+"\nFailed: "+failed); + Alert.showAndWait(); + }); + } + }, files); + + + + // Task selesai, return null + return null; + } + }; + + monitorFTP.valueProperty().addListener( + (observable1, oldValue, newValue) -> { + if (newValue!=null){ + if (newValue.progress!=null){ + newValue.progress.SetStatus(newValue.information); + newValue.progress.SetProgress(newValue.current, newValue.total); + } + } + } + ); + + new Thread(monitorFTP).start(); } + }; - @Override - public void onUploadFailed(String file) { - Logger.info("Upload Failed: {}",file); - UploadProgress up = progressmap.get(GetFileName(file)); - if (up!=null){ - Platform.runLater(()->{ - up.SetStatus("Failed"); - up.SetProgress(0,1); - }); + progressanchor.getChildren().addListener(progressanchorlistener); - } - } - @Override - public void onUploadProgress(String file, long bytes, long total) { - UploadProgress up = progressmap.get(GetFileName(file)); - if (up!=null){ - Platform.runLater(()->up.SetProgress(bytes, total)); - } - } - - @Override - public void onUploadStarted(String file) { - Logger.info("Upload Started: {}",file); - UploadProgress up = progressmap.get(GetFileName(file)); - if (up!=null){ - Platform.runLater(()->{ - up.SetStatus("Started"); - up.SetProgress(0,0); - }); - } - - } - - @Override - public void uploadLog(String msg) { - Logger.info("Upload Log: {}",msg); - } - - @Override - public void onUploadFinished(int total, int success, int failed, String[] files) { - Logger.info("Upload Finished, Total: {}, Success: {}, Failed: {}", total, success, failed); - Platform.runLater(()->{ - audioPlayer.PlayFile(audio_ke_ruangtunggu, ps); - Alert Alert = new Alert(AlertType.INFORMATION); - Alert.setTitle("Upload Finished"); - Alert.setHeaderText("Upload Finished"); - Alert.setContentText("Total: "+total+"\nSuccess: "+success+"\nFailed: "+failed); - Alert.showAndWait(); - }); - } - }, files); } -// private void Load_UploadProgress(Map progressmap, String filename, double uploadprogressheight){ -// try{ -// FXMLLoader loader = new FXMLLoader(getClass().getResource("uploadprogress.fxml")); -// AnchorPane pane = loader.load(); -// pane.prefWidthProperty().bind(progressanchor.widthProperty()); -// pane.setPrefHeight(uploadprogressheight); -// UploadProgress up = loader.getController(); -// up.SetFile(filename); -// up.SetStatus("Started"); -// up.SetProgress(0,0); -// int ii = progressmap.size(); -// AnchorPane.setTopAnchor(pane, (ii*uploadprogressheight)+10); -// progressanchor.getChildren().add(pane); -// progressmap.put(filename, up); -// -// } catch (Exception e){ -// Logger.error("Error loading uploadprogress.fxml: "+e.getMessage()); -// } -// } + private void InsertSQL(PhotoReviewClass prc){ Sqlite sql = new Sqlite();