From 7270d1cb4e2cd005db4249a1c00d60ba7b79e8e2 Mon Sep 17 00:00:00 2001 From: Ivan Olexyn Date: Sat, 10 Aug 2019 05:32:04 +0200 Subject: [PATCH] Add PDF split feature. + Add UI candy. + Make sub-packages. + Add PDF split feature. - fileCut.sh - routines.RetrieveSubFies.java - update to Tools.java + Add a logo/icon. --- mucc-logo.png | Bin 0 -> 19228 bytes src/app/Controller.java | 130 ++++++-- src/app/Tools.java | 33 +- src/app/layout.fxml | 293 ++++++++++-------- .../DeleteDuplicates.java} | 41 +-- src/app/routines/FilePool.java | 49 +++ src/app/routines/RetrieveSubFiles.java | 114 +++++++ src/app/shell/fileCut.sh | 23 ++ src/app/shell/pipe.sh | 6 + src/app/shell/pipe2.sh | 7 + src/app/{ => shell}/toFile.sh | 0 11 files changed, 503 insertions(+), 193 deletions(-) create mode 100644 mucc-logo.png rename src/app/{Routines.java => routines/DeleteDuplicates.java} (57%) create mode 100644 src/app/routines/FilePool.java create mode 100644 src/app/routines/RetrieveSubFiles.java create mode 100755 src/app/shell/fileCut.sh create mode 100755 src/app/shell/pipe.sh create mode 100755 src/app/shell/pipe2.sh rename src/app/{ => shell}/toFile.sh (100%) diff --git a/mucc-logo.png b/mucc-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fd8ffd50f780253d9c4c08222f3f4d4c78680717 GIT binary patch literal 19228 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 C&C3=5 literal 0 HcmV?d00001 diff --git a/src/app/Controller.java b/src/app/Controller.java index 47dedf3..1b8bda6 100644 --- a/src/app/Controller.java +++ b/src/app/Controller.java @@ -1,13 +1,15 @@ package app; +import app.routines.DeleteDuplicates; +import app.routines.FilePool; +import app.routines.RetrieveSubFiles; import javafx.concurrent.Task; import javafx.fxml.FXML; -import javafx.scene.Node; import javafx.scene.control.*; +import javafx.scene.paint.Color; import javafx.scene.text.Text; -import java.awt.event.ActionEvent; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; @@ -23,9 +25,14 @@ import javafx.stage.Window; */ public class Controller { - Map doubles; + private Map doubles; + private Map dupblicate_base_pool; + private Map pdf_base_pool; + // Delete Duplicates + // ---------------------------------------------------------------------------------------------------------------- + @FXML protected Text loadDirState; @@ -42,17 +49,16 @@ public class Controller { protected Text delDuplicateState; @FXML - protected Text fileNr; + protected Text fileNrCount; @FXML - protected Text doubleNr; + protected Text doubleNrCount; @FXML protected TextField directoryField; - @FXML - protected void openDir(){ + protected void openDir() { Window stage = loadDirState.getScene().getWindow(); @@ -60,58 +66,58 @@ public class Controller { directoryChooser.setTitle("Select Directory."); directoryChooser.setInitialDirectory(new File(System.getProperty("user.home"))); - TextArea textArea = new TextArea(); - textArea.setMinHeight(70); - File dir = directoryChooser.showDialog(stage); - if (dir != null){ + if (dir != null) { directoryField.setText(dir.getAbsolutePath()); - }else{ - //textArea.setText(null); } } - @FXML - protected void loadDir() { + protected void loadDuplicateDir() { Task loadDirTask = new Task() { @Override public Void call() { - loadDirState.setText(""); - calcMd5State.setText(""); - sortFileState.setText(""); - findDuplicateState.setText(""); - delDuplicateState.setText(""); - fileNr.setText("Number of Files:"); - doubleNr.setText("Number of Duplicates:"); + loadDirState.setText("__"); + calcMd5State.setText("__"); + sortFileState.setText("__"); + findDuplicateState.setText("__"); + delDuplicateState.setText("__"); + fileNrCount.setText("__"); + doubleNrCount.setText("__"); + Path path = Paths.get(directoryField.getText()); if (!Files.isDirectory(path)) { + loadDirState.setFill(Color.RED); loadDirState.setText("ERROR."); } else { - Map pool = new Routines().loadPool(directoryField.getText(), "file"); + Map pool = new FilePool().loadPool(directoryField.getText(), "file"); new Write().textPool("pool", pool); + loadDirState.setFill(Color.GREEN); loadDirState.setText("OK."); - fileNr.setText("Number of Files: " + pool.size()); + fileNrCount.setText("" + pool.size()); - Map md5Pool = new Routines().md5Pool(pool); + Map md5Pool = new DeleteDuplicates().md5Pool(pool); new Write().textMd5Pool("md5Pool", md5Pool); + calcMd5State.setFill(Color.GREEN); calcMd5State.setText("OK."); Map qsMd5Pool = new QuicksortMd5().quicksortMd5(md5Pool); new Write().textMd5Pool("qsMd5Pool", qsMd5Pool); + sortFileState.setFill(Color.GREEN); sortFileState.setText("OK."); - doubles = new Routines().doubles(qsMd5Pool); + doubles = new DeleteDuplicates().doubles(qsMd5Pool); new Write().textMd5Pool("doubles", doubles); + findDuplicateState.setFill(Color.GREEN); findDuplicateState.setText("OK."); - doubleNr.setText("Number of Duplicates: " + doubles.size()); + doubleNrCount.setText("" + doubles.size()); } return null; @@ -120,17 +126,18 @@ public class Controller { new Thread(loadDirTask).start(); } + @FXML protected void deleteDuplicates() { Task delDuplicateTask = new Task() { @Override - public Void call() { + public Void call() { for (int i = 0; i < doubles.size(); i++) { new Execute().execute(new String[]{"rm", doubles.get(i).file.getAbsolutePath()}); - } + delDuplicateState.setFill(Color.GREEN); delDuplicateState.setText("OK."); return null; } @@ -138,5 +145,70 @@ public class Controller { new Thread(delDuplicateTask).start(); } + @FXML + protected void loadBaseFiles() { + } + + + // Retrieve Sub-Files + // ---------------------------------------------------------------------------------------------------------------- + + @FXML + protected Text loadPdfState; + + @FXML + protected Text splitPdfState; + + @FXML + protected Text baseFileCount; + + @FXML + protected Text subFileCount; + + @FXML + protected void loadBaseDir() { + Task loadDirTask = new Task() { + @Override + public Void call() { + + loadPdfState.setText("__"); + splitPdfState.setText("__"); + baseFileCount.setText("__"); + subFileCount.setText("__"); + + Path path = Paths.get(directoryField.getText()); + + if (!Files.isDirectory(path)) { + loadPdfState.setFill(Color.RED); + loadPdfState.setText("ERROR."); + } else { + + pdf_base_pool = new FilePool().loadPool(directoryField.getText(), "file"); + loadPdfState.setFill(Color.GREEN); + loadPdfState.setText("OK."); + baseFileCount.setText("" + pdf_base_pool.size()); + } + return null; + } + }; + new Thread(loadDirTask).start(); + } + + @FXML + protected void splitPdf() { + + Task splitPdfTask = new Task() { + @Override + public Void call() { + + int list_size = new RetrieveSubFiles().pdf_method(pdf_base_pool); + splitPdfState.setFill(Color.GREEN); + splitPdfState.setText("OK."); + subFileCount.setText("" + list_size); + return null; + } + }; + new Thread(splitPdfTask).start(); + } } diff --git a/src/app/Tools.java b/src/app/Tools.java index bde8c67..32e085b 100644 --- a/src/app/Tools.java +++ b/src/app/Tools.java @@ -2,8 +2,10 @@ package app; import java.io.BufferedReader; import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; -class Tools { +public class Tools { private final Execute x; @@ -27,4 +29,33 @@ class Tools { } return md5; } + + + public String brToString(BufferedReader br) { + StringBuilder sb = new StringBuilder(); + Object[] br_array = br.lines().toArray(); + for (int i = 0; i < br_array.length; i++) { + sb.append(br_array[i].toString() + "\n"); + } + return sb.toString(); + } + + /** + * + * @param input input String + * @param regex pattern String + * @return matches for pattern, separated by \n + */ + public String matchRegEx(String input, String regex){ + + Pattern pattern = Pattern.compile(regex); + Matcher m = pattern.matcher(input); + StringBuilder sb = new StringBuilder(); + while (m.find()){ + // + sb.append(m.group()+"\n"); + } + + return sb.toString(); + } } diff --git a/src/app/layout.fxml b/src/app/layout.fxml index 81708b1..c4d85ae 100644 --- a/src/app/layout.fxml +++ b/src/app/layout.fxml @@ -9,132 +9,169 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + diff --git a/src/app/Routines.java b/src/app/routines/DeleteDuplicates.java similarity index 57% rename from src/app/Routines.java rename to src/app/routines/DeleteDuplicates.java index 77a2c50..77fdc83 100644 --- a/src/app/Routines.java +++ b/src/app/routines/DeleteDuplicates.java @@ -1,4 +1,4 @@ -package app; +package app.routines; import java.io.File; import java.io.IOException; @@ -8,50 +8,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import app.Artifacts; import app.Artifacts.MFile; +import app.Execute; -class Routines { +public class DeleteDuplicates { private final Execute x; - public Routines() { + public DeleteDuplicates() { this.x = new Execute(); } - /** - * [1] Write output of find srcdir to /tmp/find .
- * [2] Read /tmp/find into List< String /> .
- * [3] Add List< String /> entries to Map>String,File> , where - * String is an int key.
- * - * @param srcdir String - * @param type String "file" OR "dir" , pick what type will be loaded. - * @return filepool - */ - public Map loadPool(String srcdir, String type) { - // [1] - x.execute(new String[]{System.getProperty("user.dir") + "/src/app/toFile.sh", "find", srcdir, "/tmp/find"}); - // [2] - List lines = null; - try { - lines = Files.readAllLines(Paths.get("/tmp/find")); - } catch (IOException e) { - e.printStackTrace(); - } - // [3] - Map filepool = new HashMap<>(); - int j = 0; - for (String line : lines) { - File file = new File(line); - if (type == "dir" && file.isDirectory() || type == "file" && file.isFile()) { - filepool.put(j, file); - j++; - } - } - return filepool; - } + /** * Calculate md5 for each file in pool . diff --git a/src/app/routines/FilePool.java b/src/app/routines/FilePool.java new file mode 100644 index 0000000..c00f99b --- /dev/null +++ b/src/app/routines/FilePool.java @@ -0,0 +1,49 @@ +package app.routines; + +import app.Execute; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FilePool { + + private final Execute x = new Execute(); + + /** + * [1] Write output of find srcdir to /tmp/find .
+ * [2] Read /tmp/find into List< String /> .
+ * [3] Add List< String /> entries to Map>String,File> , where + * String is an int key.
+ * + * @param srcdir String + * @param type String "file" OR "dir" , pick what type will be loaded. + * @return filepool + */ + public Map loadPool(String srcdir, String type) { + // [1] + x.execute(new String[]{System.getProperty("user.dir") + "/src/app/shell/toFile.sh", "find", srcdir, "/tmp/find"}); + // [2] + List lines = null; + try { + lines = Files.readAllLines(Paths.get("/tmp/find")); + } catch (IOException e) { + e.printStackTrace(); + } + // [3] + Map filepool = new HashMap<>(); + int j = 0; + for (String line : lines) { + File file = new File(line); + if (type == "dir" && file.isDirectory() || type == "file" && file.isFile()) { + filepool.put(j, file); + j++; + } + } + return filepool; + } +} diff --git a/src/app/routines/RetrieveSubFiles.java b/src/app/routines/RetrieveSubFiles.java new file mode 100644 index 0000000..2483e78 --- /dev/null +++ b/src/app/routines/RetrieveSubFiles.java @@ -0,0 +1,114 @@ +package app.routines; + +import app.Execute; +import app.Tools; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RetrieveSubFiles { + + private final Execute x; + private final Tools tools; + + + public RetrieveSubFiles() { + this.x = new Execute(); + this.tools = new Tools(); + } + + + + + + /** + * @param pool Map< Integer, File /> , a map containing files. + * @return create subfiles on disk. MFile /> of duplicates contained in md5Pool + */ + public int pdf_method(Map pool) { + + int files_created = 0; + + for (int i = 0; i < pool.size(); i++) { + + File file = pool.get(i); + String f_path = file.getAbsolutePath(); + if (f_path.endsWith("pdf")) { + // -n is for adding line numbers + // -a is for accepting binary input + // -T is for preserving tabs, this helps in some special cases. + String[] cmd = new String[]{System.getProperty("user.dir") + "/src/app/shell/pipe.sh", + "cat " + f_path, + "grep -naT %PDF"}; + String pdf = tools.brToString(x.execute(cmd).output); + // because -T was used, we now must use regex to extract the '1234:' tag + String pdf_lines = tools.matchRegEx(pdf, "[0-9]+:"); + + cmd = new String[]{System.getProperty("user.dir") + "/src/app/shell/pipe.sh", + "cat " + f_path, + "grep -naT %%EOF"}; + String eof = tools.brToString(x.execute(cmd).output); + String eof_lines = tools.matchRegEx(eof, "[0-9]+:"); + + // TODO because of PDF tags having 'error char' instad of line nums, the # of PDF tags < # EOF tags + // TODO fix this by maybe making a grep of grep + List pdf_list = pdf_list(pdf_lines, eof_lines); + int adf = 3; + + for (int j = 0; j < pdf_list.size(); j++) { + String sub_f_name = file.getName().split("\\.")[0] + "-sub" + j + ".pdf"; + String[] split = pdf_list.get(j).split(":"); + + cmd = new String[]{System.getProperty("user.dir") + "/src/app/shell/fileCut.sh", + f_path, + split[0], + split[1], + file.getParent() + "/" + sub_f_name}; + x.execute(cmd); + } + + files_created += pdf_list.size(); + // x.execute(new String[]{"rm", f_path}); + + } else { + // Do nothing. File is either not a PDF, + // or contains no usable %PDF and %%EOF sequences. + } + } + return files_created; + } + + + /** + * pdf_matrix contains rows for each subfile as hinted by params:
+ * [ %PDF line ; %%EOF line ; %PDF-version ; %%EOF ] + * + * @param pdf Record of lines containing the %PDF sequence. + * @param eof Record of lines containing the %%EOF sequence. + * @return pdf_matrix, see above. + */ + public List pdf_list(String pdf, String eof) { + List list = new ArrayList(); + + String[] pdf_list = pdf.split("\n"); + String[] eof_list = eof.split("\n"); + + if (pdf_list.length == eof_list.length) { + for (int j = 0; j < pdf_list.length; j++) { + String pdf_tag_line = pdf_list[j].split(":")[0]; + String eof_tag_line = eof_list[j].split(":")[0]; + list.add(pdf_tag_line + ":" + eof_tag_line); + } + } else { + throw new Error("Number of %PDF tags does not match the number %%EOF tags. Skipping this file."); + } + return list; + } + +} diff --git a/src/app/shell/fileCut.sh b/src/app/shell/fileCut.sh new file mode 100755 index 0000000..8fa99a8 --- /dev/null +++ b/src/app/shell/fileCut.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# ================================================================================ +# FILE: fileCut.sh +# +# USAGE: fileCut.sh [input file] [cut start] [cut end] [output file] +# +# DESCRIPTION: Cuts section between 'cut start' and 'cut end' from 'input file' +# and writes the contents of the cut to 'output file'. +# +# ================================================================================ + +input_file=$1 +start_cut=$2 +end_cut=$3 +output_file=$4 +let cut_size=$end_cut-$start_cut + + +head -n $start_cut $input_file | tail -n 1 | sed 's/.*%PDF/%PDF/g' > $output_file + + +head -n $end_cut $input_file | tail -n $cut_size >> $output_file diff --git a/src/app/shell/pipe.sh b/src/app/shell/pipe.sh new file mode 100755 index 0000000..dc6f96c --- /dev/null +++ b/src/app/shell/pipe.sh @@ -0,0 +1,6 @@ +#!/bin/bash +a=$1 +b=$2 +$a | $b + +# this is a pipe \ No newline at end of file diff --git a/src/app/shell/pipe2.sh b/src/app/shell/pipe2.sh new file mode 100755 index 0000000..826e21f --- /dev/null +++ b/src/app/shell/pipe2.sh @@ -0,0 +1,7 @@ +#!/bin/bash +a=$1 +b=$2 +c=$3 +$a | $b | $c + +# this is a double pipe \ No newline at end of file diff --git a/src/app/toFile.sh b/src/app/shell/toFile.sh similarity index 100% rename from src/app/toFile.sh rename to src/app/shell/toFile.sh