diff --git a/pom.xml b/pom.xml
index 1cd2fcd..f12c22d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- MKVAudioSubtileChanger
+ at.pcgamingfreaks
MKVAudioSubtitleChanger
3.0
@@ -20,7 +20,7 @@
./
language-codes
- version.properties
+ project.properties
true
@@ -194,6 +194,12 @@
YAML-Parser
2.0-SNAPSHOT
+
+
+ net.harawata
+ appdirs
+ 1.2.1
+
\ No newline at end of file
diff --git a/project.properties b/project.properties
new file mode 100644
index 0000000..fc543c7
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,2 @@
+version=${project.version}
+project_name=${project.artifactId}
\ No newline at end of file
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java
index 69a4d02..dc8d6a5 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java
@@ -38,6 +38,8 @@ public class Config {
private Integer coherent;
private boolean forceCoherent;
+ private boolean onlyNewFiles;
+ private Date filterDate;
private Set forcedKeywords = new HashSet<>(Arrays.asList("forced", "signs", "songs"));
private Set commentaryKeywords = new HashSet<>(Arrays.asList("commentary", "director"));
@@ -67,20 +69,29 @@ public class Config {
mkvToolNix.getAbsolutePath() + "/" + application;
}
+ public String getNormalizedLibraryPath() {
+ return this.getLibraryPath().getAbsolutePath().replace("\\", "/");
+ }
+
@Override
public String toString() {
return new StringJoiner(", ", Config.class.getSimpleName() + "[", "]")
- .add("parser=" + parser).add("\n")
- .add("formatter=" + formatter).add("\n")
- .add("configPath=" + configPath).add("\n")
- .add("libraryPath=" + libraryPath).add("\n")
- .add("isSafeMode=" + safeMode).add("\n")
- .add("forcedKeywords=" + forcedKeywords).add("\n")
- .add("commentaryKeywords=" + commentaryKeywords).add("\n")
- .add("excludedDirectories=" + excludedDirectories).add("\n")
- .add("threadCount=" + threads).add("\n")
- .add("includePattern=" + includePattern).add("\n")
- .add("mkvToolNixPath='" + mkvToolNix + "'").add("\n")
+ .add("parser=" + parser)
+ .add("formatter=" + formatter)
+ .add("configPath=" + configPath)
+ .add("libraryPath=" + libraryPath)
+ .add("mkvToolNix=" + mkvToolNix)
+ .add("threads=" + threads)
+ .add("includePattern=" + includePattern)
+ .add("safeMode=" + safeMode)
+ .add("coherent=" + coherent)
+ .add("forceCoherent=" + forceCoherent)
+ .add("onlyNewFiles=" + onlyNewFiles)
+ .add("filterDate=" + filterDate)
+ .add("forcedKeywords=" + forcedKeywords)
+ .add("commentaryKeywords=" + commentaryKeywords)
+ .add("excludedDirectories=" + excludedDirectories)
+ .add("preferredSubtitles=" + preferredSubtitles)
.add("attributeConfig=" + attributeConfig)
.toString();
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java
index adf87af..176a908 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java
@@ -2,7 +2,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator.*;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
-import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.VersionUtil;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ProjectUtil;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import org.apache.commons.cli.*;
@@ -11,19 +11,24 @@ import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
public class ConfigLoader {
- private static final List> VALIDATORS = List.of(
+ private static final List> VALIDATORS = Stream.of(
new ConfigPathValidator(CONFIG_PATH, false),
new PathValidator(LIBRARY, true, null),
new ThreadValidator(THREADS, false, 2),
new MkvToolNixPathValidator(MKV_TOOL_NIX, true, Path.of("C:\\Program Files\\MKVToolNix").toFile()),
new BooleanValidator(SAFE_MODE, false),
+ new BooleanValidator(ONLY_NEW_FILES, false),
+ new DateValidator(FILTER_DATE, false),
new PatternValidator(INCLUDE_PATTERN, false, Pattern.compile(".*")),
new SetValidator(FORCED_KEYWORDS, false, true),
new SetValidator(COMMENTARY_KEYWORDS, false, true),
@@ -32,7 +37,7 @@ public class ConfigLoader {
new AttributeConfigValidator(),
new CoherentConfigValidator(COHERENT, false),
new BooleanValidator(FORCE_COHERENT, false)
- );
+ ).sorted(Comparator.comparing((ConfigValidator> validator) -> validator.getWeight()).reversed()).collect(Collectors.toList());
public static void initConfig(String[] args) {
HelpFormatter formatter = new HelpFormatter();
@@ -98,7 +103,7 @@ public class ConfigLoader {
private static void exitIfVersion(CommandLine cmd) {
if (cmd.hasOption(VERSION.prop())) {
- System.out.printf("MKV Audio Subtitle Changer Version %s%n", VersionUtil.getVersion());
+ System.out.printf("MKV Audio Subtitle Changer Version %s%n", ProjectUtil.getVersion());
System.exit(0);
}
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigPathValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigPathValidator.java
index 6790e75..c051ca1 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigPathValidator.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigPathValidator.java
@@ -27,4 +27,9 @@ public class ConfigPathValidator extends PathValidator {
protected boolean isValid(File result) {
return super.isValid(result) && (result.getAbsolutePath().endsWith(".yml") || result.getAbsolutePath().endsWith(".yaml"));
}
+
+ @Override
+ public int getWeight() {
+ return 100;
+ }
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigValidator.java
index 3b67666..791ee77 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigValidator.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigValidator.java
@@ -6,144 +6,171 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlKeyNotFoundException;
import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
import java.util.Optional;
+import java.util.StringJoiner;
import java.util.function.BiFunction;
import java.util.function.Predicate;
-import java.util.stream.Collectors;
+@Slf4j
@RequiredArgsConstructor
public abstract class ConfigValidator {
- protected final ConfigProperty property;
- protected final boolean required;
- protected final FieldType defaultValue;
+ protected final ConfigProperty property;
+ protected final boolean required;
+ protected final FieldType defaultValue;
- /**
- * Validate the user input. Parameters of cmd are prioritised.
- *
- * @param yaml config file
- * @param cmd command line parameters
- * @return {@link ValidationResult} containing validity of input.
- */
+ /**
+ * Validate the user input. Parameters of cmd are prioritised.
+ *
+ * @param yaml config file
+ * @param cmd command line parameters
+ * @return {@link ValidationResult} containing validity of input.
+ */
public ValidationResult validate(YAML yaml, CommandLine cmd) {
- System.out.printf("%s: ", property.prop());
- FieldType result;
+ System.out.printf("%s: ", property.prop());
+ FieldType result;
- Optional cmdResult = provideDataCmd().apply(cmd, property);
- Optional yamlResult = provideDataYaml().apply(yaml, property);
+ Optional cmdResult = provideDataCmd().apply(cmd, property);
+ Optional yamlResult = provideDataYaml().apply(yaml, property);
- if (cmdResult.isPresent()) {
- result = cmdResult.get();
- } else if (yamlResult.isPresent()) {
- result = yamlResult.get();
- } else {
- if (defaultValue != null) {
- if (setValue(defaultValue)) {
- System.out.println("default");
- return ValidationResult.DEFAULT;
- } else {
- System.out.println("invalid");
- return ValidationResult.INVALID;
- }
- }
- if (required) {
- System.out.println("missing");
- return ValidationResult.MISSING;
- } else {
- System.out.println("ok");
- return ValidationResult.NOT_PRESENT;
- }
- }
+ if (isOverwritingNecessary()) {
+ result = overwriteValue();
+ } else if (cmdResult.isPresent()) {
+ result = cmdResult.get();
+ } else if (yamlResult.isPresent()) {
+ result = yamlResult.get();
+ } else {
+ if (defaultValue != null) {
+ if (setValue(defaultValue)) {
+ System.out.println("default");
+ return ValidationResult.DEFAULT;
+ } else {
+ System.out.println("invalid");
+ return ValidationResult.INVALID;
+ }
+ }
+ if (required) {
+ System.out.println("missing");
+ return ValidationResult.MISSING;
+ } else {
+ System.out.println("ok");
+ return ValidationResult.NOT_PRESENT;
+ }
+ }
- if (!isValid(result) || !setValue(result)) {
- System.out.println("invalid");
- return ValidationResult.INVALID;
- }
+ if (!isValid(result) || !setValue(result)) {
+ System.out.println("invalid");
+ return ValidationResult.INVALID;
+ }
- System.out.println("ok");
- return ValidationResult.VALID;
- }
-
- /**
- * @return parsed input of yaml config for property
- */
- protected BiFunction> provideDataYaml() {
- return (yaml, property) -> {
- if (yaml.isSet(property.prop())) {
- try {
- return Optional.of(parse(yaml.getString(property.prop())));
- } catch (YamlKeyNotFoundException e) {
- throw new RuntimeException(e);
- }
- }
- return Optional.empty();
- };
- }
-
- /**
- * @return parsed input of command line parameters config for property
- */
- protected BiFunction> provideDataCmd() {
- return (cmd, property) -> {
- if (cmd.hasOption(property.prop())) {
- return Optional.of(parse(cmd.getOptionValue(property.prop())));
- }
- return Optional.empty();
- };
- }
-
- /**
- * Parse input parameter to desired format.
- *
- * @param value input parameter
- * @return parsed property
- */
- abstract FieldType parse(String value);
-
- /**
- * Validate if the data has the desired and allowed format.
- *
- * @param result parsed property
- * @return true if data is in desired format.
- */
- abstract boolean isValid(FieldType result);
-
- /**
- * Sets valid properties to {@link Config} via reflections.
- *
- * @param result parsed property
- * @return false if method invocation failed
- */
- protected boolean setValue(FieldType result) {
- for (Method method: Config.getInstance().getClass().getDeclaredMethods()) {
- if(containsSetterOf(property).test(method)) {
- try {
- method.invoke(Config.getInstance(), result);
- return true;
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- return false;
+ System.out.println("ok");
+ return ValidationResult.VALID;
}
- protected Predicate containsSetterOf(ConfigProperty property) {
- return method -> StringUtils.startsWith(method.getName(), "set")
- && StringUtils.equalsIgnoreCase(method.getName().replace("set", ""), property.prop().replace("-", ""));
- }
+ /**
+ * @return parsed input of yaml config for property
+ */
+ protected BiFunction> provideDataYaml() {
+ return (yaml, property) -> {
+ if (yaml.isSet(property.prop())) {
+ try {
+ return Optional.of(parse(yaml.getString(property.prop())));
+ } catch (YamlKeyNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return Optional.empty();
+ };
+ }
- protected Predicate containsGetterOf(ConfigProperty property) {
- return method -> StringUtils.startsWith(method.getName(), "get")
- && StringUtils.equalsIgnoreCase(method.getName().replace("get", ""), property.prop().replace("-", ""));
- }
+ /**
+ * @return parsed input of command line parameters config for property
+ */
+ protected BiFunction> provideDataCmd() {
+ return (cmd, property) -> {
+ if (cmd.hasOption(property.prop())) {
+ return Optional.of(parse(cmd.getOptionValue(property.prop())));
+ }
+ return Optional.empty();
+ };
+ }
+ /**
+ * @return true if overwriting this property is necessary.
+ */
+ protected boolean isOverwritingNecessary() {
+ return false;
+ }
+ /**
+ * @return {@link FieldType} to overwrite result with.
+ */
+ protected FieldType overwriteValue() {
+ return null;
+ }
+
+ /**
+ * Parse input parameter to desired format.
+ *
+ * @param value input parameter
+ * @return parsed property
+ */
+ abstract FieldType parse(String value);
+
+ /**
+ * Validate if the data has the desired and allowed format.
+ *
+ * @param result parsed property
+ * @return true if data is in desired format.
+ */
+ abstract boolean isValid(FieldType result);
+
+ /**
+ * Sets valid properties to {@link Config} via reflections.
+ *
+ * @param result parsed property
+ * @return false if method invocation failed
+ */
+ protected boolean setValue(FieldType result) {
+ for (Method method : Config.getInstance().getClass().getDeclaredMethods()) {
+ if (containsSetterOf(property).test(method)) {
+ try {
+ method.invoke(Config.getInstance(), result);
+ return true;
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ protected Predicate containsSetterOf(ConfigProperty property) {
+ return method -> StringUtils.startsWith(method.getName(), "set")
+ && StringUtils.equalsIgnoreCase(method.getName().replace("set", ""), property.prop().replace("-", ""));
+ }
+
+ protected Predicate containsGetterOf(ConfigProperty property) {
+ return method -> StringUtils.startsWith(method.getName(), "get")
+ && StringUtils.equalsIgnoreCase(method.getName().replace("get", ""), property.prop().replace("-", ""));
+ }
+
+ public int getWeight() {
+ return 50;
+ }
+
+ @Override
+ public String toString() {
+ return new StringJoiner(", ", ConfigValidator.class.getSimpleName() + "[", "]")
+ .add("property=" + property)
+ .add("required=" + required)
+ .add("defaultValue=" + defaultValue)
+ .toString();
+ }
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/DateValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/DateValidator.java
new file mode 100644
index 0000000..f376af1
--- /dev/null
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/DateValidator.java
@@ -0,0 +1,61 @@
+package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
+
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.DateUtils;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ProjectUtil;
+import at.pcgamingfreaks.yaml.YAML;
+import at.pcgamingfreaks.yaml.YamlInvalidContentException;
+import lombok.extern.slf4j.Slf4j;
+import net.harawata.appdirs.AppDirsFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Date;
+
+@Slf4j
+public class DateValidator extends ConfigValidator {
+ private static final Date INVALID_DATE = new Date(0);
+ private static final Date DEFAULT_DATE = new Date(1000);
+
+ public DateValidator(ConfigProperty property, boolean required) {
+ super(property, required, null);
+ }
+
+ @Override
+ protected boolean isOverwritingNecessary() {
+ return Config.getInstance().isOnlyNewFiles();
+ }
+
+ @Override
+ protected Date overwriteValue() {
+ try {
+ String filePath = AppDirsFactory.getInstance().getUserConfigDir(ProjectUtil.getProjectName(), null, null);
+ File lastExecutionFile = Path.of(filePath + "/last-execution.yml").toFile();
+ if (!lastExecutionFile.exists()) {
+ return DEFAULT_DATE;
+ }
+ YAML yaml = new YAML(lastExecutionFile);
+ return parse(yaml.getString(Config.getInstance().getNormalizedLibraryPath(), DateUtils.convert(DEFAULT_DATE)));
+ } catch (YamlInvalidContentException | IOException e) {
+ log.error("Couldn't open last-execution.properties");
+ return INVALID_DATE;
+ }
+ }
+
+ @Override
+ Date parse(String value) {
+ return DateUtils.convert(value, INVALID_DATE);
+ }
+
+ @Override
+ boolean isValid(Date result) {
+ return !result.equals(INVALID_DATE);
+ }
+
+ @Override
+ public int getWeight() {
+ return 40;
+ }
+}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java
index 3588a2a..20b5c21 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java
@@ -2,18 +2,50 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.DateUtils;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Date;
+@Slf4j
public class FileFilter {
static boolean accept(File pathName, String[] fileExtensions) {
- if (StringUtils.endsWithAny(pathName.getAbsolutePath().toLowerCase(), fileExtensions)
- && Config.getInstance().getIncludePattern().matcher(pathName.getName()).matches()) {
+ if (hasProperFileExtension(pathName, fileExtensions)
+ && hasMatchingPattern(pathName)
+ && isNewer(pathName)) {
return true;
}
ResultStatistic.getInstance().excluded();
return false;
}
+
+ private static boolean hasProperFileExtension(File pathName, String[] fileExtensions) {
+ return StringUtils.endsWithAny(pathName.getAbsolutePath().toLowerCase(), fileExtensions);
+ }
+
+ private static boolean hasMatchingPattern(File pathName) {
+ return Config.getInstance().getIncludePattern().matcher(pathName.getName()).matches();
+ }
+
+ private static boolean isNewer(File pathName) {
+ Config config = Config.getInstance();
+ if (config.getFilterDate() == null) return true;
+ try {
+ BasicFileAttributes attributes = Files.readAttributes(pathName.toPath(), BasicFileAttributes.class);
+ return isNewer(DateUtils.convert(attributes.creationTime().toMillis()));
+ } catch (IOException e) {
+ log.warn("File attributes could not be read.", e);
+ }
+ return true;
+ }
+
+ private static boolean isNewer(Date creationDate) {
+ return creationDate.toInstant().isAfter(Config.getInstance().getFilterDate().toInstant());
+ }
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java
index e48a7b4..9a1be4f 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java
@@ -8,16 +8,23 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.DateUtils;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ProjectUtil;
+import at.pcgamingfreaks.yaml.YAML;
+import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.tongfei.progressbar.ProgressBar;
import me.tongfei.progressbar.ProgressBarBuilder;
import me.tongfei.progressbar.ProgressBarStyle;
+import net.harawata.appdirs.AppDirsFactory;
import java.io.File;
import java.io.IOException;
+import java.nio.file.Path;
import java.util.Collection;
+import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -57,6 +64,8 @@ public abstract class AttributeUpdaterKernel {
executor.awaitTermination(1, TimeUnit.DAYS);
}
+ endProcess();
+
statistic.stopTimer();
statistic.printResult();
}
@@ -139,4 +148,26 @@ public abstract class AttributeUpdaterKernel {
log.warn("File couldn't be updated: '{}', Error: {}", fileInfo.getFile().getAbsoluteFile(), e.getMessage());
}
}
+
+ protected void endProcess() {
+ if (Config.getInstance().isSafeMode()) {
+ return;
+ }
+
+ try {
+ String filePath = AppDirsFactory.getInstance().getUserConfigDir(ProjectUtil.getProjectName(), null, null);
+
+ File configDir = Path.of(filePath).toFile();
+ if (!configDir.exists()) configDir.mkdirs();
+
+ File lastExecutionFile = Path.of(filePath + "/last-execution.yml").toFile();
+ if (!lastExecutionFile.exists()) lastExecutionFile.createNewFile();
+
+ YAML yaml = new YAML(lastExecutionFile);
+ yaml.set(Config.getInstance().getNormalizedLibraryPath(), DateUtils.convert(new Date()));
+ yaml.save(lastExecutionFile);
+ } catch (IOException | YamlInvalidContentException e) {
+ log.error("last-execution.yml could not be created or read.", e);
+ }
+ }
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java
index 38f9977..c410000 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java
@@ -18,6 +18,8 @@ public enum ConfigProperty {
COHERENT("coherent", "Try to match all files in dir of depth with the same config", "c", 1),
FORCE_COHERENT("force-coherent", "Force coherent and don't update anything if config fits not whole config (default: false)", "cf", 0),
WINDOWS("windows", "Is operating system windows", null, 0),
+ ONLY_NEW_FILES("only-new-files", "Sets filter-date to last successful execution (Overwrites input of filter-date)", "n", 0),
+ FILTER_DATE("filter-date", "Only consider files created newer than entered date (format: \"dd.MM.yyyy-HH:mm:ss\")", "d", 1),
THREADS("threads", "Thread count (default: 2)", "t", 1),
INCLUDE_PATTERN("include-pattern", "Include files matching pattern (default: \".*\")", "i", 1),
EXCLUDED_DIRECTORY("excluded-directories", "Directories to be excluded, combines with config file", "e", Option.UNLIMITED_VALUES),
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/DateUtils.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/DateUtils.java
new file mode 100644
index 0000000..61eaa20
--- /dev/null
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/DateUtils.java
@@ -0,0 +1,29 @@
+package at.pcgamingfreaks.mkvaudiosubtitlechanger.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DateUtils {
+ private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy-HH:mm:ss");
+
+ public static Date convert(long millis) {
+ return new Date(millis);
+ }
+
+ /**
+ * Convert String to date.
+ * @return parsed date, defaultDate if exception occurs
+ */
+ public static Date convert(String date, Date defaultDate) {
+ try {
+ return dateFormat.parse(date);
+ } catch (ParseException e) {
+ return defaultDate;
+ }
+ }
+
+ public static String convert(Date date) {
+ return dateFormat.format(date);
+ }
+}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/ProjectUtil.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/ProjectUtil.java
new file mode 100644
index 0000000..0e2c013
--- /dev/null
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/ProjectUtil.java
@@ -0,0 +1,25 @@
+package at.pcgamingfreaks.mkvaudiosubtitlechanger.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class ProjectUtil {
+ private static final Properties PROJECT_PROPERTIES = new Properties();
+
+ static {
+ try (InputStream propertiesStream = ProjectUtil.class.getClassLoader().getResourceAsStream("project.properties")) {
+ PROJECT_PROPERTIES.load(propertiesStream);
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ public static String getVersion() {
+ return PROJECT_PROPERTIES.getProperty("version");
+ }
+
+ public static String getProjectName() {
+ return PROJECT_PROPERTIES.getProperty("project_name");
+ }
+}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/VersionUtil.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/VersionUtil.java
deleted file mode 100644
index e1e5e3a..0000000
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/VersionUtil.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package at.pcgamingfreaks.mkvaudiosubtitlechanger.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-public class VersionUtil {
- public static String getVersion() {
- try (InputStream propertiesStream = VersionUtil.class.getClassLoader().getResourceAsStream("version.properties")) {
- Properties properties = new Properties();
- properties.load(propertiesStream);
-
- return properties.getProperty("version");
- } catch (IOException e) {
- throw new RuntimeException(e.getMessage());
- }
- }
-}
diff --git a/version.properties b/version.properties
deleted file mode 100644
index e5683df..0000000
--- a/version.properties
+++ /dev/null
@@ -1 +0,0 @@
-version=${project.version}
\ No newline at end of file