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.
master
Ivan Olexyn 6 years ago
parent b1f7b33442
commit 7270d1cb4e

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

@ -1,13 +1,15 @@
package app; package app;
import app.routines.DeleteDuplicates;
import app.routines.FilePool;
import app.routines.RetrieveSubFiles;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Text; import javafx.scene.text.Text;
import java.awt.event.ActionEvent;
import java.io.File; import java.io.File;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -23,9 +25,14 @@ import javafx.stage.Window;
*/ */
public class Controller { public class Controller {
Map<Integer, MFile> doubles; private Map<Integer, MFile> doubles;
private Map<Integer, File> dupblicate_base_pool;
private Map<Integer, File> pdf_base_pool;
// Delete Duplicates
// ----------------------------------------------------------------------------------------------------------------
@FXML @FXML
protected Text loadDirState; protected Text loadDirState;
@ -42,15 +49,14 @@ public class Controller {
protected Text delDuplicateState; protected Text delDuplicateState;
@FXML @FXML
protected Text fileNr; protected Text fileNrCount;
@FXML @FXML
protected Text doubleNr; protected Text doubleNrCount;
@FXML @FXML
protected TextField directoryField; protected TextField directoryField;
@FXML @FXML
protected void openDir() { protected void openDir() {
Window stage = loadDirState.getScene().getWindow(); Window stage = loadDirState.getScene().getWindow();
@ -60,58 +66,58 @@ public class Controller {
directoryChooser.setTitle("Select Directory."); directoryChooser.setTitle("Select Directory.");
directoryChooser.setInitialDirectory(new File(System.getProperty("user.home"))); directoryChooser.setInitialDirectory(new File(System.getProperty("user.home")));
TextArea textArea = new TextArea();
textArea.setMinHeight(70);
File dir = directoryChooser.showDialog(stage); File dir = directoryChooser.showDialog(stage);
if (dir != null) { if (dir != null) {
directoryField.setText(dir.getAbsolutePath()); directoryField.setText(dir.getAbsolutePath());
}else{
//textArea.setText(null);
} }
} }
@FXML @FXML
protected void loadDir() { protected void loadDuplicateDir() {
Task<Void> loadDirTask = new Task<Void>() { Task<Void> loadDirTask = new Task<Void>() {
@Override @Override
public Void call() { public Void call() {
loadDirState.setText(""); loadDirState.setText("__");
calcMd5State.setText(""); calcMd5State.setText("__");
sortFileState.setText(""); sortFileState.setText("__");
findDuplicateState.setText(""); findDuplicateState.setText("__");
delDuplicateState.setText(""); delDuplicateState.setText("__");
fileNr.setText("Number of Files:"); fileNrCount.setText("__");
doubleNr.setText("Number of Duplicates:"); doubleNrCount.setText("__");
Path path = Paths.get(directoryField.getText()); Path path = Paths.get(directoryField.getText());
if (!Files.isDirectory(path)) { if (!Files.isDirectory(path)) {
loadDirState.setFill(Color.RED);
loadDirState.setText("ERROR."); loadDirState.setText("ERROR.");
} else { } else {
Map<Integer, File> pool = new Routines().loadPool(directoryField.getText(), "file"); Map<Integer, File> pool = new FilePool().loadPool(directoryField.getText(), "file");
new Write().textPool("pool", pool); new Write().textPool("pool", pool);
loadDirState.setFill(Color.GREEN);
loadDirState.setText("OK."); loadDirState.setText("OK.");
fileNr.setText("Number of Files: " + pool.size()); fileNrCount.setText("" + pool.size());
Map<Integer, MFile> md5Pool = new Routines().md5Pool(pool); Map<Integer, MFile> md5Pool = new DeleteDuplicates().md5Pool(pool);
new Write().textMd5Pool("md5Pool", md5Pool); new Write().textMd5Pool("md5Pool", md5Pool);
calcMd5State.setFill(Color.GREEN);
calcMd5State.setText("OK."); calcMd5State.setText("OK.");
Map<Integer, MFile> qsMd5Pool = new QuicksortMd5().quicksortMd5(md5Pool); Map<Integer, MFile> qsMd5Pool = new QuicksortMd5().quicksortMd5(md5Pool);
new Write().textMd5Pool("qsMd5Pool", qsMd5Pool); new Write().textMd5Pool("qsMd5Pool", qsMd5Pool);
sortFileState.setFill(Color.GREEN);
sortFileState.setText("OK."); sortFileState.setText("OK.");
doubles = new Routines().doubles(qsMd5Pool); doubles = new DeleteDuplicates().doubles(qsMd5Pool);
new Write().textMd5Pool("doubles", doubles); new Write().textMd5Pool("doubles", doubles);
findDuplicateState.setFill(Color.GREEN);
findDuplicateState.setText("OK."); findDuplicateState.setText("OK.");
doubleNr.setText("Number of Duplicates: " + doubles.size()); doubleNrCount.setText("" + doubles.size());
} }
return null; return null;
@ -120,6 +126,7 @@ public class Controller {
new Thread(loadDirTask).start(); new Thread(loadDirTask).start();
} }
@FXML @FXML
protected void deleteDuplicates() { protected void deleteDuplicates() {
@ -129,8 +136,8 @@ public class Controller {
for (int i = 0; i < doubles.size(); i++) { for (int i = 0; i < doubles.size(); i++) {
new Execute().execute(new String[]{"rm", doubles.get(i).file.getAbsolutePath()}); new Execute().execute(new String[]{"rm", doubles.get(i).file.getAbsolutePath()});
} }
delDuplicateState.setFill(Color.GREEN);
delDuplicateState.setText("OK."); delDuplicateState.setText("OK.");
return null; return null;
} }
@ -138,5 +145,70 @@ public class Controller {
new Thread(delDuplicateTask).start(); 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<Void> loadDirTask = new Task<Void>() {
@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<Void> splitPdfTask = new Task<Void>() {
@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();
}
} }

@ -2,8 +2,10 @@ package app;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Tools { public class Tools {
private final Execute x; private final Execute x;
@ -27,4 +29,33 @@ class Tools {
} }
return md5; 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();
}
} }

@ -14,11 +14,11 @@
<content> <content>
<GridPane fx:id="outerGridPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <GridPane fx:id="outerGridPane" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints> <columnConstraints>
<ColumnConstraints /> <ColumnConstraints hgrow="ALWAYS" />
<ColumnConstraints /> <ColumnConstraints />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints maxHeight="40.0" minHeight="40.0" prefHeight="40.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
</rowConstraints> </rowConstraints>
<children> <children>
@ -26,37 +26,67 @@
<tabs> <tabs>
<Tab text="Scan Disk Image"> <Tab text="Scan Disk Image">
<content> <content>
<GridPane> <GridPane hgap="10.0" vgap="10.0">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="ALWAYS" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="ALWAYS" />
</rowConstraints> </rowConstraints>
<children> <children>
<Label text="Not Implemented Yet." GridPane.columnSpan="2" /> <Label text="Not Implemented Yet." GridPane.columnSpan="2" GridPane.rowIndex="1" />
</children> </children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</GridPane> </GridPane>
</content> </content>
</Tab> </Tab>
<Tab text="Retreive Sub-Files"> <Tab text="Retreive Sub-Files">
<content> <content>
<GridPane> <GridPane hgap="10.0" vgap="10.0">
<columnConstraints> <columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="ALWAYS" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> <ColumnConstraints hgrow="NEVER" maxWidth="80.0" minWidth="80.0" prefWidth="80.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> <RowConstraints vgrow="NEVER" />
<RowConstraints maxHeight="20.0" minHeight="20.0" prefHeight="20.0" vgrow="NEVER" />
<RowConstraints vgrow="NEVER" />
<RowConstraints vgrow="NEVER" />
<RowConstraints maxHeight="20.0" minHeight="20.0" prefHeight="20.0" vgrow="NEVER" />
<RowConstraints vgrow="NEVER" />
</rowConstraints> </rowConstraints>
<children> <children>
<Label text="Not Implemented Yet." GridPane.columnSpan="2" /> <Text text="Load PDF Files." GridPane.columnIndex="0" GridPane.rowIndex="1" />
<Text fx:id="loadPdfState" text="__" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Text text="Split PDF Files." GridPane.columnIndex="0" GridPane.rowIndex="2" />
<Text fx:id="splitPdfState" text="__" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Text text="Number fo Files:" GridPane.columnIndex="0" GridPane.rowIndex="4" />
<Text fx:id="baseFileCount" text="__" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Text text="Number of PDF Sub-Files:" GridPane.columnIndex="0" GridPane.rowIndex="5" />
<Text fx:id="subFileCount" text="__" GridPane.columnIndex="1" GridPane.rowIndex="5" />
<Button onAction="#loadBaseDir" text="Load" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="7" />
<Button onAction="#splitPdf" text="Split" GridPane.columnIndex="1" GridPane.rowIndex="7" />
<Text text="Task">
<font>
<Font name="System Bold" size="13.0" />
</font>
</Text>
<Text text="State" GridPane.columnIndex="1">
<font>
<Font name="System Bold" size="13.0" />
</font>
</Text>
</children> </children>
<padding>
<Insets bottom="25.0" left="25.0" right="25.0" top="25.0" />
</padding>
</GridPane> </GridPane>
</content> </content>
</Tab> </Tab>
@ -64,62 +94,61 @@
<content> <content>
<GridPane alignment="center" hgap="10" vgap="10"> <GridPane alignment="center" hgap="10" vgap="10">
<padding> <padding>
<Insets bottom="10" left="25" right="25" top="25" /> <Insets bottom="25.0" left="25.0" right="25.0" top="25.0" />
</padding> </padding>
<children> <children>
<Text text="Task" GridPane.rowIndex="1" /> <Text text="Task">
<font>
<Font name="System Bold" size="13.0" />
<Text text="State" GridPane.columnIndex="1" GridPane.rowIndex="1" /> </font>
</Text>
<Text text="Load Directory." GridPane.rowIndex="2" />
<Text fx:id="loadDirState" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Text text="Calculate Md5." GridPane.rowIndex="3" />
<Text fx:id="calcMd5State" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Text text="Sort Files." GridPane.rowIndex="4" /> <Text text="State" GridPane.columnIndex="1">
<font>
<Font name="System Bold" size="13.0" />
</font>
</Text>
<Text fx:id="sortFileState" GridPane.columnIndex="1" GridPane.rowIndex="4" /> <Text text="Load Directory." GridPane.rowIndex="1" />
<Text text="Find Duplicates." GridPane.rowIndex="5" /> <Text fx:id="loadDirState" text="__" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Text fx:id="findDuplicateState" GridPane.columnIndex="1" GridPane.rowIndex="5" /> <Text text="Calculate Md5." GridPane.rowIndex="2" />
<Text text="Delete Duplicates." GridPane.rowIndex="6" />
<Text fx:id="delDuplicateState" GridPane.columnIndex="1" GridPane.rowIndex="6" />
<Button onAction="#loadDir" text="Load" GridPane.columnIndex="1" GridPane.rowIndex="8" />
<Text fx:id="fileNr" text="Number of Files:" GridPane.rowIndex="9" />
<Text fx:id="doubleNr" text="Number of Duplicates:" GridPane.rowIndex="10" />
<Text fx:id="calcMd5State" text="__" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Text text="Sort Files." GridPane.rowIndex="3" />
<Text fx:id="sortFileState" text="__" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Text text="Find Duplicates." GridPane.rowIndex="4" />
<Text fx:id="findDuplicateState" text="__" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Text text="Delete Duplicates." GridPane.rowIndex="5" />
<Text fx:id="delDuplicateState" text="__" GridPane.columnIndex="1" GridPane.rowIndex="5" />
<Button onAction="#loadDuplicateDir" text="Load" GridPane.halignment="RIGHT" GridPane.rowIndex="10" />
<Text text="Number of Files:" GridPane.rowIndex="7" />
<Text text="Number of Duplicates:" GridPane.rowIndex="8" />
<Button onAction="#deleteDuplicates" text="Delete" GridPane.columnIndex="1" GridPane.rowIndex="10" /> <Button onAction="#deleteDuplicates" text="Delete" GridPane.columnIndex="1" GridPane.rowIndex="10" />
<Text fx:id="fileNrCount" strokeType="OUTSIDE" strokeWidth="0.0" text="__" GridPane.columnIndex="1" GridPane.rowIndex="7" />
<Text fx:id="doubleNrCount" strokeType="OUTSIDE" strokeWidth="0.0" text="__" GridPane.columnIndex="1" GridPane.rowIndex="8" />
</children> </children>
<columnConstraints> <columnConstraints>
<ColumnConstraints /> <ColumnConstraints hgrow="ALWAYS" />
<ColumnConstraints /> <ColumnConstraints hgrow="NEVER" maxWidth="80.0" minWidth="80.0" prefWidth="80.0" />
</columnConstraints> </columnConstraints>
<rowConstraints> <rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" /> <RowConstraints vgrow="NEVER" />
<RowConstraints /> <RowConstraints vgrow="NEVER" />
<RowConstraints /> <RowConstraints vgrow="NEVER" />
<RowConstraints /> <RowConstraints vgrow="NEVER" />
<RowConstraints /> <RowConstraints vgrow="NEVER" />
<RowConstraints /> <RowConstraints vgrow="NEVER" />
<RowConstraints /> <RowConstraints minHeight="20.0" prefHeight="20.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" /> <RowConstraints vgrow="NEVER" />
<RowConstraints /> <RowConstraints vgrow="NEVER" />
<RowConstraints /> <RowConstraints minHeight="20.0" prefHeight="20.0" vgrow="NEVER" />
<RowConstraints /> <RowConstraints vgrow="NEVER" />
<RowConstraints vgrow="ALWAYS" />
</rowConstraints> </rowConstraints>
@ -130,8 +159,16 @@
</TabPane> </TabPane>
<TextField fx:id="directoryField" text="Select Directory." /> <TextField fx:id="directoryField" text="Select Directory.">
<Button onAction="#openDir" text="Open..." GridPane.columnIndex="1" /> <GridPane.margin>
<Insets bottom="20.0" left="20.0" top="20.0" />
</GridPane.margin>
</TextField>
<Button onAction="#openDir" text="Open..." GridPane.columnIndex="1">
<GridPane.margin>
<Insets right="20.0" />
</GridPane.margin>
</Button>
</children> </children>
</GridPane> </GridPane>
</content> </content>

@ -1,4 +1,4 @@
package app; package app.routines;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -8,50 +8,21 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import app.Artifacts;
import app.Artifacts.MFile; import app.Artifacts.MFile;
import app.Execute;
class Routines { public class DeleteDuplicates {
private final Execute x; private final Execute x;
public Routines() { public DeleteDuplicates() {
this.x = new Execute(); this.x = new Execute();
} }
/**
* [1] Write output of <b>find srcdir</b> to <b>/tmp/find</b> .<br>
* [2] Read <b>/tmp/find</b> into <b>List< String /></b> .<br>
* [3] Add <b>List< String /></b> entries to <b>Map>String,File></b> , where
* <b>String</b> is an <b>int</b> key. <br>
*
* @param srcdir <i>String</i>
* @param type <i>String</i> "file" OR "dir" , pick what type will be loaded.
* @return filepool
*/
public Map<Integer, File> loadPool(String srcdir, String type) {
// [1]
x.execute(new String[]{System.getProperty("user.dir") + "/src/app/toFile.sh", "find", srcdir, "/tmp/find"});
// [2]
List<String> lines = null;
try {
lines = Files.readAllLines(Paths.get("/tmp/find"));
} catch (IOException e) {
e.printStackTrace();
}
// [3]
Map<Integer, File> 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 <b>pool</b> . * Calculate md5 for each file in <b>pool</b> .

@ -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 <b>find srcdir</b> to <b>/tmp/find</b> .<br>
* [2] Read <b>/tmp/find</b> into <b>List< String /></b> .<br>
* [3] Add <b>List< String /></b> entries to <b>Map>String,File></b> , where
* <b>String</b> is an <b>int</b> key. <br>
*
* @param srcdir <i>String</i>
* @param type <i>String</i> "file" OR "dir" , pick what type will be loaded.
* @return filepool
*/
public Map<Integer, File> 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<String> lines = null;
try {
lines = Files.readAllLines(Paths.get("/tmp/find"));
} catch (IOException e) {
e.printStackTrace();
}
// [3]
Map<Integer, File> 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;
}
}

@ -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 <b>md5Pool</b>
*/
public int pdf_method(Map<Integer, File> 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<String> 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 <i>params</i>:<br>
* [ %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<String> pdf_list(String pdf, String eof) {
List<String> list = new ArrayList<String>();
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;
}
}

@ -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

@ -0,0 +1,6 @@
#!/bin/bash
a=$1
b=$2
$a | $b
# this is a pipe

@ -0,0 +1,7 @@
#!/bin/bash
a=$1
b=$2
c=$3
$a | $b | $c
# this is a double pipe
Loading…
Cancel
Save