diff --git a/pom.xml b/pom.xml index fc17d43..e7ae762 100644 --- a/pom.xml +++ b/pom.xml @@ -149,6 +149,11 @@ commons-cli 1.5.0 + + org.apache.commons + commons-lang3 + 3.12.0 + diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java index 1663935..42883d9 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/AttributeUpdaterKernel.java @@ -1,10 +1,12 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.intimpl.ConfigProcessor; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.intimpl.MkvFileCollector; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.ConfigProcessorOld; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto; import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2; @@ -16,19 +18,30 @@ import java.util.concurrent.*; public class AttributeUpdaterKernel { ExecutorService executor = Executors.newFixedThreadPool(Config.getInstance().getThreadCount()); - MkvFileCollector collector = new MkvFileCollector(); + FileCollector collector; + FileProcessor processor; int filesChangedAmount = 0; int filesNotChangedAmount = 0; long runtime = 0; + public AttributeUpdaterKernel(FileCollector collector, FileProcessor processor) { + this.collector = collector; + this.processor = processor; + } + @SneakyThrows public void execute() { long beforeTimer = System.currentTimeMillis(); - collector.loadFiles(Config.getInstance().getLibraryPath()) - .forEach(file -> executor.submit(() -> process(file))); + + + List files = collector.loadFiles(Config.getInstance().getLibraryPath()); + files.forEach(file -> executor.submit(() -> process(file))); executor.shutdown(); executor.awaitTermination(1, TimeUnit.DAYS); + + + runtime = System.currentTimeMillis() - beforeTimer; System.out.printf("%nFiles %schanged: %s%n", @@ -40,13 +53,13 @@ public class AttributeUpdaterKernel { System.out.printf("Runtime: %ss%n", runtime / 1000); } - private void process(File file) { - List attributes = collector.loadAttributes(file); + private void processOld(File file) { + List attributes = processor.loadAttributes(file); boolean fileHasChanged = false; if (attributes.isEmpty()) return; for(AttributeConfig config : Config.getInstance().getAttributeConfig()){ - fileHasChanged = new ConfigProcessor(config).processConfig(file, attributes); + fileHasChanged = new ConfigProcessorOld(config).processConfig(file, attributes); if(fileHasChanged) break; } if(!fileHasChanged){ @@ -57,4 +70,12 @@ public class AttributeUpdaterKernel { } System.out.print("."); } + + private void process(File file) { + List attributes = processor.loadAttributes(file); + FileInfoDto fileInfo = processor.filterAttributes(attributes); + if (fileInfo.isChangeNecessary() && !Config.getInstance().isSafeMode()) { + processor.update(file, fileInfo); + } + } } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java index 8b1932c..e99e7e6 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/Main.java @@ -1,6 +1,8 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger; import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileCollector; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileProcessor; import lombok.extern.log4j.Log4j2; import org.apache.commons.cli.*; @@ -10,7 +12,7 @@ import static java.lang.Integer.parseInt; public class Main { public static void main(String[] args) { initConfig(args); - AttributeUpdaterKernel kernel = new AttributeUpdaterKernel(); + AttributeUpdaterKernel kernel = new AttributeUpdaterKernel(new MkvFileCollector(), new MkvFileProcessor()); kernel.execute(); } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/intimpl/ConfigProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/ConfigProcessorOld.java similarity index 94% rename from src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/intimpl/ConfigProcessor.java rename to src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/ConfigProcessorOld.java index 9b31f3b..44c2dab 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/intimpl/ConfigProcessor.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/ConfigProcessorOld.java @@ -1,4 +1,4 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.intimpl; +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; @@ -17,12 +17,12 @@ import java.util.List; import static java.lang.String.format; @Log4j2 -public class ConfigProcessor { +public class ConfigProcessorOld { private int audioDefault = - 1; private int subtitleDefault = - 1; private final AttributeConfig config; - public ConfigProcessor(AttributeConfig config) { + public ConfigProcessorOld(AttributeConfig config) { this.config = config; } @@ -59,22 +59,22 @@ public class ConfigProcessor { if(elem.isDefaultTrack()){ audioDefault = elem.getId(); } - if(config.getAudio().contains("OFF")){ + if(config.getAudioLanguage().contains("OFF")){ transfer.setAudioOn(false); transfer.setAudioIndex(- 2); } - if(! config.getAudio().contains(elem.getLanguage())){ + if(! config.getAudioLanguage().contains(elem.getLanguage())){ iterator.remove(); } }else if("subtitles".equals(elem.getType())){ if(elem.isDefaultTrack()){ subtitleDefault = elem.getId(); } - if(config.getSubtitle().contains("OFF")){ + if(config.getSubtitleLanguage().contains("OFF")){ transfer.setSubtitleOn(false); transfer.setSubtitleIndex(- 2); } - if(! config.getSubtitle().contains(elem.getLanguage())){ + if(! config.getSubtitleLanguage().contains(elem.getLanguage())){ iterator.remove(); } } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileCollector.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileCollector.java new file mode 100644 index 0000000..d60ac8b --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileCollector.java @@ -0,0 +1,13 @@ +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); +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileProcessor.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileProcessor.java new file mode 100644 index 0000000..5175e3e --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/FileProcessor.java @@ -0,0 +1,20 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto; + +import java.io.File; +import java.util.List; + +public interface FileProcessor { + + /** + * @param file Takes the file from which the attributes will be returned + * @return list of all important attributes + */ + List loadAttributes(File file); + + FileInfoDto filterAttributes(List attributes); + + void update(File file, FileInfoDto fileInfo); +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileCollector.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileCollector.java new file mode 100644 index 0000000..6de706b --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileCollector.java @@ -0,0 +1,40 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; + +import lombok.extern.log4j.Log4j2; + +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; + +@Log4j2 +public class MkvFileCollector implements FileCollector { + + @Override + public List loadFiles(String path) { + File file = new File(path); + if (file.isFile() && file.getAbsolutePath().endsWith(".mkv")) { + return new ArrayList() {{ + add(file); + }}; + } else if (file.isDirectory()) { + try (Stream paths = Files.walk(Paths.get(path))) { + return paths + .filter(Files::isRegularFile) + .map(Path::toFile) + .filter(f -> f.getAbsolutePath().endsWith(".mkv")) + .collect(Collectors.toList()); + } catch (IOException e) { + log.error("Couldn't find file or directory!", e); + return new ArrayList<>(); + } + } else { + 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 new file mode 100644 index 0000000..c13eb1c --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/impl/MkvFileProcessor.java @@ -0,0 +1,100 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl; + +import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config; +import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.*; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.log4j.Log4j2; +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType.AUDIO; +import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType.SUBTITLES; + +@Log4j2 +public class MkvFileProcessor implements FileProcessor { + private final ObjectMapper mapper = new ObjectMapper(); + + @Override + public List loadAttributes(File file) { + Map jsonMap; + List fileAttributes = new ArrayList<>(); + try { + String command = String.format("\"%s\"", Config.getInstance().getPathFor(MkvToolNix.MKV_MERGER)); + String[] arguments = new String[]{ + command, + "--identify", + "--identification-format", + "json", + file.getAbsoluteFile().toString() + }; + + InputStream inputStream = Runtime.getRuntime().exec(arguments).getInputStream(); + jsonMap = mapper.readValue(inputStream, Map.class); + List> tracks = (List>) jsonMap.get("tracks"); + if (tracks == null) { + log.warn("Couldn't retrieve information of {}", file.getAbsoluteFile().toString()); + 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)))); + } + } + } catch (IOException e) { + e.printStackTrace(); + log.error("File could not be found or loaded!"); + } + return fileAttributes; + } + + @Override + public FileInfoDto filterAttributes(List attributes) { + FileInfoDto info = new FileInfoDto(); + for (FileAttribute attribute: attributes) { + if (attribute.isDefaultTrack() && AUDIO.equals(attribute.getType())) info.setDefaultAudioLane(attribute); + if (attribute.isForcedTrack() && AUDIO.equals(attribute.getType())) info.setForcedAudioLane(attribute); + + if (attribute.isDefaultTrack() && SUBTITLES.equals(attribute.getType())) info.setDefaultSubtitleLane(attribute); + if (attribute.isForcedTrack() && SUBTITLES.equals(attribute.getType())) info.setForcedSubtitleLane(attribute); + } + List nonForcedTracks = attributes.stream() + .filter(elem -> !StringUtils.containsIgnoreCase(elem.getTrackName(), "forced")) + .collect(Collectors.toList()); + for (AttributeConfig config: Config.getInstance().getAttributeConfig()) { + FileAttribute desiredAudio = null; + FileAttribute desiredSubtitle = null; + for (FileAttribute attribute: nonForcedTracks) { + if ( attribute.getLanguage().equals(config.getAudioLanguage()) + && AUDIO.equals(attribute.getType())) desiredAudio = attribute; + if ( attribute.getLanguage().equals(config.getSubtitleLanguage()) + && SUBTITLES.equals(attribute.getType())) desiredSubtitle = attribute; + } + if (desiredAudio != null && desiredSubtitle != null) { + info.setDesiredAudioLane(desiredAudio); + info.setDesiredSubtitleLane(desiredSubtitle); + break; + } + } + return info; + } + + @Override + public void update(File file, FileInfoDto fileInfo) { + + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/intimpl/FileCollector.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/intimpl/FileCollector.java deleted file mode 100644 index b369067..0000000 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/intimpl/FileCollector.java +++ /dev/null @@ -1,12 +0,0 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.intimpl; - -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; - -import java.io.File; -import java.util.List; - -public interface FileCollector { - List loadFiles(String path); - - List loadAttributes(File file); -} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/intimpl/MkvFileCollector.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/intimpl/MkvFileCollector.java deleted file mode 100644 index f83dd57..0000000 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/intimpl/MkvFileCollector.java +++ /dev/null @@ -1,95 +0,0 @@ -package at.pcgamingfreaks.mkvaudiosubtitlechanger.intimpl; - -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config; -import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.extern.log4j.Log4j2; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -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.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -@Log4j2 -public class MkvFileCollector implements FileCollector { - private final ObjectMapper mapper = new ObjectMapper(); - - /** - * @param path Is entered path, which leads to one file directly or a directory which will be loaded recursive - * @return list of all files within the directory, if it's only a file, the file will be returned in a list - */ - @Override - public List loadFiles(String path) { - File file = new File(path); - if (file.isFile() && file.getAbsolutePath().endsWith(".mkv")) { - return new ArrayList() {{ - add(file); - }}; - } else if (file.isDirectory()) { - try (Stream paths = Files.walk(Paths.get(path))) { - return paths - .filter(Files::isRegularFile) - .map(Path::toFile) - .filter(f -> f.getAbsolutePath().endsWith(".mkv")) - .collect(Collectors.toList()); - } catch (IOException e) { - log.error("Couldn't find file or directory!", e); - return new ArrayList<>(); - } - } else { - return new ArrayList<>(); - } - } - - /** - * @param file Takes the file from which the attributes will be returned - * @return list of all important attributes - */ - @Override - public List loadAttributes(File file) { - Map jsonMap; - List fileAttributes = new ArrayList<>(); - try { - String command = String.format("\"%s\"", Config.getInstance().getPathFor(MkvToolNix.MKV_MERGER)); - String[] array = new String[]{ - command, - "--identify", - "--identification-format", - "json", - file.getAbsoluteFile().toString() - }; - - InputStream inputStream = Runtime.getRuntime().exec(array).getInputStream(); - jsonMap = mapper.readValue(inputStream, Map.class); - List> tracks = (List>) jsonMap.get("tracks"); - if (tracks == null) { - log.warn("Couldn't retrieve information of {}", file.getAbsoluteFile().toString()); - 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), - (String) attribute.get("type"))); - } - } - } catch (IOException e) { - e.printStackTrace(); - log.error("File could not be found or loaded!"); - } - return fileAttributes; - } -} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/AttributeConfig.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/AttributeConfig.java index 354a6d4..2849946 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/AttributeConfig.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/AttributeConfig.java @@ -3,29 +3,26 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.model; import lombok.Getter; import lombok.extern.log4j.Log4j2; -import java.util.List; -import java.util.stream.Collectors; - @Log4j2 @Getter public class AttributeConfig { - private String audio; - private String subtitle; + private String audioLanguage; + private String subtitleLanguage; - public AttributeConfig(String audio, String subtitle) { - this.audio = audio; - this.subtitle = subtitle; + public AttributeConfig(String audioLanguage, String subtitleLanguage) { + this.audioLanguage = audioLanguage; + this.subtitleLanguage = subtitleLanguage; } public boolean isValid() { - return audio != null && subtitle != null; + return audioLanguage != null && subtitleLanguage != null; } @Override public String toString() { final StringBuffer sb = new StringBuffer("AttributeConfig{"); - sb.append("audio='").append(audio).append('\''); - sb.append(", subtitle='").append(subtitle).append('\''); + sb.append("audioLanguage='").append(audioLanguage).append('\''); + sb.append(", subtitleLanguage='").append(subtitleLanguage).append('\''); sb.append('}'); return sb.toString(); } diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java index 28a50f4..0932c0c 100644 --- a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileAttribute.java @@ -20,9 +20,10 @@ public class FileAttribute { private String trackName; private boolean defaultTrack; private boolean forcedTrack; - private String type; + private LaneType type; - public FileAttribute(int id, String language, String trackName, boolean defaultTrack, boolean forcedTrack, String type) { + public FileAttribute(int id, String language, String trackName, boolean defaultTrack, boolean forcedTrack, + LaneType type) { this.id = id; this.language = language; this.trackName = trackName; diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoDto.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoDto.java new file mode 100644 index 0000000..9b8592e --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/FileInfoDto.java @@ -0,0 +1,20 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.model; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class FileInfoDto { + private FileAttribute defaultAudioLane; + private FileAttribute defaultSubtitleLane; + private FileAttribute forcedAudioLane; + private FileAttribute forcedSubtitleLane; + private FileAttribute desiredAudioLane; + private FileAttribute desiredSubtitleLane; + + public boolean isChangeNecessary() { + return defaultAudioLane.getId() != desiredAudioLane.getId() + || defaultSubtitleLane.getId() != desiredSubtitleLane.getId(); + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/LaneType.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/LaneType.java new file mode 100644 index 0000000..0145370 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/LaneType.java @@ -0,0 +1,14 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.model; + +public enum LaneType { + AUDIO, + SUBTITLES; + + LaneType() { + } + + @Override + public String toString() { + return name(); + } +} diff --git a/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java new file mode 100644 index 0000000..8c354f0 --- /dev/null +++ b/src/main/java/at/pcgamingfreaks/mkvaudiosubtitlechanger/model/ResultStatistic.java @@ -0,0 +1,4 @@ +package at.pcgamingfreaks.mkvaudiosubtitlechanger.model; + +public class ResultStatistic { +}