22 Commits

Author SHA1 Message Date
RatzzFatzz
36bd93bb50 Fix windows artifact upload 2025-02-04 12:33:19 +01:00
RatzzFatzz
ecc5c56c8c Update github action 2025-02-04 00:54:09 +01:00
RatzzFatzz
f6310c71ee Update github action 2025-02-04 00:52:09 +01:00
RatzzFatzz
bb4a686dfc Update github action 2025-02-04 00:39:13 +01:00
RatzzFatzz
c63fcd4f37 Update maven plugins 2025-02-04 00:34:40 +01:00
RatzzFatzz
9f15b542bd Update github action 2025-02-04 00:31:07 +01:00
RatzzFatzz
76321bb904 Update dependencies 2025-02-04 00:03:56 +01:00
RatzzFatzz
895597b91f Fix github action 2025-02-03 23:32:37 +01:00
RatzzFatzz
4fa5448e1c Fix logging on installed app 2025-02-03 01:13:15 +01:00
RatzzFatzz
f3accd77d6 Replace GraalVM with jpackage and wix 2025-02-01 17:00:01 +01:00
RatzzFatzz
2710ea2602 Update graalvm and lombok config 2025-01-28 23:45:06 +01:00
RatzzFatzz
547b5ad86c Update threads test 2024-11-27 21:19:08 +01:00
RatzzFatzz
1863432dc6 Make mkvtoolnix path default value of dependant 2024-11-27 00:32:23 +01:00
RatzzFatzz
7ea0ab17b0 Update mkvtoolnix path test 2024-11-26 23:42:16 +01:00
RatzzFatzz
47b4cdc896 Update path & pattern tests 2024-11-24 23:57:24 +01:00
RatzzFatzz
b638d93358 Improve command description 2024-11-22 00:44:02 +01:00
RatzzFatzz
939f6053dd Update collection config parameter config 2024-11-22 00:21:13 +01:00
RatzzFatzz
4714ef8db1 Update config tests 2024-11-18 23:59:17 +01:00
RatzzFatzz
321115b9ca Rework app to use picocli 2024-11-17 23:42:06 +01:00
RatzzFatzz
ed8e592963 Fix file change detection 2024-05-27 22:24:47 +02:00
RatzzFatzz
0a7996f049 Remove forced audio tracks & minor refactoring 2024-05-24 01:09:11 +02:00
Michael
dd60ca93da Merge pull request #50 from RatzzFatzz/bugfix/file-with-no-default-subtitle-track
Fix setting of default audio track on files with no default subtitle track
2024-02-19 21:11:10 +01:00
46 changed files with 1123 additions and 731 deletions

View File

@@ -6,24 +6,32 @@ on:
types: [ created ] types: [ created ]
jobs: jobs:
build: portable-build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Install mkvtoolnix
uses: actions/checkout@v2 run: sudo apt-get install -y mkvtoolnix
- name: Set up JDK 11 - name: Checkout
uses: actions/setup-java@v2 uses: actions/checkout@v4
- name: Set timezone
uses: szenius/set-timezone@v2.0
with:
timezoneLinux: "Europe/Berlin"
- name: Set up JDK 21
uses: actions/setup-java@v4.7.0
with: with:
distribution: temurin distribution: temurin
java-version: 11 java-version: 21
- name: Setup workspace - name: Setup workspace
run: mkdir artifacts run: mkdir artifacts
- name: Build with Maven - name: Build with Maven
run: | run: |
mvn clean package --file pom.xml mvn clean package --file pom.xml -P portable
cp target/M*.{zip,tar} artifacts/ cp target/M*.{zip,tar} artifacts/
- name: Upload artifacts - name: Upload artifacts
@@ -33,3 +41,36 @@ jobs:
with: with:
args: 'artifacts/M*' args: 'artifacts/M*'
windows-installer-build:
runs-on: windows-latest
steps:
- name: Install mkvtoolnix
uses: crazy-max/ghaction-chocolatey@v3
with:
args: install mkvtoolnix -y
- name: Checkout
uses: actions/checkout@v4
- name: Set timezone
uses: szenius/set-timezone@v2.0
with:
timezoneWindows: "Berlin Standard Time"
- name: Set up JDK 21
uses: actions/setup-java@v4.7.0
with:
distribution: temurin
java-version: 21
- name: Setup workspace
run: mkdir artifacts
- name: Build with Maven
run: mvn clean package --file pom.xml -P windows
- name: Upload artifacts
uses: AButler/upload-release-assets@v3.0
with:
files: 'target/installer/*'
repo-token: ${{ secrets.GITHUB_TOKEN }}

280
pom.xml
View File

@@ -6,21 +6,135 @@
<groupId>at.pcgamingfreaks</groupId> <groupId>at.pcgamingfreaks</groupId>
<artifactId>MKVAudioSubtitleChanger</artifactId> <artifactId>MKVAudioSubtitleChanger</artifactId>
<version>3.0.1</version> <version>4.0.0</version>
<properties>
<mainClass>at.pcgamingfreaks.mkvaudiosubtitlechanger.Main</mainClass>
<lombok-version>1.18.36</lombok-version>
</properties>
<profiles>
<profile>
<id>portable</id>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>log4j2.yml</include>
<include>log4j2-debug.yml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>archive</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>maven/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>windows</id>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>log4j2-installed.yaml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.1</version>
</plugin>
<plugin>
<groupId>org.panteleyev</groupId>
<artifactId>jpackage-maven-plugin</artifactId>
<version>1.6.5</version>
<executions>
<execution>
<id>windows</id>
<configuration>
<resourceDir>${project.basedir}/src/main/resources/</resourceDir>
<type>EXE</type>
<winConsole>true</winConsole>
<winShortcut>false</winShortcut>
<winMenu>false</winMenu>
<javaOptions>
<javaOption>-Dlog4j.configurationFile=log4j2-installed.yaml</javaOption>
</javaOptions>
</configuration>
<phase>package</phase>
<goals>
<goal>jpackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>linux</id>
<build>
<plugins>
<plugin>
<groupId>org.panteleyev</groupId>
<artifactId>jpackage-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<id>linux-deb</id>
<configuration>
<type>DEB</type>
<installDir>/usr/local/bin</installDir>
<linuxShortcut>false</linuxShortcut>
<linuxPackageName>mkvasc</linuxPackageName>
<linuxDebMaintainer>your@email.com</linuxDebMaintainer>
</configuration>
<phase>package</phase>
<goals>
<goal>jpackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build> <build>
<defaultGoal>clean package</defaultGoal> <defaultGoal>clean package</defaultGoal>
<sourceDirectory>src/main/java</sourceDirectory> <sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory> <testSourceDirectory>src/test/java</testSourceDirectory>
<resources> <resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource> <resource>
<directory>./</directory> <directory>./</directory>
<includes> <includes>
<include>language-codes</include> <include>language-codes</include>
<include>project.properties</include> <include>project.properties</include>
<include>LICENSE</include>
</includes> </includes>
<filtering>true</filtering> <filtering>true</filtering>
</resource> </resource>
@@ -35,11 +149,11 @@
<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.2.2</version> <version>3.4.2</version>
<configuration> <configuration>
<archive> <archive>
<manifestEntries> <manifestEntries>
<Main-Class>at/pcgamingfreaks/mkvaudiosubtitlechanger/Main</Main-Class> <Main-Class>${mainClass}</Main-Class>
</manifestEntries> </manifestEntries>
</archive> </archive>
</configuration> </configuration>
@@ -47,7 +161,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.4.1</version> <version>3.6.0</version>
<executions> <executions>
<execution> <execution>
<phase>package</phase> <phase>package</phase>
@@ -76,36 +190,79 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version> <version>3.5.2</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration> <configuration>
<source>11</source> <source>21</source>
<target>11</target> <target>21</target>
<compilerArgs>
<arg>-Aproject=${project.groupId}/${project.artifactId}</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok-version}</version>
</path>
<path>
<groupId>info.picocli</groupId>
<artifactId>picocli-codegen</artifactId>
<version>4.7.6</version>
</path>
</annotationProcessorPaths>
</configuration> </configuration>
</plugin> </plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId>
<artifactId>maven-assembly-plugin</artifactId> <version>3.3.1</version>
<version>3.3.0</version>
<executions> <executions>
<execution> <execution>
<id>copy-jpackage-input</id>
<phase>package</phase> <phase>package</phase>
<goals> <goals>
<goal>single</goal> <goal>copy-resources</goal>
</goals> </goals>
<configuration> <configuration>
<appendAssemblyId>false</appendAssemblyId> <outputDirectory>${project.build.directory}/jpackage-input</outputDirectory>
<descriptors> <resources>
<descriptor>maven/assembly.xml</descriptor> <resource>
</descriptors> <directory>${project.build.directory}</directory>
<includes>
<include>${project.artifactId}-${project.version}.jar</include>
</includes>
</resource>
</resources>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>org.panteleyev</groupId>
<artifactId>jpackage-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<name>${project.artifactId}</name>
<vendor>RatzzFatzz</vendor>
<appVersion>${project.version}</appVersion>
<destination>target/installer</destination>
<input>target/jpackage-input</input>
<mainClass>at.pcgamingfreaks.mkvaudiosubtitlechanger.Main</mainClass>
<mainJar>${project.artifactId}-${project.version}.jar</mainJar>
</configuration>
</plugin>
</plugins> </plugins>
</pluginManagement>
</build> </build>
<repositories> <repositories>
@@ -116,86 +273,139 @@
</repositories> </repositories>
<dependencies> <dependencies>
<!-- https://mvnrepository.com/artifact/com.intellij/forms_rt -->
<dependency> <dependency>
<groupId>com.intellij</groupId> <groupId>com.intellij</groupId>
<artifactId>forms_rt</artifactId> <artifactId>forms_rt</artifactId>
<version>7.0.3</version> <version>7.0.3</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.24</version> <version>${lombok-version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/info.picocli/picocli -->
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>4.7.6</version>
</dependency>
<!-- Hibernate Validator -->
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.2.Final</version>
</dependency>
<!-- Expression Language Implementation -->
<!-- https://mvnrepository.com/artifact/jakarta.el/jakarta.el-api -->
<dependency>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
<version>6.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<version>5.0.0-M1</version>
</dependency>
<!-- Jakarta Bean Validation -->
<!-- https://mvnrepository.com/artifact/jakarta.validation/jakarta.validation-api -->
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<version>3.0.2</version>
</dependency>
<!-- region logging --> <!-- region logging -->
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId> <artifactId>log4j-api</artifactId>
<version>2.18.0</version> <version>2.24.3</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <artifactId>log4j-core</artifactId>
<version>2.18.0</version> <version>2.24.3</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j18-impl --> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j18-impl -->
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j2-impl -->
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j18-impl</artifactId> <artifactId>log4j-slf4j2-impl</artifactId>
<version>2.18.0</version> <version>2.24.3</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-yaml -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId> <groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId> <artifactId>jackson-dataformat-yaml</artifactId>
<version>2.13.4</version> <version>2.18.2</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.13.4.2</version> <version>2.18.2</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
<dependency> <dependency>
<groupId>commons-cli</groupId> <groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId> <artifactId>commons-cli</artifactId>
<version>1.5.0</version> <version>1.9.0</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
<version>3.12.0</version> <version>3.17.0</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/me.tongfei/progressbar -->
<dependency> <dependency>
<groupId>me.tongfei</groupId> <groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId> <artifactId>progressbar</artifactId>
<version>0.9.5</version> <version>0.10.1</version>
</dependency> </dependency>
<!-- endregion --> <!-- endregion -->
<!-- region unit-tests --> <!-- region unit-tests -->
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId> <artifactId>junit-jupiter-api</artifactId>
<version>5.9.0</version> <version>5.11.4</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId> <artifactId>junit-jupiter-engine</artifactId>
<version>5.9.0</version> <version>5.11.4</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all --> <!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId> <artifactId>mockito-core</artifactId>
<version>1.10.19</version> <version>5.15.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-params -->
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId> <artifactId>junit-jupiter-params</artifactId>
<version>5.9.0</version> <version>5.11.4</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- endregion --> <!-- endregion -->
<dependency> <dependency>
<groupId>at.pcgamingfreaks</groupId> <groupId>at.pcgamingfreaks</groupId>
@@ -206,7 +416,7 @@
<dependency> <dependency>
<groupId>net.harawata</groupId> <groupId>net.harawata</groupId>
<artifactId>appdirs</artifactId> <artifactId>appdirs</artifactId>
<version>1.2.1</version> <version>1.3.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -1,21 +1,65 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger; 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.impl.CachedMkvFileProcessor; 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.util.ProjectUtil;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
import java.util.Set;
@Slf4j @Slf4j
public class Main { @CommandLine.Command(
public static void main(String[] args) { name = "mkvasc",
ConfigLoader.initConfig(args); usageHelpWidth = 120,
customSynopsis = {
"mkvasc -a <attributeConfig>... -l <libraryPath> [-s]",
"Example: mkvasc -a eng:eng eng:ger -l /mnt/media/ -s"
},
mixinStandardHelpOptions = true,
versionProvider = ProjectUtil.class
)
public class Main implements Runnable {
@Getter
@CommandLine.ArgGroup(exclusive = false)
private Config config;
@CommandLine.Spec
CommandLine.Model.CommandSpec spec;
@Override
public void run() {
validate();
Config.setInstance(config);
AttributeUpdaterKernel kernel = Config.getInstance().getCoherent() != null AttributeUpdaterKernel kernel = Config.getInstance().getCoherent() != null
? new CoherentAttributeUpdaterKernel(new MkvFileCollector(), new CachedMkvFileProcessor()) ? new CoherentAttributeUpdaterKernel(new MkvFileCollector(), new CachedMkvFileProcessor())
: new DefaultAttributeUpdaterKernel(new MkvFileCollector(), new CachedMkvFileProcessor()); : new DefaultAttributeUpdaterKernel(new MkvFileCollector(), new CachedMkvFileProcessor());
kernel.execute(); kernel.execute();
} }
private void validate() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Config>> violations = validator.validate(config);
if (!violations.isEmpty()) {
StringBuilder errorMsg = new StringBuilder();
for (ConstraintViolation<Config> violation : violations) {
errorMsg.append("ERROR: ").append(violation.getPropertyPath()).append(" ").append(violation.getMessage()).append("\n");
}
throw new CommandLine.ParameterException(spec.commandLine(), errorMsg.toString());
}
}
public static void main(String[] args) {
new CommandLine(Main.class).execute(args);
}
} }

View File

@@ -0,0 +1,58 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
import picocli.CommandLine;
import java.util.regex.Pattern;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.LanguageValidatorUtil.isAudioLanguageValid;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.LanguageValidatorUtil.isLanguageValid;
public class AttributeConfigConverter implements CommandLine.ITypeConverter<AttributeConfig> {
private static final String SEPARATOR = ":";
private static final Pattern PATTERN = Pattern.compile("^.{3}:.{3}$");
/**
* Converts the input string into an AttributeConfig object.
*
* @param s The input string containing audio and subtitle language configuration in format "audioLang:subtitleLang"
* @return An AttributeConfig object representing the parsed configuration
* @throws CommandLine.TypeConversionException if the input string is invalid or contains invalid language codes
*/
@Override
public AttributeConfig convert(String s) throws Exception {
validateInput(s);
String[] split = s.split(SEPARATOR);
AttributeConfig attr = new AttributeConfig(split[0], split[1]);
validateResult(attr);
return attr;
}
/**
* Validates that the input string matches the expected pattern.
*
* @param s String to validate
* @throws CommandLine.TypeConversionException if the value doesn't match the expected pattern
*/
private static void validateInput(String s) {
if (!PATTERN.matcher(s).matches()) {
throw new CommandLine.TypeConversionException("Invalid Attribute config: " + s);
}
}
/**
* Validates that both language codes in the AttributeConfig object are valid.
*
* @param attr AttributeConfig object to validate
* @throws CommandLine.TypeConversionException if either language code is invalid
*/
private static void validateResult(AttributeConfig attr) {
if (!isAudioLanguageValid(attr.getAudioLanguage()))
throw new CommandLine.TypeConversionException("Audio language invalid: " + attr.getAudioLanguage());
if (!isLanguageValid(attr.getSubtitleLanguage()))
throw new CommandLine.TypeConversionException("Subtitle language invalid: " + attr.getSubtitleLanguage());
}
}

View File

@@ -2,51 +2,96 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix;
import jakarta.validation.constraints.Min;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.cli.CommandLineParser; import org.apache.commons.lang3.SystemUtils;
import org.apache.commons.cli.DefaultParser; import picocli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import java.io.File; import java.io.File;
import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@Slf4j @Slf4j
@Getter @Getter
@Setter @Setter
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor
public class Config { public class Config {
@Getter(AccessLevel.NONE) @Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE) @Setter(AccessLevel.NONE)
private static Config config = null; private static Config config = null;
@Getter(AccessLevel.NONE)
CommandLineParser parser = new DefaultParser();
@Getter(AccessLevel.NONE)
HelpFormatter formatter = new HelpFormatter();
private File configPath;
private File libraryPath;
@Getter(AccessLevel.NONE)
private File mkvToolNix;
private int threads; private File configPath;
private Pattern includePattern;
@CommandLine.Spec
CommandLine.Model.CommandSpec spec;
@CommandLine.Option(names = {"-a", "--attribute-config"}, required = true, arity = "1..*", converter = AttributeConfigConverter.class)
private List<AttributeConfig> attributeConfig;
@Setter(AccessLevel.NONE)
private File libraryPath;
@CommandLine.Option(names = {"-s", "--safemode"}, description = "test run (no files will be changes)")
private boolean safeMode; private boolean safeMode;
private Integer coherent; @Setter(AccessLevel.NONE)
private boolean forceCoherent; private File mkvToolNix;
private boolean onlyNewFiles;
private Date filterDate;
private Set<String> forcedKeywords = new HashSet<>(Arrays.asList("forced", "signs", "songs")); @Min(value = 1)
private Set<String> commentaryKeywords = new HashSet<>(Arrays.asList("commentary", "director")); @CommandLine.Option(names = {"-t", "--threads"}, defaultValue = "2", description = "thread count (default: ${DEFAULT-VALUE})")
private int threads;
@CommandLine.Option(names = {"-c", "--coherent"}, description = "try to match all files in dir of depth with the same attribute config")
private Integer coherent;
@CommandLine.Option(names = {"-cf", "--force-coherent"}, description = "changes are only applied if it's a coherent match")
private boolean forceCoherent;
@CommandLine.Option(names = {"-n"}, description = "sets filter-date to last successful execution (overwrites input of filter-date)")
private boolean onlyNewFiles;
@CommandLine.Option(names = {"-d", "--filter-date"}, defaultValue = CommandLine.Option.NULL_VALUE, description = "only consider files created newer than entered date (format: \"dd.MM.yyyy-HH:mm:ss\")")
private Date filterDate;
@CommandLine.Option(names = {"-i", "--include-pattern"}, defaultValue = ".*", description = "include files matching pattern (default: \".*\")")
private Pattern includePattern;
@CommandLine.Option(names = {"-e", "--excluded-directory"}, arity = "1..*",
description = "Directories to be excluded, combines with config file")
private Set<String> excludedDirectories = new HashSet<>(); private Set<String> excludedDirectories = new HashSet<>();
@CommandLine.Option(names = {"-fk", "--force-keywords"}, arity = "1..*",
description = "Additional keywords to identify forced tracks (Defaults are will be overwritten; Default: ${DEFAULT-VALUE}")
private Set<String> forcedKeywords = new HashSet<>(Arrays.asList("forced", "signs", "songs"));
@CommandLine.Option(names = {"-ck", "--commentary-keywords"}, arity = "1..*",
description = "Additional keywords to identify commentary tracks (Defaults are will be overwritten; Default: ${DEFAULT-VALUE}")
private Set<String> commentaryKeywords = new HashSet<>(Arrays.asList("commentary", "director"));
@CommandLine.Option(names = {"-ps", "--preferred-subtiltes"}, arity = "1..*",
description = "Additional keywords to prefer specific subtitle tracks (Defaults are will be overwritten; Default: ${DEFAULT-VALUE}")
private Set<String> preferredSubtitles = new HashSet<>(Arrays.asList("unstyled")); private Set<String> preferredSubtitles = new HashSet<>(Arrays.asList("unstyled"));
private List<AttributeConfig> attributeConfig; @CommandLine.Option(names = {"-l", "--library"}, required = true, description = "path to library")
public void setLibraryPath(File libraryPath) {
if (!libraryPath.exists()) throw new CommandLine.ParameterException(spec.commandLine(), "Path does not exist: " + libraryPath.getAbsolutePath());
this.libraryPath = libraryPath;
}
static {
// Set default value into system properties to picocli can read the conditional value
System.setProperty("DEFAULT_MKV_TOOL_NIX", SystemUtils.IS_OS_WINDOWS ? "C:\\Program Files\\MKVToolNix" : "/usr/bin/");
}
@CommandLine.Option(names = {"-m", "--mkvtoolnix"}, defaultValue = "${DEFAULT_MKV_TOOL_NIX}", description = "path to mkvtoolnix installation")
public void setMkvToolNix(File mkvToolNix) {
this.mkvToolNix = mkvToolNix;
if (!mkvToolNix.exists()
|| !Path.of(getPathFor(MkvToolNix.MKV_MERGE, SystemUtils.IS_OS_WINDOWS)).toFile().exists()
|| !Path.of(getPathFor(MkvToolNix.MKV_PROP_EDIT, SystemUtils.IS_OS_WINDOWS)).toFile().exists()) {
throw new CommandLine.ParameterException(spec.commandLine(),
"Invalid path to mkvtoolnix installation: " + mkvToolNix.getAbsolutePath());
}
}
public static Config getInstance() { public static Config getInstance() {
return getInstance(false); return getInstance(false);
@@ -59,14 +104,23 @@ public class Config {
return config; return config;
} }
public static void setInstance(Config c) {
config = c;
}
/** /**
* Get path to specific mkvtoolnix application. * Get path to specific mkvtoolnix application.
* *
* @return absolute path to desired application. * @return absolute path to desired application.
*/ */
public String getPathFor(MkvToolNix application) { public String getPathFor(MkvToolNix application) {
return mkvToolNix.getAbsolutePath().endsWith("/") ? mkvToolNix.getAbsolutePath() + application : return mkvToolNix.getAbsolutePath().endsWith("/")
mkvToolNix.getAbsolutePath() + "/" + application; ? mkvToolNix.getAbsolutePath() + application
: mkvToolNix.getAbsolutePath() + "/" + application;
}
public String getPathFor(MkvToolNix application, boolean isWindows) {
return getPathFor(application) + (isWindows ? ".exe" : "");
} }
public String getNormalizedLibraryPath() { public String getNormalizedLibraryPath() {
@@ -76,8 +130,6 @@ public class Config {
@Override @Override
public String toString() { public String toString() {
return new StringJoiner(", ", Config.class.getSimpleName() + "[", "]") return new StringJoiner(", ", Config.class.getSimpleName() + "[", "]")
.add("parser=" + parser)
.add("formatter=" + formatter)
.add("configPath=" + configPath) .add("configPath=" + configPath)
.add("libraryPath=" + libraryPath) .add("libraryPath=" + libraryPath)
.add("mkvToolNix=" + mkvToolNix) .add("mkvToolNix=" + mkvToolNix)

View File

@@ -1,110 +0,0 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator.*;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ProjectUtil;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import org.apache.commons.cli.*;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
public class ConfigLoader {
private static final List<ConfigValidator<?>> VALIDATORS = Stream.of(
new ConfigPathValidator(CONFIG_PATH, false),
new PathValidator(LIBRARY, true, null),
new ThreadValidator(THREADS, false, 2),
new MkvToolNixPathValidator(MKV_TOOL_NIX, true, Path.of("C:\\Program Files\\MKVToolNix").toFile()),
new BooleanValidator(SAFE_MODE, false),
new BooleanValidator(ONLY_NEW_FILES, false),
new DateValidator(FILTER_DATE, false),
new PatternValidator(INCLUDE_PATTERN, false, Pattern.compile(".*")),
new SetValidator(FORCED_KEYWORDS, false, true),
new SetValidator(COMMENTARY_KEYWORDS, false, true),
new SetValidator(EXCLUDED_DIRECTORY, false, true),
new SetValidator(PREFERRED_SUBTITLES, false, true),
new AttributeConfigValidator(),
new CoherentConfigValidator(COHERENT, false),
new BooleanValidator(FORCE_COHERENT, false)
).sorted(Comparator.comparing((ConfigValidator<?> validator) -> validator.getWeight()).reversed()).collect(Collectors.toList());
public static void initConfig(String[] args) {
HelpFormatter formatter = new HelpFormatter();
formatter.setOptionComparator(null);
YAML yamlConfig = null;
Options options = initOptions();
CommandLine cmd = parseCommandLineArgs(formatter, options, args);
exitIfHelp(cmd, options, formatter);
exitIfVersion(cmd);
List<ValidationResult> results = new ArrayList<>();
for (ConfigValidator<?> validator: VALIDATORS) {
results.add(validator.validate(yamlConfig, cmd));
if (yamlConfig == null) {
try {
yamlConfig = Config.getInstance().getConfigPath() != null
? new YAML(Config.getInstance().getConfigPath())
: new YAML("");
} catch (IOException | YamlInvalidContentException ignored) {}
}
}
if (results.contains(ValidationResult.INVALID) || results.contains(ValidationResult.MISSING)) System.exit(1);
System.out.println();
}
private static Options initOptions() {
Options options = new Options();
Arrays.stream(ConfigProperty.values())
.filter(prop -> prop.abrv() != null)
.map(prop -> optionOf(prop, prop.abrv(), prop.args()))
.forEach(options::addOption);
return options;
}
private static CommandLine parseCommandLineArgs(HelpFormatter formatter, Options options, String[] args) {
CommandLineParser parser = new DefaultParser();
try {
CommandLine cmd = parser.parse(options, args);
if (cmd == null) throw new NullPointerException();
return cmd;
} catch (ParseException | NullPointerException e) {
formatter.printHelp(130, "java -jar MKVAudioSubtitlesChanger.jar -l <path_to_library>",
"\nParameters:", options,
"\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues");
System.exit(1);
}
return null; // can't be reached
}
private static void exitIfHelp(CommandLine cmd, Options options, HelpFormatter formatter) {
if (cmd.hasOption(HELP.prop())) {
formatter.printHelp(130, "java -jar MKVAudioSubtitlesChanger.jar -l <path_to_library>",
"\nParameters:", options,
"\nFeature requests and bug reports: https://github.com/RatzzFatzz/MKVAudioSubtitleChanger/issues");
System.exit(0);
}
}
private static void exitIfVersion(CommandLine cmd) {
if (cmd.hasOption(VERSION.prop())) {
System.out.printf("MKV Audio Subtitle Changer Version %s%n", ProjectUtil.getVersion());
System.exit(0);
}
}
}

View File

@@ -1,5 +1,6 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config; package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
@Deprecated
public enum ValidationResult { public enum ValidationResult {
VALID, VALID,
DEFAULT, DEFAULT,

View File

@@ -13,6 +13,7 @@ import java.util.stream.Collectors;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.LanguageValidatorUtil.isAudioLanguageValid; import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.LanguageValidatorUtil.isAudioLanguageValid;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.LanguageValidatorUtil.isLanguageValid; import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.LanguageValidatorUtil.isLanguageValid;
@Deprecated
public class AttributeConfigValidator extends ConfigValidator<List<AttributeConfig>> { public class AttributeConfigValidator extends ConfigValidator<List<AttributeConfig>> {
private static final String SEPARATOR = ":"; private static final String SEPARATOR = ":";

View File

@@ -12,6 +12,7 @@ import java.util.function.BiFunction;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.ARGUMENTS; import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.ARGUMENTS;
@Deprecated
public class BooleanValidator extends ConfigValidator<Boolean> { public class BooleanValidator extends ConfigValidator<Boolean> {
public BooleanValidator(ConfigProperty property, boolean required) { public BooleanValidator(ConfigProperty property, boolean required) {

View File

@@ -3,6 +3,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.lang3.math.NumberUtils;
@Deprecated
public class CoherentConfigValidator extends ConfigValidator<Integer> { public class CoherentConfigValidator extends ConfigValidator<Integer> {
private static final Integer DISABLED = -1; private static final Integer DISABLED = -1;

View File

@@ -7,6 +7,7 @@ import java.io.File;
import java.util.Optional; import java.util.Optional;
import java.util.function.BiFunction; import java.util.function.BiFunction;
@Deprecated
public class ConfigPathValidator extends PathValidator { public class ConfigPathValidator extends PathValidator {
public ConfigPathValidator(ConfigProperty property, boolean required) { public ConfigPathValidator(ConfigProperty property, boolean required) {
super(property, required, null); super(property, required, null);

View File

@@ -19,6 +19,7 @@ import java.util.function.Predicate;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@Deprecated
public abstract class ConfigValidator<FieldType> { public abstract class ConfigValidator<FieldType> {
protected final ConfigProperty property; protected final ConfigProperty property;
protected final boolean required; protected final boolean required;

View File

@@ -15,6 +15,7 @@ import java.nio.file.Path;
import java.util.Date; import java.util.Date;
@Slf4j @Slf4j
@Deprecated
public class DateValidator extends ConfigValidator<Date> { public class DateValidator extends ConfigValidator<Date> {
private static final Date INVALID_DATE = new Date(0); private static final Date INVALID_DATE = new Date(0);
private static final Date DEFAULT_DATE = new Date(1000); private static final Date DEFAULT_DATE = new Date(1000);

View File

@@ -5,9 +5,10 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import java.io.File; import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix.MKV_MERGER; import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix.MKV_MERGE;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix.MKV_PROP_EDIT; import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix.MKV_PROP_EDIT;
@Deprecated
public class MkvToolNixPathValidator extends PathValidator { public class MkvToolNixPathValidator extends PathValidator {
private static final String EXE = ".exe"; private static final String EXE = ".exe";
@@ -18,9 +19,9 @@ public class MkvToolNixPathValidator extends PathValidator {
@Override @Override
protected boolean isValid(File result) { protected boolean isValid(File result) {
return result.isDirectory() return result.isDirectory()
&& (Path.of(result.getAbsolutePath() + "/" + MKV_MERGER + EXE).toFile().isFile() && (Path.of(result.getAbsolutePath() + "/" + MKV_MERGE + EXE).toFile().isFile()
&& Path.of(result.getAbsolutePath() + "/" + MKV_PROP_EDIT + EXE).toFile().isFile()) && Path.of(result.getAbsolutePath() + "/" + MKV_PROP_EDIT + EXE).toFile().isFile())
|| (Path.of(result.getAbsolutePath() + "/" + MKV_MERGER).toFile().isFile() || (Path.of(result.getAbsolutePath() + "/" + MKV_MERGE).toFile().isFile()
&& Path.of(result.getAbsolutePath() + "/" + MKV_PROP_EDIT).toFile().isFile()); && Path.of(result.getAbsolutePath() + "/" + MKV_PROP_EDIT).toFile().isFile());
} }
} }

View File

@@ -5,6 +5,7 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import java.io.File; import java.io.File;
import java.nio.file.Path; import java.nio.file.Path;
@Deprecated
public class PathValidator extends ConfigValidator<File> { public class PathValidator extends ConfigValidator<File> {
public PathValidator(ConfigProperty property, boolean required, File defaultValue) { public PathValidator(ConfigProperty property, boolean required, File defaultValue) {

View File

@@ -5,6 +5,7 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
@Deprecated
public class PatternValidator extends ConfigValidator<Pattern> { public class PatternValidator extends ConfigValidator<Pattern> {
private static final Pattern EMPTY_PATTERN = Pattern.compile(""); private static final Pattern EMPTY_PATTERN = Pattern.compile("");

View File

@@ -13,6 +13,7 @@ import java.util.*;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Deprecated
public class SetValidator extends ConfigValidator<Set<String>> { public class SetValidator extends ConfigValidator<Set<String>> {
private final boolean append; private final boolean append;

View File

@@ -3,6 +3,7 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import org.apache.commons.lang3.math.NumberUtils; import org.apache.commons.lang3.math.NumberUtils;
@Deprecated
public class ThreadValidator extends ConfigValidator<Integer>{ public class ThreadValidator extends ConfigValidator<Integer>{
public ThreadValidator(ConfigProperty property, boolean required, Integer defaultValue) { public ThreadValidator(ConfigProperty property, boolean required, Integer defaultValue) {
super(property, required, defaultValue); super(property, required, defaultValue);

View File

@@ -30,6 +30,7 @@ public class MkvFileProcessor implements FileProcessor {
private static final String DISABLE_DEFAULT_TRACK = "--edit track:%s --set flag-default=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 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 "; private static final String ENABLE_FORCED_TRACK = "--edit track:%s --set flag-forced=1 ";
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -38,7 +39,7 @@ public class MkvFileProcessor implements FileProcessor {
Map<String, Object> jsonMap; Map<String, Object> jsonMap;
List<FileAttribute> fileAttributes = new ArrayList<>(); List<FileAttribute> fileAttributes = new ArrayList<>();
try { try {
String command = format("\"%s\"", Config.getInstance().getPathFor(MkvToolNix.MKV_MERGER)); String command = format("\"%s\"", Config.getInstance().getPathFor(MkvToolNix.MKV_MERGE));
String[] arguments = new String[]{ String[] arguments = new String[]{
command, command,
"--identify", "--identify",
@@ -69,8 +70,8 @@ public class MkvFileProcessor implements FileProcessor {
log.debug(fileAttributes.toString()); log.debug(fileAttributes.toString());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); log.error("File could not be found or loaded: ", e);
log.error("File could not be found or loaded!"); System.out.println("File could not be found or loaded: " + file.getAbsolutePath());
} }
return fileAttributes; return fileAttributes;
} }
@@ -80,21 +81,17 @@ public class MkvFileProcessor implements FileProcessor {
*/ */
@Override @Override
public 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) { for (FileAttribute attribute : attributes) {
if (attribute.isDefaultTrack() && AUDIO.equals(attribute.getType())) if (AUDIO.equals(attribute.getType())) {
info.getDefaultAudioLanes().add(attribute); if (attribute.isDefaultTrack()) info.getExistingDefaultAudioLanes().add(attribute);
if (attribute.isDefaultTrack() && SUBTITLES.equals(attribute.getType())) if (attribute.isForcedTrack()) info.getExistingForcedAudioLanes().add(attribute);
info.getDefaultSubtitleLanes().add(attribute); } else if (SUBTITLES.equals(attribute.getType())) {
if (attribute.isForcedTrack() && SUBTITLES.equals(attribute.getType())) if (attribute.isDefaultTrack()) info.getExistingDefaultSubtitleLanes().add(attribute);
detectedForcedSubtitleLanes.add(attribute);
}
info.setDesiredForcedSubtitleLanes(attributes.stream() if (attribute.isForcedTrack()) info.getExistingForcedSubtitleLanes().add(attribute);
.filter(e -> !nonForcedTracks.contains(e)) else if (!nonForcedTracks.contains(attribute)) info.getDesiredForcedSubtitleLanes().add(attribute);
.filter(e -> !detectedForcedSubtitleLanes.contains(e)) }
.collect(Collectors.toSet()) }
);
} }
/** /**
@@ -113,8 +110,8 @@ public class MkvFileProcessor implements FileProcessor {
if (desiredAudio.isPresent() && ("OFF".equals(config.getSubtitleLanguage()) || desiredSubtitle.isPresent())) { if (desiredAudio.isPresent() && ("OFF".equals(config.getSubtitleLanguage()) || desiredSubtitle.isPresent())) {
info.setMatchedConfig(config); info.setMatchedConfig(config);
info.setDesiredAudioLane(desiredAudio.get()); info.setDesiredDefaultAudioLane(desiredAudio.get());
info.setDesiredSubtitleLane(desiredSubtitle.orElse(null)); info.setDesiredDefaultSubtitleLane(desiredSubtitle.orElse(null));
break; break;
} }
} }
@@ -156,22 +153,28 @@ public class MkvFileProcessor implements FileProcessor {
sb.append(format("\"%s\" ", file.getAbsolutePath())); sb.append(format("\"%s\" ", file.getAbsolutePath()));
if (fileInfo.isAudioDifferent()) { if (fileInfo.isAudioDifferent()) {
if (fileInfo.getDefaultAudioLanes() != null && !fileInfo.getDefaultAudioLanes().isEmpty()) { if (fileInfo.getExistingDefaultAudioLanes() != null && !fileInfo.getExistingDefaultAudioLanes().isEmpty()) {
for (FileAttribute track: fileInfo.getDefaultAudioLanes()) { for (FileAttribute track: fileInfo.getExistingDefaultAudioLanes()) {
sb.append(format(DISABLE_DEFAULT_TRACK, track.getId())); sb.append(format(DISABLE_DEFAULT_TRACK, track.getId()));
} }
} }
sb.append(format(ENABLE_DEFAULT_TRACK, fileInfo.getDesiredAudioLane().getId())); sb.append(format(ENABLE_DEFAULT_TRACK, fileInfo.getDesiredDefaultAudioLane().getId()));
}
if (!fileInfo.getExistingForcedAudioLanes().isEmpty()) {
for (FileAttribute track: fileInfo.getExistingForcedAudioLanes()) {
sb.append(format(DISABLE_FORCED_TRACK, track.getId()));
}
} }
if (fileInfo.isSubtitleDifferent()) { if (fileInfo.isSubtitleDifferent()) {
if (fileInfo.getDefaultSubtitleLanes() != null && !fileInfo.getDefaultSubtitleLanes().isEmpty()) { if (fileInfo.getExistingDefaultSubtitleLanes() != null && !fileInfo.getExistingDefaultSubtitleLanes().isEmpty()) {
for (FileAttribute track: fileInfo.getDefaultSubtitleLanes()) { for (FileAttribute track: fileInfo.getExistingDefaultSubtitleLanes()) {
sb.append(format(DISABLE_DEFAULT_TRACK, track.getId())); sb.append(format(DISABLE_DEFAULT_TRACK, track.getId()));
} }
} }
if (fileInfo.getDesiredSubtitleLane() != null) { if (fileInfo.getDesiredDefaultSubtitleLane() != null) {
sb.append(format(ENABLE_DEFAULT_TRACK, fileInfo.getDesiredSubtitleLane().getId())); sb.append(format(ENABLE_DEFAULT_TRACK, fileInfo.getDesiredDefaultSubtitleLane().getId()));
} }
} }

View File

@@ -19,6 +19,7 @@ import me.tongfei.progressbar.ProgressBar;
import me.tongfei.progressbar.ProgressBarBuilder; import me.tongfei.progressbar.ProgressBarBuilder;
import me.tongfei.progressbar.ProgressBarStyle; import me.tongfei.progressbar.ProgressBarStyle;
import net.harawata.appdirs.AppDirsFactory; import net.harawata.appdirs.AppDirsFactory;
import picocli.CommandLine;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;

View File

@@ -11,9 +11,7 @@ import me.tongfei.progressbar.ProgressBarBuilder;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.io.File; import java.io.File;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
@@ -85,16 +83,16 @@ public class CoherentAttributeUpdaterKernel extends AttributeUpdaterKernel {
processor.detectDesiredTracks(fileInfo, nonForcedTracks, nonCommentaryTracks, config); processor.detectDesiredTracks(fileInfo, nonForcedTracks, nonCommentaryTracks, config);
} }
if (fileInfos.stream().allMatch(elem -> ("OFF".equals(config.getSubtitleLanguage()) || elem.getDesiredSubtitleLane() != null) if (fileInfos.stream().allMatch(elem -> ("OFF".equals(config.getSubtitleLanguage()) || elem.getDesiredDefaultSubtitleLane() != null)
&& elem.getDesiredAudioLane() != null)) { && elem.getDesiredDefaultAudioLane() != null)) {
log.info("Found {}/{} match for {}", config.getAudioLanguage(), config.getSubtitleLanguage(), file.getAbsolutePath()); log.info("Found {}/{} match for {}", config.getAudioLanguage(), config.getSubtitleLanguage(), file.getAbsolutePath());
fileInfos.forEach(this::updateFile); fileInfos.forEach(this::updateFile);
return; // match found, end process here return; // match found, end process here
} }
fileInfos.forEach(f -> { fileInfos.forEach(f -> {
f.setDesiredAudioLane(null); f.setDesiredDefaultAudioLane(null);
f.setDesiredSubtitleLane(null); f.setDesiredDefaultSubtitleLane(null);
}); });
} }

View File

@@ -13,16 +13,21 @@ import java.util.Set;
@RequiredArgsConstructor @RequiredArgsConstructor
public class FileInfoDto { public class FileInfoDto {
private final File file; private final File file;
private Set<FileAttribute> defaultAudioLanes = new HashSet<>();
private Set<FileAttribute> defaultSubtitleLanes = new HashSet<>(); private Set<FileAttribute> existingDefaultAudioLanes = new HashSet<>();
private Set<FileAttribute> desiredForcedSubtitleLanes; private Set<FileAttribute> existingForcedAudioLanes = new HashSet<>();
private FileAttribute desiredAudioLane;
private FileAttribute desiredSubtitleLane; private Set<FileAttribute> existingDefaultSubtitleLanes = new HashSet<>();
private Set<FileAttribute> existingForcedSubtitleLanes = new HashSet<>();
private Set<FileAttribute> desiredForcedSubtitleLanes = new HashSet<>();
private FileAttribute desiredDefaultAudioLane;
private FileAttribute desiredDefaultSubtitleLane;
private AttributeConfig matchedConfig; private AttributeConfig matchedConfig;
public boolean isAudioDifferent() { public boolean isAudioDifferent() {
return desiredAudioLane != null && return desiredDefaultAudioLane != null &&
(defaultAudioLanes == null || !defaultAudioLanes.contains(desiredAudioLane) || defaultAudioLanes.size() > 1); (existingDefaultAudioLanes == null || !existingDefaultAudioLanes.contains(desiredDefaultAudioLane) || existingDefaultAudioLanes.size() > 1);
} }
public boolean isSubtitleDifferent() { public boolean isSubtitleDifferent() {
@@ -30,17 +35,17 @@ public class FileInfoDto {
} }
private boolean isSubtitleMatchDifferent() { private boolean isSubtitleMatchDifferent() {
return desiredSubtitleLane != null return desiredDefaultSubtitleLane != null
&& (defaultSubtitleLanes == null || !defaultSubtitleLanes.contains(desiredSubtitleLane) || defaultSubtitleLanes.size() > 1); && (existingDefaultSubtitleLanes == null || !existingDefaultSubtitleLanes.contains(desiredDefaultSubtitleLane) || existingDefaultSubtitleLanes.size() > 1);
} }
private boolean isSubtitleOFF() { private boolean isSubtitleOFF() {
return desiredSubtitleLane == null && "OFF".equals(matchedConfig.getSubtitleLanguage()) && return desiredDefaultSubtitleLane == null && "OFF".equals(matchedConfig.getSubtitleLanguage()) &&
(defaultSubtitleLanes != null && !defaultSubtitleLanes.isEmpty()); (existingDefaultSubtitleLanes != null && !existingDefaultSubtitleLanes.isEmpty());
} }
public boolean areForcedTracksDifferent() { public boolean areForcedTracksDifferent() {
return desiredForcedSubtitleLanes.size() > 0; return !desiredForcedSubtitleLanes.isEmpty();
} }
public FileStatus getStatus() { public FileStatus getStatus() {
@@ -51,24 +56,24 @@ public class FileInfoDto {
} }
private boolean isUnableToApplyConfig() { private boolean isUnableToApplyConfig() {
return desiredAudioLane == null && desiredSubtitleLane == null; return desiredDefaultAudioLane == null && desiredDefaultSubtitleLane == null;
} }
private boolean isAlreadySuitable() { private boolean isAlreadySuitable() {
return defaultAudioLanes.contains(desiredAudioLane) && defaultSubtitleLanes.contains(desiredSubtitleLane); return existingDefaultAudioLanes.contains(desiredDefaultAudioLane) && existingDefaultSubtitleLanes.contains(desiredDefaultSubtitleLane);
} }
private boolean isChangeNecessary() { private boolean isChangeNecessary() {
return isAudioDifferent() || isSubtitleDifferent() || areForcedTracksDifferent(); return isAudioDifferent() || isSubtitleDifferent() || areForcedTracksDifferent() || !existingForcedAudioLanes.isEmpty();
} }
@Override @Override
public String toString() { public String toString() {
return "[" + "defaultAudioLanes=" + defaultAudioLanes + return "[" + "defaultAudioLanes=" + existingDefaultAudioLanes +
", defaultSubtitleLanes=" + defaultSubtitleLanes + ", defaultSubtitleLanes=" + existingDefaultSubtitleLanes +
", desiredForcedSubtitleLanes=" + desiredForcedSubtitleLanes + ", desiredForcedSubtitleLanes=" + desiredForcedSubtitleLanes +
", desiredAudioLane=" + desiredAudioLane + ", desiredAudioLane=" + desiredDefaultAudioLane +
", desiredSubtitleLane=" + desiredSubtitleLane + ", desiredSubtitleLane=" + desiredDefaultSubtitleLane +
']'; ']';
} }
} }

View File

@@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
@AllArgsConstructor @AllArgsConstructor
public enum MkvToolNix { public enum MkvToolNix {
MKV_MERGER("mkvmerge"), MKV_MERGE("mkvmerge"),
MKV_PROP_EDIT("mkvpropedit"); MKV_PROP_EDIT("mkvpropedit");
private final String file; private final String file;

View File

@@ -24,7 +24,7 @@ public class LanguageValidatorUtil {
} }
public static boolean isAudioLanguageValid(String language) { public static boolean isAudioLanguageValid(String language) {
return !language.equals("OFF") && ISO3_LANGUAGES.contains(language); return !language.equals("OFF") && isLanguageValid(language);
} }
public static boolean isLanguageValid(String language) { public static boolean isLanguageValid(String language) {

View File

@@ -1,10 +1,12 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.util; package at.pcgamingfreaks.mkvaudiosubtitlechanger.util;
import picocli.CommandLine;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Properties; import java.util.Properties;
public class ProjectUtil { public class ProjectUtil implements CommandLine.IVersionProvider {
private static final Properties PROJECT_PROPERTIES = new Properties(); private static final Properties PROJECT_PROPERTIES = new Properties();
static { static {
@@ -15,8 +17,8 @@ public class ProjectUtil {
} }
} }
public static String getVersion() { public String[] getVersion() {
return PROJECT_PROPERTIES.getProperty("version"); return new String[] {getProjectName() + " " + PROJECT_PROPERTIES.getProperty("version")};
} }
public static String getProjectName() { public static String getProjectName() {

View File

@@ -7,13 +7,17 @@ Configuration:
Pattern: "%d{DEFAULT} | %-5level | %thread | %msg %n %throwable" Pattern: "%d{DEFAULT} | %-5level | %thread | %msg %n %throwable"
ThresholdFilter: ThresholdFilter:
level: debug level: debug
File: RollingFile:
name: FileAppender name: FileAppender
fileName: default.log fileName: logs/application.log
filePattern: logs/archive/application-%d{yyyy-MM-dd}-%i.log
PatternLayout: PatternLayout:
Pattern: "%d{DEFAULT} | %-5level | %thread | %msg %n %throwable" Pattern: "%d{DEFAULT} | %-5level | %thread | %msg %n %throwable"
ThresholdFilter: ThresholdFilter:
level: debug level: debug
Policies:
OnStartupTriggeringPolicy:
minSize: 0
Loggers: Loggers:
Root: Root:
level: debug level: debug

View File

@@ -0,0 +1,31 @@
Configuration:
name: DefaultLogger
Appenders:
File:
name: FileAppender
fileName: ${sys:user.home}/AppData/Roaming/MyApplication/MyApplication.log
PatternLayout:
Pattern: "%d{DEFAULT} | %-5level | %thread | %msg %n %throwable"
ThresholdFilter:
level: info
RollingFile:
name: FileAppender
fileName: ${sys:user.home}/AppData/Roaming/MKVAudioSubtitleChanger/logs/application.log
filePattern: ${sys:user.home}/AppData/Roaming/MKVAudioSubtitleChanger/logs/archive/application-%d{yyyy-MM-dd}-%i.log
PatternLayout:
Pattern: "%d{DEFAULT} | %-5level | %thread | %msg %n %throwable"
ThresholdFilter:
level: info
Policies:
OnStartupTriggeringPolicy:
minSize: 0
Loggers:
Root:
level: info
AppenderRef:
- ref: FileAppender
Logger:
name: "com.zaxxer.hikari.HikariConfig"
level: info
AppenderRef:
- ref: FileAppender

View File

@@ -1,13 +1,17 @@
Configuration: Configuration:
name: DefaultLogger name: DefaultLogger
Appenders: Appenders:
File: RollingFile:
name: FileAppender name: FileAppender
fileName: default.log fileName: logs/application.log
filePattern: logs/archive/application-%d{yyyy-MM-dd}-%i.log
PatternLayout: PatternLayout:
Pattern: "%d{DEFAULT} | %-5level | %thread | %msg %n %throwable" Pattern: "%d{DEFAULT} | %-5level | %thread | %msg %n %throwable"
ThresholdFilter: ThresholdFilter:
level: info level: info
Policies:
OnStartupTriggeringPolicy:
minSize: 0
Loggers: Loggers:
Root: Root:
level: info level: info

144
src/main/resources/main.wxs Normal file
View File

@@ -0,0 +1,144 @@
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?ifdef JpIsSystemWide ?>
<?define JpInstallScope="perMachine"?>
<?else?>
<?define JpInstallScope="perUser"?>
<?endif?>
<?define JpProductLanguage=1033 ?>
<?define JpInstallerVersion=200 ?>
<?define JpCompressedMsi=yes ?>
<?ifdef JpAllowUpgrades ?>
<?define JpUpgradeVersionOnlyDetectUpgrade="no"?>
<?else?>
<?define JpUpgradeVersionOnlyDetectUpgrade="yes"?>
<?endif?>
<?ifdef JpAllowDowngrades ?>
<?define JpUpgradeVersionOnlyDetectDowngrade="no"?>
<?else?>
<?define JpUpgradeVersionOnlyDetectDowngrade="yes"?>
<?endif?>
<?define JpProductCode="*"?>
<?define JpAppName="MKVAudioSubtitleChanger"?>
<?define JpAppVersion="4.0.0"?>
<?define JpAppVendor="RatzzFatzz"?>
<?define JpProductUpgradeCode="a9527300-d364-4cc3-a392-94035065d8c9"?>
<?define JpAppDescription="Change audio and subtitle tracks for .mkv files"?>
<?define JpHelpURL="github.com/RatzzFatzz"?>
<Product
Id="$(var.JpProductCode)"
Name="$(var.JpAppName)"
Language="$(var.JpProductLanguage)"
Version="$(var.JpAppVersion)"
Manufacturer="$(var.JpAppVendor)"
UpgradeCode="$(var.JpProductUpgradeCode)">
<Package
Description="$(var.JpAppDescription)"
Manufacturer="$(var.JpAppVendor)"
InstallerVersion="$(var.JpInstallerVersion)"
Compressed="$(var.JpCompressedMsi)"
InstallScope="$(var.JpInstallScope)" Platform="x64"
/>
<Media Id="1" Cabinet="Data.cab" EmbedCab="yes" />
<Upgrade Id="$(var.JpProductUpgradeCode)">
<UpgradeVersion
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectUpgrade)"
Property="JP_UPGRADABLE_FOUND"
Maximum="$(var.JpAppVersion)"
MigrateFeatures="yes"
IncludeMaximum="$(var.JpUpgradeVersionOnlyDetectUpgrade)" />
<UpgradeVersion
OnlyDetect="$(var.JpUpgradeVersionOnlyDetectDowngrade)"
Property="JP_DOWNGRADABLE_FOUND"
Minimum="$(var.JpAppVersion)"
MigrateFeatures="yes"
IncludeMinimum="$(var.JpUpgradeVersionOnlyDetectDowngrade)" />
</Upgrade>
<?ifndef JpAllowUpgrades ?>
<CustomAction Id="JpDisallowUpgrade" Error="!(loc.DisallowUpgradeErrorMessage)" />
<?endif?>
<?ifndef JpAllowDowngrades ?>
<CustomAction Id="JpDisallowDowngrade" Error="!(loc.DowngradeErrorMessage)" />
<?endif?>
<Binary Id="JpCaDll" SourceFile="wixhelper.dll"/>
<CustomAction Id="JpFindRelatedProducts" BinaryKey="JpCaDll" DllEntry="FindRelatedProductsEx" />
<!-- Standard required root -->
<Directory Id="TARGETDIR" Name="SourceDir"/>
<Feature Id="DefaultFeature" Title="!(loc.MainFeatureTitle)" Level="1">
<ComponentGroupRef Id="Shortcuts"/>
<ComponentGroupRef Id="Files"/>
<ComponentGroupRef Id="FileAssociations"/>
<Component Id="pathEnvironmentVariable" Guid="$(var.JpProductUpgradeCode)" KeyPath="yes" Directory="TARGETDIR">
<Environment Id="MyPathVariable" Name="Path" Value="[INSTALLDIR]" Action="set" System="no" Permanent="no" Part="last" Separator=";" />
</Component>
</Feature>
<CustomAction Id="JpSetARPINSTALLLOCATION" Property="ARPINSTALLLOCATION" Value="[INSTALLDIR]" />
<CustomAction Id="JpSetARPCOMMENTS" Property="ARPCOMMENTS" Value="$(var.JpAppDescription)" />
<CustomAction Id="JpSetARPCONTACT" Property="ARPCONTACT" Value="$(var.JpAppVendor)" />
<!-- <CustomAction Id="JpSetARPSIZE" Property="ARPSIZE" Value="$(var.JpAppSizeKb)" /> -->
<?ifdef JpHelpURL ?>
<CustomAction Id="JpSetARPHELPLINK" Property="ARPHELPLINK" Value="$(var.JpHelpURL)" />
<?endif?>
<?ifdef JpAboutURL ?>
<CustomAction Id="JpSetARPURLINFOABOUT" Property="ARPURLINFOABOUT" Value="$(var.JpAboutURL)" />
<?endif?>
<?ifdef JpUpdateURL ?>
<CustomAction Id="JpSetARPURLUPDATEINFO" Property="ARPURLUPDATEINFO" Value="$(var.JpUpdateURL)" />
<?endif?>
<?ifdef JpIcon ?>
<Property Id="ARPPRODUCTICON" Value="JpARPPRODUCTICON"/>
<Icon Id="JpARPPRODUCTICON" SourceFile="$(var.JpIcon)"/>
<?endif?>
<UIRef Id="JpUI"/>
<InstallExecuteSequence>
<Custom Action="JpSetARPINSTALLLOCATION" After="CostFinalize">Not Installed</Custom>
<Custom Action="JpSetARPCOMMENTS" After="CostFinalize">Not Installed</Custom>
<Custom Action="JpSetARPCONTACT" After="CostFinalize">Not Installed</Custom>
<!-- <Custom Action="JpSetARPSIZE" After="CostFinalize">Not Installed</Custom> -->
<?ifdef JpHelpURL ?>
<Custom Action="JpSetARPHELPLINK" After="CostFinalize">Not Installed</Custom>
<?endif?>
<?ifdef JpAboutURL ?>
<Custom Action="JpSetARPURLINFOABOUT" After="CostFinalize">Not Installed</Custom>
<?endif?>
<?ifdef JpUpdateURL ?>
<Custom Action="JpSetARPURLUPDATEINFO" After="CostFinalize">Not Installed</Custom>
<?endif?>
<?ifndef JpAllowUpgrades ?>
<Custom Action="JpDisallowUpgrade" After="JpFindRelatedProducts">JP_UPGRADABLE_FOUND</Custom>
<?endif?>
<?ifndef JpAllowDowngrades ?>
<Custom Action="JpDisallowDowngrade" After="JpFindRelatedProducts">JP_DOWNGRADABLE_FOUND</Custom>
<?endif?>
<RemoveExistingProducts Before="CostInitialize"/>
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
</InstallExecuteSequence>
<InstallUISequence>
<Custom Action="JpFindRelatedProducts" After="FindRelatedProducts"/>
</InstallUISequence>
</Product>
</Wix>

View File

@@ -0,0 +1,61 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
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.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
class AttributeConfigTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("-a", "jpn:ger"), attrConf("jpn", "ger")),
Arguments.of(args("-a", "jpn:ger", "jpn:eng"), attrConf("jpn", "ger", "jpn", "eng")),
Arguments.of(args("-a", "jpn:ger", "jpn:OFF"), attrConf("jpn", "ger", "jpn", "OFF"))
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, List<AttributeConfig> expectedConfig) {
Main underTest = new Main();
CommandLine.populateCommand(underTest, cmdArgs);
assertIterableEquals(expectedConfig, underTest.getConfig().getAttributeConfig());
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, new String[]{"-l", "/"}));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, new String[]{"-l", "/", "-a"}));
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, new String[]{"-l", "/", "-a", "ger:"}));
assertThrows(CommandLine.ParameterException.class,
() -> CommandLine.populateCommand(sut, new String[]{"-l", "/", "-a", "ger:qwf"})); // Invalid language code
}
private static String[] args(String... args) {
String[] staticArray = new String[]{"-l", "/"};
String[] result = new String[staticArray.length + args.length];
System.arraycopy(staticArray, 0, result, 0, staticArray.length);
System.arraycopy(args, 0, result, staticArray.length, args.length);
return result;
}
private static List<AttributeConfig> attrConf(String... languages) {
List<AttributeConfig> conf = new ArrayList<>();
for (int i = 0; i < languages.length; i += 2) {
conf.add(new AttributeConfig(languages[i], languages[i+1]));
}
return conf;
}
}

View File

@@ -0,0 +1,37 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
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.util.function.Function;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
import static org.junit.jupiter.api.Assertions.assertEquals;
class BooleanConfigParameterTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("-s"), true, (Function<Config, Boolean>) Config::isSafeMode),
Arguments.of(args("--safemode"), true, (Function<Config, Boolean>) Config::isSafeMode),
Arguments.of(args(), false, (Function<Config, Boolean>) Config::isSafeMode),
Arguments.of(args("-cf"), true, (Function<Config, Boolean>) Config::isForceCoherent),
Arguments.of(args("--force-coherent"), true, (Function<Config, Boolean>) Config::isForceCoherent),
Arguments.of(args(), false, (Function<Config, Boolean>) Config::isForceCoherent),
Arguments.of(args("-n"), true, (Function<Config, Boolean>) Config::isOnlyNewFiles),
Arguments.of(args(), false, (Function<Config, Boolean>) Config::isOnlyNewFiles)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, boolean expected, Function<Config, Boolean> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(expected, fieldUnderTest.apply(sut.getConfig()));
}
}

View File

@@ -2,17 +2,18 @@ package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig; import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import picocli.CommandLine;
import java.util.List; import java.util.List;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.PathUtils.TEST_FILE; import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.PathUtils.TEST_FILE;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class ConfigLoaderTest { class ConfigTest {
@Test @Test
void initConfig() { void initConfig() {
String[] sut = new String[]{"-a", "ger:ger", "-l", TEST_FILE, String[] sut = new String[]{"-a", "ger:ger", "eng:eng", "-l", TEST_FILE,
"-s", "-cf", "-n", "-s", "-cf", "-n",
"-c", "2", "-c", "2",
"-t", "4", "-t", "4",
@@ -21,15 +22,16 @@ class ConfigLoaderTest {
"-ck", "testCommentary", "-ck", "testCommentary",
"-ps", "testPreferred" "-ps", "testPreferred"
}; };
ConfigLoader.initConfig(sut); CommandLine.populateCommand(Config.getInstance(), sut);
assertTrue(Config.getInstance().getLibraryPath().exists()); assertTrue(Config.getInstance().getLibraryPath().exists());
assertEquals(List.of(new AttributeConfig("ger", "ger")), Config.getInstance().getAttributeConfig()); assertEquals(List.of(new AttributeConfig("ger", "ger"), new AttributeConfig("eng", "eng")),
Config.getInstance().getAttributeConfig());
assertTrue(Config.getInstance().isSafeMode()); assertTrue(Config.getInstance().isSafeMode());
assertTrue(Config.getInstance().isForceCoherent()); assertTrue(Config.getInstance().isForceCoherent());
assertTrue(Config.getInstance().isOnlyNewFiles()); assertTrue(Config.getInstance().isOnlyNewFiles());
assertNotNull(Config.getInstance().getFilterDate()); assertNull(Config.getInstance().getFilterDate());
assertEquals(2, Config.getInstance().getCoherent()); assertEquals(2, Config.getInstance().getCoherent());
assertEquals(4, Config.getInstance().getThreads()); assertEquals(4, Config.getInstance().getThreads());

View File

@@ -0,0 +1,50 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
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;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
import static org.junit.jupiter.api.Assertions.*;
class IntegerConfigParameterTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args(), 2, (Function<Config, Integer>) Config::getThreads),
Arguments.of(args("-t", "5"), 5, (Function<Config, Integer>) Config::getThreads),
Arguments.of(args("--threads", "5"), 5, (Function<Config, Integer>) Config::getThreads)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, int expected, Function<Config, Integer> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(expected, fieldUnderTest.apply(sut.getConfig()));
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-t")));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("--threads")));
StringWriter writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
CommandLine underTest = new CommandLine(sut);
underTest = underTest.setErr(printWriter);
underTest.execute(args("-t", "0"));
printWriter.flush();
assertTrue(writer.toString().contains("ERROR: threads must be greater than or equal to 1"));
}
}

View File

@@ -0,0 +1,54 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
import org.apache.commons.lang3.SystemUtils;
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.File;
import java.nio.file.Path;
import java.util.function.Function;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
import static org.junit.jupiter.api.Assertions.*;
class MkvToolNixPathConfigParameterTest {
private static final String TEST_INVALID_DIR = "src/test/resources/test-dir";
private static final String TEST_MKVTOOLNIX_DIR = "src/test/resources/mkvtoolnix";
private static final String TEST_MKVTOOLNIX_EXE_DIR = "src/test/resources/mkvtoolnix_exe";
private static Stream<Arguments> provideTestCases() {
if (SystemUtils.IS_OS_WINDOWS) {
return Stream.of(
Arguments.of(args("-m", TEST_MKVTOOLNIX_EXE_DIR), TEST_MKVTOOLNIX_EXE_DIR, (Function<Config, File>) Config::getMkvToolNix),
Arguments.of(args("--mkvtoolnix", TEST_MKVTOOLNIX_EXE_DIR), TEST_MKVTOOLNIX_EXE_DIR, (Function<Config, File>) Config::getMkvToolNix)
);
}
return Stream.of(
Arguments.of(args("-m", TEST_MKVTOOLNIX_DIR), TEST_MKVTOOLNIX_DIR, (Function<Config, File>) Config::getMkvToolNix),
Arguments.of(args("--mkvtoolnix", TEST_MKVTOOLNIX_DIR), TEST_MKVTOOLNIX_DIR, (Function<Config, File>) Config::getMkvToolNix)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, String expected, Function<Config, File> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(Path.of(expected).toFile().getAbsolutePath(), fieldUnderTest.apply(sut.getConfig()).getAbsolutePath());
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("-m", TEST_INVALID_DIR)));
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("-m")));
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("")));
}
}

View File

@@ -0,0 +1,53 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
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.File;
import java.nio.file.Path;
import java.util.function.Function;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.PathUtils.TEST_DIR;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.PathUtils.TEST_FILE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class PathConfigParameterTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("-l", TEST_DIR), Path.of(TEST_DIR).toFile(), true, (Function<Config, File>) Config::getLibraryPath),
Arguments.of(args("-l", TEST_FILE), Path.of(TEST_FILE).toFile(), true, (Function<Config, File>) Config::getLibraryPath)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, File expected, boolean exists, Function<Config, File> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(expected.getAbsolutePath(), fieldUnderTest.apply(sut.getConfig()).getAbsolutePath());
assertEquals(exists, fieldUnderTest.apply(sut.getConfig()).exists());
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("-l", "arst")));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-l")));
assertThrows(CommandLine.UnmatchedArgumentException.class, () -> CommandLine.populateCommand(sut, args("")));
}
private static String[] args(String... args) {
String[] staticArray = new String[]{"-a", "ger:ger"};
String[] result = new String[staticArray.length + args.length];
System.arraycopy(staticArray, 0, result, 0, staticArray.length);
System.arraycopy(args, 0, result, staticArray.length, args.length);
return result;
}
}

View File

@@ -0,0 +1,42 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
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.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class PatternConfigParameterTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("-i", "[abd]?.*"), Pattern.compile("[abd]?.*"), (Function<Config, Pattern>) Config::getIncludePattern),
Arguments.of(args("-i", ".*"), Pattern.compile(".*"), (Function<Config, Pattern>) Config::getIncludePattern),
Arguments.of(args(), Pattern.compile(".*"), (Function<Config, Pattern>) Config::getIncludePattern)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, Pattern expected, Function<Config, Pattern> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(expected.pattern(), fieldUnderTest.apply(sut.getConfig()).pattern());
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-i")));
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("-i", "[")));
}
}

View File

@@ -0,0 +1,50 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
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.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class SetConfigParameterTest {
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(args("-ck", "test"), 1, (Function<Config, Set<String>>) Config::getCommentaryKeywords),
Arguments.of(args("-ck", "test", "test1", "test2", "test3", "test4"), 5, (Function<Config, Set<String>>) Config::getCommentaryKeywords),
Arguments.of(args(), 2, (Function<Config, Set<String>>) Config::getCommentaryKeywords),
Arguments.of(args("-fk", "test"), 1, (Function<Config, Set<String>>) Config::getForcedKeywords),
Arguments.of(args("-fk", "test", "test1", "test2", "test3", "test4"), 5, (Function<Config, Set<String>>) Config::getForcedKeywords),
Arguments.of(args(), 3, (Function<Config, Set<String>>) Config::getForcedKeywords),
Arguments.of(args("-ps", "test"), 1, (Function<Config, Set<String>>) Config::getPreferredSubtitles),
Arguments.of(args("-ps", "test", "test1", "test2", "test3", "test4"), 5, (Function<Config, Set<String>>) Config::getPreferredSubtitles),
Arguments.of(args(), 1, (Function<Config, Set<String>>) Config::getPreferredSubtitles)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String[] cmdArgs, int expectedSize, Function<Config, Set<String>> fieldUnderTest) {
Main sut = new Main();
CommandLine.populateCommand(sut, cmdArgs);
assertEquals(expectedSize, fieldUnderTest.apply(sut.getConfig()).size());
}
@Test
void validate() {
Main sut = new Main();
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-ck")));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-fk")));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-e")));
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-ps")));
}
}

View File

@@ -1,85 +0,0 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
import static org.junit.jupiter.api.Assertions.*;
class AttributeConfigValidatorTest {
private static CommandLineParser parser;
private static Options options;
@BeforeAll
static void before() {
parser = new DefaultParser();
options = new Options();
options.addOption(optionOf(ATTRIBUTE_CONFIG, ATTRIBUTE_CONFIG.abrv(), ATTRIBUTE_CONFIG.args()));
}
@BeforeEach
void beforeEach() {
Config.getInstance(true);
}
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(attrConfYaml("jpn", "ger"), new String[]{}, VALID, attrConf("jpn", "ger")),
Arguments.of("", new String[]{"-a", "jpn:ger"}, VALID, attrConf("jpn", "ger")),
Arguments.of(attrConfYaml("jpn", "ger", "jpn", "eng"), new String[]{}, VALID, attrConf("jpn", "ger", "jpn", "eng")),
Arguments.of("", new String[]{"-a", "jpn:ger", "jpn:eng"}, VALID, attrConf("jpn", "ger", "jpn", "eng")),
Arguments.of(attrConfYaml("jpn", "ger", "jpn", "OFF"), new String[]{}, VALID, attrConf("jpn", "ger", "jpn", "OFF")),
Arguments.of("", new String[]{"-a", "jpn:ger", "jpn:OFF"}, VALID, attrConf("jpn", "ger", "jpn", "OFF")),
Arguments.of(attrConfYaml("jpn", "invalid"), new String[]{}, INVALID, null),
Arguments.of("", new String[]{}, MISSING, null)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(String yamlArgs, String[] cmdArgs, ValidationResult expectedResult, List<AttributeConfig> expectedConfig)
throws ParseException, YamlInvalidContentException {
AttributeConfigValidator underTest = new AttributeConfigValidator();
ValidationResult result = underTest.validate(new YAML(yamlArgs), parser.parse(options, cmdArgs));
assertEquals(expectedResult, result);
assertIterableEquals(expectedConfig, Config.getInstance().getAttributeConfig());
}
private static String attrConfYaml(String... languages) {
StringBuilder yaml = new StringBuilder("attribute-config: ");
int counter = 0;
for (int i = 0; i < languages.length; i += 2) {
counter++;
yaml.append(String.format("\n %s:\n audio: %s\n subtitle: %s", counter, languages[i], languages[i+1]));
}
return yaml.toString();
}
private static List<AttributeConfig> attrConf(String... languages) {
List<AttributeConfig> conf = new ArrayList<>();
for (int i = 0; i < languages.length; i += 2) {
conf.add(new AttributeConfig(languages[i], languages[i+1]));
}
return conf;
}
}

View File

@@ -1,58 +0,0 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.yamlList;
import static org.junit.jupiter.api.Assertions.assertEquals;
class BooleanValidatorTest {
private static CommandLineParser parser;
private static Options options;
@BeforeAll
static void before() {
parser = new DefaultParser();
options = new Options();
options.addOption(optionOf(SAFE_MODE, SAFE_MODE.abrv(), SAFE_MODE.args()));
}
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(SAFE_MODE, false, "", new String[]{"-safe-mode"}, VALID),
Arguments.of(SAFE_MODE, true, "", new String[]{"-safe-mode"}, VALID),
Arguments.of(SAFE_MODE, false, "", new String[]{""}, NOT_PRESENT),
Arguments.of(SAFE_MODE, true, "", new String[]{""}, MISSING),
Arguments.of(SAFE_MODE, false, yamlList(ARGUMENTS, SAFE_MODE), new String[]{""}, VALID),
Arguments.of(SAFE_MODE, true, yamlList(ARGUMENTS, SAFE_MODE), new String[]{""}, VALID),
Arguments.of(SAFE_MODE, false, yamlList(ARGUMENTS, WINDOWS), new String[]{""}, NOT_PRESENT),
Arguments.of(SAFE_MODE, true, yamlList(ARGUMENTS, WINDOWS), new String[]{""}, MISSING)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(ConfigProperty property, boolean required, String yamlArgs, String[] cmdArgs,
ValidationResult expectedResult) throws ParseException, YamlInvalidContentException {
BooleanValidator underTest = new BooleanValidator(property, required);
ValidationResult result = underTest.validate(new YAML(yamlArgs), parser.parse(options, cmdArgs));
assertEquals(expectedResult, result);
}
}

View File

@@ -1,65 +0,0 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.io.File;
import java.nio.file.Path;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.MISSING;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
import static org.junit.jupiter.api.Assertions.*;
class MkvToolNixPathValidatorTest {
private static final String TEST_INVALID_DIR = "src/test/resources/test-dir";
private static final String TEST_MKVTOOLNIX_DIR = "src/test/resources/mkvtoolnix";
private static final String TEST_MKVTOOLNIX_EXE_DIR = "src/test/resources/mkvtoolnix_exe";
private static CommandLineParser parser;
private static Options options;
@BeforeAll
static void before() {
parser = new DefaultParser();
options = new Options();
options.addOption(optionOf(MKV_TOOL_NIX, MKV_TOOL_NIX.abrv(), MKV_TOOL_NIX.args()));
}
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of(MKV_TOOL_NIX, false, null, "", new String[]{"-m", TEST_MKVTOOLNIX_DIR}, VALID),
Arguments.of(MKV_TOOL_NIX, true, null, "", new String[]{"-m", TEST_MKVTOOLNIX_EXE_DIR}, VALID),
Arguments.of(MKV_TOOL_NIX, false, null, "mkvtoolnix: " + TEST_MKVTOOLNIX_EXE_DIR, new String[]{}, VALID),
Arguments.of(MKV_TOOL_NIX, true, null, "mkvtoolnix: " + TEST_MKVTOOLNIX_DIR, new String[]{}, VALID),
Arguments.of(MKV_TOOL_NIX, false, Path.of(TEST_MKVTOOLNIX_EXE_DIR).toFile(), "", new String[]{}, DEFAULT),
Arguments.of(MKV_TOOL_NIX, false, null, "", new String[]{}, NOT_PRESENT),
Arguments.of(MKV_TOOL_NIX, true, null, "", new String[]{}, MISSING),
Arguments.of(MKV_TOOL_NIX, true, null, "", new String[]{"-m", TEST_INVALID_DIR}, INVALID)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(ConfigProperty property, boolean required, File defaultValue, String yamlArgs, String[] cmdArgs,
ValidationResult expectedResult) throws ParseException, YamlInvalidContentException {
MkvToolNixPathValidator underTest = new MkvToolNixPathValidator(property, required, defaultValue);
ValidationResult result = underTest.validate(new YAML(yamlArgs), parser.parse(options, cmdArgs));
assertEquals(expectedResult, result);
}
}

View File

@@ -1,65 +0,0 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.io.File;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.INVALID;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.LIBRARY;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.PathUtils.TEST_DIR;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.PathUtils.TEST_FILE;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.argumentsOf;
import static org.junit.jupiter.api.Assertions.*;
class PathValidatorTest {
private static CommandLineParser parser;
private static Options options;
@BeforeAll
static void before() {
parser = new DefaultParser();
options = new Options();
options.addOption(optionOf(LIBRARY, LIBRARY.abrv(), LIBRARY.args()));
}
private static Stream<Arguments> provideTestCases() {
return Stream.of(
argumentsOf(LIBRARY, false, null, "library-path: " + TEST_DIR, new String[]{}, VALID),
argumentsOf(LIBRARY, true, null, "", new String[]{"-l", TEST_FILE}, VALID),
argumentsOf(LIBRARY, false, TEST_DIR, "", new String[]{}, DEFAULT),
argumentsOf(LIBRARY, true, TEST_FILE, "", new String[]{}, DEFAULT),
argumentsOf(LIBRARY, true, null, "", new String[]{}, MISSING),
argumentsOf(LIBRARY, false, null, "", new String[]{}, NOT_PRESENT),
argumentsOf(LIBRARY, true, null, "", new String[]{"-l", TEST_DIR + "/invalid"}, INVALID),
argumentsOf(LIBRARY, false, null, "library-path: " + TEST_DIR + "/invalid", new String[]{}, INVALID),
argumentsOf(LIBRARY, true, TEST_DIR, "", new String[]{"-l", TEST_DIR + "/invalid"}, INVALID)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(ConfigProperty property, boolean required, File defaultValue, String yamlArgs, String[] cmdArgs,
ValidationResult expectedResult) throws ParseException, YamlInvalidContentException {
PathValidator underTest = new PathValidator(property, required, defaultValue);
ValidationResult result = underTest.validate(new YAML(yamlArgs), parser.parse(options, cmdArgs));
assertEquals(expectedResult, result);
}
}

View File

@@ -1,64 +0,0 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.INVALID;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.INCLUDE_PATTERN;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.argumentsOf;
import static org.junit.jupiter.api.Assertions.*;
class PatternValidatorTest {
private static CommandLineParser parser;
private static Options options;
@BeforeAll
static void before() {
parser = new DefaultParser();
options = new Options();
options.addOption(optionOf(INCLUDE_PATTERN, INCLUDE_PATTERN.abrv(), INCLUDE_PATTERN.args()));
}
private static Stream<Arguments> provideTestCases() {
return Stream.of(
argumentsOf(INCLUDE_PATTERN, false, null, "include-pattern: \"[abd]?.*\"", new String[]{}, VALID),
argumentsOf(INCLUDE_PATTERN, true, null, "", new String[]{"-i", "[abd]?.*"}, VALID),
argumentsOf(INCLUDE_PATTERN, false, Pattern.compile(".*"), "", new String[]{}, DEFAULT),
argumentsOf(INCLUDE_PATTERN, true, Pattern.compile(".*"), "", new String[]{}, DEFAULT),
argumentsOf(INCLUDE_PATTERN, true, null, "", new String[]{}, MISSING),
argumentsOf(INCLUDE_PATTERN, false, null, "", new String[]{}, NOT_PRESENT),
argumentsOf(INCLUDE_PATTERN, true, null, "", new String[]{"-i", "?."}, INVALID),
argumentsOf(INCLUDE_PATTERN, false, null, "include-pattern: \"[arst*\"", new String[]{}, INVALID),
argumentsOf(INCLUDE_PATTERN, true, Pattern.compile(".?"), "", new String[]{"-i", "?."}, INVALID)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(ConfigProperty property, boolean required, Pattern defaultValue, String yamlArgs, String[] cmdArgs,
ValidationResult expectedResult) throws ParseException, YamlInvalidContentException {
PatternValidator underTest = new PatternValidator(property, required, defaultValue);
ValidationResult result = underTest.validate(new YAML(yamlArgs), parser.parse(options, cmdArgs));
assertEquals(expectedResult, result);
}
}

View File

@@ -1,68 +0,0 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.Config;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.COMMENTARY_KEYWORDS;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.argumentsOf;
import static org.junit.jupiter.api.Assertions.assertEquals;
class SetValidatorTest {
private static CommandLineParser parser;
private static Options options;
@BeforeAll
static void before() {
parser = new DefaultParser();
options = new Options();
options.addOption(optionOf(COMMENTARY_KEYWORDS, COMMENTARY_KEYWORDS.abrv(), COMMENTARY_KEYWORDS.args()));
}
@BeforeEach
void beforeEach() {
Config.getInstance(true);
}
private static Stream<Arguments> provideTestCases() {
return Stream.of(
argumentsOf(COMMENTARY_KEYWORDS, true, true, "", new String[]{"-ck", "test"}, VALID, 3),
argumentsOf(COMMENTARY_KEYWORDS, true, false, COMMENTARY_KEYWORDS.prop() + ": [test]", new String[]{}, VALID, 1),
argumentsOf(COMMENTARY_KEYWORDS, true, false, COMMENTARY_KEYWORDS.prop() + ":\n - test\n - test2", new String[]{}, VALID, 2),
argumentsOf(COMMENTARY_KEYWORDS, false, true, COMMENTARY_KEYWORDS.prop() + ": [test]", new String[]{}, VALID, 3),
argumentsOf(COMMENTARY_KEYWORDS, false, false, "", new String[]{"-ck", "test"}, VALID, 1),
argumentsOf(COMMENTARY_KEYWORDS, true, true, COMMENTARY_KEYWORDS.prop() + ": [commentary]", new String[]{}, VALID, 2),
argumentsOf(COMMENTARY_KEYWORDS, true, true, "", new String[]{}, MISSING, 2),
argumentsOf(COMMENTARY_KEYWORDS, false, true, "", new String[]{}, NOT_PRESENT, 2)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(ConfigProperty property, boolean required, boolean append, String yamlArgs, String[] cmdArgs,
ValidationResult expectedResult, int expectedSize) throws ParseException, YamlInvalidContentException {
SetValidator underTest = new SetValidator(property, required, append);
ValidationResult result = underTest.validate(new YAML(yamlArgs), parser.parse(options, cmdArgs));
assertEquals(expectedResult, result);
assertEquals(expectedSize, Config.getInstance().getCommentaryKeywords().size());
}
}

View File

@@ -1,61 +0,0 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validator;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult;
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty;
import at.pcgamingfreaks.yaml.YAML;
import at.pcgamingfreaks.yaml.YamlInvalidContentException;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.config.ValidationResult.*;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.model.ConfigProperty.THREADS;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.CommandLineOptionsUtil.optionOf;
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.argumentsOf;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ThreadValidatorTest {
private static CommandLineParser parser;
private static Options options;
@BeforeAll
static void before() {
parser = new DefaultParser();
options = new Options();
options.addOption(optionOf(THREADS, "t", THREADS.args()));
}
private static Stream<Arguments> provideTestCases() {
return Stream.of(
argumentsOf(THREADS, false, null, "", new String[]{"-t", "10"}, VALID),
argumentsOf(THREADS, true, null, "", new String[]{"-t", "10"}, VALID),
argumentsOf(THREADS, false, null, "threads: 10", new String[]{}, VALID),
argumentsOf(THREADS, true, null, "threads: 10", new String[]{}, VALID),
argumentsOf(THREADS, false, 2, "", new String[]{}, DEFAULT),
argumentsOf(THREADS, true, null, "", new String[]{}, MISSING),
argumentsOf(THREADS, false, null, "", new String[]{}, NOT_PRESENT),
argumentsOf(THREADS, true, null, "", new String[]{"-t", "-1"}, INVALID),
argumentsOf(THREADS, true, null, "threads: 0", new String[]{}, INVALID),
argumentsOf(THREADS, true, 2, "", new String[]{"-t", "0"}, INVALID)
);
}
@ParameterizedTest
@MethodSource("provideTestCases")
void validate(ConfigProperty property, boolean required, Integer defaultValue, String yamlArgs, String[] cmdArgs,
ValidationResult expectedResult) throws ParseException, YamlInvalidContentException {
ThreadValidator underTest = new ThreadValidator(property, required, defaultValue);
ValidationResult result = underTest.validate(new YAML(yamlArgs), parser.parse(options, cmdArgs));
assertEquals(expectedResult, result);
}
}

View File

@@ -1,11 +1,13 @@
package at.pcgamingfreaks.mkvaudiosubtitlechanger.util; package at.pcgamingfreaks.mkvaudiosubtitlechanger.util;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.Date; import java.util.Date;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@Disabled
class DateUtilsTest { class DateUtilsTest {
@Test @Test

View File

@@ -31,16 +31,24 @@ public class TestUtil {
public static FileInfoDto createFileInfo(Set<FileAttribute> defaultAudio, FileAttribute desiredAudio) { public static FileInfoDto createFileInfo(Set<FileAttribute> defaultAudio, FileAttribute desiredAudio) {
FileInfoDto fileInfoDto = new FileInfoDto(null); FileInfoDto fileInfoDto = new FileInfoDto(null);
fileInfoDto.setDefaultAudioLanes(defaultAudio); fileInfoDto.setExistingDefaultAudioLanes(defaultAudio);
fileInfoDto.setDesiredAudioLane(desiredAudio); fileInfoDto.setDesiredDefaultAudioLane(desiredAudio);
return fileInfoDto; return fileInfoDto;
} }
public static FileInfoDto createFileInfo(Set<FileAttribute> defaultSubtitle, FileAttribute desiredSubtitle, AttributeConfig config) { public static FileInfoDto createFileInfo(Set<FileAttribute> defaultSubtitle, FileAttribute desiredSubtitle, AttributeConfig config) {
FileInfoDto fileInfoDto = new FileInfoDto(null); FileInfoDto fileInfoDto = new FileInfoDto(null);
fileInfoDto.setDefaultSubtitleLanes(defaultSubtitle); fileInfoDto.setExistingDefaultSubtitleLanes(defaultSubtitle);
fileInfoDto.setDesiredSubtitleLane(desiredSubtitle); fileInfoDto.setDesiredDefaultSubtitleLane(desiredSubtitle);
fileInfoDto.setMatchedConfig(config); fileInfoDto.setMatchedConfig(config);
return fileInfoDto; return fileInfoDto;
} }
public static String[] args(String... args) {
String[] staticArray = new String[]{"-l", "/", "-a", "jpn:ger"};
String[] result = new String[staticArray.length + args.length];
System.arraycopy(staticArray, 0, result, 0, staticArray.length);
System.arraycopy(args, 0, result, staticArray.length, args.length);
return result;
}
} }