mirror of
https://github.com/RatzzFatzz/MKVAudioSubtitleChanger.git
synced 2026-02-11 02:05:56 +01:00
Prepare for coherent feature by restructuring AttributeUpdaterKernel
This commit is contained in:
@@ -1,92 +0,0 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import me.tongfei.progressbar.ProgressBar;
|
||||
import me.tongfei.progressbar.ProgressBarBuilder;
|
||||
import me.tongfei.progressbar.ProgressBarStyle;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Log4j2
|
||||
public class AttributeUpdaterKernel {
|
||||
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(Config.getInstance().getThreads());
|
||||
private final FileCollector collector;
|
||||
private final FileProcessor processor;
|
||||
private final ResultStatistic statistic = new ResultStatistic();
|
||||
|
||||
public AttributeUpdaterKernel(FileCollector collector, FileProcessor processor) {
|
||||
this.collector = collector;
|
||||
this.processor = processor;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void execute() {
|
||||
statistic.startTimer();
|
||||
|
||||
try (ProgressBar progressBar = pbBuilder().build()) {
|
||||
List<File> excludedFiles = Config.getInstance().getExcludedDirectories().stream()
|
||||
.map(collector::loadFiles)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
List<File> files = collector.loadFiles(Config.getInstance().getLibraryPath().getAbsolutePath()).stream()
|
||||
.filter(file -> !excludedFiles.contains(file))
|
||||
.collect(Collectors.toList());
|
||||
progressBar.maxHint(files.size());
|
||||
files.forEach(file -> executor.submit(() -> process(file, progressBar)));
|
||||
executor.shutdown();
|
||||
executor.awaitTermination(1, TimeUnit.DAYS);
|
||||
}
|
||||
|
||||
statistic.stopTimer();
|
||||
System.out.println(statistic);
|
||||
log.info(statistic);
|
||||
}
|
||||
|
||||
private void process(File file, ProgressBar progressBar) {
|
||||
List<FileAttribute> attributes = processor.loadAttributes(file);
|
||||
FileInfoDto fileInfo = processor.filterAttributes(attributes);
|
||||
statistic.total();
|
||||
if (fileInfo.isChangeNecessary()) {
|
||||
statistic.shouldChange();
|
||||
if (!Config.getInstance().isSafeMode()) {
|
||||
try {
|
||||
processor.update(file, fileInfo);
|
||||
statistic.success();
|
||||
log.info("Updated {}", file.getAbsolutePath());
|
||||
} catch (IOException | RuntimeException e) {
|
||||
statistic.failedChanging();
|
||||
log.warn("File couldn't be updated: '{}', Error: {}", file.getAbsoluteFile(), e.getMessage().replaceAll("\\r|\\n", " "));
|
||||
}
|
||||
}
|
||||
} else if (fileInfo.isUnableToApplyConfig()) {
|
||||
statistic.noSuitableConfigFound();
|
||||
} else if (fileInfo.isAlreadySuitable()){
|
||||
statistic.alreadyFits();
|
||||
} else {
|
||||
statistic.failure();
|
||||
}
|
||||
progressBar.step();
|
||||
}
|
||||
|
||||
private static ProgressBarBuilder pbBuilder() {
|
||||
return new ProgressBarBuilder()
|
||||
.setStyle(ProgressBarStyle.ASCII)
|
||||
.setUpdateIntervalMillis(250)
|
||||
.setMaxRenderedLength(75);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,17 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ConfigLoader;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.AttributeUpdaterKernel;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.DefaultAttributeUpdaterKernel;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileCollector;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.MkvFileProcessor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Log4j2
|
||||
@Slf4j
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
ConfigLoader.initConfig(args);
|
||||
AttributeUpdaterKernel kernel = new AttributeUpdaterKernel(new MkvFileCollector(), new MkvFileProcessor());
|
||||
AttributeUpdaterKernel kernel = new DefaultAttributeUpdaterKernel(new MkvFileCollector(), new MkvFileProcessor());
|
||||
kernel.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.DefaultParser;
|
||||
import org.apache.commons.cli.HelpFormatter;
|
||||
@@ -15,7 +15,7 @@ import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Log4j2
|
||||
@Slf4j
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
|
||||
@@ -27,7 +27,7 @@ public class ConfigLoader {
|
||||
new PatternValidator(INCLUDE_PATTERN, false, Pattern.compile(".*")),
|
||||
new SetValidator(FORCED_KEYWORDS, false, true),
|
||||
new SetValidator(COMMENTARY_KEYWORDS, false, true),
|
||||
new SetValidator(EXCLUDE_DIRECTORY, false, true),
|
||||
new SetValidator(EXCLUDED_DIRECTORY, false, true),
|
||||
new AttributeConfigValidator()
|
||||
);
|
||||
|
||||
@@ -55,7 +55,7 @@ public class ConfigLoader {
|
||||
}
|
||||
}
|
||||
|
||||
if (results.contains(ValidationResult.INVALID)) System.exit(1);
|
||||
if (results.contains(ValidationResult.INVALID) || results.contains(ValidationResult.MISSING)) System.exit(1);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions;
|
||||
|
||||
public class MkvToolNixException extends RuntimeException{
|
||||
|
||||
public MkvToolNixException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return super.getMessage().replaceAll("\\r|\\n", " ");
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions.MkvToolNixException;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
|
||||
|
||||
@@ -10,12 +11,35 @@ 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<FileAttribute> loadAttributes(File file);
|
||||
|
||||
FileInfoDto filterAttributes(List<FileAttribute> attributes);
|
||||
/**
|
||||
* Populate FileInfoDto with the currently set default tracks.
|
||||
* @param info to be populated
|
||||
* @param attributes Track information of FileInfoDto
|
||||
* @param nonForcedTracks List of all not forced tracks
|
||||
*/
|
||||
void detectDefaultTracks(FileInfoDto info, List<FileAttribute> attributes, List<FileAttribute> nonForcedTracks);
|
||||
|
||||
void update(File file, FileInfoDto fileInfo) throws IOException;
|
||||
/**
|
||||
* Populate FileInfoDto with the desired tracks, based on AttributeConfig.
|
||||
* @param info to be populated
|
||||
* @param nonForcedTracks List of all not forced tracks
|
||||
* @param nonCommentaryTracks List of all not commentary tracks
|
||||
*/
|
||||
void detectDesiredTracks(FileInfoDto info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks);
|
||||
|
||||
/**
|
||||
* Update the file.
|
||||
* @param file to be updated
|
||||
* @param fileInfo information to update file
|
||||
* @throws IOException
|
||||
* @throws MkvToolNixException when error occurs while sending query to mkvpropedit
|
||||
*/
|
||||
void update(File file, FileInfoDto fileInfo) throws IOException, MkvToolNixException;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
|
||||
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -12,7 +12,7 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Log4j2
|
||||
@Slf4j
|
||||
public class MkvFileCollector implements FileCollector {
|
||||
private static final String[] fileExtensions = new String[]{".mkv", ".mka", ".mks", ".mk3d"};
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions.MkvToolNixException;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.*;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.SetUtils;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.logging.log4j.core.util.IOUtils;
|
||||
|
||||
import java.io.File;
|
||||
@@ -19,14 +19,13 @@ import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType.AUDIO;
|
||||
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.LaneType.SUBTITLES;
|
||||
import static java.lang.String.format;
|
||||
|
||||
@Log4j2
|
||||
@Slf4j
|
||||
public class MkvFileProcessor implements FileProcessor {
|
||||
private final ObjectMapper mapper = new ObjectMapper();
|
||||
private static final String DISABLE_DEFAULT_TRACK = "--edit track:%s --set flag-default=0 ";
|
||||
private static final String ENABLE_DEFAULT_TRACK = "--edit track:%s --set flag-default=1 ";
|
||||
private static final String ENABLE_FORCED_TRACK = "--edit track:%s --set flag-forced=1 ";
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<FileAttribute> loadAttributes(File file) {
|
||||
@@ -62,7 +61,7 @@ public class MkvFileProcessor implements FileProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
log.debug(fileAttributes);
|
||||
log.debug(fileAttributes.toString());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error("File could not be found or loaded!");
|
||||
@@ -70,27 +69,11 @@ public class MkvFileProcessor implements FileProcessor {
|
||||
return fileAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public FileInfoDto filterAttributes(List<FileAttribute> attributes) {
|
||||
FileInfoDto info = new FileInfoDto();
|
||||
List<FileAttribute> nonForcedTracks = attributes.stream()
|
||||
.filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.getTrackName(),
|
||||
Config.getInstance().getForcedKeywords().toArray(new CharSequence[0])))
|
||||
.filter(elem -> !elem.isForcedTrack())
|
||||
.collect(Collectors.toList());
|
||||
List<FileAttribute> nonCommentaryTracks = attributes.stream()
|
||||
.filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.getTrackName(),
|
||||
Config.getInstance().getCommentaryKeywords().toArray(new CharSequence[0])))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
detectDefaultTracks(info, attributes, nonForcedTracks);
|
||||
detectDesiredTracks(info, nonForcedTracks, nonCommentaryTracks);
|
||||
log.debug(info);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
protected void detectDefaultTracks(FileInfoDto info, List<FileAttribute> attributes, List<FileAttribute> nonForcedTracks) {
|
||||
public void detectDefaultTracks(FileInfoDto info, List<FileAttribute> attributes, List<FileAttribute> nonForcedTracks) {
|
||||
Set<FileAttribute> detectedForcedSubtitleLanes = new HashSet<>();
|
||||
for (FileAttribute attribute : attributes) {
|
||||
if (attribute.isDefaultTrack() && AUDIO.equals(attribute.getType()))
|
||||
@@ -108,7 +91,11 @@ public class MkvFileProcessor implements FileProcessor {
|
||||
);
|
||||
}
|
||||
|
||||
protected void detectDesiredTracks(FileInfoDto info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks) {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void detectDesiredTracks(FileInfoDto info, List<FileAttribute> nonForcedTracks, List<FileAttribute> nonCommentaryTracks) {
|
||||
for (AttributeConfig config : Config.getInstance().getAttributeConfig()) {
|
||||
FileAttribute desiredAudio = null;
|
||||
FileAttribute desiredSubtitle = null;
|
||||
@@ -126,11 +113,15 @@ public class MkvFileProcessor implements FileProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void update(File file, FileInfoDto fileInfo) throws IOException, RuntimeException {
|
||||
public void update(File file, FileInfoDto fileInfo) throws IOException, MkvToolNixException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(format("\"%s\" ", Config.getInstance().getPathFor(MkvToolNix.MKV_PROP_EDIT)));
|
||||
sb.append(format("\"%s\" ", file.getAbsolutePath()));
|
||||
|
||||
if (fileInfo.isAudioDifferent()) {
|
||||
if (fileInfo.getDefaultAudioLanes() != null && !fileInfo.getDefaultSubtitleLanes().isEmpty()) {
|
||||
for (FileAttribute track: fileInfo.getDefaultAudioLanes()) {
|
||||
@@ -139,6 +130,7 @@ public class MkvFileProcessor implements FileProcessor {
|
||||
}
|
||||
sb.append(format(ENABLE_DEFAULT_TRACK, fileInfo.getDesiredAudioLane().getId()));
|
||||
}
|
||||
|
||||
if (fileInfo.isSubtitleDifferent()) {
|
||||
if (fileInfo.getDefaultSubtitleLanes() != null && !fileInfo.getDefaultSubtitleLanes().isEmpty()) {
|
||||
for (FileAttribute track: fileInfo.getDefaultSubtitleLanes()) {
|
||||
@@ -147,6 +139,7 @@ public class MkvFileProcessor implements FileProcessor {
|
||||
}
|
||||
sb.append(format(ENABLE_DEFAULT_TRACK, fileInfo.getDesiredSubtitleLane().getId()));
|
||||
}
|
||||
|
||||
if (fileInfo.areForcedTracksDifferent()) {
|
||||
for (FileAttribute attribute : fileInfo.getDesiredForcedSubtitleLanes()) {
|
||||
sb.append(format(ENABLE_FORCED_TRACK, attribute.getId()));
|
||||
@@ -156,6 +149,6 @@ public class MkvFileProcessor implements FileProcessor {
|
||||
InputStream inputstream = Runtime.getRuntime().exec(sb.toString()).getInputStream();
|
||||
String output = IOUtils.toString(new InputStreamReader(inputstream));
|
||||
log.debug(output);
|
||||
if (output.contains("Error")) throw new RuntimeException(output);
|
||||
if (output.contains("Error")) throw new MkvToolNixException(output);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.exceptions.MkvToolNixException;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ResultStatistic;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.tongfei.progressbar.ProgressBar;
|
||||
import me.tongfei.progressbar.ProgressBarBuilder;
|
||||
import me.tongfei.progressbar.ProgressBarStyle;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public abstract class AttributeUpdaterKernel {
|
||||
|
||||
protected final FileCollector collector;
|
||||
protected final FileProcessor processor;
|
||||
protected final ResultStatistic statistic = new ResultStatistic();
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(Config.getInstance().getThreads());
|
||||
|
||||
private static ProgressBarBuilder pbBuilder() {
|
||||
return new ProgressBarBuilder()
|
||||
.setStyle(ProgressBarStyle.ASCII)
|
||||
.setUpdateIntervalMillis(250)
|
||||
.setMaxRenderedLength(75);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void execute() {
|
||||
statistic.startTimer();
|
||||
|
||||
try (ProgressBar progressBar = pbBuilder().build()) {
|
||||
List<File> files = loadFiles(Config.getInstance().getLibraryPath().getAbsolutePath());
|
||||
progressBar.maxHint(files.size());
|
||||
|
||||
files.forEach(file -> executor.submit(() -> {
|
||||
process(file);
|
||||
progressBar.step();
|
||||
}));
|
||||
|
||||
executor.shutdown();
|
||||
executor.awaitTermination(1, TimeUnit.DAYS);
|
||||
}
|
||||
|
||||
statistic.stopTimer();
|
||||
statistic.printResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load files or directories to update.
|
||||
* Remove excluded directories.
|
||||
*
|
||||
* @param path Path to library
|
||||
* @return List of files to update.
|
||||
*/
|
||||
abstract List<File> loadFiles(String path);
|
||||
|
||||
/**
|
||||
* Start of the file updating process.
|
||||
* This method is called by the executor and its contents are executed in parallel.
|
||||
*
|
||||
* @param file file or directory to update
|
||||
*/
|
||||
abstract void process(File file);
|
||||
|
||||
/**
|
||||
* Persist file changes.
|
||||
*
|
||||
* @param fileInfoDto contains information about file and desired configuration.
|
||||
*/
|
||||
protected void updateFile(FileInfoDto fileInfoDto) {
|
||||
statistic.total();
|
||||
switch (fileInfoDto.getStatus()) {
|
||||
case CHANGE_NECESSARY:
|
||||
statistic.shouldChange();
|
||||
commitChange(fileInfoDto);
|
||||
break;
|
||||
case UNABLE_TO_APPLY:
|
||||
statistic.noSuitableConfigFound();
|
||||
break;
|
||||
case ALREADY_SUITED:
|
||||
statistic.alreadyFits();
|
||||
break;
|
||||
case UNKNOWN:
|
||||
default:
|
||||
statistic.failure();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void commitChange(FileInfoDto fileInfo) {
|
||||
if (Config.getInstance().isSafeMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
processor.update(fileInfo.getFile(), fileInfo);
|
||||
statistic.success();
|
||||
log.info("Updated {}", fileInfo.getFile().getAbsolutePath());
|
||||
} catch (IOException | MkvToolNixException e) {
|
||||
statistic.failedChanging();
|
||||
log.warn("File couldn't be updated: '{}', Error: {}", fileInfo.getFile().getAbsoluteFile(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel{
|
||||
|
||||
public CoherentAttributeUpdaterKernel(FileCollector collector, FileProcessor processor) {
|
||||
super(collector, processor);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
List<File> loadFiles(String path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
void process(File file) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel;
|
||||
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileCollector;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.FileProcessor;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileAttribute;
|
||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.FileInfoDto;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
public class DefaultAttributeUpdaterKernel extends AttributeUpdaterKernel {
|
||||
|
||||
public DefaultAttributeUpdaterKernel(FileCollector collector, FileProcessor processor) {
|
||||
super(collector, processor);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
List<File> loadFiles(String path) {
|
||||
List<File> excludedFiles = Config.getInstance().getExcludedDirectories().stream()
|
||||
.map(collector::loadFiles)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
statistic.increaseTotalBy(excludedFiles.size());
|
||||
statistic.increaseExcludedBy(excludedFiles.size());
|
||||
return collector.loadFiles(Config.getInstance().getLibraryPath().getAbsolutePath()).stream()
|
||||
.filter(file -> !excludedFiles.contains(file))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
void process(File file) {
|
||||
FileInfoDto fileInfo = new FileInfoDto(file);
|
||||
List<FileAttribute> attributes = processor.loadAttributes(file);
|
||||
|
||||
// TODO: extract this to a attributeProcessor?
|
||||
List<FileAttribute> nonForcedTracks = attributes.stream()
|
||||
.filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.getTrackName(),
|
||||
Config.getInstance().getForcedKeywords().toArray(new CharSequence[0])))
|
||||
.filter(elem -> !elem.isForcedTrack())
|
||||
.collect(Collectors.toList());
|
||||
List<FileAttribute> nonCommentaryTracks = attributes.stream()
|
||||
.filter(elem -> !StringUtils.containsAnyIgnoreCase(elem.getTrackName(),
|
||||
Config.getInstance().getCommentaryKeywords().toArray(new CharSequence[0])))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
processor.detectDefaultTracks(fileInfo, attributes, nonForcedTracks);
|
||||
processor.detectDesiredTracks(fileInfo, nonForcedTracks, nonCommentaryTracks);
|
||||
|
||||
updateFile(fileInfo);
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,11 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Log4j2
|
||||
@Slf4j
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class AttributeConfig {
|
||||
|
||||
@@ -19,7 +19,7 @@ public enum ConfigProperty {
|
||||
WINDOWS("windows", "Is operating system windows", null, 0),
|
||||
THREADS("threads", "Thread count (default: 2)", "t", 1),
|
||||
INCLUDE_PATTERN("include-pattern", "Include files matching pattern (default: \".*\")", "i", 1),
|
||||
EXCLUDE_DIRECTORY("exclude-directories", "Directories to be excluded, combines with config file", "e", 1),
|
||||
EXCLUDED_DIRECTORY("excluded-directories", "Directories to be excluded, combines with config file", "e", Option.UNLIMITED_VALUES),
|
||||
FORCED_KEYWORDS("forced-keywords", "Additional keywords to identify forced tracks", "fk", Option.UNLIMITED_VALUES),
|
||||
COMMENTARY_KEYWORDS("commentary-keywords", "Additional keywords to identify commentary tracks", "ck", Option.UNLIMITED_VALUES),
|
||||
ARGUMENTS("arguments", "List of arguments", null, 0),
|
||||
|
||||
@@ -2,9 +2,9 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Log4j2
|
||||
@Slf4j
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class FileAttribute {
|
||||
|
||||
@@ -1,32 +1,24 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@RequiredArgsConstructor
|
||||
public class FileInfoDto {
|
||||
private final File file;
|
||||
private Set<FileAttribute> defaultAudioLanes = new HashSet<>();
|
||||
private Set<FileAttribute> defaultSubtitleLanes = new HashSet<>();
|
||||
private Set<FileAttribute> desiredForcedSubtitleLanes;
|
||||
private FileAttribute desiredAudioLane;
|
||||
private FileAttribute desiredSubtitleLane;
|
||||
|
||||
public boolean isUnableToApplyConfig() {
|
||||
return desiredAudioLane == null && desiredSubtitleLane == null;
|
||||
}
|
||||
|
||||
public boolean isAlreadySuitable() {
|
||||
return defaultAudioLanes.contains(desiredAudioLane) && defaultSubtitleLanes.contains(desiredSubtitleLane);
|
||||
}
|
||||
|
||||
public boolean isChangeNecessary() {
|
||||
return isAudioDifferent() || isSubtitleDifferent() || areForcedTracksDifferent();
|
||||
}
|
||||
|
||||
public boolean isAudioDifferent() {
|
||||
return desiredAudioLane != null &&
|
||||
(defaultAudioLanes == null || !defaultAudioLanes.contains(desiredAudioLane));
|
||||
@@ -41,6 +33,25 @@ public class FileInfoDto {
|
||||
return desiredForcedSubtitleLanes.size() > 0;
|
||||
}
|
||||
|
||||
public FileStatus getStatus() {
|
||||
if (isChangeNecessary()) return FileStatus.CHANGE_NECESSARY;
|
||||
if (isUnableToApplyConfig()) return FileStatus.UNABLE_TO_APPLY;
|
||||
if (isAlreadySuitable()) return FileStatus.ALREADY_SUITED;
|
||||
return FileStatus.UNKNOWN;
|
||||
}
|
||||
|
||||
private boolean isUnableToApplyConfig() {
|
||||
return desiredAudioLane == null && desiredSubtitleLane == null;
|
||||
}
|
||||
|
||||
private boolean isAlreadySuitable() {
|
||||
return defaultAudioLanes.contains(desiredAudioLane) && defaultSubtitleLanes.contains(desiredSubtitleLane);
|
||||
}
|
||||
|
||||
private boolean isChangeNecessary() {
|
||||
return isAudioDifferent() || isSubtitleDifferent() || areForcedTracksDifferent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + "defaultAudioLanes=" + defaultAudioLanes +
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
|
||||
|
||||
public enum FileStatus {
|
||||
CHANGE_NECESSARY,
|
||||
UNABLE_TO_APPLY,
|
||||
ALREADY_SUITED,
|
||||
UNKNOWN;
|
||||
}
|
||||
@@ -2,10 +2,13 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.model;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Getter
|
||||
@Slf4j
|
||||
public class ResultStatistic {
|
||||
private static final String result = "Total files: %s%n" +
|
||||
"├─ Excluded: %s%n" +
|
||||
"├─ Should change: %s%n" +
|
||||
"│ ├─ Failed changing: %s%n" +
|
||||
"│ └─ Successfully changed: %s%n" +
|
||||
@@ -15,6 +18,7 @@ public class ResultStatistic {
|
||||
"Runtime: %s";
|
||||
|
||||
private int filesTotal = 0;
|
||||
private int excluded = 0;
|
||||
|
||||
private int shouldChange = 0;
|
||||
private int failedChanging = 0;
|
||||
@@ -28,10 +32,22 @@ public class ResultStatistic {
|
||||
private long startTime = 0;
|
||||
private long runtime = 0;
|
||||
|
||||
public void increaseTotalBy(int amount) {
|
||||
filesTotal += amount;
|
||||
}
|
||||
|
||||
public synchronized void total() {
|
||||
filesTotal++;
|
||||
}
|
||||
|
||||
public void increaseExcludedBy(int amount) {
|
||||
excluded += amount;
|
||||
}
|
||||
|
||||
public synchronized void excluded() {
|
||||
excluded++;
|
||||
}
|
||||
|
||||
public synchronized void shouldChange() {
|
||||
shouldChange++;
|
||||
}
|
||||
@@ -64,6 +80,11 @@ public class ResultStatistic {
|
||||
runtime = System.currentTimeMillis() - startTime;
|
||||
}
|
||||
|
||||
public void printResult() {
|
||||
System.out.println(this);
|
||||
log.info(this.toString());
|
||||
}
|
||||
|
||||
private String formatTimer() {
|
||||
int seconds = (int) (runtime / 1000);
|
||||
int minutes = seconds / 60;
|
||||
@@ -83,7 +104,7 @@ public class ResultStatistic {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(result, filesTotal, shouldChange, failedChanging, successfullyChanged,
|
||||
return String.format(result, filesTotal, excluded, shouldChange, failedChanging, successfullyChanged,
|
||||
noSuitableConfigFound, alreadyFits, failed, formatTimer());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user