Merge pull request #45 from RatzzFatzz/dev

Implement cache & fix minor bugs
This commit is contained in:
Michael
2023-04-16 14:44:32 +02:00
committed by GitHub
12 changed files with 102 additions and 52 deletions

View File

@@ -19,23 +19,28 @@ Attribute-config must be entered in pairs: `audio:subtitle`; Example: `jpn:eng`.
[here](https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/wiki/Attribute-Config). [here](https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/wiki/Attribute-Config).
## Available parameters ## Available parameters
```shell ```
-l,--library <arg> Path to library -l,--library-path <arg> Path to library
-a,--attribute-config <arg> Attribute config to decide which tracks to choose when -a,--attribute-config <arg> Attribute config to decide which tracks to choose when
-p,--config-path <arg> Path to config file -p,--config-path <arg> Path to config file
-m,--mkvtoolnix <arg> Path to mkv tool nix installation -m,--mkvtoolnix <arg> Path to mkv tool nix installation
-s,--safe-mode Test run (no files will be changes) -s,--safe-mode Test run (no files will be changes)
-c,--coherent <arg> Try to match all files in dir of depth with the same config
-cf,--force-coherent Force coherent and don't update anything if config fits not whole config (default: false)
-n,--only-new-files Sets filter-date to last successful execution (Overwrites input of filter-date)
-d,--filter-date <arg> Only consider files created newer than entered date (format: "dd.MM.yyyy-HH:mm:ss")
-t,--threads <arg> Thread count (default: 2) -t,--threads <arg> Thread count (default: 2)
-i,--include-pattern <arg> Include files matching pattern (default: ".*") -i,--include-pattern <arg> Include files matching pattern (default: ".*")
-e,--exclude-directories <arg> Directories to be excluded, combines with config file -e,--excluded-directories <arg> Directories to be excluded, combines with config file
-fk,--forced-keywords <arg> Additional keywords to identify forced tracks -fk,--forced-keywords <arg> Additional keywords to identify forced tracks
-ck,--commentary-keywords <arg> Additional keywords to identify commentary tracks -ck,--commentary-keywords <arg> Additional keywords to identify commentary tracks
-ps,--preferred-subtitles <arg> Additional keywords to prefer specific subtitle tracks
-v,--version Display version -v,--version Display version
-h,--help "For help this is" - Yoda -h,--help "For help this is" - Yoda
``` ```
If you need more information about how each parameter works, check out [this wiki page](https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/wiki/Parameters).
All parameters can also be defined in a config file. All parameters can also be defined in a [config file](https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/wiki/How-to-config-file).
Please read [this wiki page](https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/wiki/How-to-config-file) for more information.
## Build requirements ## Build requirements
- JDK 11 or higher - JDK 11 or higher

View File

@@ -1,7 +1,7 @@
mkvtoolnix: C:\Program Files\MKVToolNix mkvtoolnix: C:\Program Files\MKVToolNix
library: X:/Files library: X:/Files
config: attribute-config:
1: 1:
audio: ger audio: ger
subtitle: OFF subtitle: OFF
@@ -14,6 +14,7 @@ config:
#forced-keywords: ["forced", "signs"] #forced-keywords: ["forced", "signs"]
#commentary-keywords: ["commentary", "director"] #commentary-keywords: ["commentary", "director"]
#preferred-subtitles: ["unstyled"]
#exclude-directories: #exclude-directories:
# - "D:/Path/To/File.mkv" # - "D:/Path/To/File.mkv"
@@ -22,7 +23,12 @@ config:
# If pattern is negated, can be used to exclude files # If pattern is negated, can be used to exclude files
#include-pattern: "regex" #include-pattern: "regex"
# Only files newer than
#filter-date: 20.03.2021-10:11:12
safe-mode: safe-mode:
#coherent: #coherent:
#force-coherent:
#only-new-files:

20
pom.xml
View File

@@ -35,7 +35,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>3.1.1</version> <version>3.2.2</version>
<configuration> <configuration>
<archive> <archive>
<manifestEntries> <manifestEntries>
@@ -47,7 +47,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId> <artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version> <version>3.4.1</version>
<executions> <executions>
<execution> <execution>
<phase>package</phase> <phase>package</phase>
@@ -62,6 +62,13 @@
<include>*:*</include> <include>*:*</include>
</includes> </includes>
</artifactSet> </artifactSet>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</transformer>
</transformers>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
@@ -124,17 +131,18 @@
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId> <artifactId>log4j-api</artifactId>
<version>2.17.1</version> <version>2.18.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <artifactId>log4j-core</artifactId>
<version>2.17.1</version> <version>2.18.0</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j18-impl -->
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId> <artifactId>log4j-slf4j18-impl</artifactId>
<version>2.17.1</version> <version>2.18.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId> <groupId>com.fasterxml.jackson.dataformat</groupId>

View File

@@ -2,11 +2,11 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config; import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ConfigLoader; import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ConfigLoader;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.CachedMkvFileProcessor;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.AttributeUpdaterKernel; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.AttributeUpdaterKernel;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.CoherentAttributeUpdaterKernel; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.CoherentAttributeUpdaterKernel;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.DefaultAttributeUpdaterKernel; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.DefaultAttributeUpdaterKernel;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileCollector; import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileCollector;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileProcessor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@@ -14,8 +14,8 @@ public class Main {
public static void main(String[] args) { public static void main(String[] args) {
ConfigLoader.initConfig(args); ConfigLoader.initConfig(args);
AttributeUpdaterKernel kernel = Config.getInstance().getCoherent() != null AttributeUpdaterKernel kernel = Config.getInstance().getCoherent() != null
? new CoherentAttributeUpdaterKernel(new MkvFileCollector(), new MkvFileProcessor()) ? new CoherentAttributeUpdaterKernel(new MkvFileCollector(), new CachedMkvFileProcessor())
: new DefaultAttributeUpdaterKernel(new MkvFileCollector(), new MkvFileProcessor()); : new DefaultAttributeUpdaterKernel(new MkvFileCollector(), new CachedMkvFileProcessor());
kernel.execute(); kernel.execute();
} }
} }

View File

@@ -84,7 +84,7 @@ public class ConfigLoader {
if (cmd == null) throw new NullPointerException(); if (cmd == null) throw new NullPointerException();
return cmd; return cmd;
} catch (ParseException | NullPointerException e) { } catch (ParseException | NullPointerException e) {
formatter.printHelp(106, "java -jar MKVAudioSubtitlesChanger.jar -l <path_to_library>", formatter.printHelp(130, "java -jar MKVAudioSubtitlesChanger.jar -l <path_to_library>",
"\nParameters:", options, "\nParameters:", options,
"\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues"); "\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues");
System.exit(1); System.exit(1);
@@ -94,7 +94,7 @@ public class ConfigLoader {
private static void exitIfHelp(CommandLine cmd, Options options, HelpFormatter formatter) { private static void exitIfHelp(CommandLine cmd, Options options, HelpFormatter formatter) {
if (cmd.hasOption("help")) { if (cmd.hasOption("help")) {
formatter.printHelp(106, "java -jar MKVAudioSubtitlesChanger.jar -l <path_to_library>", formatter.printHelp(130, "java -jar MKVAudioSubtitlesChanger.jar -l <path_to_library>",
"\nParameters:", options, "\nParameters:", options,
"\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues"); "\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues");
System.exit(0); System.exit(0);

View File

@@ -0,0 +1,19 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public class Cache<Key, Value> {
private final Map<Key, Value> cache = new HashMap<>();
/**
* Retrieve {@link Value} from Cache or run creationFunction and return its value.
* @param key key of cache map
* @param creationFunction function to create missing values
* @return {@link Value} from Cache, or if missing result from creationFunction.
*/
public synchronized Value retrieve(Key key, Function<Key, Value> creationFunction) {
return cache.computeIfAbsent(key, creationFunction::apply);
}
}

View File

@@ -0,0 +1,15 @@
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<File, List<FileAttribute>> cache = new Cache<>();
@Override
public List<FileAttribute> loadAttributes(File file) {
return cache.retrieve(file, super::loadAttributes);
}
}

View File

@@ -21,6 +21,7 @@ public class FileFilter {
return true; return true;
} }
ResultStatistic.getInstance().total();
ResultStatistic.getInstance().excluded(); ResultStatistic.getInstance().excluded();
return false; return false;
} }

View File

@@ -30,9 +30,8 @@ public interface FileProcessor {
/** /**
* Populate FileInfoDto with the desired tracks, based on AttributeConfig. * Populate FileInfoDto with the desired tracks, based on AttributeConfig.
* @param info to be populated * @param info to be populated
* @param nonForcedTracks List of all not forced tracks * @param nonForcedTracks List of all non-forced tracks
* @param nonCommentaryTracks List of all not commentary tracks * @param nonCommentaryTracks List of all non-commentary tracks
* @param configs
*/ */
void detectDesiredTracks(FileInfoDto info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks, void detectDesiredTracks(FileInfoDto info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks,
AttributeConfig... configs); AttributeConfig... configs);
@@ -45,7 +44,7 @@ public interface FileProcessor {
* Update the file. * Update the file.
* @param file to be updated * @param file to be updated
* @param fileInfo information to update file * @param fileInfo information to update file
* @throws IOException * @throws IOException when error occurs accessing file retrieving information
* @throws MkvToolNixException when error occurs while sending query to mkvpropedit * @throws MkvToolNixException when error occurs while sending query to mkvpropedit
*/ */
void update(File file, FileInfoDto fileInfo) throws IOException, MkvToolNixException; void update(File file, FileInfoDto fileInfo) throws IOException, MkvToolNixException;

View File

@@ -115,6 +115,7 @@ public abstract class AttributeUpdaterKernel {
* @param fileInfoDto contains information about file and desired configuration. * @param fileInfoDto contains information about file and desired configuration.
*/ */
protected void updateFile(FileInfoDto fileInfoDto) { protected void updateFile(FileInfoDto fileInfoDto) {
statistic.total();
switch (fileInfoDto.getStatus()) { switch (fileInfoDto.getStatus()) {
case CHANGE_NECESSARY: case CHANGE_NECESSARY:
statistic.shouldChange(); statistic.shouldChange();
@@ -139,7 +140,6 @@ public abstract class AttributeUpdaterKernel {
} }
try { try {
statistic.total();
processor.update(fileInfo.getFile(), fileInfo); processor.update(fileInfo.getFile(), fileInfo);
statistic.success(); statistic.success();
log.info("Updated {}", fileInfo.getFile().getAbsolutePath()); log.info("Updated {}", fileInfo.getFile().getAbsolutePath());

View File

@@ -34,8 +34,12 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel {
*/ */
@Override @Override
List<File> loadFiles(String path) { List<File> loadFiles(String path) {
return loadFiles(path, Config.getInstance().getCoherent());
}
List<File> loadFiles(String path, int depth) {
List<File> excludedFiles = loadExcludedFiles(); List<File> excludedFiles = loadExcludedFiles();
List<File> directories = collector.loadDirectories(path, Config.getInstance().getCoherent()) List<File> directories = collector.loadDirectories(path, depth)
.stream().filter(file -> !excludedFiles.contains(file)) .stream().filter(file -> !excludedFiles.contains(file))
.collect(Collectors.toList()); .collect(Collectors.toList());
return directories.stream() return directories.stream()
@@ -59,25 +63,20 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel {
*/ */
@Override @Override
void process(File file) { void process(File file) {
process(file, Config.getInstance().getCoherent());
}
void process(File file, int depth) {
// TODO: Implement level crawl if coherence is not possible on user entered depth // TODO: Implement level crawl if coherence is not possible on user entered depth
// IMPL idea: recursive method call, cache needs to be implemented // IMPL idea: recursive method call, cache needs to be implemented
List<FileInfoDto> fileInfos = collector.loadFiles(file.getAbsolutePath()) List<FileInfoDto> fileInfos = collector.loadFiles(file.getAbsolutePath()).stream()
.stream().map(FileInfoDto::new) .map(FileInfoDto::new)
.collect(Collectors.toList()); .collect(Collectors.toList());
Map<FileInfoDto, List<FileAttribute>> fileAttributeCache = new HashMap<>();
for (FileInfoDto fileInfo : fileInfos) {
if (!Config.getInstance().getIncludePattern().matcher(fileInfo.getFile().getAbsolutePath()).matches()) {
statistic.excluded();
continue;
}
fileAttributeCache.put(fileInfo, processor.loadAttributes(fileInfo.getFile()));
}
for (AttributeConfig config : Config.getInstance().getAttributeConfig()) { for (AttributeConfig config : Config.getInstance().getAttributeConfig()) {
for (FileInfoDto fileInfo : fileInfos) { for (FileInfoDto fileInfo : fileInfos) {
List<FileAttribute> attributes = fileAttributeCache.get(fileInfo); List<FileAttribute> attributes = processor.loadAttributes(fileInfo.getFile());
List<FileAttribute> nonForcedTracks = processor.retrieveNonForcedTracks(attributes); List<FileAttribute> nonForcedTracks = processor.retrieveNonForcedTracks(attributes);
List<FileAttribute> nonCommentaryTracks = processor.retrieveNonCommentaryTracks(attributes); List<FileAttribute> nonCommentaryTracks = processor.retrieveNonCommentaryTracks(attributes);
@@ -88,7 +87,6 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel {
if (fileInfos.stream().allMatch(elem -> elem.getDesiredSubtitleLane() != null && elem.getDesiredAudioLane() != null)) { if (fileInfos.stream().allMatch(elem -> elem.getDesiredSubtitleLane() != null && elem.getDesiredAudioLane() != null)) {
log.info("Found {}/{} match for {}", config.getAudioLanguage(), config.getSubtitleLanguage(), file.getAbsolutePath()); log.info("Found {}/{} match for {}", config.getAudioLanguage(), config.getSubtitleLanguage(), file.getAbsolutePath());
statistic.increaseTotalBy(fileInfos.size());
fileInfos.forEach(this::updateFile); fileInfos.forEach(this::updateFile);
return; // match found, end process here return; // match found, end process here
} }
@@ -99,9 +97,10 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel {
}); });
} }
log.info("No coherent match found for {}", file.getAbsoluteFile());
for (FileInfoDto fileInfo : fileInfos) { for (FileInfoDto fileInfo : fileInfos) {
statistic.total(); if (!Config.getInstance().isForceCoherent()) {
if (Config.getInstance().isForceCoherent()) {
super.process(fileInfo.getFile()); super.process(fileInfo.getFile());
} else { } else {
statistic.excluded(); statistic.excluded();

View File

@@ -116,7 +116,7 @@ public class ResultStatistic {
@Override @Override
public String toString() { public String toString() {
String sb = "ResultStatistic[" + "filesTotal=" + filesTotal + return "ResultStatistic: " + "filesTotal=" + filesTotal +
", excluded=" + excluded + ", excluded=" + excluded +
", shouldChange=" + shouldChange + ", shouldChange=" + shouldChange +
" (failedChanging=" + failedChanging + " (failedChanging=" + failedChanging +
@@ -124,8 +124,6 @@ public class ResultStatistic {
"), noSuitableConfigFound=" + noSuitableConfigFound + "), noSuitableConfigFound=" + noSuitableConfigFound +
", alreadyFits=" + alreadyFits + ", alreadyFits=" + alreadyFits +
", failed=" + failed + ", failed=" + failed +
", runtime=" + formatTimer() + ", runtime=" + formatTimer();
']';
return sb;
} }
} }