diff --git a/README.md b/README.md index 1a6533f..3c47942 100644 --- a/README.md +++ b/README.md @@ -26,31 +26,44 @@ Attribute-config must be entered in pairs: `audio:subtitle`; Example: `jpn:eng`. ### Available parameters ``` - -a, --attribute-config=... - List of audio:subtitle pairs used to match in order and update files accordingly (e.g. jpn:eng jpn:ger) - -c, --coherent= try to match all files in dir of depth with the same attribute config - -cf, --force-coherent changes are only applied if it's a coherent match - --commentary-keywords=[, ...]... - Keywords to identify commentary tracks (Defaults will be overwritten; Default: commentary, director) - -d, --filter-date= - only consider files created newer than entered date (format: "dd.MM.yyyy-HH:mm:ss") - --debug Enable debug logging - -e, --excluded-directory=... - Directories to be excluded, combines with config file - --forced-keywords=[, ...]... - Keywords to identify forced tracks (Defaults will be overwritten; Default: forced, signs, songs) - -h, --help Show this help message and exit. - -i, --include-pattern= - include files matching pattern (default: ".*") - -l, --library= +* -a, --attribute-config=... + List of audio:subtitle pairs used to match in order + and update files accordingly (e.g. jpn:eng jpn: + ger) +* -l, --library= path to library -m, --mkvtoolnix= path to mkvtoolnix installation - -n, --only-new-file sets filter-date to last successful execution (overwrites input of filter-date) - --preferred-subtitles=[, ...]... - Keywords to prefer specific subtitle tracks (Defaults will be overwritten; Default: unstyled) -s, --safemode test run (no files will be changes) -t, --threads= thread count (default: 2) + -c, --coherent= try to match all files in dir of depth with the + same attribute config + -cf, --force-coherent changes are only applied if it's a coherent match + -n, --only-new-file sets filter-date to last successful execution + (overwrites input of filter-date) + -d, --filter-date= + only consider files created newer than entered date + (format: "dd.MM.yyyy-HH:mm:ss") + -i, --include-pattern= + include files matching pattern (default: ".*") + -e, --excluded=... + Directories and files to be excluded (no wildcard) + -o, -overwrite-forced remove all forced flags + --forced-keywords=[, ...]... + Keywords to identify forced tracks (Defaults will + be overwritten; Default: forced, signs, songs) + --commentary-keywords=[, ...]... + Keywords to identify commentary tracks (Defaults + will be overwritten; Default: comment, + commentary, director) + --hearing-impaired=[, ...]... + Keywords to identify hearing impaired tracks + (Defaults will be overwritten; Default: SDH + --preferred-subtitles=[, ...]... + Keywords to prefer specific subtitle tracks + (Defaults will be overwritten; Default: unstyled) + --debug Enable debug logging + -h, --help Show this help message and exit. -V, --version Print version information and exit. ``` If you need more information how each parameter works, check out [this wiki page](https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/wiki/Parameters-v4). diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java index ed47d6d..f487886 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java @@ -1,12 +1,11 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation.ValidationExecutionStrategy; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.CachedMkvFileProcessor; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation.ValidationExecutionStrategy; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors.CachedMkvFileProcessor; 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.util.ProjectUtil; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -53,8 +52,8 @@ public class Main implements Runnable { InputConfig.setInstance(config); AttributeUpdaterKernel kernel = InputConfig.getInstance().getCoherent() != null - ? new CoherentAttributeUpdaterKernel(new MkvFileCollector(), new CachedMkvFileProcessor()) - : new DefaultAttributeUpdaterKernel(new MkvFileCollector(), new CachedMkvFileProcessor()); + ? new CoherentAttributeUpdaterKernel(new CachedMkvFileProcessor()) + : new DefaultAttributeUpdaterKernel(new CachedMkvFileProcessor()); kernel.execute(); } } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/CachedMkvFileProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/CachedMkvFileProcessor.java deleted file mode 100644 index acd9198..0000000 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/CachedMkvFileProcessor.java +++ /dev/null @@ -1,15 +0,0 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; - -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; - -import java.io.File; -import java.util.List; - -public class CachedMkvFileProcessor extends MkvFileProcessor { - Cache> cache = new Cache<>(); - - @Override - public List loadAttributes(File file) { - return cache.retrieve(file, super::loadAttributes); - } -} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileCollector.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileCollector.java deleted file mode 100644 index 5ea56da..0000000 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileCollector.java +++ /dev/null @@ -1,22 +0,0 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; - -import java.io.File; -import java.util.List; - -public interface FileCollector { - - /** - * @param path leads to one file directly or a directory which will be loaded recursively - * @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 f556ef6..68d39a2 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilter.java @@ -1,33 +1,45 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; 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; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @Slf4j public class FileFilter { - static boolean accept(File pathName, String[] fileExtensions) { - if (hasProperFileExtension(pathName, fileExtensions) - && hasMatchingPattern(pathName) - && isNewer(pathName)) { - return true; + private static final String EXTENSION_GROUP = "extension"; + private static final Pattern extensionPattern = Pattern.compile(String.format(".*(?<%s>\\..*)", EXTENSION_GROUP)); + + public static boolean accept(File pathName, Set fileExtensions) { + // Ignore files irrelevant for statistics + if (!hasProperFileExtension(pathName, new HashSet<>(fileExtensions))) { + return false; } ResultStatistic.getInstance().total(); - ResultStatistic.getInstance().excluded(); - return false; + if (!hasMatchingPattern(pathName) + || !isNewer(pathName) + || isExcluded(pathName, new HashSet<>(InputConfig.getInstance().getExcluded()))) { + ResultStatistic.getInstance().excluded(); + return false; + } + + return true; } - private static boolean hasProperFileExtension(File pathName, String[] fileExtensions) { - return StringUtils.endsWithAny(pathName.getAbsolutePath().toLowerCase(), fileExtensions); + private static boolean hasProperFileExtension(File pathName, Set fileExtensions) { + Matcher matcher = extensionPattern.matcher(pathName.getName()); + return matcher.find() && fileExtensions.contains(matcher.group(EXTENSION_GROUP)); } private static boolean hasMatchingPattern(File pathName) { @@ -49,4 +61,15 @@ public class FileFilter { private static boolean isNewer(Date creationDate) { return creationDate.toInstant().isAfter(InputConfig.getInstance().getFilterDate().toInstant()); } + + private static boolean isExcluded(File pathName, Set excludedDirs) { + if (excludedDirs.contains(pathName.getPath())) return true; + + // TODO improve partial matches and wildcard? + for (String excludedDir : excludedDirs) { + if (pathName.getPath().startsWith(excludedDir)) return true; + } + + return false; + } } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileProcessor.java deleted file mode 100644 index 4d0b91c..0000000 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileProcessor.java +++ /dev/null @@ -1,51 +0,0 @@ -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.FileInfo; - -import java.io.File; -import java.io.IOException; -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); - - /** - * 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(FileInfo info, List attributes, List nonForcedTracks); - - /** - * Populate FileInfoDto with the desired tracks, based on AttributeConfig. - * @param info to be populated - * @param nonForcedTracks List of all non-forced tracks - * @param nonCommentaryTracks List of all non-commentary tracks - */ - void detectDesiredTracks(FileInfo 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 used to update file - * @throws IOException when error occurs accessing file retrieving information - * @throws MkvToolNixException when error occurs while sending query to mkvpropedit - */ - void update(File file, FileInfo 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 deleted file mode 100644 index b48a57b..0000000 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileCollector.java +++ /dev/null @@ -1,49 +0,0 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; - -import lombok.extern.slf4j.Slf4j; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -@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))) { - return paths.filter(Files::isRegularFile) - .map(Path::toFile) - .filter(file -> FileFilter.accept(file, fileExtensions)) - .collect(Collectors.toList()); - } catch (IOException e) { - log.error("Couldn't find file or directory!", e); - 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 deleted file mode 100644 index ebf771d..0000000 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessor.java +++ /dev/null @@ -1,198 +0,0 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; - -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; -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.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.core.util.IOUtils; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType.AUDIO; -import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType.SUBTITLES; -import static java.lang.String.format; - -@Slf4j -public class MkvFileProcessor implements FileProcessor { - private final ObjectMapper mapper = new ObjectMapper(); - - private static final SubtitleTrackComparator subtitleTrackComparator = - new SubtitleTrackComparator(InputConfig.getInstance().getPreferredSubtitles().toArray(new String[0])); - - 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 DISABLE_FORCED_TRACK = "--edit track:%s --set flag-forced=0"; - private static final String ENABLE_FORCED_TRACK = "--edit track:%s --set flag-forced=1"; - - @SuppressWarnings("unchecked") - @Override - public List loadAttributes(File file) { - Map jsonMap; - List fileAttributes = new ArrayList<>(); - try { - String[] command = new String[]{ - InputConfig.getInstance().getPathFor(MkvToolNix.MKV_MERGE), - "--identify", - "--identification-format", - "json", - file.getAbsolutePath() - }; - - log.debug("Executing '{}': {}", file.getAbsolutePath(), String.join(" ", command)); - InputStream inputStream = Runtime.getRuntime().exec(command) - .getInputStream(); - jsonMap = mapper.readValue(inputStream, Map.class); - List> tracks = (List>) jsonMap.get("tracks"); - if (tracks == null) { - log.warn("Couldn't retrieve information of {}", file.getAbsolutePath()); - return new ArrayList<>(); - } - for (Map attribute : tracks) { - if (!"video".equals(attribute.get("type"))) { - Map properties = (Map) attribute.get("properties"); - fileAttributes.add(new FileAttribute( - (int) properties.get("number"), - (String) properties.get("language"), - (String) properties.get("track_name"), - (Boolean) properties.getOrDefault("default_track", false), - (Boolean) properties.getOrDefault("forced_track", false), - LaneType.valueOf(((String) attribute.get("type")).toUpperCase(Locale.ENGLISH)))); - } - } - - log.debug("File attributes of '{}': {}", file.getAbsolutePath(), fileAttributes.toString()); - } catch (IOException e) { - log.error("File could not be found or loaded: ", e); - System.out.println("File could not be found or loaded: " + file.getAbsolutePath()); - } - return fileAttributes; - } - - /** - * {@inheritDoc} - */ - @Override - public void detectDefaultTracks(FileInfo info, List attributes, List nonForcedTracks) { - for (FileAttribute attribute : attributes) { - if (AUDIO.equals(attribute.type())) { - if (attribute.defaultTrack()) info.getExistingDefaultAudioLanes().add(attribute); - if (attribute.forcedTrack()) info.getExistingForcedAudioLanes().add(attribute); - } else if (SUBTITLES.equals(attribute.type())) { - if (attribute.defaultTrack()) info.getExistingDefaultSubtitleLanes().add(attribute); - - if (attribute.forcedTrack()) info.getExistingForcedSubtitleLanes().add(attribute); - else if (!nonForcedTracks.contains(attribute)) info.getDesiredForcedSubtitleLanes().add(attribute); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public void detectDesiredTracks(FileInfo info, List nonForcedTracks, List nonCommentaryTracks, - AttributeConfig... configs) { - Set tracks = SetUtils.retainOf(nonForcedTracks, nonCommentaryTracks); - Set audioTracks = tracks.stream().filter(a -> AUDIO.equals(a.type())).collect(Collectors.toSet()); - Set subtitleTracks = tracks.stream().filter(a -> SUBTITLES.equals(a.type())).collect(Collectors.toSet()); - - for (AttributeConfig config : configs) { - Optional desiredAudio = detectDesiredTrack(config.getAudioLanguage(), audioTracks).findFirst(); - Optional desiredSubtitle = detectDesiredSubtitleTrack(config.getSubtitleLanguage(), subtitleTracks).findFirst(); - - if (("OFF".equals(config.getAudioLanguage()) || desiredAudio.isPresent()) - && ("OFF".equals(config.getSubtitleLanguage()) || desiredSubtitle.isPresent())) { - info.setMatchedConfig(config); - info.setDesiredDefaultAudioLane(desiredAudio.orElse(null)); - info.setDesiredDefaultSubtitleLane(desiredSubtitle.orElse(null)); - break; - } - } - } - - private Stream detectDesiredTrack(String language, Set tracks) { - return tracks.stream().filter(track -> language.equals(track.language())); - } - - private Stream detectDesiredSubtitleTrack(String language, Set tracks) { - return detectDesiredTrack(language, tracks) - .sorted(subtitleTrackComparator.reversed()); - } - - @Override - public List retrieveNonForcedTracks(List attributes) { - return attributes.stream() - .filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.trackName(), - InputConfig.getInstance().getForcedKeywords().toArray(new CharSequence[0]))) - .filter(elem -> !elem.forcedTrack()) - .collect(Collectors.toList()); - } - - @Override - public List retrieveNonCommentaryTracks(List attributes) { - return attributes.stream() - .filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.trackName(), - InputConfig.getInstance().getCommentaryKeywords().toArray(new CharSequence[0]))) - .collect(Collectors.toList()); - } - - /** - * {@inheritDoc} - */ - @Override - public void update(File file, FileInfo fileInfo) throws IOException, MkvToolNixException { - List command = new ArrayList<>(); - command.add(InputConfig.getInstance().getPathFor(MkvToolNix.MKV_PROP_EDIT)); - command.add(String.format(file.getAbsolutePath())); - - if (fileInfo.isAudioDifferent()) { - removeExistingAndAddDesiredLanes(fileInfo.getExistingDefaultAudioLanes(), fileInfo.getDesiredDefaultAudioLane(), command); - } - - if (!fileInfo.getExistingForcedAudioLanes().isEmpty()) { - for (FileAttribute track : fileInfo.getExistingForcedAudioLanes()) { - command.addAll(format(DISABLE_FORCED_TRACK, track.id())); - } - } - - if (fileInfo.isSubtitleDifferent()) { - removeExistingAndAddDesiredLanes(fileInfo.getExistingDefaultSubtitleLanes(), fileInfo.getDesiredDefaultSubtitleLane(), command); - } - - if (fileInfo.areForcedTracksDifferent()) { - for (FileAttribute track : fileInfo.getDesiredForcedSubtitleLanes()) { - command.addAll(format(ENABLE_FORCED_TRACK, track.id())); - } - } - - log.debug("Executing '{}'", String.join(" ", command)); - InputStream inputstream = Runtime.getRuntime().exec(command.toArray(new String[0])).getInputStream(); - String output = IOUtils.toString(new InputStreamReader(inputstream)); - log.debug("Result: {}", output); - if (output.contains("Error")) throw new MkvToolNixException(output); - } - - private void removeExistingAndAddDesiredLanes(Set existingDefaultLanes, FileAttribute desiredDefaultLanes, List command) { - if (existingDefaultLanes != null && !existingDefaultLanes.isEmpty()) { - for (FileAttribute track : existingDefaultLanes) { - command.addAll(format(DISABLE_DEFAULT_TRACK, track.id())); - } - } - if (desiredDefaultLanes != null) { - command.addAll(format(ENABLE_DEFAULT_TRACK, desiredDefaultLanes.id())); - } - } - - private List format(String format, Object... args) { - return Arrays.asList(String.format(format, args).split(" ")); - } -} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/SubtitleTrackComparator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/SubtitleTrackComparator.java index 86539b1..e9c16da 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/SubtitleTrackComparator.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/SubtitleTrackComparator.java @@ -1,20 +1,20 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import java.util.Comparator; @RequiredArgsConstructor -public class SubtitleTrackComparator implements Comparator { +public class SubtitleTrackComparator implements Comparator { private final String[] preferredSubtitles; /** * {@inheritDoc} */ @Override - public int compare(FileAttribute track1, FileAttribute track2) { + public int compare(TrackAttributes track1, TrackAttributes track2) { int result = 0; if (StringUtils.containsAnyIgnoreCase(track1.trackName(), preferredSubtitles)) { @@ -25,8 +25,8 @@ public class SubtitleTrackComparator implements Comparator { } if (result == 0) { - if (track1.defaultTrack()) result++; - if (track2.defaultTrack()) result--; + if (track1.defaultt()) result++; + if (track2.defaultt()) result--; } return result; diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/converter/AttributeConfigConverter.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/converter/AttributeConfigConverter.java similarity index 94% rename from src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/converter/AttributeConfigConverter.java rename to src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/converter/AttributeConfigConverter.java index 1966828..ba4e5e2 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/converter/AttributeConfigConverter.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/converter/AttributeConfigConverter.java @@ -1,4 +1,4 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.converter; +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.converter; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; import picocli.CommandLine; @@ -26,7 +26,7 @@ public class AttributeConfigConverter implements CommandLine.ITypeConverter files = loadFiles(InputConfig.getInstance().getLibraryPath().getAbsolutePath()); + List files = processor.loadFiles(InputConfig.getInstance().getLibraryPath().getAbsolutePath()); + progressBar.maxHint(files.size()); + progressBar.refresh(); files.forEach(file -> executor.submit(() -> { process(file); @@ -64,31 +59,12 @@ public abstract class AttributeUpdaterKernel { executor.awaitTermination(1, TimeUnit.DAYS); } - endProcess(); + writeLastExecutionDate(); statistic.stopTimer(); statistic.printResult(); } - protected List loadExcludedFiles() { - List excludedFiles = InputConfig.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. @@ -96,24 +72,20 @@ public abstract class AttributeUpdaterKernel { * @param file file or directory to update */ void process(File file) { - FileInfo fileInfo = new FileInfo(file); - List attributes = processor.loadAttributes(file); + FileInfo fileInfo = processor.readAttributes(file); - if (attributes == null || attributes.isEmpty()) { + if (fileInfo.getTracks().isEmpty()) { log.warn("No attributes found for file {}", file); - statistic.total(); statistic.failure(); return; } - List nonForcedTracks = processor.retrieveNonForcedTracks(attributes); - List nonCommentaryTracks = processor.retrieveNonCommentaryTracks(attributes); + AttributeProcessor.findDefaultMatchAndApplyChanges(fileInfo); + AttributeProcessor.findForcedTracksAndApplyChanges(fileInfo); + AttributeProcessor.findCommentaryTracksAndApplyChanges(fileInfo); + AttributeProcessor.findHearingImpairedTracksAndApplyChanges(fileInfo); - processor.detectDefaultTracks(fileInfo, attributes, nonForcedTracks); - processor.detectDesiredTracks(fileInfo, nonForcedTracks, nonCommentaryTracks, - InputConfig.getInstance().getAttributeConfig().toArray(new AttributeConfig[]{})); - - updateFile(fileInfo); + checkStatusAndUpdate(fileInfo); } /** @@ -121,8 +93,7 @@ public abstract class AttributeUpdaterKernel { * * @param fileInfo contains information about file and desired configuration. */ - protected void updateFile(FileInfo fileInfo) { - statistic.total(); + protected void checkStatusAndUpdate(FileInfo fileInfo) { switch (fileInfo.getStatus()) { case CHANGE_NECESSARY: statistic.shouldChange(); @@ -142,12 +113,10 @@ public abstract class AttributeUpdaterKernel { } private void commitChange(FileInfo fileInfo) { - if (InputConfig.getInstance().isSafeMode()) { - return; - } + if (InputConfig.getInstance().isSafeMode()) return; try { - processor.update(fileInfo.getFile(), fileInfo); + processor.update(fileInfo); statistic.success(); log.info("Commited {} to '{}'", fileInfo.getMatchedConfig().toStringShort(), fileInfo.getFile().getAbsolutePath()); } catch (IOException | MkvToolNixException e) { @@ -156,7 +125,8 @@ public abstract class AttributeUpdaterKernel { } } - protected void endProcess() { + // should this be here? + protected void writeLastExecutionDate() { if (InputConfig.getInstance().isSafeMode()) { return; } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java index 6e9602f..d92f5af 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/CoherentAttributeUpdaterKernel.java @@ -1,11 +1,8 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors.FileProcessor; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo; import lombok.extern.slf4j.Slf4j; import me.tongfei.progressbar.ProgressBarBuilder; import org.apache.commons.lang3.StringUtils; @@ -17,8 +14,8 @@ import java.util.stream.Collectors; @Slf4j public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel { - public CoherentAttributeUpdaterKernel(FileCollector collector, FileProcessor processor) { - super(collector, processor); + public CoherentAttributeUpdaterKernel(FileProcessor processor) { + super(processor); } @Override @@ -27,18 +24,10 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel { .setUnit(" directories", 1); } - /** - * {@inheritDoc} - */ - @Override - List loadFiles(String path) { - return loadFiles(path, InputConfig.getInstance().getCoherent()); - } - List loadFiles(String path, int depth) { - List excludedFiles = loadExcludedFiles(); - List directories = collector.loadDirectories(path, depth) - .stream().filter(file -> !excludedFiles.contains(file)) + List directories = processor.loadDirectories(path, depth) + .stream() +// .filter(file -> !excludedFiles.contains(file)) .collect(Collectors.toList()); return directories.stream() .filter(dir -> isParentDirectory(dir, directories)) @@ -67,43 +56,43 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel { void process(File file, int depth) { // 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(FileInfo::new) - .collect(Collectors.toList()); +// List fileInfoOlds = collector.loadFiles(file.getAbsolutePath()).stream() +// .map(FileInfoOld::new) +// .collect(Collectors.toList()); for (AttributeConfig config : InputConfig.getInstance().getAttributeConfig()) { - for (FileInfo fileInfo : fileInfos) { - List attributes = processor.loadAttributes(fileInfo.getFile()); +// for (FileInfoOld fileInfoOld : fileInfoOlds) { +// List attributes = processor.readAttributes(fileInfoOld.getFile()); +// +// List nonForcedTracks = processor.retrieveNonForcedTracks(attributes); +// List nonCommentaryTracks = processor.retrieveNonCommentaryTracks(attributes); +// +// processor.detectDefaultTracks(fileInfoOld, attributes, nonForcedTracks); +// processor.detectDesiredTracks(fileInfoOld, nonForcedTracks, nonCommentaryTracks, config); +// } +// +// if (fileInfoOlds.stream().allMatch(elem -> ("OFF".equals(config.getSubtitleLanguage()) || elem.getDesiredDefaultSubtitleLane() != null) +// && elem.getDesiredDefaultAudioLane() != null)) { +// log.info("Found {} match for {}", config.toStringShort(), file.getAbsolutePath()); +// fileInfoOlds.forEach(this::updateFile); +// return; // match found, end process here +// } - 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 -> ("OFF".equals(config.getSubtitleLanguage()) || elem.getDesiredDefaultSubtitleLane() != null) - && elem.getDesiredDefaultAudioLane() != null)) { - log.info("Found {} match for {}", config.toStringShort(), file.getAbsolutePath()); - fileInfos.forEach(this::updateFile); - return; // match found, end process here - } - - fileInfos.forEach(f -> { - f.setDesiredDefaultAudioLane(null); - f.setDesiredDefaultSubtitleLane(null); - }); +// fileInfoOlds.forEach(f -> { +// f.setDesiredDefaultAudioLane(null); +// f.setDesiredDefaultSubtitleLane(null); +// }); } log.info("No coherent match found for {}", file.getAbsoluteFile()); - for (FileInfo fileInfo : fileInfos) { - if (!InputConfig.getInstance().isForceCoherent()) { - super.process(fileInfo.getFile()); - } else { - statistic.excluded(); - } - } +// for (FileInfoOld fileInfoOld : fileInfoOlds) { +// if (!InputConfig.getInstance().isForceCoherent()) { +// super.process(fileInfoOld.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 index ca70a89..119dd1b 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/DefaultAttributeUpdaterKernel.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/kernel/DefaultAttributeUpdaterKernel.java @@ -1,8 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors.FileProcessor; import lombok.extern.slf4j.Slf4j; import me.tongfei.progressbar.ProgressBarBuilder; @@ -13,8 +12,8 @@ import java.util.stream.Collectors; @Slf4j public class DefaultAttributeUpdaterKernel extends AttributeUpdaterKernel { - public DefaultAttributeUpdaterKernel(FileCollector collector, FileProcessor processor) { - super(collector, processor); + public DefaultAttributeUpdaterKernel(FileProcessor processor) { + super(processor); } @Override @@ -22,15 +21,4 @@ public class DefaultAttributeUpdaterKernel extends AttributeUpdaterKernel { return super.pbBuilder() .setUnit(" files", 1); } - - /** - * {@inheritDoc} - */ - @Override - List loadFiles(String path) { - List excludedFiles = loadExcludedFiles(); - return collector.loadFiles(InputConfig.getInstance().getLibraryPath().getAbsolutePath()).stream() - .filter(file -> !excludedFiles.contains(file)) - .collect(Collectors.toList()); - } } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/AttributeProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/AttributeProcessor.java new file mode 100644 index 0000000..a677a3b --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/AttributeProcessor.java @@ -0,0 +1,129 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.SubtitleTrackComparator; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.*; + +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public class AttributeProcessor { + private static final SubtitleTrackComparator subtitleTrackComparator = + new SubtitleTrackComparator(InputConfig.getInstance().getPreferredSubtitles().toArray(new String[0])); + + private static List filterForPossibleDefaults(List tracks) { + InputConfig config = InputConfig.getInstance(); + Stream attributes = tracks.stream(); + + if (true) { // TODO: config for including commentary + attributes = attributes + .filter(attr -> !attr.commentary()) + .filter(attr -> { + if (attr.trackName() == null) return true; + return config.getCommentaryKeywords().stream().noneMatch(keyword -> keyword.compareToIgnoreCase(attr.trackName()) == 0); + }); + + } + + if (true) { // TODO: config for including hearing impaired + attributes = attributes + .filter(attr -> !attr.hearingImpaired()) + .filter(attr -> { + if (attr.trackName() == null) return true; + return config.getHearingImpaired().stream().noneMatch(keyword -> keyword.compareToIgnoreCase(attr.trackName()) == 0); + });; + } + + return attributes + .filter(attr -> !attr.forced()) + .filter(attr -> { + if (attr.trackName() == null) return true; + return config.getForcedKeywords().stream().noneMatch(keyword -> keyword.compareToIgnoreCase(attr.trackName()) == 0); + }) + .toList(); + } + + public static void findDefaultMatchAndApplyChanges(FileInfo fileInfo) { + findDefaultMatchAndApplyChanges(fileInfo, InputConfig.getInstance().getAttributeConfig().toArray(new AttributeConfig[0])); + } + + public static void findDefaultMatchAndApplyChanges(FileInfo fileInfo, AttributeConfig... configs) { + Map> audiosByLanguage = new HashMap<>(fileInfo.getTracks().size()); + Map> subsByLanguage = new HashMap<>(fileInfo.getTracks().size()); + filterForPossibleDefaults(fileInfo.getTracks()).forEach(track -> { + if (TrackType.AUDIO.equals(track.type())) + audiosByLanguage.computeIfAbsent(track.language(), (k) -> new ArrayList<>()).add(track); + else if (TrackType.SUBTITLES.equals(track.type())) + subsByLanguage.computeIfAbsent(track.language(), (k) -> new ArrayList<>()).add(track); + }); + + for (AttributeConfig config : configs) { + if (("OFF".equals(config.getAudioLanguage()) || audiosByLanguage.containsKey(config.getAudioLanguage())) + && ("OFF".equals(config.getSubtitleLanguage()) || subsByLanguage.containsKey(config.getSubtitleLanguage()))) { + fileInfo.setMatchedConfig(config); + break; + } + // TODO: forced if OFF + } + + if (fileInfo.getMatchedConfig() == null) return; + + applyDefaultChanges(fileInfo, FileInfo::getAudioTracks, fileInfo.getMatchedConfig().getAudioLanguage(), + () -> audiosByLanguage.get(fileInfo.getMatchedConfig().getAudioLanguage()).get(0)); + applyDefaultChanges(fileInfo, FileInfo::getSubtitleTracks, fileInfo.getMatchedConfig().getSubtitleLanguage(), + () -> subsByLanguage.get(fileInfo.getMatchedConfig().getSubtitleLanguage()).stream().max(subtitleTrackComparator).get()); + } + + private static void applyDefaultChanges(FileInfo fileInfo, Function> tracks, String language, Supplier targetDefaultSupplier) { + tracks.apply(fileInfo).stream() + .filter(TrackAttributes::defaultt) + .forEach(attr -> fileInfo.getChanges().getDefaultTrack().put(attr, false)); + if (!"OFF".equals(language)) { + TrackAttributes targetDefault = targetDefaultSupplier.get(); + if (fileInfo.getChanges().getDefaultTrack().containsKey(targetDefault)) { + fileInfo.getChanges().getDefaultTrack().remove(targetDefault); + } else { + fileInfo.getChanges().getDefaultTrack().put(targetDefault, true); + } + } + } + + public static void findForcedTracksAndApplyChanges(FileInfo fileInfo) { + Stream forcedTracks = fileInfo.getTracks().stream() + .filter(track -> track.trackName() != null) + .filter(track -> InputConfig.getInstance().getForcedKeywords().stream().anyMatch(keyword -> track.trackName().toLowerCase().contains(keyword.toLowerCase(Locale.ROOT)))); + + if (InputConfig.getInstance().isOverwriteForced()) { + fileInfo.getTracks().stream().filter(TrackAttributes::forced).forEach(attr -> { + fileInfo.getChanges().getForcedTrack().put(attr, false); + }); + } else { + forcedTracks = forcedTracks.filter(attr -> !attr.forced()); + } + + forcedTracks.forEach(attr -> { + fileInfo.getChanges().getForcedTrack().put(attr, true); + }); + } + + public static void findCommentaryTracksAndApplyChanges(FileInfo fileInfo) { + fileInfo.getTracks().stream() + .filter(track -> !track.commentary()) + .filter(track -> track.trackName() != null) + .filter(track -> InputConfig.getInstance().getCommentaryKeywords().stream().anyMatch(keyword -> track.trackName().toLowerCase().contains(keyword.toLowerCase(Locale.ROOT)))) + .forEach(attr -> { + fileInfo.getChanges().getCommentaryTrack().put(attr, true); + }); + } + + public static void findHearingImpairedTracksAndApplyChanges(FileInfo fileInfo) { + fileInfo.getTracks().stream() + .filter(track -> !track.commentary()) + .filter(track -> track.trackName() != null) + .filter(track -> InputConfig.getInstance().getHearingImpaired().stream().anyMatch(keyword -> track.trackName().toLowerCase().contains(keyword.toLowerCase(Locale.ROOT)))) + .forEach(attr -> { + fileInfo.getChanges().getHearingImpairedTrack().put(attr, true); + }); + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/CachedMkvFileProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/CachedMkvFileProcessor.java new file mode 100644 index 0000000..2f16c01 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/CachedMkvFileProcessor.java @@ -0,0 +1,15 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.Cache; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo; + +import java.io.File; + +public class CachedMkvFileProcessor extends MkvFileProcessor { + Cache cache = new Cache<>(); + + @Override + public FileInfo readAttributes(File file) { + return cache.retrieve(file, super::readAttributes); + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/FileProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/FileProcessor.java new file mode 100644 index 0000000..bdadaaf --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/FileProcessor.java @@ -0,0 +1,44 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions.MkvToolNixException; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +public interface FileProcessor { + + /** + * @param path leads to one file directly or a directory which will be loaded recursively + * @return list of all files within the directory + */ + List loadFiles(String path); + + /** + * Load all directories from path, but only until depth is reached. + * This will ignore all files between root and directories at depth. + * + * @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); + + /** + * Load track information from file. + * + * @param file Takes the file from which the attributes will be returned + * @return list of all important attributes + */ + FileInfo readAttributes(File file); + + /** + * Update the file. + * + * @param fileInfo information used to update file + * @throws IOException when error occurs accessing file retrieving information + * @throws MkvToolNixException when error occurs while sending query to mkvpropedit + */ + void update(FileInfo fileInfo) throws IOException, MkvToolNixException; +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/MkvFileProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/MkvFileProcessor.java new file mode 100644 index 0000000..d851135 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/MkvFileProcessor.java @@ -0,0 +1,143 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileFilter; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.SubtitleTrackComparator; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; +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.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.core.util.IOUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackType.AUDIO; +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackType.SUBTITLES; +import static java.lang.String.format; + +@Slf4j +public class MkvFileProcessor implements FileProcessor { + private final ObjectMapper mapper = new ObjectMapper(); + + private static final Set fileExtensions = new HashSet<>(Set.of(".mkv", ".mka", ".mks", ".mk3d")); + + private static final String DEFAULT_TRACK = "--edit track:%s --set flag-default=%s"; + private static final String FORCED_TRACK = "--edit track:%s --set flag-forced=%s"; + private static final String COMMENTARY_TRACK = "--edit track:%s --set flag-commentary=%s"; + private static final String HEARING_IMPAIRED_TRACK = "--edit track:%s --set flag-hearing-impaired=%s"; + + /** + * {@inheritDoc} + */ + @Override + public List loadFiles(String path) { + try (Stream paths = Files.walk(Paths.get(path))) { + return paths + .filter(Files::isRegularFile) + .map(Path::toFile) + .filter(file -> FileFilter.accept(file, fileExtensions)) + .collect(Collectors.toList()); + } catch (IOException e) { + log.error("Couldn't find file or directory!", e); + return new ArrayList<>(); + } + } + + /** + * {@inheritDoc} + */ + @Override + // does this load /arst/arst & /arst ? + 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<>(); + } + } + + @SuppressWarnings("unchecked") + @Override + public FileInfo readAttributes(File file) { + FileInfo fileInfo = new FileInfo(file); + try { + String[] command = new String[]{ + InputConfig.getInstance().getPathFor(MkvToolNix.MKV_MERGE), + "--identify", + "--identification-format", + "json", + file.getAbsolutePath() + }; + + log.debug("Executing: {}", String.join(" ", command)); + InputStream inputStream = Runtime.getRuntime().exec(command) + .getInputStream(); + Map jsonMap = mapper.readValue(inputStream, Map.class); + List> tracks = (List>) jsonMap.get("tracks"); + if (tracks != null) { + for (Map attribute : tracks) { + if (!"video".equals(attribute.get("type"))) { + Map properties = (Map) attribute.get("properties"); + fileInfo.getTracks().add(new TrackAttributes( + (int) properties.get("number"), + (String) properties.get("language"), + (String) properties.get("track_name"), + (Boolean) properties.getOrDefault("default_track", false), + (Boolean) properties.getOrDefault("forced_track", false), + (Boolean) properties.getOrDefault("commentary_track", false), + (Boolean) properties.getOrDefault("hearing_impaired_track", false), + TrackType.valueOf(((String) attribute.get("type")).toUpperCase(Locale.ENGLISH)))); + } + } + } else { + log.warn("Couldn't retrieve information of {}", file.getAbsolutePath()); + } + + log.debug("File attributes of '{}': {}", file.getAbsolutePath(), fileInfo.getTracks()); + } catch (IOException e) { + log.error("File could not be found or loaded: ", e); + System.out.println("File could not be found or loaded: " + file.getAbsolutePath()); + } + return fileInfo; + } + + /** + * {@inheritDoc} + */ + @Override + public void update(FileInfo fileInfo) throws IOException, MkvToolNixException { + List command = new ArrayList<>(); + command.add(InputConfig.getInstance().getPathFor(MkvToolNix.MKV_PROP_EDIT)); + command.add(String.format(fileInfo.getFile().getAbsolutePath())); + + PlannedChange changes = fileInfo.getChanges(); + changes.getDefaultTrack().forEach((key, value) -> command.addAll(format(DEFAULT_TRACK, key.id(), value ? 1 : 0))); + changes.getForcedTrack().forEach((key, value) -> command.addAll(format(FORCED_TRACK, key.id(), value ? 1 : 0))); + changes.getCommentaryTrack().forEach((key, value) -> command.addAll(format(COMMENTARY_TRACK, key.id(), value ? 1 : 0))); + changes.getHearingImpairedTrack().forEach((key, value) -> command.addAll(format(HEARING_IMPAIRED_TRACK, key.id(), value ? 1 : 0))); + + log.debug("Executing '{}'", String.join(" ", command)); + InputStream inputstream = Runtime.getRuntime().exec(command.toArray(new String[0])).getInputStream(); + String output = IOUtils.toString(new InputStreamReader(inputstream)); + log.debug("Result: {}", output); + if (output.contains("Error")) throw new MkvToolNixException(output); + } + + private List format(String format, Object... args) { + return Arrays.asList(String.format(format, args).split(" ")); + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidFile.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidFile.java similarity index 86% rename from src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidFile.java rename to src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidFile.java index 43c2ab0..5cbba3e 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidFile.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidFile.java @@ -1,4 +1,4 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation; +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation; import jakarta.validation.Constraint; import jakarta.validation.Payload; diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidFileValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidFileValidator.java similarity index 86% rename from src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidFileValidator.java rename to src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidFileValidator.java index 07686c0..b111865 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidFileValidator.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidFileValidator.java @@ -1,4 +1,4 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation; +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation; import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidMkvToolNix.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidMkvToolNix.java similarity index 86% rename from src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidMkvToolNix.java rename to src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidMkvToolNix.java index c099452..d6f18a1 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidMkvToolNix.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidMkvToolNix.java @@ -1,4 +1,4 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation; +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation; import jakarta.validation.Constraint; import jakarta.validation.Payload; diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidMkvToolNixValidator.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidMkvToolNixValidator.java similarity index 91% rename from src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidMkvToolNixValidator.java rename to src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidMkvToolNixValidator.java index 6463a6e..1475638 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidMkvToolNixValidator.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidMkvToolNixValidator.java @@ -1,4 +1,4 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation; +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix; import jakarta.validation.ConstraintValidator; diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidationExecutionStrategy.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidationExecutionStrategy.java similarity index 76% rename from src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidationExecutionStrategy.java rename to src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidationExecutionStrategy.java index 0ef773d..2ff6763 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/validation/ValidationExecutionStrategy.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/validation/ValidationExecutionStrategy.java @@ -1,7 +1,7 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation; +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation; import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ValidationUtil; import jakarta.validation.ConstraintViolation; import jakarta.validation.Validator; @@ -12,8 +12,8 @@ import java.util.Set; public class ValidationExecutionStrategy implements CommandLine.IExecutionStrategy { public int execute(CommandLine.ParseResult parseResult) { - validate(parseResult.commandSpec()); - return new CommandLine.RunLast().execute(parseResult); // default execution strategy + if (!parseResult.isVersionHelpRequested() && !parseResult.isUsageHelpRequested()) validate(parseResult.commandSpec()); + return new CommandLine.RunLast().execute(parseResult); } private static void validate(CommandLine.Model.CommandSpec spec) { diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java deleted file mode 100644 index c410000..0000000 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ConfigProperty.java +++ /dev/null @@ -1,68 +0,0 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.model; - -import lombok.AllArgsConstructor; -import org.apache.commons.cli.Option; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Collectors; - -@AllArgsConstructor -public enum ConfigProperty { - 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 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), - 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), - PREFERRED_SUBTITLES("preferred-subtitles", "Additional keywords to prefer specific subtitle tracks", "ps", Option.UNLIMITED_VALUES), - ARGUMENTS("arguments", "List of arguments", null, 0), - VERSION("version", "Display version", "v", 0), - HELP("help", "\"For help this is\" - Yoda", "h", 0); - - /* - * Verify at startup that there are no duplicated shortParameters. - */ - static { - Set shortParameters = new HashSet<>(); - for (String param : Arrays.stream(ConfigProperty.values()).map(ConfigProperty::abrv).collect(Collectors.toList())) { - if (shortParameters.contains(param)) { - throw new IllegalStateException("It is not allowed to have multiple properties with the same abbreviation!"); - } - if (param != null) { - shortParameters.add(param); - } - } - } - - private final String property; - private final String description; - private final String shortParameter; - private final int args; - - public String prop() { - return property; - } - - public String desc() { - return description; - } - - public String abrv() { - return shortParameter; - } - - public int args() { - return args; - } -} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfo.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfo.java index d8f2444..fc92b76 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfo.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfo.java @@ -5,80 +5,38 @@ import lombok.RequiredArgsConstructor; import lombok.Setter; import java.io.File; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Function; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; @Getter -@Setter @RequiredArgsConstructor public class FileInfo { private final File file; - private Set existingDefaultAudioLanes = new HashSet<>(); - private Set existingForcedAudioLanes = new HashSet<>(); + private final List tracks = new ArrayList<>(); - private Set existingDefaultSubtitleLanes = new HashSet<>(); - private Set existingForcedSubtitleLanes = new HashSet<>(); + private final List audioTracks = new ArrayList<>(); + private final List subtitleTracks = new ArrayList<>(); - private Set desiredForcedSubtitleLanes = new HashSet<>(); - private FileAttribute desiredDefaultAudioLane; - private FileAttribute desiredDefaultSubtitleLane; + private final PlannedChange changes = new PlannedChange(); + @Setter private AttributeConfig matchedConfig; - public boolean isAudioDifferent() { - return isMatchDifferent(existingDefaultAudioLanes, desiredDefaultAudioLane) - || isLaneOff(existingDefaultAudioLanes, desiredDefaultAudioLane, AttributeConfig::getAudioLanguage); + public void addTrack(TrackAttributes track) { + tracks.add(track); + if (TrackType.AUDIO.equals(track.type())) audioTracks.add(track); + else if (TrackType.SUBTITLES.equals(track.type())) subtitleTracks.add(track); } - public boolean isSubtitleDifferent() { - return isMatchDifferent(existingDefaultSubtitleLanes, desiredDefaultSubtitleLane) - || isLaneOff(existingDefaultSubtitleLanes, desiredDefaultSubtitleLane, AttributeConfig::getSubtitleLanguage); - } - - private boolean isMatchDifferent(Set existingDefault, FileAttribute desiredDefault) { - return desiredDefault != null && - (existingDefault == null || !existingDefault.contains(desiredDefault) || existingDefault.size() > 1); - } - - private boolean isLaneOff(Set existingDefault, FileAttribute desiredDefault, Function inputLane) { - return desiredDefault == null - && (matchedConfig != null && "OFF".equals(inputLane.apply(matchedConfig))) - && (existingDefault != null && !existingDefault.isEmpty()); - } - - public boolean areForcedTracksDifferent() { - return !desiredForcedSubtitleLanes.isEmpty() && !existingForcedSubtitleLanes.containsAll(desiredForcedSubtitleLanes); + public void addTracks(Collection tracks) { + for (TrackAttributes track : tracks) addTrack(track); } public FileStatus getStatus() { - if (isChangeNecessary()) return FileStatus.CHANGE_NECESSARY; - if (isUnableToApplyConfig()) return FileStatus.NO_SUITABLE_CONFIG; - if (isAlreadySuited()) return FileStatus.ALREADY_SUITED; + if (!changes.isEmpty()) return FileStatus.CHANGE_NECESSARY; + if (matchedConfig == null) return FileStatus.NO_SUITABLE_CONFIG; + if (changes.isEmpty()) return FileStatus.ALREADY_SUITED; return FileStatus.UNKNOWN; } - - private boolean isUnableToApplyConfig() { - return desiredDefaultAudioLane == null && !"OFF".equals(matchedConfig.getAudioLanguage()) - && desiredDefaultSubtitleLane == null && !"OFF".equals(matchedConfig.getSubtitleLanguage()); - } - - private boolean isAlreadySuited() { - return (desiredDefaultAudioLane == null || existingDefaultAudioLanes.contains(desiredDefaultAudioLane)) - && (desiredDefaultSubtitleLane == null || existingDefaultSubtitleLanes.contains(desiredDefaultSubtitleLane)); - } - - private boolean isChangeNecessary() { - return isAudioDifferent() || isSubtitleDifferent() || areForcedTracksDifferent() || !existingForcedAudioLanes.isEmpty(); - } - - @Override - public String toString() { - return "[" + "defaultAudioLanes=" + existingDefaultAudioLanes + - ", defaultSubtitleLanes=" + existingDefaultSubtitleLanes + - ", desiredForcedSubtitleLanes=" + desiredForcedSubtitleLanes + - ", desiredAudioLane=" + desiredDefaultAudioLane + - ", desiredSubtitleLane=" + desiredDefaultSubtitleLane + - ']'; - } } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/InputConfig.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfig.java similarity index 84% rename from src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/InputConfig.java rename to src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfig.java index 797b14c..eb8be2a 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/InputConfig.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfig.java @@ -1,10 +1,8 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.config; +package at.pcgamingfreaks.mkvaudiosubtitlechanger.model; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.converter.AttributeConfigConverter; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation.ValidFile; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation.ValidMkvToolNix; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.converter.AttributeConfigConverter; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation.ValidFile; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation.ValidMkvToolNix; import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.FileUtils; import jakarta.validation.constraints.Min; import lombok.AccessLevel; @@ -38,18 +36,16 @@ public class InputConfig { @Option(names = {"-a", "--attribute-config"}, required = true, arity = "1..*", converter = AttributeConfigConverter.class, description = "List of audio:subtitle pairs used to match in order and update files accordingly (e.g. jpn:eng jpn:ger)") private List attributeConfig; - @ValidFile(message = "does not exist") @Option(names = {"-l", "--library"}, required = true, description = "path to library") private File libraryPath; - - @Option(names = {"-s", "--safemode"}, description = "test run (no files will be changes)") - private boolean safeMode; - @ValidMkvToolNix(message = "does not exist") @Option(names = {"-m", "--mkvtoolnix"}, defaultValue = "${DEFAULT_MKV_TOOL_NIX}", description = "path to mkvtoolnix installation") private File mkvToolNix; + @Option(names = {"-s", "--safemode"}, description = "test run (no files will be changes)") + private boolean safeMode; + @Min(1) @Option(names = {"-t", "--threads"}, defaultValue = "2", description = "thread count (default: ${DEFAULT-VALUE})") private int threads; @@ -57,35 +53,34 @@ public class InputConfig { @Min(0) @Option(names = {"-c", "--coherent"}, description = "try to match all files in dir of depth with the same attribute config") private Integer coherent; - @Option(names = {"-cf", "--force-coherent"}, description = "changes are only applied if it's a coherent match") private boolean forceCoherent; @Option(names = {"-n", "--only-new-file"}, description = "sets filter-date to last successful execution (overwrites input of filter-date)") private boolean onlyNewFiles; - @Option(names = {"-d", "--filter-date"}, defaultValue = Option.NULL_VALUE, description = "only consider files created newer than entered date (format: \"dd.MM.yyyy-HH:mm:ss\")") private Date filterDate; - @Option(names = {"-i", "--include-pattern"}, defaultValue = ".*", description = "include files matching pattern (default: \".*\")") private Pattern includePattern; + @Option(names = {"-e", "--excluded"}, arity = "1..*", + description = "Directories and files to be excluded (no wildcard)") + private Set excluded = new HashSet<>(); - @Option(names = {"-e", "--excluded-directory"}, arity = "1..*", - description = "Directories to be excluded, combines with config file") - private Set excludedDirectories = new HashSet<>(); + @Option(names = {"-o", "-overwrite-forced"}, description = "remove all forced flags") + private boolean overwriteForced; @Option(names = {"--forced-keywords"}, arity = "1..*", defaultValue = "forced, signs, songs", split = ", ", description = "Keywords to identify forced tracks (Defaults will be overwritten; Default: ${DEFAULT-VALUE})") private Set forcedKeywords; - - @Option(names = {"--commentary-keywords"}, arity = "1..*", defaultValue = "commentary, director", split = ", ", + @Option(names = {"--commentary-keywords"}, arity = "1..*", defaultValue = "comment, commentary, director", split = ", ", description = "Keywords to identify commentary tracks (Defaults will be overwritten; Default: ${DEFAULT-VALUE})") private Set commentaryKeywords; - + @Option(names = {"--hearing-impaired"}, arity = "1..*", defaultValue = "SDH", split = ", ", + description = "Keywords to identify hearing impaired tracks (Defaults will be overwritten; Default: ${DEFAULT-VALUE}") + private Set hearingImpaired; @Option(names = {"--preferred-subtitles"}, arity = "1..*", defaultValue = "unstyled", split = ", ", description = "Keywords to prefer specific subtitle tracks (Defaults will be overwritten; Default: ${DEFAULT-VALUE})") private Set preferredSubtitles; - @Option(names = {"--debug"}, description = "Enable debug logging") private boolean debug; @@ -136,7 +131,7 @@ public class InputConfig { .add("filterDate=" + filterDate) .add("forcedKeywords=" + forcedKeywords) .add("commentaryKeywords=" + commentaryKeywords) - .add("excludedDirectories=" + excludedDirectories) + .add("excludedDirectories=" + excluded) .add("preferredSubtitles=" + preferredSubtitles) .add("attributeConfig=" + attributeConfig) .toString(); diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/PlannedChange.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/PlannedChange.java new file mode 100644 index 0000000..b2a280e --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/PlannedChange.java @@ -0,0 +1,18 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.model; + +import lombok.Getter; + +import java.util.HashMap; +import java.util.Map; + +@Getter +public class PlannedChange { + private final Map defaultTrack = new HashMap<>(); + private final Map forcedTrack = new HashMap<>(); + private final Map commentaryTrack = new HashMap<>(); + private final Map hearingImpairedTrack = new HashMap<>(); + + public boolean isEmpty() { + return defaultTrack.isEmpty() && forcedTrack.isEmpty() && commentaryTrack.isEmpty() && hearingImpairedTrack.isEmpty(); + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java index 8147625..82915d0 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java @@ -17,7 +17,7 @@ public class ResultStatistic { "└─ Failed: %s%n" + "Runtime: %s"; private static ResultStatistic instance; - private int filesTotal = 0; + private int total = 0; private int excluded = 0; private int shouldChange = 0; @@ -33,18 +33,22 @@ public class ResultStatistic { private long runtime = 0; public static ResultStatistic getInstance() { - if (instance == null) { + return getInstance(false); + } + + public static ResultStatistic getInstance(boolean reset) { + if (instance == null || reset) { instance = new ResultStatistic(); } return instance; } public void increaseTotalBy(int amount) { - filesTotal += amount; + total += amount; } public synchronized void total() { - filesTotal++; + total++; } public void increaseExcludedBy(int amount) { @@ -110,13 +114,13 @@ public class ResultStatistic { } public String prettyPrint() { - return String.format(result, filesTotal, excluded, shouldChange, failedChanging, successfullyChanged, + return String.format(result, total, excluded, shouldChange, failedChanging, successfullyChanged, noSuitableConfigFound, alreadyFits, failed, formatTimer()); } @Override public String toString() { - return "ResultStatistic: " + "filesTotal=" + filesTotal + + return "ResultStatistic: " + "total=" + total + ", excluded=" + excluded + ", shouldChange=" + shouldChange + " (failedChanging=" + failedChanging + diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/TrackAttributes.java similarity index 61% rename from src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java rename to src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/TrackAttributes.java index b86952d..5d7dc26 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/TrackAttributes.java @@ -5,16 +5,17 @@ import lombok.extern.slf4j.Slf4j; import java.util.Objects; @Slf4j -public record FileAttribute(int id, String language, String trackName, boolean defaultTrack, boolean forcedTrack, - LaneType type) { +public record TrackAttributes(int id, String language, String trackName, + boolean defaultt, boolean forced, boolean commentary, boolean hearingImpaired, + TrackType type) { @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - FileAttribute attribute = (FileAttribute) o; + TrackAttributes attribute = (TrackAttributes) o; return id == attribute.id - && defaultTrack == attribute.defaultTrack - && forcedTrack == attribute.forcedTrack + && defaultt == attribute.defaultt + && forced == attribute.forced && Objects.equals(language, attribute.language) && Objects.equals(trackName, attribute.trackName) && type == attribute.type; @@ -25,8 +26,8 @@ public record FileAttribute(int id, String language, String trackName, boolean d return "[" + "id=" + id + ", language='" + language + '\'' + ", trackName='" + trackName + '\'' + - ", defaultTrack=" + defaultTrack + - ", forcedTrack=" + forcedTrack + + ", defaultt=" + defaultt + + ", forced=" + forced + ", type=" + type + ']'; } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/LaneType.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/TrackType.java similarity index 78% rename from src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/LaneType.java rename to src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/TrackType.java index 36f18b3..462490c 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/LaneType.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/TrackType.java @@ -1,6 +1,6 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.model; -public enum LaneType { +public enum TrackType { AUDIO, SUBTITLES; } diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/converter/AttributeConfigConverterTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/converter/AttributeConfigConverterTest.java index 315004e..fe8b6f4 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/converter/AttributeConfigConverterTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/converter/AttributeConfigConverterTest.java @@ -1,5 +1,6 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.converter; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.converter.AttributeConfigConverter; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/BooleanConfigParameterTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/BooleanConfigParameterTest.java index 46ef8fb..9c5938e 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/BooleanConfigParameterTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/BooleanConfigParameterTest.java @@ -1,7 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields; import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/IntegerConfigParameterTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/IntegerConfigParameterTest.java index 6c0e8c7..eefeb1f 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/IntegerConfigParameterTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/IntegerConfigParameterTest.java @@ -1,15 +1,13 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields; import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import picocli.CommandLine; -import java.io.PrintWriter; -import java.io.StringWriter; import java.util.function.Function; import java.util.stream.Stream; diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/MkvToolNixPathConfigParameterTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/MkvToolNixPathConfigParameterTest.java index ddfd49a..0a37e1c 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/MkvToolNixPathConfigParameterTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/MkvToolNixPathConfigParameterTest.java @@ -1,7 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields; import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import org.apache.commons.lang3.SystemUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/PathConfigParameterTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/PathConfigParameterTest.java index bef4a85..82326fe 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/PathConfigParameterTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/PathConfigParameterTest.java @@ -1,7 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields; import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/PatternConfigParameterTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/PatternConfigParameterTest.java index d47f2de..64bce97 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/PatternConfigParameterTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/PatternConfigParameterTest.java @@ -1,7 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields; import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/SetConfigParameterTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/SetConfigParameterTest.java index 986f3be..2a7aab6 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/SetConfigParameterTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/fields/SetConfigParameterTest.java @@ -1,7 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields; import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilterTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilterTest.java index fd0e965..be83a65 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilterTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileFilterTest.java @@ -1,6 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic; import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.DateUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; @@ -16,7 +17,9 @@ import java.io.File; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.util.Date; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Stream; @@ -34,38 +37,44 @@ class FileFilterTest { @BeforeEach void beforeEach() { - + ResultStatistic.getInstance(true); } private static Stream accept() { return Stream.of( - Arguments.of("~/video.mkv", new String[]{".mkv"}, null, null, ".*", true), - Arguments.of("~/video.mp4", new String[]{".mkv"}, null, null, ".*", false), + Arguments.of("~/video.mkv", Set.of(".mkv"), -1, ".*", true, 1, 0), + Arguments.of("~/video.mp4", Set.of(".mkv"), -1, ".*", false, 0, 0), - Arguments.of("~/video.mkv", new String[]{".mkv"}, null, null, "v.*", true), - Arguments.of("~/video.mkv", new String[]{".mkv"}, null, null, "a.*", false), + Arguments.of("~/video.mkv", Set.of(".mkv"), -1, "v.*", true, 1, 0), + Arguments.of("~/video.mkv", Set.of(".mkv"), -1, "a.*", false, 1, 1), - Arguments.of("~/video.mkv", new String[]{".mkv"}, new Date(System.currentTimeMillis() - 1000), new Date(), ".*", false), - Arguments.of("~/video.mkv", new String[]{".mkv"}, new Date(), new Date(System.currentTimeMillis() - 1000), ".*", true) + Arguments.of("~/video.mkv", Set.of(".mkv"), -1000, ".*", true, 1, 0), + Arguments.of("~/video.mkv", Set.of(".mkv"), 1000, ".*", false, 1, 1) ); } + /** + * @param filterDateOffset move filter data into the future or past by positive and negative values + */ @ParameterizedTest @MethodSource - void accept(String path, String[] args, Date fileCreationDate, Date filterDate, String pattern, boolean expected) { + void accept(String path, Set args, int filterDateOffset, String pattern, boolean expectedHit, int total, int excluded) { when(file.getAbsolutePath()).thenReturn(path); when(file.getName()).thenReturn(List.of(path.split("/")).get(1)); when(file.toPath()).thenReturn(Path.of(TEST_FILE)); InputConfig.getInstance(true).setIncludePattern(Pattern.compile(pattern)); - if (filterDate != null) InputConfig.getInstance().setFilterDate(filterDate); + long currentTime = System.currentTimeMillis(); + InputConfig.getInstance().setFilterDate(new Date(currentTime + filterDateOffset)); try (MockedStatic mockedFiles = Mockito.mockStatic(DateUtils.class)) { mockedFiles .when(() -> DateUtils.convert(anyLong())) - .thenReturn(fileCreationDate); + .thenReturn(new Date(currentTime)); - assertEquals(expected, FileFilter.accept(file, args)); + assertEquals(expectedHit, FileFilter.accept(file, new HashSet<>(args)), "File is accepted"); + assertEquals(total, ResultStatistic.getInstance().getTotal(), "Total files"); + assertEquals(excluded, ResultStatistic.getInstance().getExcluded(), "Excluded files"); } } } \ No newline at end of file diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessorTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessorTest.java index 0539a3f..c92acac 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessorTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessorTest.java @@ -1,9 +1,11 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors.MkvFileProcessor; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -29,11 +31,12 @@ class MkvFileProcessorTest { @ParameterizedTest @MethodSource - void detectDesiredTracks(AttributeConfig expectedMatch, List tracks, AttributeConfig... configs) { + @Disabled + void detectDesiredTracks(AttributeConfig expectedMatch, List tracks, AttributeConfig... configs) { InputConfig.getInstance().setPreferredSubtitles(Set.of()); FileInfo info = new FileInfo(null); MkvFileProcessor processor = new MkvFileProcessor(); - processor.detectDesiredTracks(info, tracks, tracks, configs); +// processor.detectDesiredTracks(info, tracks, tracks, configs); assertEquals(expectedMatch.getAudioLanguage(), info.getMatchedConfig().getAudioLanguage()); assertEquals(expectedMatch.getSubtitleLanguage(), info.getMatchedConfig().getSubtitleLanguage()); } @@ -48,43 +51,4 @@ class MkvFileProcessorTest { Arguments.of(List.of(), List.of()) ); } - - @ParameterizedTest - @MethodSource - void retrieveNonForcedTracks(List attributes, List expected) { - InputConfig.getInstance().setPreferredSubtitles(Set.of()); - InputConfig.getInstance().setForcedKeywords(Set.of("forced")); - MkvFileProcessor processor = new MkvFileProcessor(); - List actual = processor.retrieveNonForcedTracks(attributes); - - assertEquals(expected.size(), actual.size()); - for (int i = 0; i < expected.size(); i++) { - assertEquals(expected.get(i), actual.get(i)); - } - } - - private static Stream retrieveNonCommentaryTracks() { - return Stream.of( - Arguments.of(List.of(SUB_GER, SUB_ENG, AUDIO_GER_COMMENTARY), List.of(SUB_GER, SUB_ENG)), - Arguments.of(List.of(SUB_GER, SUB_ENG), List.of(SUB_GER, SUB_ENG)), - Arguments.of(List.of(AUDIO_GER, SUB_GER, SUB_ENG), List.of(AUDIO_GER, SUB_GER, SUB_ENG)), - Arguments.of(List.of(AUDIO_GER), List.of(AUDIO_GER)), - Arguments.of(List.of(AUDIO_GER_COMMENTARY), List.of()), - Arguments.of(List.of(), List.of()) - ); - } - - @ParameterizedTest - @MethodSource - void retrieveNonCommentaryTracks(List attributes, List expected) { - InputConfig.getInstance().setPreferredSubtitles(Set.of()); - InputConfig.getInstance().setCommentaryKeywords(Set.of("commentary")); - MkvFileProcessor processor = new MkvFileProcessor(); - List actual = processor.retrieveNonCommentaryTracks(attributes); - - assertEquals(expected.size(), actual.size()); - for (int i = 0; i < expected.size(); i++) { - assertEquals(expected.get(i), actual.get(i)); - } - } } \ No newline at end of file diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/SubtitleTrackComparatorTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/SubtitleTrackComparatorTest.java index 3324395..8ff3b3c 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/SubtitleTrackComparatorTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/SubtitleTrackComparatorTest.java @@ -1,7 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackType; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -34,13 +34,13 @@ class SubtitleTrackComparatorTest { @ParameterizedTest @MethodSource("compareArguments") - void compare(List input, List expected) { - List result = input.stream().sorted(comparator.reversed()).collect(Collectors.toList()); + void compare(List input, List expected) { + List result = input.stream().sorted(comparator.reversed()).collect(Collectors.toList()); - assertArrayEquals(expected.toArray(new FileAttribute[0]), result.toArray(new FileAttribute[0])); + assertArrayEquals(expected.toArray(new TrackAttributes[0]), result.toArray(new TrackAttributes[0])); } - private static FileAttribute attr(String trackName, boolean defaultTrack) { - return new FileAttribute(0, "", trackName, defaultTrack, false, LaneType.SUBTITLES); + private static TrackAttributes attr(String trackName, boolean defaultTrack) { + return new TrackAttributes(0, "", trackName, defaultTrack, false, false, false, TrackType.SUBTITLES); } } \ No newline at end of file diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/AttributeProcessorTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/AttributeProcessorTest.java new file mode 100644 index 0000000..7402657 --- /dev/null +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/processors/AttributeProcessorTest.java @@ -0,0 +1,238 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.processors; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.InputConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes; +import org.apache.logging.log4j.util.Strings; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.FileInfoTestUtil.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class AttributeProcessorTest { + + private static Stream attributeConfigMatching() { + return Stream.of( + Arguments.of( + List.of(withName(AUDIO_ENG, null), SUB_ENG), + arr(a("eng:eng")), "eng:eng", + Map.ofEntries(on(withName(AUDIO_ENG, null)), on(SUB_ENG)) + ), + Arguments.of( + List.of(AUDIO_ENG, SUB_ENG), + arr(a("eng:eng")), "eng:eng", + Map.ofEntries(on(AUDIO_ENG), on(SUB_ENG)) + ), + Arguments.of( + List.of(AUDIO_ENG, AUDIO_GER, SUB_ENG, SUB_GER), + arr(a("eng:eng")), "eng:eng", + Map.ofEntries(on(AUDIO_ENG), on(SUB_ENG)) + ), + Arguments.of( + List.of(AUDIO_ENG_DEFAULT, AUDIO_GER, SUB_ENG, SUB_GER), + arr(a("ger:eng")), "ger:eng", + Map.ofEntries(off(AUDIO_ENG_DEFAULT), on(AUDIO_GER), on(SUB_ENG)) + ), + Arguments.of( + List.of(AUDIO_ENG_DEFAULT, AUDIO_GER, SUB_ENG, SUB_GER), + arr(a("eng:ger")), "eng:ger", + Map.ofEntries(on(SUB_GER)) + ), + Arguments.of( + List.of(AUDIO_ENG_DEFAULT, AUDIO_GER, SUB_ENG_DEFAULT, SUB_GER), + arr(a("eng:OFF")), "eng:OFF", + Map.ofEntries(off(SUB_ENG_DEFAULT)) + ), + Arguments.of( + List.of(AUDIO_ENG_DEFAULT, AUDIO_GER, SUB_ENG_DEFAULT, SUB_GER), + arr(a("OFF:OFF")), "OFF:OFF", + Map.ofEntries(off(AUDIO_ENG_DEFAULT), off(SUB_ENG_DEFAULT)) + ), + Arguments.of( + List.of(AUDIO_ENG_DEFAULT, AUDIO_GER, SUB_GER), + arr(a("eng:eng"), a("eng:ger")), "eng:ger", + Map.ofEntries(on(SUB_GER)) + ) + ); + } + + @ParameterizedTest + @MethodSource("attributeConfigMatching") + void findDefaultMatchAndApplyChanges(List tracks, AttributeConfig[] config, String expectedConfig, Map changes) { + InputConfig.getInstance().setPreferredSubtitles(new HashSet<>()); + InputConfig.getInstance().setCommentaryKeywords(new HashSet<>()); + InputConfig.getInstance().setForcedKeywords(new HashSet<>()); + + FileInfo fileInfo = new FileInfo(null); + fileInfo.addTracks(tracks); + AttributeProcessor.findDefaultMatchAndApplyChanges(fileInfo, config); + assertEquals(Strings.isBlank(expectedConfig), fileInfo.getMatchedConfig() == null); + assertEquals(expectedConfig, fileInfo.getMatchedConfig().toStringShort()); + assertEquals(changes.size(), fileInfo.getChanges().getDefaultTrack().size()); + changes.forEach((key, value) -> { + assertTrue(fileInfo.getChanges().getDefaultTrack().containsKey(key)); + assertEquals(value, fileInfo.getChanges().getDefaultTrack().get(key)); + }); + } + + private static AttributeConfig[] arr(AttributeConfig... configs) { + return configs; + } + + private static AttributeConfig a(String config) { + String[] split = config.split(":"); + return new AttributeConfig(split[0], split[1]); + } + + private static Map.Entry on(TrackAttributes track) { + return Map.entry(track, true); + } + + private static Map.Entry off(TrackAttributes track) { + return Map.entry(track, false); + } + + private static Stream filterForPossibleDefaults() { + return Stream.of( + + ); + } + + @ParameterizedTest + @MethodSource("filterForPossibleDefaults") + void filterForPossibleDefaults(List tracks, Set expected) { + + } + + private static Stream findForcedTracksAndApplyChanges() { + return Stream.of( + Arguments.of(List.of(withName(SUB_GER, "song & signs"), withName(SUB_GER, null)), + Set.of("song & signs"), false, + Map.ofEntries(on(withName(SUB_GER, "song & signs"))) + ), + Arguments.of(List.of(withName(SUB_GER, "song & signs")), + Set.of("song & signs"), false, + Map.ofEntries(on(withName(SUB_GER, "song & signs"))) + ), + Arguments.of(List.of(withName(SUB_GER_FORCED, "song & signs")), + Set.of("song & signs"), false, + Map.ofEntries() + ), + Arguments.of(List.of(SUB_GER_FORCED, withName(SUB_GER, "song & signs")), + Set.of("song & signs"), true, + Map.ofEntries(off(SUB_GER_FORCED), on(withName(SUB_GER, "song & signs"))) + ) + ); + } + + @ParameterizedTest + @MethodSource("findForcedTracksAndApplyChanges") + void findForcedTracksAndApplyChanges(List tracks, Set keywords, boolean overwrite, Map changes) { + InputConfig.getInstance().setPreferredSubtitles(new HashSet<>()); + InputConfig.getInstance().setCommentaryKeywords(new HashSet<>()); + InputConfig.getInstance().setHearingImpaired(new HashSet<>()); + InputConfig.getInstance().setForcedKeywords(keywords); + InputConfig.getInstance().setOverwriteForced(overwrite); + + FileInfo fileInfo = new FileInfo(null); + fileInfo.addTracks(tracks); + AttributeProcessor.findForcedTracksAndApplyChanges(fileInfo); + + assertEquals(changes.size(), fileInfo.getChanges().getForcedTrack().size()); + changes.forEach((key, value) -> { + assertTrue(fileInfo.getChanges().getForcedTrack().containsKey(key)); + assertEquals(value, fileInfo.getChanges().getForcedTrack().get(key)); + }); + } + + private static Stream findCommentaryTracksAndApplyChanges() { + return Stream.of( + Arguments.of(List.of(withName(SUB_GER, "commentary"), withName(SUB_GER, null)), + Set.of("commentary"), + Map.ofEntries(on(withName(SUB_GER, "commentary"))) + ), + Arguments.of(List.of(withName(SUB_GER, "commentary")), + Set.of("commentary"), + Map.ofEntries(on(withName(SUB_GER, "commentary"))) + ), + Arguments.of(List.of(withName(AUDIO_GER_COMMENTARY, "commentary")), + Set.of("commentary"), + Map.ofEntries() + ), + Arguments.of(List.of(AUDIO_GER_COMMENTARY, withName(SUB_GER, "commentary")), + Set.of("commentary"), + Map.ofEntries(on(withName(SUB_GER, "commentary"))) + ) + ); + } + + @ParameterizedTest + @MethodSource("findCommentaryTracksAndApplyChanges") + void findCommentaryTracksAndApplyChanges(List tracks, Set keywords, Map changes) { + InputConfig.getInstance().setPreferredSubtitles(new HashSet<>()); + InputConfig.getInstance().setCommentaryKeywords(keywords); + InputConfig.getInstance().setHearingImpaired(new HashSet<>()); + InputConfig.getInstance().setForcedKeywords(new HashSet<>()); + + FileInfo fileInfo = new FileInfo(null); + fileInfo.addTracks(tracks); + AttributeProcessor.findCommentaryTracksAndApplyChanges(fileInfo); + + assertEquals(changes.size(), fileInfo.getChanges().getCommentaryTrack().size()); + changes.forEach((key, value) -> { + assertTrue(fileInfo.getChanges().getCommentaryTrack().containsKey(key)); + assertEquals(value, fileInfo.getChanges().getCommentaryTrack().get(key)); + }); + } + + private static Stream findHearingImpairedTracksAndApplyChanges() { + return Stream.of( + Arguments.of(List.of(withName(SUB_GER, "SDH"), withName(SUB_GER, null)), + Set.of("SDH"), + Map.ofEntries(on(withName(SUB_GER, "SDH"))) + ), + Arguments.of(List.of(withName(SUB_GER, "SDH")), + Set.of("SDH"), + Map.ofEntries(on(withName(SUB_GER, "SDH"))) + ), + Arguments.of(List.of(withName(AUDIO_GER_COMMENTARY, "SDH")), + Set.of("SDH"), + Map.ofEntries() + ), + Arguments.of(List.of(AUDIO_GER_HEARING, withName(SUB_GER, "SDH")), + Set.of("SDH"), + Map.ofEntries(on(withName(SUB_GER, "SDH"))) + ) + ); + } + + @ParameterizedTest + @MethodSource("findCommentaryTracksAndApplyChanges") + void findHearingImpairedTracksAndApplyChanges(List tracks, Set keywords, Map changes) { + InputConfig.getInstance().setPreferredSubtitles(new HashSet<>()); + InputConfig.getInstance().setCommentaryKeywords(new HashSet<>()); + InputConfig.getInstance().setHearingImpaired(keywords); + InputConfig.getInstance().setForcedKeywords(new HashSet<>()); + + FileInfo fileInfo = new FileInfo(null); + fileInfo.addTracks(tracks); + AttributeProcessor.findHearingImpairedTracksAndApplyChanges(fileInfo); + + assertEquals(changes.size(), fileInfo.getChanges().getHearingImpairedTrack().size()); + changes.forEach((key, value) -> { + assertTrue(fileInfo.getChanges().getHearingImpairedTrack().containsKey(key)); + assertEquals(value, fileInfo.getChanges().getHearingImpairedTrack().get(key)); + }); + } +} \ No newline at end of file diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoTest.java index 425d415..72ee92a 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import java.nio.file.attribute.FileAttribute; import java.util.Set; import java.util.stream.Stream; @@ -14,67 +15,11 @@ import static org.junit.jupiter.api.Assertions.*; class FileInfoTest { - private static Stream isAudioDifferent() { - return Stream.of( - Arguments.of(createFileInfoAudio(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, new AttributeConfig("ger", "")), false), - Arguments.of(createFileInfoAudio(Set.of(AUDIO_GER_DEFAULT), AUDIO_ENG, new AttributeConfig("eng", "")), true), - Arguments.of(createFileInfoAudio(Set.of(AUDIO_GER_DEFAULT, AUDIO_ENG_DEFAULT), AUDIO_GER_DEFAULT, new AttributeConfig("ger", "")), true), - Arguments.of(createFileInfoAudio(Set.of(), AUDIO_GER, new AttributeConfig("ger", "")), true), - Arguments.of(createFileInfoAudio(null, AUDIO_GER, new AttributeConfig("ger", "")), true), - - Arguments.of(createFileInfoAudio(Set.of(AUDIO_GER_DEFAULT), null, new AttributeConfig("OFF", "")), true), - Arguments.of(createFileInfoAudio(Set.of(), null, new AttributeConfig("OFF", "")), false), - Arguments.of(createFileInfoAudio(null, null, new AttributeConfig("OFF", "")), false) - ); - } - - @ParameterizedTest - @MethodSource - void isAudioDifferent(FileInfo underTest, boolean expected) { - assertEquals(expected, underTest.isAudioDifferent()); - } - - private static Stream isSubtitleDifferent() { - return Stream.of( - Arguments.of(createFileInfoSubs(Set.of(SUB_GER_DEFAULT), SUB_GER_DEFAULT, new AttributeConfig("", "ger")), false), - Arguments.of(createFileInfoSubs(Set.of(SUB_GER_DEFAULT), SUB_ENG, new AttributeConfig("", "eng")), true), - Arguments.of(createFileInfoSubs(Set.of(SUB_GER_DEFAULT, SUB_ENG_DEFAULT), SUB_ENG, new AttributeConfig("", "eng")), true), - Arguments.of(createFileInfoSubs(Set.of(), SUB_ENG, new AttributeConfig("", "ger")), true), - Arguments.of(createFileInfoSubs(null, SUB_GER, new AttributeConfig("", "ger")), true), - Arguments.of(createFileInfoSubs(null, null, new AttributeConfig("", "OFF")), false), - Arguments.of(createFileInfoSubs(Set.of(), null, new AttributeConfig("", "OFF")), false), - Arguments.of(createFileInfoSubs(Set.of(SUB_GER_DEFAULT), null, new AttributeConfig("", "OFF")), true) - ); - } - - @ParameterizedTest - @MethodSource - void isSubtitleDifferent(FileInfo underTest, boolean expected) { - assertEquals(expected, underTest.isSubtitleDifferent()); - } - private static Stream getStatus() { return Stream.of( - Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_ENG, Set.of(), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("eng", "OFF"))), - Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(), null, Set.of(SUB_GER_DEFAULT), SUB_ENG, Set.of(), Set.of(), Set.of(), new AttributeConfig("OFF", "eng"))), - Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_ENG, Set.of(SUB_GER_DEFAULT), SUB_ENG, Set.of(), Set.of(), Set.of(), new AttributeConfig("OFF", "eng"))), - Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, Set.of(SUB_GER_DEFAULT), SUB_GER_DEFAULT, Set.of(AUDIO_ENG_FORCED), Set.of(), Set.of(), new AttributeConfig("ger", "ger"))), - Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(), null, Set.of(), null, Set.of(AUDIO_ENG_FORCED), Set.of(), Set.of(), new AttributeConfig("OFF", "OFF"))), - Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(), null, Set.of(), null, Set.of(), Set.of(), Set.of(SUB_GER_FORCED), new AttributeConfig("OFF", "OFF"))), - Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(), null, Set.of(), null, Set.of(), Set.of(SUB_ENG_FORCED), Set.of(SUB_GER_FORCED), new AttributeConfig("OFF", "OFF"))), - Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(), null, Set.of(), null, Set.of(AUDIO_ENG_FORCED), Set.of(SUB_ENG_FORCED), Set.of(SUB_GER_FORCED), new AttributeConfig("OFF", "OFF"))), - Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_ENG, Set.of(SUB_GER_DEFAULT), SUB_ENG, Set.of(AUDIO_ENG_FORCED), Set.of(SUB_ENG_FORCED), Set.of(SUB_GER_FORCED), new AttributeConfig("eng", "eng"))), - Arguments.of(CHANGE_NECESSARY, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, Set.of(SUB_GER_DEFAULT), SUB_GER_DEFAULT, Set.of(), Set.of(SUB_ENG_FORCED), Set.of(SUB_ENG_FORCED, SUB_GER), new AttributeConfig("ger", "ger"))), - - Arguments.of(NO_SUITABLE_CONFIG, createFileInfo(Set.of(AUDIO_ENG_DEFAULT), null, Set.of(SUB_GER_DEFAULT), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("eng", "ger"))), - Arguments.of(NO_SUITABLE_CONFIG, createFileInfo(Set.of(AUDIO_ENG_DEFAULT), null, Set.of(), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("eng", "ger"))), - Arguments.of(NO_SUITABLE_CONFIG, createFileInfo(Set.of(), null, Set.of(), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("eng", "ger"))), - - Arguments.of(ALREADY_SUITED, createFileInfo(Set.of(), null, Set.of(), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("OFF", "OFF"))), - Arguments.of(ALREADY_SUITED, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, Set.of(), null, Set.of(), Set.of(), Set.of(), new AttributeConfig("ger", "OFF"))), - Arguments.of(ALREADY_SUITED, createFileInfo(Set.of(), null, Set.of(SUB_ENG_DEFAULT), SUB_ENG_DEFAULT, Set.of(), Set.of(), Set.of(), new AttributeConfig("OFF", "ger"))), - Arguments.of(ALREADY_SUITED, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, Set.of(SUB_ENG_DEFAULT), SUB_ENG_DEFAULT, Set.of(), Set.of(), Set.of(), new AttributeConfig("ger", "eng"))), - Arguments.of(ALREADY_SUITED, createFileInfo(Set.of(AUDIO_GER_DEFAULT), AUDIO_GER_DEFAULT, Set.of(SUB_ENG_DEFAULT), SUB_ENG_DEFAULT, Set.of(), Set.of(SUB_GER_FORCED), Set.of(SUB_GER_FORCED), new AttributeConfig("ger", "eng"))) + Arguments.of(CHANGE_NECESSARY, info(new AttributeConfig("ger", "ger"), AUDIO_GER)), + Arguments.of(ALREADY_SUITED, info(new AttributeConfig("ger", "ger"), null)), + Arguments.of(NO_SUITABLE_CONFIG, info(null, null)) ); } @@ -84,4 +29,11 @@ class FileInfoTest { FileStatus actual = underTest.getStatus(); assertEquals(expected, actual); } + + private static FileInfo info(AttributeConfig config, TrackAttributes attr) { + FileInfo fileInfo = new FileInfo(null); + fileInfo.setMatchedConfig(config); + if(attr != null) fileInfo.getChanges().getDefaultTrack().put(attr, true); + return fileInfo; + } } \ No newline at end of file diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/InputConfigTest.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfigTest.java similarity index 93% rename from src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/InputConfigTest.java rename to src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfigTest.java index 68885b6..bdc0652 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/config/InputConfigTest.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/InputConfigTest.java @@ -1,8 +1,7 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.config; +package at.pcgamingfreaks.mkvaudiosubtitlechanger.model; import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation.ValidationExecutionStrategy; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.validation.ValidationExecutionStrategy; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/FileInfoTestUtil.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/FileInfoTestUtil.java index b54262b..303261b 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/FileInfoTestUtil.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/FileInfoTestUtil.java @@ -1,22 +1,28 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.util; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackAttributes; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.TrackType; public class FileInfoTestUtil { - public static final FileAttribute AUDIO_GER_DEFAULT = new FileAttribute(0, "ger", "", true, false, LaneType.AUDIO); - public static final FileAttribute AUDIO_ENG_DEFAULT = new FileAttribute(1, "eng", "", true, false, LaneType.AUDIO); - public static final FileAttribute AUDIO_GER = new FileAttribute(0, "ger", "", false, false, LaneType.AUDIO); - public static final FileAttribute AUDIO_ENG = new FileAttribute(1, "eng", "", false, false, LaneType.AUDIO); - public static final FileAttribute AUDIO_GER_FORCED = new FileAttribute(0, "ger", "", false, true, LaneType.AUDIO); - public static final FileAttribute AUDIO_ENG_FORCED = new FileAttribute(1, "eng", "", false, true, LaneType.AUDIO); - public static final FileAttribute AUDIO_GER_COMMENTARY = new FileAttribute(1, "ger", "commentary", false, false, LaneType.AUDIO); - public static final FileAttribute AUDIO_ENG_COMMENTARY = new FileAttribute(1, "eng", "commentary", false, false, LaneType.AUDIO); + public static final TrackAttributes AUDIO_GER_DEFAULT = new TrackAttributes(0, "ger", "", true, false, false, false, TrackType.AUDIO); + public static final TrackAttributes AUDIO_ENG_DEFAULT = new TrackAttributes(1, "eng", "", true, false, false, false, TrackType.AUDIO); + public static final TrackAttributes AUDIO_GER = new TrackAttributes(0, "ger", "", false, false, false, false, TrackType.AUDIO); + public static final TrackAttributes AUDIO_ENG = new TrackAttributes(1, "eng", "", false, false, false, false, TrackType.AUDIO); + public static final TrackAttributes AUDIO_GER_FORCED = new TrackAttributes(0, "ger", "", false, true, false, false, TrackType.AUDIO); + public static final TrackAttributes AUDIO_ENG_FORCED = new TrackAttributes(1, "eng", "", false, true, false, false, TrackType.AUDIO); + public static final TrackAttributes AUDIO_GER_COMMENTARY = new TrackAttributes(0, "ger", "", false, false, true, false, TrackType.AUDIO); + public static final TrackAttributes AUDIO_ENG_COMMENTARY = new TrackAttributes(1, "eng", "", false, false, true, false, TrackType.AUDIO); + public static final TrackAttributes AUDIO_GER_HEARING = new TrackAttributes(0, "ger", "", false, false, false, true, TrackType.AUDIO); + public static final TrackAttributes AUDIO_ENG_HEARING = new TrackAttributes(1, "ger", "", false, false, false, true, TrackType.AUDIO); - public static final FileAttribute SUB_GER_DEFAULT = new FileAttribute(0, "ger", "", true, false, LaneType.SUBTITLES); - public static final FileAttribute SUB_ENG_DEFAULT = new FileAttribute(1, "eng", "", true, false, LaneType.SUBTITLES); - public static final FileAttribute SUB_GER = new FileAttribute(0, "ger", "", false, false, LaneType.SUBTITLES); - public static final FileAttribute SUB_ENG = new FileAttribute(1, "eng", "", false, false, LaneType.SUBTITLES); - public static final FileAttribute SUB_GER_FORCED = new FileAttribute(0, "ger", "", false, true, LaneType.SUBTITLES); - public static final FileAttribute SUB_ENG_FORCED = new FileAttribute(1, "eng", "", false, true, LaneType.SUBTITLES); + public static final TrackAttributes SUB_GER_DEFAULT = new TrackAttributes(0, "ger", "", true, false, false, false, TrackType.SUBTITLES); + public static final TrackAttributes SUB_ENG_DEFAULT = new TrackAttributes(1, "eng", "", true, false, false, false, TrackType.SUBTITLES); + public static final TrackAttributes SUB_GER = new TrackAttributes(0, "ger", "", false, false, false, false, TrackType.SUBTITLES); + public static final TrackAttributes SUB_ENG = new TrackAttributes(1, "eng", "", false, false, false, false, TrackType.SUBTITLES); + public static final TrackAttributes SUB_GER_FORCED = new TrackAttributes(0, "ger", "", false, true, false, false, TrackType.SUBTITLES); + public static final TrackAttributes SUB_ENG_FORCED = new TrackAttributes(1, "eng", "", false, true, false, false, TrackType.SUBTITLES); + + public static TrackAttributes withName(TrackAttributes track, String trackName) { + return new TrackAttributes(track.id(), track.language(), trackName, track.defaultt(), track.forced(), track.commentary(), track.hearingImpaired(), track.type()); + } } diff --git a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/TestUtil.java b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/TestUtil.java index fddc343..f0c665c 100644 --- a/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/TestUtil.java +++ b/src/test/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/util/TestUtil.java @@ -1,46 +1,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.util; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfo; - -import java.util.Set; - public class TestUtil { - public static FileInfo createFileInfoAudio(Set defaultAudio, FileAttribute desiredAudio, AttributeConfig config) { - FileInfo fileInfo = new FileInfo(null); - fileInfo.setExistingDefaultAudioLanes(defaultAudio); - fileInfo.setDesiredDefaultAudioLane(desiredAudio); - fileInfo.setMatchedConfig(config); - return fileInfo; - } - - public static FileInfo createFileInfoSubs(Set defaultSubtitle, FileAttribute desiredSubtitle, AttributeConfig config) { - FileInfo fileInfo = new FileInfo(null); - fileInfo.setExistingDefaultSubtitleLanes(defaultSubtitle); - fileInfo.setDesiredDefaultSubtitleLane(desiredSubtitle); - fileInfo.setMatchedConfig(config); - return fileInfo; - } - - public static FileInfo createFileInfo(Set defaultAudio, FileAttribute desiredAudio, - Set defaultSubtitle, FileAttribute desiredSubtitle, - Set existingForcedAudioLanes, - Set existingForcedSubs, Set desiredForcedSubs, - AttributeConfig matchedConfig) { - FileInfo fileInfo = new FileInfo(null); - fileInfo.setExistingDefaultAudioLanes(defaultAudio); - fileInfo.setDesiredDefaultAudioLane(desiredAudio); - fileInfo.setExistingDefaultSubtitleLanes(defaultSubtitle); - fileInfo.setDesiredDefaultSubtitleLane(desiredSubtitle); - fileInfo.setExistingForcedAudioLanes(existingForcedAudioLanes); - fileInfo.setExistingForcedSubtitleLanes(existingForcedSubs); - fileInfo.setDesiredForcedSubtitleLanes(desiredForcedSubs); - fileInfo.setMatchedConfig(matchedConfig); - return fileInfo; - } - public static String[] args(String... args) { String[] staticArray = new String[]{"-l", "/", "-a", "jpn:ger"}; String[] result = new String[staticArray.length + args.length];