Commit 13052025

Old Photo Deleter .
This commit is contained in:
2025-05-13 14:52:26 +07:00
parent d2e7d1155d
commit bc6821a33e
9 changed files with 302 additions and 14 deletions

View File

@@ -12,6 +12,7 @@ import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.PixelFormat;
import javafx.scene.image.WritableImage;
import lombok.NonNull;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter;
@@ -34,9 +35,12 @@ import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.bytedeco.opencv.global.opencv_core.CV_64F;
@@ -182,6 +186,74 @@ public class SomeCodes {
return x.format(dtf);
}
public static LocalDateTime StringToLocalDateTime(String x){
if (ValidString(x)){
try{
return LocalDateTime.parse(x, dtf);
} catch (Exception e){
Logger.error("Error parsing date: "+x+", Msg : "+e.getMessage());
}
}
return null;
}
public static LocalDateTime GetCreationTime(Path p){
try{
BasicFileAttributes attr = Files.readAttributes(p, BasicFileAttributes.class);
FileTime ft = attr.creationTime();
return LocalDateTime.ofInstant(ft.toInstant(), java.time.ZoneId.systemDefault());
} catch (Exception e){
Logger.error("Error getting creation time: "+p+", Msg : "+e.getMessage());
}
return null;
}
public static @NonNull Path[] GetFilesInDirectory(String path) {
if (ValidDirectory(path)) {
try{
return Files.list(Path.of(path))
.filter(Files::isRegularFile)
.toArray(Path[]::new);
} catch (Exception ignored){}
}
return new Path[0];
}
public static boolean Delete(String... path){
if (path!=null && path.length>0){
Boolean[] result = new Boolean[path.length];
for(int i=0; i<path.length; i++){
try{
result[i] = Files.deleteIfExists(Path.of(path[i]));
if (result[i]) System.out.println("Delete: "+path[i]);
} catch (Exception e){
result[i] = false;
System.out.println("Error deleting file: "+path[i]+", Msg : "+e.getMessage());
}
}
return Arrays.stream(result).allMatch(x->x);
}
return false;
}
public static boolean Delete(Path... path){
if (path!=null && path.length>0){
Boolean[] result = new Boolean[path.length];
for(int i=0; i<path.length; i++){
try{
result[i] = Files.deleteIfExists(path[i]);
if (result[i]) System.out.println("Delete: "+path[i]);
} catch (Exception e){
result[i] = false;
System.out.println("Error deleting file: "+path[i]+", Msg : "+e.getMessage());
}
}
return Arrays.stream(result).allMatch(x->x);
}
return false;
}
/**
* Extract resource file to current directory
* @param filename resource file name

View File

@@ -0,0 +1,130 @@
package Database;
import Config.SomeCodes;
import org.tinylog.Logger;
import java.nio.file.Path;
import java.time.LocalDateTime;
/**
* PhotoCleaner class
* Responsible for deleting photos older than a certain number of days
*/
public class PhotoCleaner {
private final int days;
private final boolean[] started;
/**
* PhotoCleaner constructor
* @param days how many days old photos to delete
*/
public PhotoCleaner(int days){
this.days = days;
this.started = new boolean[]{false};
System.out.println("PhotoCleaner created, days: "+days);
}
/**
* Start PhotoCleaner Thread
*/
@SuppressWarnings("BusyWait")
public void Start(){
Thread thread = new Thread(() -> {
started[0] = true;
System.out.println("PhotoCleaner started");
while (started[0]) {
try {
System.out.println("Rechecking Database for older photos...");
// Delete photos older than the specified number of days
LocalDateTime now = LocalDateTime.now();
// delete from database
Thread sqldelete = new Thread(()->{
Sqlite sql = new Sqlite();
PhotoReviewClass[] prcs = sql.GetAll();
System.out.println("Database contains "+prcs.length+" PhotoReviewClass");
for (PhotoReviewClass prc : prcs) {
if (!started[0]) break;
if (prc != null && prc.getDateTime() != null) {
LocalDateTime ldt = SomeCodes.StringToLocalDateTime(prc.getDateTime());
if (ldt!=null){
if (ldt.isBefore(now.minusDays(days))) {
SomeCodes.Delete(prc.fullres());
SomeCodes.Delete(prc.cropped());
SomeCodes.Delete(prc.compressed());
SomeCodes.Delete(prc.compressedcrop());
SomeCodes.Delete(prc.thumbnails());
sql.Delete(prc);
System.out.println("Deleted PhotoReviewClass: " + prc.getDateTime() + " " + prc.getPrefix());
}
}
}
}
});
RunThread(sqldelete, "DeleteFromDatabase");
// delete from disk
Thread deletefullres = new Thread(new DiskDeleter(SomeCodes.config.getFullQualityDirectory()));
RunThread(deletefullres, "DeleteFullRes");
Thread deletefullrescrop = new Thread(new DiskDeleter(SomeCodes.config.getFullQualityCropDirectory()));
RunThread(deletefullrescrop, "DeleteFullResCrop");
Thread deletecompressed = new Thread(new DiskDeleter(SomeCodes.config.getCompressedDirectory()));
RunThread(deletecompressed, "DeleteCompressed");
Thread deletecompressedcrop = new Thread(new DiskDeleter(SomeCodes.config.getCompressedCropDirectory()));
RunThread(deletecompressedcrop, "DeleteCompressedCrop");
Thread deletethumbnails = new Thread(new DiskDeleter(SomeCodes.config.getThumbsDirectory()));
RunThread(deletethumbnails, "DeleteThumbnails");
// Sleep for 1 hour
Thread.sleep(60 * 60 * 1000);
} catch (Exception e) {
Logger.error("Error in PhotoCleaner Thread: " + e.getMessage());
}
}
System.out.println("PhotoCleaner stopped");
});
thread.setName("PhotoCleaner Thread");
thread.setDaemon(true);
thread.start();
}
private void RunThread(Thread thread, String name){
thread.setName(name);
thread.setDaemon(true);
thread.start();
}
class DiskDeleter implements Runnable{
private final String path;
private final LocalDateTime now ;
public DiskDeleter(String path){
this.path = path;
this.now = LocalDateTime.now();
}
public void run(){
System.out.println("DiskDeleter started, path: "+path);
Path[] ppp = SomeCodes.GetFilesInDirectory(path);
if (ppp != null){
System.out.println("DiskDeleter found "+ppp.length+" files in path: "+path);
for(Path p : ppp){
if (!started[0]) break;
LocalDateTime ldt = SomeCodes.GetCreationTime(p);
if (ldt != null) {
if (ldt.isBefore(now.minusDays(days))) {
SomeCodes.Delete(p);
}
}
}
}
}
}
/**
* Stop PhotoCleaner Thread
*/
public void Stop(){
started[0] = false;
}
}

View File

@@ -2,6 +2,8 @@ package Database;
import lombok.Data;
import java.time.LocalDateTime;
import static Config.SomeCodes.MakeArray;
@Data

View File

@@ -40,13 +40,32 @@ public class Sqlite {
*/
public void Insert(PhotoReviewClass pr){
if (pr!=null){
// System.out.println("Inserting PhotoReviewClass");
// System.out.println(pr);
Insert(pr.getPrefix(), pr.getFileLeft90(), pr.getFileLeft45(), pr.getFileCenter(), pr.getFileRight45(), pr.getFileRight90(), pr.getThumbLeft90(), pr.getThumbLeft45(), pr.getThumbCenter(), pr.getThumbRight45(), pr.getThumbRight90());
}
}
/**
* Delete PhotoReviewClass object from database
* @param pr PhotoReviewClass objects
*/
public void Delete(PhotoReviewClass... pr){
if (pr!=null && pr.length>0){
try{
Connection conn = GetConnection();
if (conn != null){
for (PhotoReviewClass photo : pr) {
PreparedStatement stmt = conn.prepareStatement("DELETE FROM photos WHERE id = ?");
stmt.setInt(1, photo.getId());
stmt.execute();
}
conn.close();
Logger.info("Data deleted successfully");
} else Logger.info("Delete failed, connection is null");
} catch (Exception e){
Logger.error("Error deleting data: "+e.getMessage());
}
}
}
/**
* Get all PhotoReviewClass object from database
@@ -108,14 +127,6 @@ public class Sqlite {
try{
Connection conn = GetConnection();
if (conn != null){
// System.out.println("Inserting data");
// System.out.println("prefix: "+prefix);
// System.out.println("fileLeft90: "+fileLeft90);
// System.out.println("fileLeft45: "+fileLeft45);
// System.out.println("fileCenter: "+fileCenter);
// System.out.println("fileRight45: "+fileRight45);
// System.out.println("fileRight90: "+fileRight90);
PreparedStatement stmt = conn.prepareStatement("INSERT INTO photos (DateTime, Prefix, FileLeft90, FileLeft45, FileCenter, FileRight45, FileRight90, ThumbLeft90, ThumbLeft45, ThumbCenter, ThumbRight45, ThumbRight90 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
stmt.setString(1, LocalDateTimeToString(LocalDateTime.now()));
stmt.setString(2, ValidString(prefix)?prefix:"");

View File

@@ -1,6 +1,7 @@
package id.co.gtc.erhacam;
import Config.SomeCodes;
import Database.PhotoCleaner;
import SecureDongle.SecureDongle;
import SecureDongle.SecureDongleEvent;
import javafx.application.Application;
@@ -21,6 +22,8 @@ import static Config.SomeCodes.config;
public class MainApplication extends Application {
PhotoCleaner photoCleaner;
@Override
public void start(Stage stage) throws IOException {
@@ -31,6 +34,7 @@ public class MainApplication extends Application {
System.out.println("Thread: " + thread.getName()+", State: " + thread.getState()+", Daemon: " + thread.isDaemon());
//thread.interrupt();
}
if (photoCleaner!=null) photoCleaner.Stop();
}));
@@ -46,7 +50,7 @@ public class MainApplication extends Application {
Screen screen = Screen.getPrimary();
Rectangle2D screenbound = screen.getBounds();
Scene scene = new Scene(fxmlLoader.load(), screenbound.getWidth(), screenbound.getHeight());
stage.setTitle("MultiCam Capture App for ERHA 09052025-001");
stage.setTitle("MultiCam Capture App for ERHA 13052025-001");
stage.setScene(scene);
stage.setResizable(true);
stage.setMaximized(true);
@@ -82,6 +86,9 @@ public class MainApplication extends Application {
});
sd.StartMonitor();
photoCleaner = new PhotoCleaner(90);
photoCleaner.Start();
} else {
ShowAlert(Alert.AlertType.ERROR, "Secure Dongle UserID not valid", "Secure Dongle UserID not valid", "Secure Dongle UserID not valid");
Logger.error("Secure Dongle UserID not valid");