Add config validator tests & Improve mkvtoolnix error logging & ConfigPathValidator

This commit is contained in:
2023-02-12 21:34:38 +01:00
parent 1d6098efc1
commit 51b4885e65
12 changed files with 239 additions and 59 deletions

View File

@@ -68,9 +68,9 @@ public class AttributeUpdaterKernel {
processor.update(file, fileInfo);
statistic.success();
log.info("Updated {}", file.getAbsolutePath());
} catch (IOException e) {
} catch (IOException | RuntimeException e) {
statistic.failedChanging();
log.warn("File couldn't be updated: {}", file.getAbsoluteFile());
log.warn("File couldn't be updated: '{}', Error: {}", file.getAbsoluteFile(), e.getMessage().replaceAll("\\R|\\n", "\\s"));
}
}
} else if (fileInfo.isUnableToApplyConfig()) {

View File

@@ -2,39 +2,31 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.VersionUtil;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import lombok.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.cli.*;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.LanguageValidatorUtil.isLanguageValid;
@Log4j2
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Config {
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private static Config config = null;
@Getter(AccessLevel.NONE)
CommandLineParser parser = new DefaultParser();
@Getter(AccessLevel.NONE)
HelpFormatter formatter = new HelpFormatter();
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private static Config config = null;
private File configPath;
private File libraryPath;
@Getter(AccessLevel.NONE)
@@ -45,14 +37,18 @@ public class Config {
private boolean windows;
private boolean safeMode;
private final Set<String> forcedKeywords = new HashSet<>(Arrays.asList("forced", "signs"));
private final Set<String> commentaryKeywords = new HashSet<>(Arrays.asList("commentary", "director"));
private final Set<String> excludedDirectories = new HashSet<>();
private Set<String> forcedKeywords = new HashSet<>(Arrays.asList("forced", "signs"));
private Set<String> commentaryKeywords = new HashSet<>(Arrays.asList("commentary", "director"));
private Set<String> excludedDirectories = new HashSet<>();
private List<AttributeConfig> attributeConfig;
public static Config getInstance() {
if (config == null) {
return getInstance(false);
}
public static Config getInstance(boolean reset) {
if (config == null || reset) {
config = new Config();
}
return config;

View File

@@ -17,8 +17,9 @@ import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
public class ConfigLoader {
private static final ConfigValidator<?> CONFIG_VALIDATOR =
new ConfigPathValidator(CONFIG_PATH, false, Path.of("./config.yaml").toFile());
private static final List<ConfigValidator<?>> VALIDATORS = List.of(
// new PathValidator(CONFIG_PATH, false, Path.of("./").toFile()), Singelton for yaml instance
new PathValidator(LIBRARY, true, null),
new ThreadValidator(THREADS, false, 2),
new MkvToolNixPathValidator(MKV_TOOL_NIX, true, Path.of("C:\\Program Files\\MKVToolNix").toFile()),
@@ -32,32 +33,24 @@ public class ConfigLoader {
);
public static void initConfig(String[] args) {
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine cmd = null;
Options options = initOptions();
try {
cmd = parser.parse(options, args);
if (cmd == null) throw new NullPointerException();
} catch (ParseException | NullPointerException e) {
formatter.printHelp(106, "java -jar MKVAudioSubtitlesChanger.jar -l <path_to_library>",
"\nParameters:", options,
"\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues");
System.exit(1);
}
Options options = initOptions();
CommandLine cmd = parseCommandLineArgs(formatter, options, args);
exitIfHelp(cmd, options, formatter);
exitIfVersion(cmd);
exitIfConfigIsMissing(cmd);
List<ValidationResult> results = new ArrayList<>();
try (YAML config = new YAML(loadConfigPath(cmd))) {
try (YAML config = new YAML(Config.getInstance().getConfigPath())) {
for (ConfigValidator<?> validator : VALIDATORS) {
results.add(validator.validate(config, cmd));
}
} catch (IOException | YamlInvalidContentException ignored) {}
if (results.contains(ValidationResult.INVALID)) System.exit(1);
System.out.println();
}
private static Options initOptions() {
@@ -75,6 +68,22 @@ public class ConfigLoader {
return options;
}
private static CommandLine parseCommandLineArgs(HelpFormatter formatter, Options options, String[] args) {
CommandLineParser parser = new DefaultParser();
try {
CommandLine cmd = parser.parse(options, args);
if (cmd == null) throw new NullPointerException();
return cmd;
} catch (ParseException | NullPointerException e) {
formatter.printHelp(106, "java -jar MKVAudioSubtitlesChanger.jar -l <path_to_library>",
"\nParameters:", options,
"\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues");
System.exit(1);
}
return null; // can't be reached
}
private static void exitIfHelp(CommandLine cmd, Options options, HelpFormatter formatter) {
if (cmd.hasOption("help")) {
formatter.printHelp(106, "java -jar MKVAudioSubtitlesChanger.jar -l <path_to_library>",
@@ -91,6 +100,13 @@ public class ConfigLoader {
}
}
private static void exitIfConfigIsMissing(CommandLine cmd) {
if (CONFIG_VALIDATOR.validate(null, cmd).equals(ValidationResult.INVALID)) {
System.out.println("\nPlease use a valid config path!");
System.exit(0);
};
}
private static File loadConfigPath(CommandLine cmd) {
File configPath = new File(cmd.getOptionValue(CONFIG_PATH.prop(), "config.yaml"));
if (configPath.isFile()) return configPath;

View File

@@ -0,0 +1,19 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import at.pcgamingfreaks.yaml.YAML;
import java.io.File;
import java.util.Optional;
import java.util.function.BiFunction;
public class ConfigPathValidator extends PathValidator {
public ConfigPathValidator(ConfigProperty property, boolean required, File defaultValue) {
super(property, required, defaultValue);
}
@Override
protected BiFunction<YAML, ConfigProperty, Optional<File>> provideDataYaml() {
return (yaml, property) -> Optional.empty();
}
}

View File

@@ -15,7 +15,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

View File

@@ -70,6 +70,7 @@ public class SetValidator extends ConfigValidator<Set<String>> {
return Optional.empty();
};
}
@Override
Set<String> parse(String value) {
throw new RuntimeException("This should not be called");
@@ -84,6 +85,7 @@ public class SetValidator extends ConfigValidator<Set<String>> {
return true;
}
@SuppressWarnings("unchecked")
protected boolean setValue(Set<String> result) {
List<Method> methods = append
? Arrays.stream(Config.getInstance().getClass().getDeclaredMethods())

View File

@@ -1,7 +1,7 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
public class ThreadValidator extends ConfigValidator<Integer>{
public ThreadValidator(ConfigProperty property, boolean required, Integer defaultValue) {
@@ -10,7 +10,7 @@ public class ThreadValidator extends ConfigValidator<Integer>{
@Override
Integer parse(String value) {
return StringUtils.isNumeric(value) ? Integer.parseInt(value) : defaultValue;
return NumberUtils.isParsable(value) ? Integer.parseInt(value) : defaultValue;
}
@Override

View File

@@ -90,7 +90,7 @@ public class MkvFileProcessor implements FileProcessor {
return info;
}
private void detectDefaultTracks(FileInfoDto info, List<FileAttribute> attributes, List<FileAttribute> nonForcedTracks) {
protected void detectDefaultTracks(FileInfoDto info, List<FileAttribute> attributes, List<FileAttribute> nonForcedTracks) {
Set<FileAttribute> detectedForcedSubtitleLanes = new HashSet<>();
for (FileAttribute attribute : attributes) {
if (attribute.isDefaultTrack() && AUDIO.equals(attribute.getType()))
@@ -108,7 +108,7 @@ public class MkvFileProcessor implements FileProcessor {
);
}
private void detectDesiredTracks(FileInfoDto info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks) {
protected void detectDesiredTracks(FileInfoDto info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks) {
for (AttributeConfig config : Config.getInstance().getAttributeConfig()) {
FileAttribute desiredAudio = null;
FileAttribute desiredSubtitle = null;
@@ -127,7 +127,7 @@ public class MkvFileProcessor implements FileProcessor {
}
@Override
public void update(File file, FileInfoDto fileInfo) throws IOException {
public void update(File file, FileInfoDto fileInfo) throws IOException, RuntimeException {
StringBuilder sb = new StringBuilder();
sb.append(format("\"%s\" ", Config.getInstance().getPathFor(MkvToolNix.MKV_PROP_EDIT)));
sb.append(format("\"%s\" ", file.getAbsolutePath()));
@@ -154,6 +154,8 @@ public class MkvFileProcessor implements FileProcessor {
}
InputStream inputstream = Runtime.getRuntime().exec(sb.toString()).getInputStream();
log.debug(IOUtils.toString(new InputStreamReader(inputstream)));
String output = IOUtils.toString(new InputStreamReader(inputstream));
if (output.contains("Error")) throw new RuntimeException(output);
log.debug(output);
}
}

View File

@@ -4,28 +4,33 @@ import lombok.AllArgsConstructor;
@AllArgsConstructor
public enum ConfigProperty {
CONFIG_PATH("config", "Path to config file"),
LIBRARY("library", "Path to library"),
SAFE_MODE("safe-mode", "Test run (no files will be changes)"),
WINDOWS("windows", "Is operating system windows"),
THREADS("threads", "thread count (default: 2)"),
INCLUDE_PATTERN("include-pattern", "Include files matching pattern"),
MKV_TOOL_NIX("mkvtoolnix", "Path to mkv tool nix installation"),
FORCED_KEYWORDS("forcedKeywords", "Additional keywords to identify forced tracks"),
COMMENTARY_KEYWORDS("excludedKeywords", "Additional keywords to identify commentary tracks"),
EXCLUDE_DIRECTORY("exclude-directories", "Directories to be excluded, combines with config file"),
HELP("help", "\"for help this is\" - Yoda"),
VERSION("version", "Display version"),
ARGUMENTS("arguments", "List of arguments"),
ATTRIBUTE_CONFIG("attribute-config", "Attribute config to decide which tracks to choose when");
CONFIG_PATH("config-path", "c", "Path to config file"),
LIBRARY("library", "l", "Path to library"),
SAFE_MODE("safe-mode", "s", "Test run (no files will be changes)"),
WINDOWS("windows", null, "Is operating system windows"),
THREADS("threads", "t", "thread count (default: 2)"),
INCLUDE_PATTERN("include-pattern", "i", "Include files matching pattern"),
MKV_TOOL_NIX("mkvtoolnix", "m", "Path to mkv tool nix installation"),
FORCED_KEYWORDS("forcedKeywords", "fk", "Additional keywords to identify forced tracks"),
COMMENTARY_KEYWORDS("commentary-keywords", "ck", "Additional keywords to identify commentary tracks"),
EXCLUDE_DIRECTORY("exclude-directories", "e", "Directories to be excluded, combines with config file"),
HELP("help", "h", "\"for help this is\" - Yoda"),
VERSION("version", "v", "Display version"),
ARGUMENTS("arguments", null, "List of arguments"),
ATTRIBUTE_CONFIG("attribute-config", "a", "Attribute config to decide which tracks to choose when");
private final String property;
private final String shortParameter;
private final String description;
public String prop() {
return property;
}
public String abrv() {
return shortParameter;
}
public String desc() {
return description;
}