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 images = allFilesForUpload(); // Lists for either dirs or pictures List dirs = new ArrayList(); List pics = new ArrayList(); // 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 limitdirs = new ArrayList(); 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 limitpics = new ArrayList(); 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 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 task = new Task() { @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 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 task = new Task() { @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 allFilesForUpload() { File dir = SOMConfig.PICTURES_PATH; Collection filesAndDirs = FileUtils.listFilesAndDirs(dir, TrueFileFilter.INSTANCE, DirectoryFileFilter.DIRECTORY); return new ArrayList(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 ev = (WatchEvent) 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; } } }