Files
Application/src/main/java/workers/FilesWorker.java
T

489 lines
16 KiB
Java

package workers;
import GUI.SOMGUI;
import javafx.concurrent.Task;
import model.SOMConfig;
import model.SOMEvent;
import model.SOMImage;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
import javax.activation.MimetypesFileTypeMap;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static java.nio.file.StandardWatchEventKinds.*;
public class FilesWorker {
private static final SOMEvent event = SOMEvent.getInstance();
public FilesWorker() {
}
/**
* Returns true if a File is an image and returns false if not.
*
* @param path
* @return
*/
public static boolean isImage(Path path) {
File f = path.toFile();
String mimeType = new MimetypesFileTypeMap().getContentType(f);
String type = mimeType.split("/")[0];
return type.equals("image");
}
/**
* Returns the Path to the Source (direct from Camera) images directory, or
* if a File of one of the other Folders is given the Source File' Path
*
* @return
*/
public static File getSourcePath() {
File src = new File(SOMConfig.PICTURES_PATH.toString() + "/src");
// TODO catch possible fail
src.mkdirs();
return src;
}
/**
* Returns the Path to the Preview Images (Full Screen) images directory, or
* if a File of one of the other Folders is given the Preview File' Path
*
* @return
*/
public static File getPreviewPath() {
File prv = new File(SOMConfig.PICTURES_PATH.toString() + "/prv");
// TODO catch possible fail
prv.mkdirs();
return prv;
}
/**
* Returns the Path to the Thumbnail (Gallery) images directory, or if a
* File of one of the other Folders is given the Thumbnail File' Path
*
* @return
*/
public static File getThumbPath() {
File tmb = new File(SOMConfig.PICTURES_PATH.toString() + "/tmb");
// TODO catch possible fail
tmb.mkdirs();
return tmb;
}
/**
* Returns the Path to the Final images directory, or if a File of one of
* the other Folders is given the Final Files' Path
*
* @return
*/
public static File getFinalPath() {
File fnl = new File(SOMConfig.PICTURES_PATH.toString() + "/fnl");
// TODO catch possible fail
fnl.mkdirs();
return fnl;
}
/**
* Returns the Path to the Temporary (pre-source) images directory, or if a
* File of one of the other Folders is given the Thumbnail File' Path
*
* @return
*/
public static File getTempPath() {
File tmp = new File(SOMConfig.PICTURES_PATH.toString() + "/tmp");
// TODO catch possible fail
tmp.mkdirs();
return tmp;
}
private static boolean internet() {
Socket sock = new Socket();
InetSocketAddress socketAddress = new InetSocketAddress("google.com", 80);
try {
sock.connect(socketAddress, 3000);
System.out.println("Internet available");
return true;
} catch (IOException e) {
System.out.println("Internet NOT available");
return false;
} finally {
try {
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void upload() {
try {
// Get all Files in the image Folder
List<File> images = allFilesForUpload();
// Lists for either dirs or pictures
List<File> dirs = new ArrayList<File>();
List<File> pics = new ArrayList<File>();
// Check for internet connection
if (internet()) {
// Count Files and Dirs
// DIRS
String[] splits = SOMConfig.getEventPicDir().split("/");
String currentdir = "";
for (String split : splits) {
currentdir = currentdir + "/" + split;
dirs.add(new File(currentdir));
System.out.println("DIR added:" + currentdir);
}
// FILES
for (int i = 0; i < images.size(); i++) {
// get the current file
File file = images.get(i);
System.out.println(file);
// get pics
if (file.isFile()
&& file.toString().contains("src")) {
pics.add(file);
}
}
// REPORT TO CONSOLE
System.out.println(dirs.size() + " Directories");
System.out.println(pics.size() + " Pics");
int uploadeddirs = 0;
int uploadedfiles = 0;
// GET THE UI
SOMGUI.changetoupload();
// UPLOAD DIRECTORIES
List<File> limitdirs = new ArrayList<File>();
for (File dir : dirs) {
uploadeddirs++;
System.out.println("Queueing Directories " + dir.toString());
limitdirs.add(dir);
if (limitdirs.size() >= SOMConfig.PARALLEL_UPLOADS
// Upload even if limit is not reached
|| (dirs.size() - uploadeddirs) < SOMConfig.PARALLEL_UPLOADS) {
System.out.println("Launch Dir upload");
uploadDir(limitdirs);
System.out.println("Clear Queue");
limitdirs.clear();
}
}
// UPLOAD FILES
List<File> limitpics = new ArrayList<File>();
for (File pic : pics
) {
uploadedfiles++;
System.out.println("Queueing File " + pic.toString());
limitpics.add(pic);
if (limitpics.size() >= SOMConfig.PARALLEL_UPLOADS
// Upload even if limit is not reached
|| (pics.size() - uploadedfiles) < SOMConfig.PARALLEL_UPLOADS) {
System.out.println("Launch File upload");
uploadFile(limitpics);
System.out.println("Clear File Queue");
limitpics.clear();
}
}
SOMGUI.changetopicture();
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void uploadFile(final List<File> files) throws Exception {
final Thread[] threads = new Thread[files.size()];
for (int i = 0; i < threads.length; i++) {
System.out.println("LAUNCH Upload Process: " + i);
final File file = files.get(i);
final String target = "https://cloud.selfomat.de/remote.php/webdav/" + SOMConfig.getEventPicDir() + "/" + file.getName();
System.out.println(file.toString());
System.out.println("----------->");
System.out.println(target);
System.out.println("");
System.out.println("");
final int pictureCounter = i + 1;
Task<Boolean> task = new Task<Boolean>() {
@Override
protected Boolean call() throws Exception {
// build the upload process
// TODO remove -k option (this option skips certificate verification)
ProcessBuilder builder = new ProcessBuilder(
"bash",
"SELFOMAT/sh/upload.sh",
file.toString(),
target,
SOMConfig.CLOUD_CREDENTIALS
);
// make the process traceable
builder.redirectErrorStream(true);
// launch upload process
Process process = builder.start();
// wait for the process to end
if (process.waitFor() == 0) {
// process ended successful
System.out.println("file uploaded: " + file);
// TODO get the length of all threads
// TODO bind to UI
updateProgress(pictureCounter, threads.length);
return true;
} else {
// process ended failing
// TODO Catch failed uploads
System.out.println("process ended failing " + file);
Thread.sleep(1000);
return false;
}
}
};
SOMGUI.uploadCtl.pictureProgressBar.progressProperty().bind(task.progressProperty());
threads[i] = new Thread(task);
threads[i].setDaemon(true);
threads[i].start();
}
int i = 0;
while (i < threads.length) {
threads[i].join();
i++;
}
//TODO Catch fails
}
private static void uploadDir(final List<File> dirs) throws Exception {
final Thread[] threads = new Thread[dirs.size()];
for (int i = 0; i < threads.length; i++) {
System.out.println("launch mkdir Process: " + i);
final File dir = dirs.get(i);
final int directoryCounter = i + 1;
Task<Boolean> task = new Task<Boolean>() {
@Override
protected Boolean call() throws Exception {
// build the Upload process with curl
// TODO remove -k option (this option skips certificate verification)
ProcessBuilder builder = new ProcessBuilder("curl",
"-u",
"upload:geheim",
"-X",
"MKCOL",
"https://cloud.selfom.at/remote.php/webdav/" + SOMConfig.getEventPicDir(),
// dir.toString().replace("/src", ""),
"-k");
// make the process traceable
builder.redirectErrorStream(true);
// launch upload process
Process process = builder.start();
// wait for the process to end
if (process.waitFor() == 0) {
// Process ended successful
System.out.println("directory made: " + dir);
//Set upload Progress
// TODO get the length of all threads
// TODO bind to UI
updateProgress(directoryCounter, threads.length);
return true;
} else {
// Process ended failing
System.out.println("process ended failing " + dir);
return false;
}
}
};
SOMGUI.uploadCtl.folderProgressBar.progressProperty().bind(task.progressProperty());
// Start the Task
threads[i] = new Thread(task);
threads[i].setDaemon(true);
threads[i].start();
} // End of loop
// Join the tasks
int i = 0;
while (i < threads.length) {
threads[i].join();
i++;
}
//TODO Catch upload fails
}
private static List<File> allFilesForUpload() {
File dir = SOMConfig.PICTURES_PATH;
Collection filesAndDirs = FileUtils.listFilesAndDirs(dir, TrueFileFilter.INSTANCE, DirectoryFileFilter.DIRECTORY);
return new ArrayList<File>(filesAndDirs);
}
// TODO static??
public static SOMImage waitForImageAndCapture() {
//Behandelt
try {
// Set the Source Path to be watched
Path dir = getSourcePath().toPath();
// REGISTER WATCH SERVICE
WatchService watcher = FileSystems.getDefault().newWatchService();
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
System.out.println("Watch Service registered for dir: "
+ dir.getFileName());
// TRIGGER THE CAPTURE
System.out.println("START CAPTURE THREAD");
SOMImage newImage = CaptureWorker.now();
while (true) {
WatchKey key;
try {
key = watcher.take();
} catch (InterruptedException ex) {
return newImage;
}
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
@SuppressWarnings("unchecked")
WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path fileName = ev.context();
System.out.println(kind.name() + ": " + fileName);
// check for a file being created
if (
// Make sure there is an Image created
kind == ENTRY_CREATE
// Check that filename is the same as expected image
&& fileName.toString().equals(
newImage.getSrc().getName())) {
//Set the Progress Indicator to 0.5
SOMGUI.captureCtl.pictureLoadIndicator.setProgress(0.5);
// START THE "PICTURE HAS ARRIVED" ACTION
System.out.println("The image is there!!!");
// ADD THE IMAGE TO THE EVENT
FilesWorker.event.addImage(newImage);
// Set last Image
System.out.println("Set the taken Picture to UI");
FilesWorker.event.createAndSetImage(FilesWorker.event.getLastImage());
// Hide the Progress Indicator
SOMGUI.captureCtl.pictureLoadIndicator.setVisible(false);
// Set back the Progress Indicator
SOMGUI.captureCtl.pictureLoadIndicator.setProgress(-1);
//Close Watcher
watcher.close();
} else if (
// Make sure there is an Image created
kind == ENTRY_CREATE
// Check that filename is the same as expected image
&& !fileName.toString().equals(
newImage.getSrc().getName())) {
// TODO Catch wrong pictures, only for testing
// Hide the Progress Indicator
SOMGUI.captureCtl.pictureLoadIndicator.setVisible(false);
// Set back the Progress Indicator
SOMGUI.captureCtl.pictureLoadIndicator.setProgress(-1);
//Close Watcher
watcher.close();
}
}
boolean valid = key.reset();
if (!valid) {
break;
}
}
// return the new image
newImage.updateImageState();
return newImage;
} catch (IOException ex) {
System.err.println(ex);
return null;
}
}
}