diff --git a/.classpath b/.classpath
index 899de31..b3a1b28 100644
--- a/.classpath
+++ b/.classpath
@@ -6,16 +6,18 @@
+
+
+
-
diff --git a/pom.xml b/pom.xml
index dea8da7..fdfd606 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,8 +4,36 @@
4.0.0
BelegScanner
BelegScanner
- 0.0.2
+ 0.0.3
BelegScanner
+ jar
+ BelegScanner
+ https://github.com/srsoftware-de/Belegscanner
+
+
+ SRSoftware
+ https://srsoftware.de
+
+
+
+ UTF-8
+
+
+
+
+ MIT License
+ http://www.opensource.org/licenses/mit-license.php
+
+
+
+
+
+ Stephan Richter
+ s.richter@srsoftware.de
+ SRSoftware
+ http://www.srsoftware.de
+
+
@@ -47,6 +75,41 @@
11
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ package
+
+ single
+
+
+
+
+
+ de.srsoftware.web4rail.Application
+
+
+
+
+ jar-with-dependencies
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.4.0
+
+ de.srsoftware.web4rail.Application
+
+
+
+
\ No newline at end of file
diff --git a/resources/logback.xml b/resources/logback.xml
new file mode 100644
index 0000000..29567a5
--- /dev/null
+++ b/resources/logback.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/resources/translations/Application.de.translation b/resources/translations/Application.de.translation
new file mode 100644
index 0000000..e69de29
diff --git a/src/main/java/de/srsoftware/belegscanner/Configuration.java b/src/main/java/de/srsoftware/belegscanner/Configuration.java
index c8a512b..ec02449 100644
--- a/src/main/java/de/srsoftware/belegscanner/Configuration.java
+++ b/src/main/java/de/srsoftware/belegscanner/Configuration.java
@@ -128,11 +128,13 @@ public class Configuration {
String localKey = parts[i];
LOG.debug("localKey = {}",localKey);
boolean lastPart = i == parts.length-1;
- if (!localJson.has(localKey)) {
- LOG.debug("{} not present in {}, creating…",localKey,localJson);
- localJson.put(localKey, lastPart ? value : new JSONObject());
+ if (!lastPart && !localJson.has(localKey)) {
+ localJson.put(localKey, new JSONObject());
+ }
+ if (lastPart) {
+ localJson.put(localKey, value);
+ break;
}
- if (lastPart) break;
localJson = localJson.getJSONObject(localKey);
}
LOG.debug("altered json: {}",json);
diff --git a/src/main/java/de/srsoftware/belegscanner/gui/MainFrame.java b/src/main/java/de/srsoftware/belegscanner/gui/MainFrame.java
index 8151f28..2ad5042 100644
--- a/src/main/java/de/srsoftware/belegscanner/gui/MainFrame.java
+++ b/src/main/java/de/srsoftware/belegscanner/gui/MainFrame.java
@@ -2,9 +2,18 @@ package de.srsoftware.belegscanner.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
+import java.awt.Point;
import java.awt.event.ActionEvent;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map.Entry;
import java.util.Vector;
import java.util.regex.Matcher;
@@ -12,6 +21,7 @@ import java.util.regex.Pattern;
import javax.swing.JFrame;
+import org.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,6 +35,7 @@ public class MainFrame extends JFrame {
private static final String HOME = System.getProperty("user.home");
private static final Pattern MARKEN = Pattern.compile("\\$([a-zA-Z]+)");
+ private static FilenameFilter PAGES = (dir,name) -> name.toLowerCase().endsWith("pdf") && name.toLowerCase().startsWith("page");
private StatusBar statusBar;
private Toolbar toolbar;
@@ -41,7 +52,13 @@ public class MainFrame extends JFrame {
private Configuration config;
+ private int xSize = 209;
+ private int ySize = 297;
+ private int resoultion = 150;
+ private String mode = "Color";
+
public MainFrame(Configuration config) {
+ super("BelegScanner");
this.config = config;
int width = config.getOrCreate("app.main.dimenstion.w",800);
int height = config.getOrCreate("app.main.dimenstion.h",600);
@@ -57,8 +74,14 @@ public class MainFrame extends JFrame {
toolbar.addCategoryListener(this::setCategory)
.addDateListener(this::setDate)
.addFieldListener(this::setField)
+ .addFolderListener(this::openFolder)
+ .addJoinListener(this::join)
.addPathListener(this::setPath)
- .addScanListener(this::scan);
+ .addScanListener(this::scan);
+
+ int x = config.getOrCreate("app.main.position.x", 20);
+ int y = config.getOrCreate("app.main.position.y", 20);
+ setLocation(new Point(x, y));
setPreferredSize(new Dimension(width,height));
pack();
@@ -72,9 +95,159 @@ public class MainFrame extends JFrame {
toolbar.addFieldsFor(marks);
};
+ private void join(ActionEvent ev) {
+ new Thread(() -> joinFiles(patchedPath)).start();
+ }
+
+ private void joinFiles(String path) {
+ LOG.debug("joinFiles({})",path);
+ File folder = new File(path);
+ if (!folder.exists()) return;
+
+ List pdfs = Arrays.asList(folder.list(PAGES));
+ Collections.sort(pdfs);
+
+ Vector cmd = new Vector<>();
+ cmd.add("pdftk");
+ cmd.addAll(pdfs);
+ cmd.add("cat");
+ cmd.add("output");
+ cmd.add(folder.getName()+".pdf");
+ LOG.debug("executing {}",cmd);
+ ProcessBuilder builder = new ProcessBuilder(cmd);
+ builder.directory(folder);
+ try {
+ Process process = builder.start();
+ statusBar.setAction("Verbinde PDFs…");
+ int errorCode = process.waitFor();
+ if (errorCode != 0) {
+ LOG.error("error code: {} for {}",errorCode,cmd);
+ } else LOG.debug("error code: {}",errorCode);
+ } catch (InterruptedException | IOException e) {
+ LOG.error("{} terminated: ",builder,e);
+ }
+ for (String page : pdfs) Path.of(path,page).toFile().delete();
+ statusBar.setAction("Bereit.");
+ }
+
+ private void openFolder(ActionEvent ev) {
+ new Thread(() -> openFolder(patchedPath)).start();
+ }
+
+ private void openFolder(String path) {
+ File folder = new File(path);
+ if (!folder.exists()) return;
+
+ ProcessBuilder builder = new ProcessBuilder(List.of("killall","thunar"));
+ builder.directory(folder);
+ try {
+ builder.start().waitFor();
+ } catch (IOException | InterruptedException e) {
+ LOG.error("{} terminated: ",builder,e);
+ }
+
+ builder = new ProcessBuilder("thunar");
+ builder.directory(folder);
+ try {
+ builder.start();
+ } catch (IOException e) {
+ LOG.error("{} terminated: ",builder,e);
+ }
+ }
+
+ private void performScan(String path) {
+ LOG.debug("performScan({})",path);
+ toolbar.readyToScan(false);
+ File folder = new File(path);
+ if (!folder.exists()) {
+ LOG.warn("Path '{}' does not exist!",path);
+ folder.mkdirs();
+ }
+
+ long timestamp = new Date().getTime();
+ String raw = timestamp+".jpg";
+
+ Vector cmd = new Vector<>();
+ cmd.add("scanimage");
+ cmd.add("-x");
+ cmd.add(xSize+"");
+ cmd.add("-y");
+ cmd.add(ySize+"");
+ cmd.add("--mode");
+ cmd.add(mode);
+ cmd.add("--resolution");
+ cmd.add(resoultion+"");
+ cmd.add("-o");
+ cmd.add(raw);
+ LOG.debug("executing {}",cmd);
+
+ ProcessBuilder builder = new ProcessBuilder(cmd);
+ builder.directory(folder);
+ try {
+ Process process = builder.start();
+ statusBar.setAction("Scanne nach "+path+"…");
+ int errorCode = process.waitFor();
+ if (errorCode != 0) {
+ LOG.error("error code: {} for {}",errorCode,cmd);
+ } else LOG.debug("error code: {}",errorCode);
+
+ } catch (InterruptedException | IOException e) {
+ LOG.error("{} terminated: ",builder,e);
+ }
+
+ String pdf = "page."+timestamp+".pdf";
+ cmd = new Vector<>();
+ cmd.add("convert");
+ cmd.add(raw);
+ cmd.add(pdf);
+ builder = new ProcessBuilder(cmd);
+ builder.directory(folder);
+ try {
+ Process process = builder.start();
+ statusBar.setAction("Kovertiere zu PDF…");
+ toolbar.readyToScan(true);
+ int errorCode = process.waitFor();
+ if (errorCode != 0) {
+ LOG.error("error code: {} for {}",errorCode,cmd);
+ } else LOG.debug("error code: {}",errorCode);
+
+ } catch (InterruptedException | IOException e) {
+ LOG.error("{} terminated: ",builder,e);
+ }
+
+ Path.of(path, raw).toFile().delete();
+ String ocr = "page."+timestamp+".ocr.pdf";
+
+ cmd = new Vector<>();
+ cmd.add("pdfsandwich");
+ cmd.add("-lang");
+ cmd.add("deu");
+ cmd.add("-rgb");
+ cmd.add("-o");
+
+ cmd.add(ocr);
+ cmd.add(pdf);
+ builder = new ProcessBuilder(cmd);
+ builder.directory(folder);
+ try {
+ Process process = builder.start();
+ statusBar.setAction("Texterkennung…");
+ toolbar.readyToScan(true);
+ int errorCode = process.waitFor();
+ if (errorCode != 0) {
+ LOG.error("error code: {} for {}",errorCode,cmd);
+ } else LOG.debug("error code: {}",errorCode);
+
+ } catch (InterruptedException | IOException e) {
+ LOG.error("{} terminated: ",builder,e);
+ }
+ Path.of(path, pdf).toFile().delete();
+ statusBar.setAction("Bereit.");
+ }
+
private void scan(ActionEvent ev) {
- LOG.debug("Scanning into '{}'",patchedPath);
- config.set("app.categories."+category+".path",path);
+ updateConfig();
+ new Thread(() -> performScan(patchedPath)).start();
}
private void setCategory(String category) {
@@ -89,7 +262,9 @@ public class MainFrame extends JFrame {
}
private void setField(String key, String val) {
- fields.put(key, val);
+ if (val == null || val.isEmpty()) {
+ fields.remove(key);
+ } else fields.put(key, val);
updatePath();
}
@@ -99,6 +274,23 @@ public class MainFrame extends JFrame {
updatePath();
}
+ private void updateConfig() {
+
+ String prefix = "app.categories."+category+".";
+ for (Entry entry : fields.entrySet()) {
+ String key = entry.getKey();
+ String val = entry.getValue();
+ JSONArray arr = config.getOrCreateArray(prefix+"fields."+key);
+ HashSet