improved file naming
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
95
doc/rework.md
Normal file
95
doc/rework.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# Ideen
|
||||||
|
|
||||||
|
Verbesserung des Pfad-Handlings
|
||||||
|
## Stand
|
||||||
|
|
||||||
|
Aktuell werden Dokumente nach folgendem Muster erzeugt:
|
||||||
|
|
||||||
|
Wenn der gesetzte Pfad
|
||||||
|
`$HOME/Dokumente/$YEAR/$MONTH/$BETREFF`
|
||||||
|
ist, würde am 5.2.2023 ein von `srichter` ausgelöster PDF-Auftrag mit Betreff „Demo“ zunächst eine Datei
|
||||||
|
`/home/srichter/2023/02/Demo/<timestamp.jpg>` ergeben.
|
||||||
|
|
||||||
|
Falls das Ziel ein PDF ist, würde sofort danach die Datei zu
|
||||||
|
`/home/srichter/2023/02/Demo/<timestamp.page.pdf>` konvertiert.
|
||||||
|
|
||||||
|
Falls OCR aktiviert ist, würde danach
|
||||||
|
`/home/srichter/2023/02/Demo/<timestamp.page.ocr.pdf>` erzeugt.
|
||||||
|
|
||||||
|
Beim Zusammenfügen ergäbe sich dann
|
||||||
|
`/home/srichter/2023/02/Demo/Demo.pdf`.
|
||||||
|
|
||||||
|
## Gewünschtes Verfahren
|
||||||
|
|
||||||
|
Sinnvoll wäre es, wenn bei gesetzem Pfad
|
||||||
|
`$HOME/Dokumente/$YEAR/$MONTH/$BETREFF`
|
||||||
|
die Dateien wie folgt erzeugt würden:
|
||||||
|
|
||||||
|
### Ziel JPG
|
||||||
|
|
||||||
|
Die Datei wird direkt nach
|
||||||
|
`/home/srichter/2023/02/Demo.jpg` gescannt.
|
||||||
|
|
||||||
|
### Ziel PDF
|
||||||
|
|
||||||
|
Die Datei wird nach
|
||||||
|
`/home/srichter/2023/02/Demo.jpg` gescannt und dann nach
|
||||||
|
`/home/srichter/2023/02/Demo.pdf` konvertiert.
|
||||||
|
|
||||||
|
### Ziel PDF+OCR
|
||||||
|
|
||||||
|
Die Datei wird nach
|
||||||
|
`/home/srichter/2023/02/Demo.jpg` gescannt,
|
||||||
|
dann nach
|
||||||
|
`/home/srichter/2023/02/Demo.tmp.pdf` konvertiert.
|
||||||
|
Nach Texterkennung wird
|
||||||
|
`/home/srichter/2023/02/Demo.pdf` erzeugt.
|
||||||
|
|
||||||
|
## Mehrseitige Dokumente
|
||||||
|
|
||||||
|
Für mehrseitige Dokument kann die Variable $PAGE eingebaut werden:
|
||||||
|
|
||||||
|
Ist diese im Pfad vorhanden, so wird ein Eingabefeld für den aktuellen Stand eingeblendet.
|
||||||
|
Dieses soll ggf. schon vorhandene Dokumente berücksichtigen.
|
||||||
|
|
||||||
|
Es sei der Pfad also
|
||||||
|
`$HOME/Dokumente/$YEAR/$MONTH/$BETREFF/Dok {$PAGE. Seite}`.
|
||||||
|
|
||||||
|
Das Page-Eingabefeld wird mit 1 initialisiert.
|
||||||
|
|
||||||
|
### Ziel JPG
|
||||||
|
|
||||||
|
Die Datei wird direkt nach
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 1. Seite.jpg` gescannt.
|
||||||
|
Danach wird der Zähler erhöht, die nachfolgende Seite wird als
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 2. Seite.jpg` gescannt.
|
||||||
|
|
||||||
|
### Ziel PDF
|
||||||
|
|
||||||
|
Die erste Datei wird als
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 1. Seite.jpg`
|
||||||
|
gescannt und dann zu
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 1. Seite.pdf` konvertiert.
|
||||||
|
Die nächste Seite wäre dann entsprechend
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 2. Seite.jpg`
|
||||||
|
↓
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 2. Seite.pdf`
|
||||||
|
|
||||||
|
### Ziel PDF-OCR
|
||||||
|
|
||||||
|
Die erste Datei wird als
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 1. Seite.jpg`
|
||||||
|
gescannt und dann zu
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 1. Seite.tmp.png` konvertiert.
|
||||||
|
Nach der Texterkennung ist die Ausgabe-Datei
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 1. Seite.pdf`.
|
||||||
|
Für die nächste Seite wäre dann entsprechend
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 12. Seite.jpg`
|
||||||
|
↓
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 2. Seite.tmp.pdf`
|
||||||
|
↓
|
||||||
|
`/home/srichter/2023/02/Demo/Dok 1. Seite.pdf` die Ausgabe.
|
||||||
|
|
||||||
|
### Zusammenfügen
|
||||||
|
|
||||||
|
In den letzten Beiden fällen ergäbe das Zusammenfügen dann `/home/srichter/2023/02/Demo/Dok.pdf`
|
||||||
20
pom.xml
20
pom.xml
@@ -53,7 +53,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>de.srsoftware</groupId>
|
<groupId>de.srsoftware</groupId>
|
||||||
<artifactId>tools.gui.selectcombobox</artifactId>
|
<artifactId>tools.gui.selectcombobox</artifactId>
|
||||||
<version>0.1.8</version>
|
<version>0.1.9</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -90,13 +90,6 @@
|
|||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.8.1</version>
|
|
||||||
<configuration>
|
|
||||||
<release>11</release>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
@@ -130,7 +123,16 @@
|
|||||||
<mainClass>de.srsoftware.web4rail.Application</mainClass>
|
<mainClass>de.srsoftware.web4rail.Application</mainClass>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>17</source>
|
||||||
|
<target>17</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
|
||||||
</build>
|
</build>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ Language support : Sprach-Unterstützung
|
|||||||
MONTH : MONAT
|
MONTH : MONAT
|
||||||
OCR failed. : OCR fehlgeschlagen.
|
OCR failed. : OCR fehlgeschlagen.
|
||||||
open folder : Ordner öffnen
|
open folder : Ordner öffnen
|
||||||
|
PAGE : SEITE
|
||||||
Path '{}' does not exist! : Pfad '{}' existiert nicht!
|
Path '{}' does not exist! : Pfad '{}' existiert nicht!
|
||||||
Path : Pfad
|
Path : Pfad
|
||||||
Please install the package : Bitte installiere das Paket
|
Please install the package : Bitte installiere das Paket
|
||||||
|
|||||||
@@ -14,10 +14,11 @@ import java.io.FilenameFilter;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.TreeMap;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
@@ -62,23 +63,23 @@ public class DocTable extends JPanel{
|
|||||||
private String path;
|
private String path;
|
||||||
private JButton joinButton;
|
private JButton joinButton;
|
||||||
|
|
||||||
public Row(String path) {
|
public Row(String project) {
|
||||||
this.path = path;
|
this.path = project;
|
||||||
rows.put(path, this);
|
rows.put(project, this);
|
||||||
constraints.gridy = ++rowCounter;
|
constraints.gridy = ++rowCounter;
|
||||||
constraints.gridx = 0;
|
constraints.gridx = 0;
|
||||||
add(pathLabel = new JLabel(path), constraints);
|
add(pathLabel = new JLabel(project), constraints);
|
||||||
constraints.gridx = 1;
|
constraints.gridx = 1;
|
||||||
add(status = new JLabel("neu"),constraints);
|
add(status = new JLabel("neu"),constraints);
|
||||||
|
|
||||||
buttons = new JPanel();
|
buttons = new JPanel();
|
||||||
buttons.setLayout(new FlowLayout());
|
buttons.setLayout(new FlowLayout());
|
||||||
|
|
||||||
buttons.add(button("⚁",t("open folder"),ev -> openFolder(path)));
|
buttons.add(button("⚁",t("open folder"),ev -> openFolder(project)));
|
||||||
buttons.add(joinButton = button("⎗",t("join PDFs"),ev -> joinDocs(path)));
|
buttons.add(joinButton = button("⎗",t("join PDFs"),ev -> joinDocs(project)));
|
||||||
buttons.add(button("✉",t("display preview"),ev -> preview(path)));
|
buttons.add(button("✉",t("display preview"),ev -> preview(project)));
|
||||||
buttons.add(button("✓",t("done"),ev -> drop(this)));
|
buttons.add(button("✓",t("done"),ev -> drop(this)));
|
||||||
buttons.add(button("❌",t("drop file"),ev -> dropFile(path)));
|
buttons.add(button("❌",t("drop file"),ev -> dropFile(project)));
|
||||||
|
|
||||||
constraints.gridx = 2;
|
constraints.gridx = 2;
|
||||||
add(buttons,constraints);
|
add(buttons,constraints);
|
||||||
@@ -111,11 +112,10 @@ public class DocTable extends JPanel{
|
|||||||
/**
|
/**
|
||||||
* remove the join button assigned with the selected document
|
* remove the join button assigned with the selected document
|
||||||
*/
|
*/
|
||||||
public void removeJoinButton() {
|
public void setJoinButton(boolean enabled) {
|
||||||
joinButton.setEnabled(false);
|
joinButton.setEnabled(enabled);
|
||||||
buttons.remove(joinButton);
|
joinButton.setVisible(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final long serialVersionUID = 1073955198529023744L;
|
private static final long serialVersionUID = 1073955198529023744L;
|
||||||
@@ -151,10 +151,13 @@ public class DocTable extends JPanel{
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Ad a table entry for the directory represented by path
|
* Ad a table entry for the directory represented by path
|
||||||
* @param path
|
* @param project
|
||||||
*/
|
*/
|
||||||
public void add(String path) {
|
public void add(String project) {
|
||||||
if (!rows.containsKey(path)) new Row(path).status("neu");
|
var row = rows.get(project);
|
||||||
|
if (row == null) {
|
||||||
|
new Row(project).status("neu");
|
||||||
|
} else row.setJoinButton(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -187,10 +190,11 @@ public class DocTable extends JPanel{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void dropFile(String path) {
|
private void dropFile(String path) {
|
||||||
Path latest = latestFile(path);
|
Path latest = latestFile(new File(path));
|
||||||
if (latest != null) {
|
if (latest != null) {
|
||||||
|
LOG.debug("Removing {}",latest);
|
||||||
latest.toFile().delete();
|
latest.toFile().delete();
|
||||||
preview(path); // show lates of remaining files
|
preview(latest.toFile().getParent()); // show lates of remaining files
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,19 +204,37 @@ public class DocTable extends JPanel{
|
|||||||
*/
|
*/
|
||||||
public void joinDocs(String path) {
|
public void joinDocs(String path) {
|
||||||
LOG.debug("joinFiles({})",path);
|
LOG.debug("joinFiles({})",path);
|
||||||
rows.get(path).removeJoinButton();
|
rows.get(path).setJoinButton(false);
|
||||||
File folder = new File(path);
|
File folder = new File(path).getParentFile();
|
||||||
if (!folder.exists()) return;
|
if (!folder.exists()) return;
|
||||||
|
|
||||||
List<String> pdfs = Arrays.asList(folder.list(PAGES));
|
String pattern = new File(path).getName();
|
||||||
Collections.sort(pdfs);
|
var parts = pattern.split("\\$"+t("PAGE"));
|
||||||
|
var prefix = parts[0];
|
||||||
|
var suffix = parts.length>1 ? parts[1] : "";
|
||||||
|
if (parts.length<2) return;
|
||||||
|
|
||||||
|
var pages = new TreeMap<Integer,String>();
|
||||||
|
for (var file : folder.list()){
|
||||||
|
Optional<Integer> opt = getPage(file, prefix, suffix);
|
||||||
|
if (opt.isPresent()){
|
||||||
|
pages.put(opt.get(),file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pages.size()<2) return;
|
||||||
|
int first = pages.firstKey();
|
||||||
|
int last = pages.lastKey();
|
||||||
|
|
||||||
|
var range = first + (last != first ? "…"+last:"");
|
||||||
|
var target = pattern.replace("$"+t("PAGE"),range);
|
||||||
|
|
||||||
|
var pdfs = pages.values();
|
||||||
Vector<String> cmd = new Vector<>();
|
Vector<String> cmd = new Vector<>();
|
||||||
cmd.add("pdftk");
|
cmd.add("pdftk");
|
||||||
cmd.addAll(pdfs);
|
cmd.addAll(pdfs);
|
||||||
cmd.add("cat");
|
cmd.add("cat");
|
||||||
cmd.add("output");
|
cmd.add("output");
|
||||||
cmd.add(folder.getName()+".pdf");
|
cmd.add(target);
|
||||||
LOG.debug("executing {}",cmd);
|
LOG.debug("executing {}",cmd);
|
||||||
ProcessBuilder builder = new ProcessBuilder(cmd);
|
ProcessBuilder builder = new ProcessBuilder(cmd);
|
||||||
builder.directory(folder);
|
builder.directory(folder);
|
||||||
@@ -226,17 +248,33 @@ public class DocTable extends JPanel{
|
|||||||
} catch (InterruptedException | IOException e) {
|
} catch (InterruptedException | IOException e) {
|
||||||
LOG.error("{} terminated: ",builder,e);
|
LOG.error("{} terminated: ",builder,e);
|
||||||
}
|
}
|
||||||
for (String page : pdfs) Path.of(path,page).toFile().delete();
|
|
||||||
|
pdfs.stream()
|
||||||
|
.peek(page -> LOG.debug("removing {}",page))
|
||||||
|
.map(page -> folder.toPath().resolve(page))
|
||||||
|
.map(Path::toFile)
|
||||||
|
.forEach(File::delete);
|
||||||
setState(path,t("PDFs joined."));
|
setState(path,t("PDFs joined."));
|
||||||
preview(path);
|
preview(folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Path latestFile(String path) {
|
private Optional<Integer> getPage(String file, String prefix, String suffix) {
|
||||||
File folder = new File(path);
|
if (file.startsWith(prefix) && file.endsWith(suffix)) {
|
||||||
|
file = file.substring(prefix.length(), file.length() - suffix.length());
|
||||||
|
try {
|
||||||
|
return Optional.of(Integer.parseInt(file));
|
||||||
|
} catch (NumberFormatException nfe) {}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path latestFile(File folder) {
|
||||||
if (!folder.exists()) return null;
|
if (!folder.exists()) return null;
|
||||||
|
if (!folder.isDirectory()) folder = folder.getParentFile();
|
||||||
List<String> files = Arrays.asList(folder.list());
|
List<String> files = Arrays.asList(folder.list());
|
||||||
String latest = files.stream().sorted(DocTable::compareFiles).findFirst().orElse(null);
|
String latest = files.stream().sorted(DocTable::compareFiles).findFirst().orElse(null);
|
||||||
return latest == null ? null : Path.of(path,latest);
|
return latest == null ? null : folder.toPath().resolve(latest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -254,17 +292,21 @@ public class DocTable extends JPanel{
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
process = new ProcessBuilder(List.of(Constants.FILE_BROWSER,path)).start();
|
process = new ProcessBuilder(List.of(Constants.FILE_BROWSER,new File(path).getParent())).start();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.error(t("{} terminated: "),process,e);
|
LOG.error(t("{} terminated: "),process,e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void preview(String path){
|
||||||
|
preview(new File(path));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* show lates document of the given directory in preview area
|
* show lates document of the given directory in preview area
|
||||||
* @param path
|
* @param path
|
||||||
*/
|
*/
|
||||||
public void preview(String path) {
|
public void preview(File path) {
|
||||||
LOG.debug("preview({})",path);
|
LOG.debug("preview({})",path);
|
||||||
previewListeners.forEach(l -> l.show(latestFile(path)));
|
previewListeners.forEach(l -> l.show(latestFile(path)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ public class MainFrame extends JFrame {
|
|||||||
private Date date = new Date();
|
private Date date = new Date();
|
||||||
|
|
||||||
private String patchedPath = "";
|
private String patchedPath = "";
|
||||||
|
private String project = "";
|
||||||
|
|
||||||
private Configuration config;
|
private Configuration config;
|
||||||
|
|
||||||
@@ -155,13 +156,26 @@ public class MainFrame extends JFrame {
|
|||||||
* Scans the given path for occurences of '$VARIABLES' and creates input fields for the found variables.
|
* Scans the given path for occurences of '$VARIABLES' and creates input fields for the found variables.
|
||||||
* @param path
|
* @param path
|
||||||
*/
|
*/
|
||||||
private void addFieldsFor(String path) {
|
private void addFieldsForPath(String path) {
|
||||||
Vector<String> marks = new Vector<>();
|
Vector<String> marks = new Vector<>();
|
||||||
Matcher matches = MARKEN.matcher(path);
|
Matcher matches = MARKEN.matcher(path);
|
||||||
while (matches.find()) marks.add(matches.group(1));
|
while (matches.find()) marks.add(matches.group(1));
|
||||||
toolbar.addFieldsFor(marks);
|
toolbar.addFieldsFor(marks);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public String appMissing(String appTest){
|
||||||
|
List<String> cmd = Arrays.asList(appTest.split(" "));
|
||||||
|
|
||||||
|
try {
|
||||||
|
Process process = new ProcessBuilder(cmd).start();
|
||||||
|
int errorCode = process.waitFor();
|
||||||
|
if (errorCode == 0) return null;
|
||||||
|
} catch (InterruptedException | IOException e) {
|
||||||
|
LOG.error(t("{} terminated: "),appTest,e);
|
||||||
|
}
|
||||||
|
return cmd.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
public void checkDependencies() {
|
public void checkDependencies() {
|
||||||
List<String> missing = List.of("convert --version", "killall --version", "pdfsandwich -version", "pdftk --version", "scanimage --version",FILE_BROWSER+" --version")
|
List<String> missing = List.of("convert --version", "killall --version", "pdfsandwich -version", "pdftk --version", "scanimage --version",FILE_BROWSER+" --version")
|
||||||
.stream().map(this::appMissing).filter(app -> app != null).collect(Collectors.toList());
|
.stream().map(this::appMissing).filter(app -> app != null).collect(Collectors.toList());
|
||||||
@@ -226,18 +240,7 @@ public class MainFrame extends JFrame {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String appMissing(String appTest){
|
|
||||||
List<String> cmd = Arrays.asList(appTest.split(" "));
|
|
||||||
|
|
||||||
try {
|
|
||||||
Process process = new ProcessBuilder(cmd).start();
|
|
||||||
int errorCode = process.waitFor();
|
|
||||||
if (errorCode == 0) return null;
|
|
||||||
} catch (InterruptedException | IOException e) {
|
|
||||||
LOG.error(t("{} terminated: "),appTest,e);
|
|
||||||
}
|
|
||||||
return cmd.get(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checks, whether the scan button may be enabled.
|
* checks, whether the scan button may be enabled.
|
||||||
@@ -246,6 +249,12 @@ public class MainFrame extends JFrame {
|
|||||||
toolbar.readyToScan(!(isScanning || patchedPath==null || patchedPath.isBlank() || patchedPath.contains("$")));
|
toolbar.readyToScan(!(isScanning || patchedPath==null || patchedPath.isBlank() || patchedPath.contains("$")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String extension(String path) {
|
||||||
|
var target = config.get(CONFIG_TARGET);
|
||||||
|
return path +"."+ (JPG.equals(target) ? "jpg":"pdf");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void notifyAppsMissing(List<String> missingApps) {
|
private void notifyAppsMissing(List<String> missingApps) {
|
||||||
StringBuilder message = new StringBuilder();
|
StringBuilder message = new StringBuilder();
|
||||||
message.append("<html>");
|
message.append("<html>");
|
||||||
@@ -267,25 +276,26 @@ public class MainFrame extends JFrame {
|
|||||||
* @param path
|
* @param path
|
||||||
* @param dimension
|
* @param dimension
|
||||||
*/
|
*/
|
||||||
private void performScan(String path, Dimension dimension) {
|
private void performScan(String project, String path, Dimension dimension) {
|
||||||
LOG.debug("performScan({})",path);
|
LOG.debug("performScan({})",path);
|
||||||
/* We need to save all required config values before starting to scan, because they might be changed during scanning */
|
/* We need to save all required config values before starting to scan, because they might be changed during scanning */
|
||||||
String target = config.getOrCreate(CONFIG_TARGET, "pdf");
|
String target = config.getOrCreate(CONFIG_TARGET, "pdf");
|
||||||
|
|
||||||
setScanning(true);
|
setScanning(true);
|
||||||
|
|
||||||
File folder = new File(path);
|
var targetFile = new File(path);
|
||||||
|
File folder = targetFile.getParentFile();
|
||||||
if (!folder.exists()) {
|
if (!folder.exists()) {
|
||||||
LOG.warn(t("Path '{}' does not exist!"),path);
|
LOG.warn(t("Path '{}' does not exist!"),path);
|
||||||
folder.mkdirs();
|
folder.mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
docTable.add(path);
|
docTable.add(project);
|
||||||
|
|
||||||
int resolution = toolbar.getResolution();
|
int resolution = toolbar.getResolution();
|
||||||
boolean improbeBrightness = toolbar.getImproveBrightness();
|
boolean improbeBrightness = toolbar.getImproveBrightness();
|
||||||
long timestamp = new Date().getTime();
|
//long timestamp = new Date().getTime();
|
||||||
String raw = timestamp+".jpg";
|
//String raw = timestamp+".jpg";
|
||||||
|
var raw = targetFile.getName()+".jpg";
|
||||||
|
|
||||||
Vector<String> cmd = new Vector<>();
|
Vector<String> cmd = new Vector<>();
|
||||||
cmd.add("scanimage");
|
cmd.add("scanimage");
|
||||||
@@ -305,19 +315,19 @@ public class MainFrame extends JFrame {
|
|||||||
builder.directory(folder);
|
builder.directory(folder);
|
||||||
try {
|
try {
|
||||||
Process process = builder.start();
|
Process process = builder.start();
|
||||||
docTable.setState(path,t("Scanning…"));
|
docTable.setState(project,t("Scanning…"));
|
||||||
int errorCode = process.waitFor();
|
int errorCode = process.waitFor();
|
||||||
if (errorCode != 0) {
|
if (errorCode != 0) {
|
||||||
LOG.error(t("Error code: {} for {}"),errorCode,cmd);
|
LOG.error(t("Error code: {} for {}"),errorCode,cmd);
|
||||||
docTable.setState(path, t("Scan failed."));
|
docTable.setState(project, t("Scan failed."));
|
||||||
setScanning(false);
|
setScanning(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (InterruptedException | IOException e) {
|
} catch (InterruptedException | IOException e) {
|
||||||
LOG.error(t("{} terminated: "),builder,e);
|
LOG.error(t("{} terminated: "),builder,e);
|
||||||
}
|
}
|
||||||
setScanning(false);
|
setScanning(false);
|
||||||
|
toolbar.nextPage();
|
||||||
|
|
||||||
if (improbeBrightness) {
|
if (improbeBrightness) {
|
||||||
cmd = new Vector<>();
|
cmd = new Vector<>();
|
||||||
@@ -329,11 +339,11 @@ public class MainFrame extends JFrame {
|
|||||||
builder.directory(folder);
|
builder.directory(folder);
|
||||||
try {
|
try {
|
||||||
Process process = builder.start();
|
Process process = builder.start();
|
||||||
docTable.setState(path,t("Adjusting brightness…"));
|
docTable.setState(project,t("Adjusting brightness…"));
|
||||||
int errorCode = process.waitFor();
|
int errorCode = process.waitFor();
|
||||||
if (errorCode != 0) {
|
if (errorCode != 0) {
|
||||||
LOG.error(t("Error code: {} for {}"),errorCode,cmd);
|
LOG.error(t("Error code: {} for {}"),errorCode,cmd);
|
||||||
docTable.setState(path, t("Adjustment failed."));
|
docTable.setState(project, t("Adjustment failed."));
|
||||||
setScanning(false);
|
setScanning(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -344,12 +354,12 @@ public class MainFrame extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (JPG.equals(target)) {
|
if (JPG.equals(target)) {
|
||||||
docTable.setState(path, t("Image scanned"));
|
docTable.setState(project, t("Image scanned"));
|
||||||
docTable.preview(path);
|
docTable.preview(folder);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
String pdf = timestamp+".page.pdf";
|
String pdf = targetFile.getName() + (PDF.equals(target) ? ".pdf" : ".tmp.pdf"); //timestamp+".page.pdf";
|
||||||
cmd = new Vector<>();
|
cmd = new Vector<>();
|
||||||
cmd.add("convert");
|
cmd.add("convert");
|
||||||
cmd.add(raw);
|
cmd.add(raw);
|
||||||
@@ -358,26 +368,27 @@ public class MainFrame extends JFrame {
|
|||||||
builder.directory(folder);
|
builder.directory(folder);
|
||||||
try {
|
try {
|
||||||
Process process = builder.start();
|
Process process = builder.start();
|
||||||
docTable.setState(path,t("Converting to PDF…"));
|
docTable.setState(project,t("Converting to PDF…"));
|
||||||
int errorCode = process.waitFor();
|
int errorCode = process.waitFor();
|
||||||
if (errorCode != 0) {
|
if (errorCode != 0) {
|
||||||
LOG.error("Error code: {} for {}",errorCode,cmd);
|
LOG.error("Error code: {} for {}",errorCode,cmd);
|
||||||
docTable.setState(path, t("Conversion failed."));
|
docTable.setState(project, t("Conversion failed."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (InterruptedException | IOException e) {
|
} catch (InterruptedException | IOException e) {
|
||||||
LOG.error("{} terminated: ",builder,e);
|
LOG.error("{} terminated: ",builder,e);
|
||||||
}
|
}
|
||||||
|
LOG.debug("removing {}",raw);
|
||||||
Path.of(path, raw).toFile().delete();
|
folder.toPath().resolve(raw).toFile().delete();
|
||||||
|
//Path.of(folder,raw).toFile().delete();
|
||||||
if (PDF.equals(target)) {
|
if (PDF.equals(target)) {
|
||||||
docTable.setState(path, t("PDF created"));
|
docTable.setState(project, t("PDF created"));
|
||||||
docTable.preview(path);
|
docTable.preview(folder);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String ocr = timestamp+".page.ocr.pdf";
|
String ocr = targetFile.getName() + ".pdf";//timestamp+".page.ocr.pdf";
|
||||||
|
|
||||||
cmd = new Vector<>();
|
cmd = new Vector<>();
|
||||||
cmd.add("pdfsandwich");
|
cmd.add("pdfsandwich");
|
||||||
@@ -396,20 +407,26 @@ public class MainFrame extends JFrame {
|
|||||||
builder.directory(folder);
|
builder.directory(folder);
|
||||||
try {
|
try {
|
||||||
Process process = builder.start();
|
Process process = builder.start();
|
||||||
docTable.setState(path,t("Text recognition…"));
|
docTable.setState(project,t("Text recognition…"));
|
||||||
int errorCode = process.waitFor();
|
int errorCode = process.waitFor();
|
||||||
if (errorCode != 0) {
|
if (errorCode != 0) {
|
||||||
LOG.error("error code: {} for {}",errorCode,cmd);
|
LOG.error("error code: {} for {}",errorCode,cmd);
|
||||||
docTable.setState(path, t("OCR failed."));
|
docTable.setState(project, t("OCR failed."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!folder.toPath().resolve(ocr).toFile().exists()){
|
||||||
|
docTable.setState(project,t("OCR failed."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (InterruptedException | IOException e) {
|
} catch (InterruptedException | IOException e) {
|
||||||
LOG.error("{} terminated: ",builder,e);
|
LOG.error("{} terminated: ",builder,e);
|
||||||
}
|
}
|
||||||
Path.of(path, pdf).toFile().delete();
|
|
||||||
docTable.setState(path,t("Finished text recognition."));
|
LOG.debug("removing {}",pdf);
|
||||||
docTable.preview(path);
|
folder.toPath().resolve(pdf).toFile().delete();
|
||||||
|
docTable.setState(project,t("Finished text recognition."));
|
||||||
|
docTable.preview(folder);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -440,7 +457,7 @@ public class MainFrame extends JFrame {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* open file in preview panel
|
* open file in preview panel
|
||||||
* @param file
|
* @param filePath
|
||||||
*/
|
*/
|
||||||
private void preview(Path filePath) {
|
private void preview(Path filePath) {
|
||||||
if (filePath == null) return;
|
if (filePath == null) return;
|
||||||
@@ -482,7 +499,7 @@ public class MainFrame extends JFrame {
|
|||||||
*/
|
*/
|
||||||
private void scan(ActionEvent ev) {
|
private void scan(ActionEvent ev) {
|
||||||
updateConfig();
|
updateConfig();
|
||||||
new Thread(() -> performScan(patchedPath,dimension)).start();
|
new Thread(() -> performScan(project,patchedPath,dimension)).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -592,10 +609,17 @@ public class MainFrame extends JFrame {
|
|||||||
.replace("$"+t("YEAR"), year+"")
|
.replace("$"+t("YEAR"), year+"")
|
||||||
.replace("$"+t("MONTH"), month<10 ? "0"+month : ""+month)
|
.replace("$"+t("MONTH"), month<10 ? "0"+month : ""+month)
|
||||||
.replace("$"+t("DAY"), day < 10 ? "0"+day : ""+day);
|
.replace("$"+t("DAY"), day < 10 ? "0"+day : ""+day);
|
||||||
|
addFieldsForPath(patchedPath);
|
||||||
|
project = extension(patchedPath);
|
||||||
|
for (Entry<String, String> entry : fields.entrySet()) {
|
||||||
|
var key = entry.getKey();
|
||||||
|
patchedPath = patchedPath.replace("$"+entry.getKey(), entry.getValue());
|
||||||
|
if (!t("PAGE").equals(key)){
|
||||||
|
project = project.replace("$"+entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
addFieldsFor(patchedPath);
|
}
|
||||||
for (Entry<String, String> entry : fields.entrySet()) patchedPath = patchedPath.replace("$"+entry.getKey(), entry.getValue());
|
statusBar.setPath(extension(patchedPath));
|
||||||
statusBar.setPath(patchedPath);
|
|
||||||
checkScanButton();
|
checkScanButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,10 @@ public class Toolbar extends JPanel {
|
|||||||
if (additonalComponents.containsKey(name)) continue;
|
if (additonalComponents.containsKey(name)) continue;
|
||||||
SelectComboBox valuePicker = new SelectComboBox(new Vector<>()).onUpdateText(newText -> updateField(name,newText));
|
SelectComboBox valuePicker = new SelectComboBox(new Vector<>()).onUpdateText(newText -> updateField(name,newText));
|
||||||
JPanel input = input(name, valuePicker);
|
JPanel input = input(name, valuePicker);
|
||||||
|
if (t("PAGE").equals(name)) {
|
||||||
|
valuePicker.setText("1");
|
||||||
|
SwingUtilities.invokeLater(() -> updateField(name,"1"));
|
||||||
|
}
|
||||||
input.setBorder(BORDER);
|
input.setBorder(BORDER);
|
||||||
add(input,getComponentCount()-OFFSET);
|
add(input,getComponentCount()-OFFSET);
|
||||||
additonalComponents.put(name, input);
|
additonalComponents.put(name, input);
|
||||||
@@ -349,6 +353,25 @@ public class Toolbar extends JPanel {
|
|||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Toolbar nextPage(){
|
||||||
|
var page = t("PAGE");
|
||||||
|
var panel = additonalComponents.get(page);
|
||||||
|
if (panel == null) return this;
|
||||||
|
for (var child : panel.getComponents()){
|
||||||
|
if (child instanceof SelectComboBox scb){
|
||||||
|
var val = scb.getText();
|
||||||
|
try {
|
||||||
|
var newVal = ""+(Integer.parseInt(val)+1);
|
||||||
|
scb.setText(newVal);
|
||||||
|
fieldListeners.forEach(l -> l.setField(page,newVal));
|
||||||
|
} catch (NumberFormatException nfe){}
|
||||||
|
}
|
||||||
|
LOG.debug("component: {}",child);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates an auto-complete text field for setting the scan target path
|
* creates an auto-complete text field for setting the scan target path
|
||||||
* @return
|
* @return
|
||||||
@@ -359,7 +382,7 @@ public class Toolbar extends JPanel {
|
|||||||
JSONObject catInfo = cats.getJSONObject(catName);
|
JSONObject catInfo = cats.getJSONObject(catName);
|
||||||
if (catInfo.has("path")) paths.add(catInfo.get("path"));
|
if (catInfo.has("path")) paths.add(catInfo.get("path"));
|
||||||
}
|
}
|
||||||
paths.add("$"+t("HOME")+"/$"+t("YEAR")+"/$"+t("MONTH")+"-$"+t("DAY")+" - $"+t("CATEGORY"));
|
paths.add("$"+t("HOME")+"/$"+t("YEAR")+"/$"+t("MONTH")+"-$"+t("DAY")+" - $"+t("CATEGORY")+"/$"+t("PAGE"));
|
||||||
return new SelectComboBox(paths).onUpdateText(this::updatePath);
|
return new SelectComboBox(paths).onUpdateText(this::updatePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +450,7 @@ public class Toolbar extends JPanel {
|
|||||||
* create one radio button for the typeSelector
|
* create one radio button for the typeSelector
|
||||||
* @param group
|
* @param group
|
||||||
* @param label
|
* @param label
|
||||||
* @param i
|
* @param selection
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private JRadioButton typeButton(ButtonGroup group, String label,String selection) {
|
private JRadioButton typeButton(ButtonGroup group, String label,String selection) {
|
||||||
@@ -440,7 +463,6 @@ public class Toolbar extends JPanel {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* create a radio group to select the target type for scanning
|
* create a radio group to select the target type for scanning
|
||||||
* @param jsonObject
|
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private JPanel typeSelector() {
|
private JPanel typeSelector() {
|
||||||
@@ -533,7 +555,4 @@ public class Toolbar extends JPanel {
|
|||||||
LOG.debug("updatePath({})",newPath);
|
LOG.debug("updatePath({})",newPath);
|
||||||
pathListeners.forEach(l -> l.setPath(newPath));
|
pathListeners.forEach(l -> l.setPath(newPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user