diff --git a/pom.xml b/pom.xml
index 4038330..3160cd7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -136,22 +136,6 @@
log4j-slf4j-impl
2.17.1
-
- org.slf4j
- slf4j-log4j12
- 1.7.28
- test
-
-
- org.slf4j
- jcl-over-slf4j
- 1.7.28
-
-
- org.slf4j
- jul-to-slf4j
- 1.7.28
-
com.fasterxml.jackson.dataformat
jackson-dataformat-yaml
@@ -175,7 +159,7 @@
me.tongfei
progressbar
- 0.9.3
+ 0.9.5
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java
deleted file mode 100644
index c009087..0000000
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package at.pcgamingfreaks.mkvaudiosubtitlechanger;
-
-import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
-import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector;
-import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor;
-import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
-import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
-import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic;
-import lombok.SneakyThrows;
-import lombok.extern.log4j.Log4j2;
-import me.tongfei.progressbar.ProgressBar;
-import me.tongfei.progressbar.ProgressBarBuilder;
-import me.tongfei.progressbar.ProgressBarStyle;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-@Log4j2
-public class AttributeUpdaterKernel {
-
- private final ExecutorService executor = Executors.newFixedThreadPool(Config.getInstance().getThreads());
- private final FileCollector collector;
- private final FileProcessor processor;
- private final ResultStatistic statistic = new ResultStatistic();
-
- public AttributeUpdaterKernel(FileCollector collector, FileProcessor processor) {
- this.collector = collector;
- this.processor = processor;
- }
-
- @SneakyThrows
- public void execute() {
- statistic.startTimer();
-
- try (ProgressBar progressBar = pbBuilder().build()) {
- List excludedFiles = Config.getInstance().getExcludedDirectories().stream()
- .map(collector::loadFiles)
- .flatMap(Collection::stream)
- .collect(Collectors.toList());
- List files = collector.loadFiles(Config.getInstance().getLibraryPath().getAbsolutePath()).stream()
- .filter(file -> !excludedFiles.contains(file))
- .collect(Collectors.toList());
- progressBar.maxHint(files.size());
- files.forEach(file -> executor.submit(() -> process(file, progressBar)));
- executor.shutdown();
- executor.awaitTermination(1, TimeUnit.DAYS);
- }
-
- statistic.stopTimer();
- System.out.println(statistic);
- log.info(statistic);
- }
-
- private void process(File file, ProgressBar progressBar) {
- List attributes = processor.loadAttributes(file);
- FileInfoDto fileInfo = processor.filterAttributes(attributes);
- statistic.total();
- if (fileInfo.isChangeNecessary()) {
- statistic.shouldChange();
- if (!Config.getInstance().isSafeMode()) {
- try {
- processor.update(file, fileInfo);
- statistic.success();
- log.info("Updated {}", file.getAbsolutePath());
- } catch (IOException | RuntimeException e) {
- statistic.failedChanging();
- log.warn("File couldn't be updated: '{}', Error: {}", file.getAbsoluteFile(), e.getMessage().replaceAll("\\r|\\n", " "));
- }
- }
- } else if (fileInfo.isUnableToApplyConfig()) {
- statistic.noSuitableConfigFound();
- } else if (fileInfo.isAlreadySuitable()){
- statistic.alreadyFits();
- } else {
- statistic.failure();
- }
- progressBar.step();
- }
-
- private static ProgressBarBuilder pbBuilder() {
- return new ProgressBarBuilder()
- .setStyle(ProgressBarStyle.ASCII)
- .setUpdateIntervalMillis(250)
- .setMaxRenderedLength(75);
- }
-}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java
index efd6077..db85668 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java
@@ -2,15 +2,20 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ConfigLoader;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.AttributeUpdaterKernel;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.CoherentAttributeUpdaterKernel;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.DefaultAttributeUpdaterKernel;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileCollector;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileProcessor;
-import lombok.extern.log4j.Log4j2;
+import lombok.extern.slf4j.Slf4j;
-@Log4j2
+@Slf4j
public class Main {
public static void main(String[] args) {
ConfigLoader.initConfig(args);
- AttributeUpdaterKernel kernel = new AttributeUpdaterKernel(new MkvFileCollector(), new MkvFileProcessor());
+ AttributeUpdaterKernel kernel = Config.getInstance().getCoherent() != null
+ ? new CoherentAttributeUpdaterKernel(new MkvFileCollector(), new MkvFileProcessor())
+ : new DefaultAttributeUpdaterKernel(new MkvFileCollector(), new MkvFileProcessor());
kernel.execute();
}
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java
index 536830c..3fae293 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/Config.java
@@ -6,7 +6,7 @@ import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
-import lombok.extern.log4j.Log4j2;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
@@ -15,7 +15,7 @@ import java.io.File;
import java.util.*;
import java.util.regex.Pattern;
-@Log4j2
+@Slf4j
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@@ -36,7 +36,10 @@ public class Config {
private Pattern includePattern;
private boolean safeMode;
- private Set forcedKeywords = new HashSet<>(Arrays.asList("forced", "signs"));
+ private Integer coherent;
+ private boolean forceCoherent;
+
+ private Set forcedKeywords = new HashSet<>(Arrays.asList("forced", "signs", "songs"));
private Set commentaryKeywords = new HashSet<>(Arrays.asList("commentary", "director"));
private Set excludedDirectories = new HashSet<>();
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java
index 19fa69d..9abab3c 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/ConfigLoader.java
@@ -27,8 +27,10 @@ public class ConfigLoader {
new PatternValidator(INCLUDE_PATTERN, false, Pattern.compile(".*")),
new SetValidator(FORCED_KEYWORDS, false, true),
new SetValidator(COMMENTARY_KEYWORDS, false, true),
- new SetValidator(EXCLUDE_DIRECTORY, false, true),
- new AttributeConfigValidator()
+ new SetValidator(EXCLUDED_DIRECTORY, false, true),
+ new AttributeConfigValidator(),
+ new CoherentConfigValidator(COHERENT, false),
+ new BooleanValidator(FORCE_COHERENT, false)
);
public static void initConfig(String[] args) {
@@ -55,7 +57,7 @@ public class ConfigLoader {
}
}
- if (results.contains(ValidationResult.INVALID)) System.exit(1);
+ if (results.contains(ValidationResult.INVALID) || results.contains(ValidationResult.MISSING)) System.exit(1);
System.out.println();
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/CoherentConfigValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/CoherentConfigValidator.java
new file mode 100644
index 0000000..25edaf9
--- /dev/null
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/CoherentConfigValidator.java
@@ -0,0 +1,22 @@
+package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
+
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
+import org.apache.commons.lang3.math.NumberUtils;
+
+public class CoherentConfigValidator extends ConfigValidator {
+ private static final Integer DISABLED = -1;
+
+ public CoherentConfigValidator(ConfigProperty property, boolean required) {
+ super(property, required, null);
+ }
+
+ @Override
+ Integer parse(String value) {
+ return NumberUtils.isParsable(value) ? Integer.parseInt(value) : DISABLED;
+ }
+
+ @Override
+ boolean isValid(Integer result) {
+ return result >= 0;
+ }
+}
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 0aa4fc3..80e701d 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigValidator.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/ConfigValidator.java
@@ -121,27 +121,27 @@ public abstract class ConfigValidator {
* @return false if method invocation failed
*/
protected boolean setValue(FieldType result) {
- List methods = Arrays.stream(Config.getInstance().getClass().getDeclaredMethods())
- .filter(containsSetterOf(property))
- .collect(Collectors.toList());
- if (methods.size() != 1) {
- return false;
- }
- try {
- methods.get(0).invoke(Config.getInstance(), result);
- } catch (IllegalAccessException | InvocationTargetException e) {
- throw new RuntimeException(e);
- }
- return true;
+ 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.containsIgnoreCase(method.getName(), "set")
- && StringUtils.containsIgnoreCase(method.getName(), property.prop().replace("-", ""));
+ return method -> StringUtils.startsWith(method.getName(), "set")
+ && StringUtils.equalsIgnoreCase(method.getName().replace("set", ""), property.prop().replace("-", ""));
}
protected Predicate containsGetterOf(ConfigProperty property) {
- return method -> StringUtils.containsIgnoreCase(method.getName(), "get")
+ return method -> StringUtils.startsWith(method.getName(), "get")
&& StringUtils.containsIgnoreCase(method.getName(), property.prop().replace("-", ""));
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/exceptions/MkvToolNixException.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/exceptions/MkvToolNixException.java
new file mode 100644
index 0000000..c2fc0b3
--- /dev/null
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/exceptions/MkvToolNixException.java
@@ -0,0 +1,13 @@
+package at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions;
+
+public class MkvToolNixException extends RuntimeException{
+
+ public MkvToolNixException(String message) {
+ super(message);
+ }
+
+ @Override
+ public String getMessage() {
+ return super.getMessage().replaceAll("\\r|\\n", " ");
+ }
+}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileCollector.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileCollector.java
index d60ac8b..5ea56da 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileCollector.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileCollector.java
@@ -10,4 +10,13 @@ public interface FileCollector {
* @return list of all files within the directory
*/
List loadFiles(String path);
+
+ /**
+ * Load all directories from path, but only until depth is reached.
+ *
+ * @param path leads to a directory which will be loaded recursively until depth
+ * @param depth limit directory crawling
+ * @return list of directory until depth
+ */
+ List loadDirectories(String path, int depth);
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java
index 94f5012..3588a2a 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java
@@ -1,13 +1,19 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
public class FileFilter {
static boolean accept(File pathName, String[] fileExtensions) {
- return StringUtils.endsWithAny(pathName.getAbsolutePath().toLowerCase(), fileExtensions)
- && Config.getInstance().getIncludePattern().matcher(pathName.getName()).matches();
+ if (StringUtils.endsWithAny(pathName.getAbsolutePath().toLowerCase(), fileExtensions)
+ && Config.getInstance().getIncludePattern().matcher(pathName.getName()).matches()) {
+ return true;
+ }
+
+ ResultStatistic.getInstance().excluded();
+ return false;
}
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileProcessor.java
index 5a5b105..4364558 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileProcessor.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileProcessor.java
@@ -1,5 +1,7 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions.MkvToolNixException;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
@@ -10,12 +12,41 @@ import java.util.List;
public interface FileProcessor {
/**
+ * Load track information from file.
+ *
* @param file Takes the file from which the attributes will be returned
* @return list of all important attributes
*/
List loadAttributes(File file);
- FileInfoDto filterAttributes(List attributes);
+ /**
+ * Populate FileInfoDto with the currently set default tracks.
+ * @param info to be populated
+ * @param attributes Track information of FileInfoDto
+ * @param nonForcedTracks List of all not forced tracks
+ */
+ void detectDefaultTracks(FileInfoDto info, List attributes, List nonForcedTracks);
- void update(File file, FileInfoDto fileInfo) throws IOException;
+ /**
+ * Populate FileInfoDto with the desired tracks, based on AttributeConfig.
+ * @param info to be populated
+ * @param nonForcedTracks List of all not forced tracks
+ * @param nonCommentaryTracks List of all not commentary tracks
+ * @param configs
+ */
+ void detectDesiredTracks(FileInfoDto info, List nonForcedTracks, List nonCommentaryTracks,
+ AttributeConfig... configs);
+
+ List retrieveNonForcedTracks(List attributes);
+
+ List retrieveNonCommentaryTracks(List attributes);
+
+ /**
+ * Update the file.
+ * @param file to be updated
+ * @param fileInfo information to update file
+ * @throws IOException
+ * @throws MkvToolNixException when error occurs while sending query to mkvpropedit
+ */
+ void update(File file, FileInfoDto fileInfo) throws IOException, MkvToolNixException;
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileCollector.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileCollector.java
index cdd739e..b48a57b 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileCollector.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileCollector.java
@@ -1,6 +1,6 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
-import lombok.extern.log4j.Log4j2;
+import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.IOException;
@@ -12,10 +12,13 @@ import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-@Log4j2
+@Slf4j
public class MkvFileCollector implements FileCollector {
private static final String[] fileExtensions = new String[]{".mkv", ".mka", ".mks", ".mk3d"};
+ /**
+ * {@inheritDoc}
+ */
@Override
public List loadFiles(String path) {
try (Stream paths = Files.walk(Paths.get(path))) {
@@ -28,4 +31,19 @@ public class MkvFileCollector implements FileCollector {
return new ArrayList<>();
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List loadDirectories(String path, int depth) {
+ try (Stream paths = Files.walk(Paths.get(path), depth)) {
+ return paths.map(Path::toFile)
+ .filter(File::isDirectory)
+ .collect(Collectors.toList());
+ } catch (IOException e) {
+ log.error("Couldn't find file or directory!", e);
+ return new ArrayList<>();
+ }
+ }
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessor.java
index 0457d38..a5423f6 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessor.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessor.java
@@ -1,10 +1,11 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions.MkvToolNixException;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.*;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.SetUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.extern.log4j.Log4j2;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.core.util.IOUtils;
@@ -19,14 +20,13 @@ import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType.AUDIO;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType.SUBTITLES;
import static java.lang.String.format;
-@Log4j2
+@Slf4j
public class MkvFileProcessor implements FileProcessor {
private final ObjectMapper mapper = new ObjectMapper();
private static final String DISABLE_DEFAULT_TRACK = "--edit track:%s --set flag-default=0 ";
private static final String ENABLE_DEFAULT_TRACK = "--edit track:%s --set flag-default=1 ";
private static final String ENABLE_FORCED_TRACK = "--edit track:%s --set flag-forced=1 ";
-
@SuppressWarnings("unchecked")
@Override
public List loadAttributes(File file) {
@@ -62,7 +62,7 @@ public class MkvFileProcessor implements FileProcessor {
}
}
- log.debug(fileAttributes);
+ log.debug(fileAttributes.toString());
} catch (IOException e) {
e.printStackTrace();
log.error("File could not be found or loaded!");
@@ -70,27 +70,11 @@ public class MkvFileProcessor implements FileProcessor {
return fileAttributes;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- public FileInfoDto filterAttributes(List attributes) {
- FileInfoDto info = new FileInfoDto();
- List nonForcedTracks = attributes.stream()
- .filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.getTrackName(),
- Config.getInstance().getForcedKeywords().toArray(new CharSequence[0])))
- .filter(elem -> !elem.isForcedTrack())
- .collect(Collectors.toList());
- List nonCommentaryTracks = attributes.stream()
- .filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.getTrackName(),
- Config.getInstance().getCommentaryKeywords().toArray(new CharSequence[0])))
- .collect(Collectors.toList());
-
- detectDefaultTracks(info, attributes, nonForcedTracks);
- detectDesiredTracks(info, nonForcedTracks, nonCommentaryTracks);
- log.debug(info);
-
- return info;
- }
-
- protected void detectDefaultTracks(FileInfoDto info, List attributes, List nonForcedTracks) {
+ public void detectDefaultTracks(FileInfoDto info, List attributes, List nonForcedTracks) {
Set detectedForcedSubtitleLanes = new HashSet<>();
for (FileAttribute attribute : attributes) {
if (attribute.isDefaultTrack() && AUDIO.equals(attribute.getType()))
@@ -108,8 +92,13 @@ public class MkvFileProcessor implements FileProcessor {
);
}
- protected void detectDesiredTracks(FileInfoDto info, List nonForcedTracks, List nonCommentaryTracks) {
- for (AttributeConfig config : Config.getInstance().getAttributeConfig()) {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void detectDesiredTracks(FileInfoDto info, List nonForcedTracks, List nonCommentaryTracks,
+ AttributeConfig... configs) {
+ for (AttributeConfig config : configs) {
FileAttribute desiredAudio = null;
FileAttribute desiredSubtitle = null;
for (FileAttribute attribute : SetUtils.retainOf(nonForcedTracks, nonCommentaryTracks)) {
@@ -127,10 +116,31 @@ public class MkvFileProcessor implements FileProcessor {
}
@Override
- public void update(File file, FileInfoDto fileInfo) throws IOException, RuntimeException {
+ public List retrieveNonForcedTracks(List attributes) {
+ return attributes.stream()
+ .filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.getTrackName(),
+ Config.getInstance().getForcedKeywords().toArray(new CharSequence[0])))
+ .filter(elem -> !elem.isForcedTrack())
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public List retrieveNonCommentaryTracks(List attributes) {
+ return attributes.stream()
+ .filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.getTrackName(),
+ Config.getInstance().getCommentaryKeywords().toArray(new CharSequence[0])))
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void update(File file, FileInfoDto fileInfo) throws IOException, MkvToolNixException {
StringBuilder sb = new StringBuilder();
sb.append(format("\"%s\" ", Config.getInstance().getPathFor(MkvToolNix.MKV_PROP_EDIT)));
sb.append(format("\"%s\" ", file.getAbsolutePath()));
+
if (fileInfo.isAudioDifferent()) {
if (fileInfo.getDefaultAudioLanes() != null && !fileInfo.getDefaultSubtitleLanes().isEmpty()) {
for (FileAttribute track: fileInfo.getDefaultAudioLanes()) {
@@ -139,6 +149,7 @@ public class MkvFileProcessor implements FileProcessor {
}
sb.append(format(ENABLE_DEFAULT_TRACK, fileInfo.getDesiredAudioLane().getId()));
}
+
if (fileInfo.isSubtitleDifferent()) {
if (fileInfo.getDefaultSubtitleLanes() != null && !fileInfo.getDefaultSubtitleLanes().isEmpty()) {
for (FileAttribute track: fileInfo.getDefaultSubtitleLanes()) {
@@ -147,6 +158,7 @@ public class MkvFileProcessor implements FileProcessor {
}
sb.append(format(ENABLE_DEFAULT_TRACK, fileInfo.getDesiredSubtitleLane().getId()));
}
+
if (fileInfo.areForcedTracksDifferent()) {
for (FileAttribute attribute : fileInfo.getDesiredForcedSubtitleLanes()) {
sb.append(format(ENABLE_FORCED_TRACK, attribute.getId()));
@@ -156,6 +168,6 @@ public class MkvFileProcessor implements FileProcessor {
InputStream inputstream = Runtime.getRuntime().exec(sb.toString()).getInputStream();
String output = IOUtils.toString(new InputStreamReader(inputstream));
log.debug(output);
- if (output.contains("Error")) throw new RuntimeException(output);
+ if (output.contains("Error")) throw new MkvToolNixException(output);
}
}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java
new file mode 100644
index 0000000..359f984
--- /dev/null
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/AttributeUpdaterKernel.java
@@ -0,0 +1,140 @@
+package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel;
+
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions.MkvToolNixException;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic;
+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 java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Slf4j
+@RequiredArgsConstructor
+public abstract class AttributeUpdaterKernel {
+
+ protected final FileCollector collector;
+ protected final FileProcessor processor;
+ protected final ResultStatistic statistic = ResultStatistic.getInstance();
+ private final ExecutorService executor = Executors.newFixedThreadPool(Config.getInstance().getThreads());
+
+ protected ProgressBarBuilder pbBuilder() {
+ return new ProgressBarBuilder()
+ .setStyle(ProgressBarStyle.ASCII)
+ .setUpdateIntervalMillis(250)
+ .setMaxRenderedLength(75);
+ }
+
+ @SneakyThrows
+ public void execute() {
+ statistic.startTimer();
+
+ try (ProgressBar progressBar = pbBuilder().build()) {
+ List files = loadFiles(Config.getInstance().getLibraryPath().getAbsolutePath());
+ progressBar.maxHint(files.size());
+
+ files.forEach(file -> executor.submit(() -> {
+ process(file);
+ progressBar.step();
+ }));
+
+ executor.shutdown();
+ executor.awaitTermination(1, TimeUnit.DAYS);
+ }
+
+ statistic.stopTimer();
+ statistic.printResult();
+ }
+
+ protected List loadExcludedFiles() {
+ List excludedFiles = Config.getInstance().getExcludedDirectories().stream()
+ .map(collector::loadFiles)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+ statistic.increaseTotalBy(excludedFiles.size());
+ statistic.increaseExcludedBy(excludedFiles.size());
+ return excludedFiles;
+ }
+
+ /**
+ * Load files or directories to update.
+ * Remove excluded directories.
+ *
+ * @param path Path to library
+ * @return List of files to update.
+ */
+ abstract List loadFiles(String path);
+
+ /**
+ * Start of the file updating process.
+ * This method is called by the executor and its contents are executed in parallel.
+ *
+ * @param file file or directory to update
+ */
+ void process(File file) {
+ FileInfoDto fileInfo = new FileInfoDto(file);
+ List attributes = processor.loadAttributes(file);
+
+ List nonForcedTracks = processor.retrieveNonForcedTracks(attributes);
+ List nonCommentaryTracks = processor.retrieveNonCommentaryTracks(attributes);
+
+ processor.detectDefaultTracks(fileInfo, attributes, nonForcedTracks);
+ processor.detectDesiredTracks(fileInfo, nonForcedTracks, nonCommentaryTracks);
+
+ updateFile(fileInfo);
+ }
+
+ /**
+ * Persist file changes.
+ *
+ * @param fileInfoDto contains information about file and desired configuration.
+ */
+ protected void updateFile(FileInfoDto fileInfoDto) {
+ switch (fileInfoDto.getStatus()) {
+ case CHANGE_NECESSARY:
+ statistic.shouldChange();
+ commitChange(fileInfoDto);
+ break;
+ case UNABLE_TO_APPLY:
+ statistic.noSuitableConfigFound();
+ break;
+ case ALREADY_SUITED:
+ statistic.alreadyFits();
+ break;
+ case UNKNOWN:
+ default:
+ statistic.failure();
+ break;
+ }
+ }
+
+ private void commitChange(FileInfoDto fileInfo) {
+ if (Config.getInstance().isSafeMode()) {
+ return;
+ }
+
+ try {
+ statistic.total();
+ processor.update(fileInfo.getFile(), fileInfo);
+ statistic.success();
+ log.info("Updated {}", fileInfo.getFile().getAbsolutePath());
+ } catch (IOException | MkvToolNixException e) {
+ statistic.failedChanging();
+ log.warn("File couldn't be updated: '{}', Error: {}", fileInfo.getFile().getAbsoluteFile(), e.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java
new file mode 100644
index 0000000..4fe1cc7
--- /dev/null
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java
@@ -0,0 +1,111 @@
+package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel;
+
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
+import lombok.extern.slf4j.Slf4j;
+import me.tongfei.progressbar.ProgressBarBuilder;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Slf4j
+public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel {
+
+ public CoherentAttributeUpdaterKernel(FileCollector collector, FileProcessor processor) {
+ super(collector, processor);
+ }
+
+ @Override
+ protected ProgressBarBuilder pbBuilder() {
+ return super.pbBuilder()
+ .setUnit(" directories", 1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ List loadFiles(String path) {
+ List excludedFiles = loadExcludedFiles();
+ List directories = collector.loadDirectories(path, Config.getInstance().getCoherent())
+ .stream().filter(file -> !excludedFiles.contains(file))
+ .collect(Collectors.toList());
+ return directories.stream()
+ .filter(dir -> isParentDirectory(dir, directories))
+ .collect(Collectors.toList());
+ }
+
+ private boolean isParentDirectory(File directory, List directories) {
+ String path = directory.getAbsolutePath();
+ return directories.stream()
+ .noneMatch(dir -> dir.getAbsolutePath().contains(path) && !StringUtils.equals(path, dir.getAbsolutePath()));
+ }
+
+ /**
+ * Update files in directory, if possible, with the same {@link AttributeConfig}.
+ * If {@link Config#isForceCoherent()} then there will be no changes to the file if they don't match the same config.
+ * Otherwise, the default behaviour is executed.
+ * This method is called by the executor and is run in parallel.
+ *
+ * @param file directory containing files
+ */
+ @Override
+ void process(File file) {
+ // TODO: Implement level crawl if coherence is not possible on user entered depth
+ // IMPL idea: recursive method call, cache needs to be implemented
+ List fileInfos = collector.loadFiles(file.getAbsolutePath())
+ .stream().map(FileInfoDto::new)
+ .collect(Collectors.toList());
+
+ Map> fileAttributeCache = new HashMap<>();
+ for (FileInfoDto fileInfo : fileInfos) {
+ if (!Config.getInstance().getIncludePattern().matcher(fileInfo.getFile().getAbsolutePath()).matches()) {
+ statistic.excluded();
+ continue;
+ }
+ fileAttributeCache.put(fileInfo, processor.loadAttributes(fileInfo.getFile()));
+ }
+
+ for (AttributeConfig config : Config.getInstance().getAttributeConfig()) {
+
+ for (FileInfoDto fileInfo : fileInfos) {
+ List attributes = fileAttributeCache.get(fileInfo);
+
+ List nonForcedTracks = processor.retrieveNonForcedTracks(attributes);
+ List nonCommentaryTracks = processor.retrieveNonCommentaryTracks(attributes);
+
+ processor.detectDefaultTracks(fileInfo, attributes, nonForcedTracks);
+ processor.detectDesiredTracks(fileInfo, nonForcedTracks, nonCommentaryTracks, config);
+ }
+
+ if (fileInfos.stream().allMatch(elem -> elem.getDesiredSubtitleLane() != null && elem.getDesiredAudioLane() != null)) {
+ log.info("Found {}/{} match for {}", config.getAudioLanguage(), config.getSubtitleLanguage(), file.getAbsolutePath());
+ statistic.increaseTotalBy(fileInfos.size());
+ fileInfos.forEach(this::updateFile);
+ return; // match found, end process here
+ }
+
+ fileInfos.forEach(f -> {
+ f.setDesiredAudioLane(null);
+ f.setDesiredSubtitleLane(null);
+ });
+ }
+
+ for (FileInfoDto fileInfo : fileInfos) {
+ statistic.total();
+ if (Config.getInstance().isForceCoherent()) {
+ super.process(fileInfo.getFile());
+ } else {
+ statistic.excluded();
+ }
+ }
+ }
+}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/DefaultAttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/DefaultAttributeUpdaterKernel.java
new file mode 100644
index 0000000..b4e27bc
--- /dev/null
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/DefaultAttributeUpdaterKernel.java
@@ -0,0 +1,36 @@
+package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel;
+
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector;
+import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor;
+import lombok.extern.slf4j.Slf4j;
+import me.tongfei.progressbar.ProgressBarBuilder;
+
+import java.io.File;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+public class DefaultAttributeUpdaterKernel extends AttributeUpdaterKernel {
+
+ public DefaultAttributeUpdaterKernel(FileCollector collector, FileProcessor processor) {
+ super(collector, processor);
+ }
+
+ @Override
+ protected ProgressBarBuilder pbBuilder() {
+ return super.pbBuilder()
+ .setUnit(" files", 1);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ List loadFiles(String path) {
+ List excludedFiles = loadExcludedFiles();
+ return collector.loadFiles(Config.getInstance().getLibraryPath().getAbsolutePath()).stream()
+ .filter(file -> !excludedFiles.contains(file))
+ .collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/AttributeConfig.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/AttributeConfig.java
index 53dd213..e905213 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/AttributeConfig.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/AttributeConfig.java
@@ -2,11 +2,11 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
-import lombok.extern.log4j.Log4j2;
+import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
-@Log4j2
+@Slf4j
@Getter
@AllArgsConstructor
public class AttributeConfig {
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java
index f525c0d..58debfd 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java
@@ -10,16 +10,17 @@ import java.util.stream.Collectors;
@AllArgsConstructor
public enum ConfigProperty {
- LIBRARY("library", "Path to library", "l", 1),
+ LIBRARY("library-path", "Path to library", "l", 1),
ATTRIBUTE_CONFIG("attribute-config", "Attribute config to decide which tracks to choose when", "a", Option.UNLIMITED_VALUES),
CONFIG_PATH("config-path", "Path to config file", "p", 1),
MKV_TOOL_NIX("mkvtoolnix", "Path to mkv tool nix installation", "m", 1),
SAFE_MODE("safe-mode", "Test run (no files will be changes)", "s", 0),
- COHERENT("coherent", "Try to match whole series with same config", null, 0),
+ 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),
THREADS("threads", "Thread count (default: 2)", "t", 1),
INCLUDE_PATTERN("include-pattern", "Include files matching pattern (default: \".*\")", "i", 1),
- EXCLUDE_DIRECTORY("exclude-directories", "Directories to be excluded, combines with config file", "e", 1),
+ EXCLUDED_DIRECTORY("excluded-directories", "Directories to be excluded, combines with config file", "e", Option.UNLIMITED_VALUES),
FORCED_KEYWORDS("forced-keywords", "Additional keywords to identify forced tracks", "fk", Option.UNLIMITED_VALUES),
COMMENTARY_KEYWORDS("commentary-keywords", "Additional keywords to identify commentary tracks", "ck", Option.UNLIMITED_VALUES),
ARGUMENTS("arguments", "List of arguments", null, 0),
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java
index cf115f5..3cb1771 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java
@@ -2,9 +2,9 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
-import lombok.extern.log4j.Log4j2;
+import lombok.extern.slf4j.Slf4j;
-@Log4j2
+@Slf4j
@Getter
@AllArgsConstructor
public class FileAttribute {
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoDto.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoDto.java
index e498689..e0e2239 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoDto.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoDto.java
@@ -1,32 +1,24 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
import lombok.Getter;
+import lombok.RequiredArgsConstructor;
import lombok.Setter;
+import java.io.File;
import java.util.HashSet;
import java.util.Set;
@Getter
@Setter
+@RequiredArgsConstructor
public class FileInfoDto {
+ private final File file;
private Set defaultAudioLanes = new HashSet<>();
private Set defaultSubtitleLanes = new HashSet<>();
private Set desiredForcedSubtitleLanes;
private FileAttribute desiredAudioLane;
private FileAttribute desiredSubtitleLane;
- public boolean isUnableToApplyConfig() {
- return desiredAudioLane == null && desiredSubtitleLane == null;
- }
-
- public boolean isAlreadySuitable() {
- return defaultAudioLanes.contains(desiredAudioLane) && defaultSubtitleLanes.contains(desiredSubtitleLane);
- }
-
- public boolean isChangeNecessary() {
- return isAudioDifferent() || isSubtitleDifferent() || areForcedTracksDifferent();
- }
-
public boolean isAudioDifferent() {
return desiredAudioLane != null &&
(defaultAudioLanes == null || !defaultAudioLanes.contains(desiredAudioLane));
@@ -41,6 +33,25 @@ public class FileInfoDto {
return desiredForcedSubtitleLanes.size() > 0;
}
+ public FileStatus getStatus() {
+ if (isChangeNecessary()) return FileStatus.CHANGE_NECESSARY;
+ if (isUnableToApplyConfig()) return FileStatus.UNABLE_TO_APPLY;
+ if (isAlreadySuitable()) return FileStatus.ALREADY_SUITED;
+ return FileStatus.UNKNOWN;
+ }
+
+ private boolean isUnableToApplyConfig() {
+ return desiredAudioLane == null && desiredSubtitleLane == null;
+ }
+
+ private boolean isAlreadySuitable() {
+ return defaultAudioLanes.contains(desiredAudioLane) && defaultSubtitleLanes.contains(desiredSubtitleLane);
+ }
+
+ private boolean isChangeNecessary() {
+ return isAudioDifferent() || isSubtitleDifferent() || areForcedTracksDifferent();
+ }
+
@Override
public String toString() {
return "[" + "defaultAudioLanes=" + defaultAudioLanes +
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileStatus.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileStatus.java
new file mode 100644
index 0000000..942faf9
--- /dev/null
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileStatus.java
@@ -0,0 +1,8 @@
+package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
+
+public enum FileStatus {
+ CHANGE_NECESSARY,
+ UNABLE_TO_APPLY,
+ ALREADY_SUITED,
+ UNKNOWN;
+}
diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java
index 99acefd..6370aa7 100644
--- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java
+++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java
@@ -2,10 +2,13 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
import lombok.AccessLevel;
import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
@Getter
+@Slf4j
public class ResultStatistic {
private static final String result = "Total files: %s%n" +
+ "├─ Excluded: %s%n" +
"├─ Should change: %s%n" +
"│ ├─ Failed changing: %s%n" +
"│ └─ Successfully changed: %s%n" +
@@ -13,8 +16,9 @@ public class ResultStatistic {
"├─ Already fit config: %s%n" +
"└─ Failed: %s%n" +
"Runtime: %s";
-
+ private static ResultStatistic instance;
private int filesTotal = 0;
+ private int excluded = 0;
private int shouldChange = 0;
private int failedChanging = 0;
@@ -28,10 +32,29 @@ public class ResultStatistic {
private long startTime = 0;
private long runtime = 0;
+ public static ResultStatistic getInstance() {
+ if (instance == null) {
+ instance = new ResultStatistic();
+ }
+ return instance;
+ }
+
+ public void increaseTotalBy(int amount) {
+ filesTotal += amount;
+ }
+
public synchronized void total() {
filesTotal++;
}
+ public void increaseExcludedBy(int amount) {
+ excluded += amount;
+ }
+
+ public synchronized void excluded() {
+ excluded++;
+ }
+
public synchronized void shouldChange() {
shouldChange++;
}
@@ -64,6 +87,11 @@ public class ResultStatistic {
runtime = System.currentTimeMillis() - startTime;
}
+ public void printResult() {
+ System.out.println(prettyPrint());
+ log.info(this.toString());
+ }
+
private String formatTimer() {
int seconds = (int) (runtime / 1000);
int minutes = seconds / 60;
@@ -75,15 +103,29 @@ public class ResultStatistic {
} else if (hours >= 1) {
return String.format("%sh %sm %ss", hours, minutes % 60, seconds % 60);
} else if (minutes >= 1) {
- return String.format("%sm %ss", minutes , seconds % 60);
+ return String.format("%sm %ss", minutes, seconds % 60);
} else {
return String.format("%ss", seconds % 60);
}
}
- @Override
- public String toString() {
- return String.format(result, filesTotal, shouldChange, failedChanging, successfullyChanged,
+ public String prettyPrint() {
+ return String.format(result, filesTotal, excluded, shouldChange, failedChanging, successfullyChanged,
noSuitableConfigFound, alreadyFits, failed, formatTimer());
}
+
+ @Override
+ public String toString() {
+ String sb = "ResultStatistic[" + "filesTotal=" + filesTotal +
+ ", excluded=" + excluded +
+ ", shouldChange=" + shouldChange +
+ " (failedChanging=" + failedChanging +
+ ", successfullyChanged=" + successfullyChanged +
+ "), noSuitableConfigFound=" + noSuitableConfigFound +
+ ", alreadyFits=" + alreadyFits +
+ ", failed=" + failed +
+ ", runtime=" + formatTimer() +
+ ']';
+ return sb;
+ }
}
diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PathValidatorTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PathValidatorTest.java
index 4e91a56..a4d6842 100644
--- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PathValidatorTest.java
+++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validator/PathValidatorTest.java
@@ -39,7 +39,7 @@ class PathValidatorTest {
private static Stream provideTestCases() {
return Stream.of(
- argumentsOf(LIBRARY, false, null, "library: " + TEST_DIR, new String[]{}, VALID),
+ argumentsOf(LIBRARY, false, null, "library-path: " + TEST_DIR, new String[]{}, VALID),
argumentsOf(LIBRARY, true, null, "", new String[]{"-l", TEST_FILE}, VALID),
argumentsOf(LIBRARY, false, TEST_DIR, "", new String[]{}, DEFAULT),
@@ -48,7 +48,7 @@ class PathValidatorTest {
argumentsOf(LIBRARY, false, null, "", new String[]{}, NOT_PRESENT),
argumentsOf(LIBRARY, true, null, "", new String[]{"-l", TEST_DIR + "/invalid"}, INVALID),
- argumentsOf(LIBRARY, false, null, "library: " + TEST_DIR + "/invalid", new String[]{}, INVALID),
+ argumentsOf(LIBRARY, false, null, "library-path: " + TEST_DIR + "/invalid", new String[]{}, INVALID),
argumentsOf(LIBRARY, true, TEST_DIR, "", new String[]{"-l", TEST_DIR + "/invalid"}, INVALID)
);
}