Rework to avoid using preferences object to retrieve options

This commit is contained in:
Guillaume Tâche
2024-09-22 21:59:10 +02:00
parent 7f99c48e2c
commit c59619da2d
115 changed files with 2294 additions and 765 deletions

8
.idea/.gitignore generated vendored
View File

@@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@@ -1,7 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<ScalaCodeStyleSettings>
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
</ScalaCodeStyleSettings>
</code_scheme>
</component>

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

282
.idea/csv-editor.xml generated Normal file
View File

@@ -0,0 +1,282 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CsvFileAttributes">
<option name="attributeMap">
<map>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\matplotlib\mpl-data\sample_data\Stocks.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\matplotlib\mpl-data\sample_data\data_x_x2_x3.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\matplotlib\mpl-data\sample_data\msft.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-arccos.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-arccosh.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-arcsin.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-arcsinh.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-arctan.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-arctanh.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-cbrt.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-cos.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-cosh.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-exp.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-exp2.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-expm1.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-log.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-log10.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-log1p.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-log2.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-sin.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-sinh.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-tan.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\core\tests\data\umath-validation-set-tanh.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\random\tests\data\mt19937-testset-1.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\random\tests\data\mt19937-testset-2.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\random\tests\data\pcg64-testset-1.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\random\tests\data\pcg64-testset-2.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\random\tests\data\pcg64dxsm-testset-1.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\random\tests\data\pcg64dxsm-testset-2.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\random\tests\data\philox-testset-1.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\random\tests\data\philox-testset-2.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\random\tests\data\sfc64-testset-1.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\numpy\random\tests\data\sfc64-testset-2.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\sklearn\datasets\data\boston_house_prices.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\sklearn\datasets\data\breast_cancer.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\sklearn\datasets\data\iris.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\sklearn\datasets\data\linnerud_exercise.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\sklearn\datasets\data\linnerud_physiological.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
<entry key="\tools\whisperx\whisperx-env\Lib\site-packages\sklearn\datasets\data\wine_data.csv">
<value>
<Attribute>
<option name="separator" value="," />
</Attribute>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@@ -1,30 +1,53 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="AbsoluteAlignmentInUserInterface" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AbstractClassExtendsConcreteClass" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AbstractClassExtendsConcreteClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AbstractClassNeverImplemented" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AbstractClassNeverImplemented" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AbstractMethodCallInConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AbstractMethodOverridesAbstractMethod" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AbstractMethodOverridesAbstractMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AbstractMethodOverridesConcreteMethod" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AbstractMethodOverridesConcreteMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AbstractMethodWithMissingImplementations" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AccessToNonThreadSafeStaticFieldFromInstance" enabled="true" level="WARNING" enabled_by_default="true">
<option name="nonThreadSafeClasses">
<value />
</option>
<option name="nonThreadSafeTypes" value="" />
</inspection_tool>
<inspection_tool class="AccessToStaticFieldLockedOnInstance" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AccessToStaticFieldLockedOnInstance" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AlphaUnsortedPropertiesFile" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="AlphaUnsortedPropertiesFile" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="AmbiguousFieldAccess" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AmbiguousFieldAccess" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AmbiguousMethodCall" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AmbiguousMethodCall" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AnonymousClassMethodCount" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_limit" value="1" />
</inspection_tool>
<inspection_tool class="AnonymousClassVariableHidesContainingMethodVariable" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AnonymousInnerClass" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AnonymousInnerClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AnonymousInnerClassMayBeStatic" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AnonymousInnerClassMayBeStatic" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ArrayEquality" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ArrayEquality" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssertEqualsCalledOnArray" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssertMessageNotString" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AssertMessageNotString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssertsWithoutMessages" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AssertsWithoutMessages" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssignmentOrReturnOfFieldWithMutableType" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssignmentToForLoopParameter" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_checkForeachParameters" value="true" />
</inspection_tool>
<inspection_tool class="AssignmentToForLoopParameterJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AssignmentToForLoopParameterJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssignmentToFunctionParameterJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AssignmentToFunctionParameterJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssignmentToLambdaParameter" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AssignmentToLambdaParameter" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssignmentToMethodParameter" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreTransformationOfOriginalParameter" value="false" />
</inspection_tool>
<inspection_tool class="AssignmentToNull" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="AssignmentToNull" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreAssignmentsToFields" value="true" /> <option name="ignoreAssignmentsToFields" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="AssignmentToStaticFieldFromInstanceMethod" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AssignmentToStaticFieldFromInstanceMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssignmentToSuperclassField" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,ch.bger.common.dbhelper.impl.AbstractDatabaseQuerier,connection|internalConnection" /> <option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,ch.bger.common.dbhelper.impl.AbstractDatabaseQuerier,connection|internalConnection,ch.bger.ajonline.client.AbstractClient,client" />
</inspection_tool> </inspection_tool>
<inspection_tool class="AutoTupling" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AutoTupling" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AwaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AwaitWithoutCorrespondingSignal" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="AwaitWithoutCorrespondingSignal" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BadExceptionCaught" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="BadExceptionCaught" enabled="true" level="WARNING" enabled_by_default="true">
<option name="exceptionsString" value="" /> <option name="exceptionsString" value="" />
@@ -59,12 +82,17 @@
<option name="questionString" value="add,are,can,check,contains,could,endsWith,equals,has,is,matches,must,put,remove,shall,should,startsWith,was,were,will,would" /> <option name="questionString" value="add,are,can,check,contains,could,endsWith,equals,has,is,matches,must,put,remove,shall,should,startsWith,was,were,will,would" />
</inspection_tool> </inspection_tool>
<inspection_tool class="BooleanParameter" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="BooleanParameter" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BoundedWildcard" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BreakStatement" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="BreakStatement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BreakStatementJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="BreakStatementJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BreakStatementWithLabel" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="BreakStatementWithLabel" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BreakStatementWithLabelJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="BreakStatementWithLabelJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BulkFileAttributesRead" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="BulkFileAttributesRead" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CallToNativeMethodWhileLocked" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="CallToNativeMethodWhileLocked" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CallToSimpleGetterInClass" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreGetterCallsOnOtherObjects" value="false" />
<option name="onlyReportPrivateGetter" value="false" />
</inspection_tool>
<inspection_tool class="CallToSimpleSetterInClass" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="CallToSimpleSetterInClass" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreSetterCallsOnOtherObjects" value="false" /> <option name="ignoreSetterCallsOnOtherObjects" value="false" />
<option name="onlyReportPrivateSetter" value="false" /> <option name="onlyReportPrivateSetter" value="false" />
@@ -98,7 +126,6 @@
<inspection_tool class="ComparableImplementedButEqualsNotOverridden" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ComparableImplementedButEqualsNotOverridden" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ComparatorNotSerializable" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ComparatorNotSerializable" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CompareToUsesNonFinalVariable" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="CompareToUsesNonFinalVariable" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ComparisonOfShortAndChar" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConditionSignal" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ConditionSignal" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConditionalExpressionWithIdenticalBranchesJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ConditionalExpressionWithIdenticalBranchesJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConfusingFloatingPointLiteral" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ConfusingFloatingPointLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -107,6 +134,7 @@
<inspection_tool class="ConnectionResource" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ConnectionResource" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConstantAssertArgument" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ConstantAssertArgument" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConstantAssertCondition" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ConstantAssertCondition" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConstantDeclaredInInterface" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConstantJUnitAssertArgument" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ConstantJUnitAssertArgument" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConstantMathCall" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ConstantMathCall" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ContinueStatement" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ContinueStatement" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -115,12 +143,13 @@
<inspection_tool class="ContinueStatementWithLabelJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ContinueStatementWithLabelJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CovariantEquals" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="CovariantEquals" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CyclicClassDependency" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="CyclicClassDependency" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CyclicPackageDependency" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DateToString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DeclareCollectionAsInterface" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="DeclareCollectionAsInterface" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreLocalVariables" value="false" /> <option name="ignoreLocalVariables" value="false" />
<option name="ignorePrivateMethodsAndFields" value="false" /> <option name="ignorePrivateMethodsAndFields" value="false" />
</inspection_tool> </inspection_tool>
<inspection_tool class="DeconstructionCanBeUsed" enabled="true" level="INFORMATION" enabled_by_default="true" /> <inspection_tool class="DeconstructionCanBeUsed" enabled="true" level="INFORMATION" enabled_by_default="true" />
<inspection_tool class="DefaultNotLastCaseInSwitch" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DefaultNotLastCaseInSwitchJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="DefaultNotLastCaseInSwitchJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DisjointPackage" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="DisjointPackage" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DivideByZeroJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="DivideByZeroJS" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -131,6 +160,7 @@
<inspection_tool class="DuplicateBooleanBranch" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="DuplicateBooleanBranch" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DuplicateConditionJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="DuplicateConditionJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DuplicatePropertyInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="DuplicatePropertyInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DynamicRegexReplaceableByCompiledPattern" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="DynamicallyGeneratedCodeJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="DynamicallyGeneratedCodeJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="EmptyCatchBlockJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="EmptyCatchBlockJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="EmptyClass" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="EmptyClass" enabled="true" level="WARNING" enabled_by_default="true">
@@ -141,6 +171,9 @@
<option name="ignoreThrowables" value="true" /> <option name="ignoreThrowables" value="true" />
<option name="commentsAreContent" value="true" /> <option name="commentsAreContent" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="EmptyDirectory" enabled="true" level="WEAK WARNING" enabled_by_default="true" editorAttributes="INFO_ATTRIBUTES">
<option name="onlyReportDirectoriesUnderSourceRoots" value="true" />
</inspection_tool>
<inspection_tool class="EmptyTryBlockJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="EmptyTryBlockJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="EnhancedSwitchBackwardMigration" enabled="false" level="INFORMATION" enabled_by_default="false" /> <inspection_tool class="EnhancedSwitchBackwardMigration" enabled="false" level="INFORMATION" enabled_by_default="false" />
<inspection_tool class="EnumerationCanBeIteration" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="EnumerationCanBeIteration" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -188,6 +221,7 @@
<inspection_tool class="HibernateResource" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="HibernateResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="insideTryAllowed" value="false" /> <option name="insideTryAllowed" value="false" />
</inspection_tool> </inspection_tool>
<inspection_tool class="HtmlTagCanBeJavadocTag" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IOResource" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="IOResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredTypesString" value="java.io.ByteArrayOutputStream,java.io.ByteArrayInputStream,java.io.StringBufferInputStream,java.io.CharArrayWriter,java.io.CharArrayReader,java.io.StringWriter,java.io.StringReader" /> <option name="ignoredTypesString" value="java.io.ByteArrayOutputStream,java.io.ByteArrayInputStream,java.io.StringBufferInputStream,java.io.CharArrayWriter,java.io.CharArrayReader,java.io.StringWriter,java.io.StringReader" />
<option name="insideTryAllowed" value="false" /> <option name="insideTryAllowed" value="false" />
@@ -195,6 +229,7 @@
<inspection_tool class="IfMayBeConditional" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="IfMayBeConditional" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IgnoredJUnitTest" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="IgnoredJUnitTest" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IllegalDependencyOnInternalPackage" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="IllegalDependencyOnInternalPackage" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="ImplicitDefaultCharsetUsage" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="InconsistentLanguageLevel" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="InconsistentLanguageLevel" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="InconsistentLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="InconsistentLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IncorrectFormatting" enabled="false" level="WEAK WARNING" enabled_by_default="false"> <inspection_tool class="IncorrectFormatting" enabled="false" level="WEAK WARNING" enabled_by_default="false">
@@ -203,6 +238,9 @@
</scope> </scope>
<option name="reportPerFile" value="true" /> <option name="reportPerFile" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="InnerClassOnInterface" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_ignoreInnerInterfaces" value="true" />
</inspection_tool>
<inspection_tool class="InnerClassReferencedViaSubclass" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="InnerClassReferencedViaSubclass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="InnerClassVariableHidesOuterClassVariable" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="InnerClassVariableHidesOuterClassVariable" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_ignoreInvisibleFields" value="true" /> <option name="m_ignoreInvisibleFields" value="true" />
@@ -215,6 +253,7 @@
<inspection_tool class="InstanceofIncompatibleInterface" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="InstanceofIncompatibleInterface" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="InstanceofThis" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="InstanceofThis" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IntLiteralMayBeLongLiteral" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="IntLiteralMayBeLongLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="InterfaceMayBeAnnotatedFunctional" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="InterfaceNeverImplemented" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="InterfaceNeverImplemented" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreInterfacesThatOnlyDeclareConstants" value="false" /> <option name="ignoreInterfacesThatOnlyDeclareConstants" value="false" />
</inspection_tool> </inspection_tool>
@@ -328,6 +367,10 @@
<option name="REPORT_VARIABLES" value="true" /> <option name="REPORT_VARIABLES" value="true" />
<option name="REPORT_PARAMETERS" value="true" /> <option name="REPORT_PARAMETERS" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="LocalVariableHidingMemberVariable" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_ignoreInvisibleFields" value="true" />
<option name="m_ignoreStaticMethods" value="true" />
</inspection_tool>
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="LoggerInitializedWithForeignClass" enabled="true" level="WARNING" enabled_by_default="true">
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" /> <option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
</inspection_tool> </inspection_tool>
@@ -349,9 +392,11 @@
<option name="ignoreStaticMethodsFromNonStaticInnerClass" value="false" /> <option name="ignoreStaticMethodsFromNonStaticInnerClass" value="false" />
<option name="onlyReportStaticMethods" value="false" /> <option name="onlyReportStaticMethods" value="false" />
</inspection_tool> </inspection_tool>
<inspection_tool class="MethodOverloadsParentMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MethodOverridesInaccessibleMethodOfSuper" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="MethodOverridesInaccessibleMethodOfSuper" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MethodOverridesStaticMethod" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="MethodOverridesStaticMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MigrateAssertToMatcherAssert" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="MigrateAssertToMatcherAssert" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisorderedAssertEqualsArguments" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisorderedAssertEqualsParameters" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="MisorderedAssertEqualsParameters" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MissingDeprecatedAnnotation" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="MissingDeprecatedAnnotation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MissingJavadoc" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="MissingJavadoc" enabled="true" level="WARNING" enabled_by_default="true">
@@ -408,6 +453,7 @@
<inspection_tool class="MisspelledEquals" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="MisspelledEquals" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MisspelledMethodName" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="MisspelledMethodName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MultipleExceptionsDeclaredOnTestMethod" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="MultipleExceptionsDeclaredOnTestMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MultipleTopLevelClassesInFile" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NativeMethods" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NativeMethods" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NegatedConditional" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="NegatedConditional" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_ignoreNegatedNullComparison" value="false" /> <option name="m_ignoreNegatedNullComparison" value="false" />
@@ -415,6 +461,7 @@
</inspection_tool> </inspection_tool>
<inspection_tool class="NegatedConditionalExpression" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NegatedConditionalExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NegatedConditionalExpressionJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NegatedConditionalExpressionJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NegatedEqualityExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NegatedIfElse" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="NegatedIfElse" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_ignoreNegatedNullComparison" value="false" /> <option name="m_ignoreNegatedNullComparison" value="false" />
<option name="m_ignoreNegatedZeroComparison" value="false" /> <option name="m_ignoreNegatedZeroComparison" value="false" />
@@ -441,6 +488,7 @@
</inspection_tool> </inspection_tool>
<inspection_tool class="NonSerializableObjectBoundToHttpSession" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NonSerializableObjectBoundToHttpSession" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NonSerializableObjectPassedToObjectStream" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NonSerializableObjectPassedToObjectStream" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NonShortCircuitBoolean" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NonShortCircuitBooleanExpressionJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NonShortCircuitBooleanExpressionJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NonStaticFinalLogger" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="NonStaticFinalLogger" enabled="true" level="WARNING" enabled_by_default="true">
<option name="loggerClassName" value="java.util.logging.Logger,org.slf4j.Logger,org.apache.commons.logging.Log,org.apache.log4j.Logger,org.apache.logging.log4j.Logger" /> <option name="loggerClassName" value="java.util.logging.Logger,org.slf4j.Logger,org.apache.commons.logging.Log,org.apache.log4j.Logger,org.apache.logging.log4j.Logger" />
@@ -448,6 +496,8 @@
<inspection_tool class="NonSynchronizedMethodOverridesSynchronizedMethod" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NonSynchronizedMethodOverridesSynchronizedMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NonThreadSafeLazyInitialization" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NonThreadSafeLazyInitialization" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NullThrown" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NullThrown" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NumericToString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ObjectAllocationInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ObjectInstantiationInEqualsHashCode" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ObjectInstantiationInEqualsHashCode" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ObjectNotify" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ObjectNotify" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ObsoleteCollection" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="ObsoleteCollection" enabled="true" level="WARNING" enabled_by_default="true">
@@ -460,8 +510,11 @@
<inspection_tool class="OverlyStrongTypeCast" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="OverlyStrongTypeCast" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreInMatchingInstanceof" value="true" /> <option name="ignoreInMatchingInstanceof" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="OverridableMethodCallDuringObjectConstruction" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="OverriddenMethodCallDuringObjectConstruction" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PackageDotHtmlMayBePackageInfo" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PackageDotHtmlMayBePackageInfo" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PackageInMultipleModules" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PackageInMultipleModules" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PackageVisibleField" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ParameterHidingMemberVariable" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="ParameterHidingMemberVariable" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_ignoreInvisibleFields" value="true" /> <option name="m_ignoreInvisibleFields" value="true" />
<option name="m_ignoreStaticMethodParametersHidingInstanceFields" value="true" /> <option name="m_ignoreStaticMethodParametersHidingInstanceFields" value="true" />
@@ -476,10 +529,14 @@
<inspection_tool class="ParameterTypePreventsOverriding" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ParameterTypePreventsOverriding" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ParameterizedParametersStaticCollection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ParameterizedParametersStaticCollection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PlatformDetectionJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PlatformDetectionJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PointlessIndexOfComparison" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PostfixMethodCall" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PostfixMethodCall" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ProblematicVarargsMethodOverride" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ProblematicWhitespace" enabled="true" level="WARNING" enabled_by_default="false"> <inspection_tool class="ProblematicWhitespace" enabled="true" level="WARNING" enabled_by_default="false">
<scope name="Project Files" level="WARNING" enabled="true" /> <scope name="Project Files" level="WARNING" enabled="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PropertyValueSetToItself" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ProtectedField" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PublicConstructorInNonPublicClass" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PublicConstructorInNonPublicClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PublicFieldAccessedInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PublicFieldAccessedInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PublicMethodNotExposedInInterface" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="PublicMethodNotExposedInInterface" enabled="true" level="WARNING" enabled_by_default="true">
@@ -488,6 +545,20 @@
</option> </option>
<option name="onlyWarnIfContainingClassImplementsAnInterface" value="false" /> <option name="onlyWarnIfContainingClassImplementsAnInterface" value="false" />
</inspection_tool> </inspection_tool>
<inspection_tool class="PyAugmentAssignmentInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyClassicStyleClassInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ourVersions">
<value>
<list size="1">
<item index="0" class="java.lang.String" itemvalue="3.13" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PyMissingTypeHintsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="QodanaJavaSanity" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="QodanaKotlinSanity" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="QsUndeclaredPathMimeTypesInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="QsUndeclaredPathMimeTypesInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="RandomDoubleForRandomInteger" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="RandomDoubleForRandomInteger" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ReadObjectAndWriteObjectPrivate" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ReadObjectAndWriteObjectPrivate" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -507,6 +578,101 @@
<option name="ignoreObscureOperators" value="false" /> <option name="ignoreObscureOperators" value="false" />
</inspection_tool> </inspection_tool>
<inspection_tool class="ReplaceAssignmentWithOperatorAssignmentJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ReplaceAssignmentWithOperatorAssignmentJS" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ResultOfObjectAllocationIgnored" enabled="true" level="WARNING" enabled_by_default="true">
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
<scope name="Tests" level="WARNING" enabled="false" />
</inspection_tool>
<inspection_tool class="ResultSetIndexZero" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ResultSetIndexZero" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ReturnOfInnerClass" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ReturnOfInnerClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ReuseOfLocalVariableJS" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ReuseOfLocalVariableJS" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -524,15 +690,20 @@
<inspection_tool class="SideEffectsInMonadicTransformation" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SideEffectsInMonadicTransformation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SimplifiableAnnotation" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SimplifiableAnnotation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SimplifiableEqualsExpression" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SimplifiableEqualsExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="Singleton" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SleepWhileHoldingLock" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SleepWhileHoldingLock" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SocketResource" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="SocketResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="insideTryAllowed" value="false" /> <option name="insideTryAllowed" value="false" />
</inspection_tool> </inspection_tool>
<inspection_tool class="SqlGotoInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StandardJS" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="StandardJS" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="StaticCallOnSubclass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StaticFieldReferenceOnSubclass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StaticGuardedByInstance" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StaticGuardedByInstance" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StaticInheritance" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StaticInheritance" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StaticNonFinalField" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StaticNonFinalField" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StaticPseudoFunctionalStyleMethod" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StaticPseudoFunctionalStyleMethod" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringBufferField" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringConcatenationArgumentToLogCall" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StringConcatenationArgumentToLogCall" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringConcatenationInFormatCall" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StringConcatenationInFormatCall" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringConcatenationInMessageFormatCall" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StringConcatenationInMessageFormatCall" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -544,13 +715,20 @@
<inspection_tool class="SubtractionInCompareTo" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SubtractionInCompareTo" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SuperTearDownInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SuppressionAnnotation" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SuppressionAnnotation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SuspiciousArrayCast" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SuspiciousGetterSetter" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SuspiciousGetterSetter" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SuspiciousLiteralUnderscore" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SuspiciousLiteralUnderscore" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SuspiciousLocalesLanguages" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SuspiciousLocalesLanguages" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SynchronizationOnStaticField" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SynchronizeOnLock" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SynchronizeOnThis" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SynchronizedMethod" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="SynchronizedMethod" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_includeNativeMethods" value="true" /> <option name="m_includeNativeMethods" value="true" />
<option name="ignoreSynchronizedSuperMethods" value="true" /> <option name="ignoreSynchronizedSuperMethods" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="SynchronizedOnLiteralObject" enabled="true" level="WARNING" enabled_by_default="true">
<option name="warnOnAllPossiblyLiterals" value="true" />
</inspection_tool>
<inspection_tool class="SystemExit" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="SystemExit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreInMainMethod" value="true" /> <option name="ignoreInMainMethod" value="true" />
</inspection_tool> </inspection_tool>
@@ -571,9 +749,12 @@
<inspection_tool class="ThreadLocalNotStaticFinal" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ThreadLocalNotStaticFinal" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ThreadPriority" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ThreadPriority" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ThreadStartInConstruction" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="ThreadStartInConstruction" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ThreadStopSuspendResume" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ThreadYield" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ThrowCaughtLocally" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="ThrowCaughtLocally" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreRethrownExceptions" value="false" /> <option name="ignoreRethrownExceptions" value="false" />
</inspection_tool> </inspection_tool>
<inspection_tool class="TimeToString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TooBroadThrows" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="TooBroadThrows" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TransientFieldNotInitialized" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="TransientFieldNotInitialized" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TsLint" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="TsLint" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -586,6 +767,12 @@
</inspection_tool> </inspection_tool>
<inspection_tool class="TypeParameterExtendsFinalClass" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="TypeParameterExtendsFinalClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnconditionalWait" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UnconditionalWait" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessarilyQualifiedStaticUsage" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_ignoreStaticFieldAccesses" value="false" />
<option name="m_ignoreStaticMethodCalls" value="false" />
<option name="m_ignoreStaticAccessFromStaticContext" value="false" />
</inspection_tool>
<inspection_tool class="UnnecessarilyQualifiedStaticallyImportedElement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryConstantArrayCreationExpression" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UnnecessaryConstantArrayCreationExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryConstructor" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UnnecessaryConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryExplicitNumericCast" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UnnecessaryExplicitNumericCast" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -593,6 +780,9 @@
<inspection_tool class="UnnecessaryJavaDocLink" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="UnnecessaryJavaDocLink" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreInlineLinkToSuper" value="false" /> <option name="ignoreInlineLinkToSuper" value="false" />
</inspection_tool> </inspection_tool>
<inspection_tool class="UnnecessarySuperConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessarySuperQualifier" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnreachableCode" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnstableTypeUsedInSignature" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UnstableTypeUsedInSignature" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnusedCatchParameterJS" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="UnusedCatchParameterJS" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_ignoreCatchBlocksWithComments" value="false" /> <option name="m_ignoreCatchBlocksWithComments" value="false" />
@@ -601,6 +791,10 @@
<inspection_tool class="UpperCaseFieldNameNotConstant" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UpperCaseFieldNameNotConstant" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UseEllipsisInPropertyInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UseEllipsisInPropertyInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UseOfAWTPeerClass" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UseOfAWTPeerClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UseOfAnotherObjectsPrivateField" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreSameClass" value="false" />
<option name="ignoreEquals" value="false" />
</inspection_tool>
<inspection_tool class="UseOfClone" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UseOfClone" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UseOfJDBCDriverClass" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UseOfJDBCDriverClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UseOfObsoleteAssert" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="UseOfObsoleteAssert" enabled="true" level="WARNING" enabled_by_default="true" />
@@ -622,6 +816,7 @@
<inspection_tool class="WaitCalledOnCondition" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="WaitCalledOnCondition" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="WaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="WaitNotInLoop" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="WaitNotifyNotInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="WaitNotifyNotInSynchronizedContext" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="WaitOrAwaitWithoutTimeout" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="WaitWithoutCorrespondingNotify" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="WaitWithoutCorrespondingNotify" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" /> <option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />

4
.idea/misc.xml generated
View File

@@ -11,7 +11,5 @@
<component name="NodePackageJsonFileManager"> <component name="NodePackageJsonFileManager">
<packageJsonPaths /> <packageJsonPaths />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
<output url="file://$PROJECT_DIR$/out" />
</component>
</project> </project>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ScalaCompilerConfiguration">
<option name="separateProdTestSources" value="false" />
</component>
</project>

11
.idea/sonarlint.xml generated
View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SonarLintProjectSettings">
<option name="moduleMapping">
<map>
<entry key="autosubtitle-gui-fx" value="autosubtitle-fx" />
<entry key="whisper-base" value="whisperbase" />
</map>
</option>
</component>
</project>

2
.idea/vcs.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="" vcs="Git" />
</component> </component>
</project> </project>

462
.idea/workspace.xml generated Normal file
View File

@@ -0,0 +1,462 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AnalysisUIOptions">
<option name="ANALYZE_INJECTED_CODE" value="false" />
</component>
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="ff40425e-42c7-4b0e-a76a-6e50cecddb1a" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/.idea/csv-editor.xml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/ExportOptions.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/ImportOptions.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/FormatException.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/FormatOptions.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/ParseOptions.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/ExtractOptions.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/api/src/test/java/com/github/gtache/autosubtitle/subtitle/converter/TestSubtitleConverterProvider.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/impl/FormatOptionsImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/impl/ParseOptionsImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/impl/ExtractOptionsImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/impl/ExportOptionsImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/impl/ImportOptionsImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/converter/impl/TestFormatOptionsImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/converter/impl/TestParseOptionsImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/extractor/impl/TestExtractOptionsImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/impl/TestExportOptionsImpl.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/impl/TestImportOptionsImpl.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/codeStyles/Project.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/codeStyles/codeStyleConfig.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/Project_Default.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/scala_compiler.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/sonarlint.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/vcs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/File.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/File.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/Language.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/Language.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/VideoConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/VideoConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/archive/Archiver.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/archive/Archiver.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/process/ProcessListener.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/process/ProcessListener.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/setup/SetupManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/setup/SetupManager.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/SubtitleImporterExporter.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/SubtitleImporterExporter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/SubtitleConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/SubtitleConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/SubtitleConverterProvider.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/SubtitleConverterProvider.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/ExtractionModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/ExtractionModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/SubtitleExtractor.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/SubtitleExtractor.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/test/java/com/github/gtache/autosubtitle/subtitle/TestSubtitleImporterExporter.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/test/java/com/github/gtache/autosubtitle/subtitle/TestSubtitleImporterExporter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/test/java/com/github/gtache/autosubtitle/subtitle/converter/TestSubtitleConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/api/src/test/java/com/github/gtache/autosubtitle/subtitle/converter/TestSubtitleConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/api/src/test/java/com/github/gtache/autosubtitle/subtitle/extractor/TestSubtitleExtractor.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/cli/src/main/java/com/github/gtache/autosubtitle/cli/Cli.java" beforeDir="false" afterPath="$PROJECT_DIR$/cli/src/main/java/com/github/gtache/autosubtitle/cli/Cli.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/client/src/main/java/com/github/gtache/autosubtitle/client/RemoteVideoConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/client/src/main/java/com/github/gtache/autosubtitle/client/RemoteVideoConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/client/src/main/java/com/github/gtache/autosubtitle/client/RemoteVideoLoader.java" beforeDir="false" afterPath="$PROJECT_DIR$/client/src/main/java/com/github/gtache/autosubtitle/client/RemoteVideoLoader.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/client/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/client/RemoteSubtitleConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/client/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/client/RemoteSubtitleConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/client/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/client/RemoteSubtitleExtractor.java" beforeDir="false" afterPath="$PROJECT_DIR$/client/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/client/RemoteSubtitleExtractor.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/client/src/main/java/com/github/gtache/autosubtitle/translation/client/RemoteTranslator.java" beforeDir="false" afterPath="$PROJECT_DIR$/client/src/main/java/com/github/gtache/autosubtitle/translation/client/RemoteTranslator.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/conda/src/main/java/com/github/gtache/autosubtitle/setup/conda/CondaSetupManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/conda/src/main/java/com/github/gtache/autosubtitle/setup/conda/CondaSetupManager.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/conda/src/test/java/com/github/gtache/autosubtitle/setup/conda/TestCondaSetupManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/conda/src/test/java/com/github/gtache/autosubtitle/setup/conda/TestCondaSetupManager.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/archive/impl/ZipDecompresser.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/archive/impl/ZipArchiver.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/modules/archive/impl/ArchiveModule.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/modules/archive/impl/ArchiveModule.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/modules/subtitle/impl/SubtitleModule.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/modules/subtitle/impl/SubtitleModule.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/impl/ASSSubtitleConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/impl/ASSSubtitleConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/impl/SRTSubtitleConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/converter/impl/SRTSubtitleConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/impl/SubtitleCollectionImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/impl/SubtitleCollectionImpl.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/impl/SubtitleImporterExporterImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/main/java/com/github/gtache/autosubtitle/subtitle/impl/SubtitleImporterExporterImpl.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/archive/impl/TestZipDecompresser.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/archive/impl/TestZipArchiver.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/impl/TestArchitecture.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/impl/TestArchitecture.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/converter/impl/TestASSSubtitleConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/converter/impl/TestASSSubtitleConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/converter/impl/TestSRTSubtitleConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/converter/impl/TestSRTSubtitleConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/extractor/impl/TestAbstractSubtitleExtractor.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/extractor/impl/TestAbstractSubtitleExtractor.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/impl/TestSubtitleImporterExporterImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/core/src/test/java/com/github/gtache/autosubtitle/subtitle/impl/TestSubtitleImporterExporterImpl.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ffmpeg/src/main/java/com/github/gtache/autosubtitle/archive/ffmpeg/TarArchiver.java" beforeDir="false" afterPath="$PROJECT_DIR$/ffmpeg/src/main/java/com/github/gtache/autosubtitle/archive/ffmpeg/TarArchiver.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ffmpeg/src/main/java/com/github/gtache/autosubtitle/archive/ffmpeg/XZArchiver.java" beforeDir="false" afterPath="$PROJECT_DIR$/ffmpeg/src/main/java/com/github/gtache/autosubtitle/archive/ffmpeg/XZArchiver.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ffmpeg/src/main/java/com/github/gtache/autosubtitle/ffmpeg/FFmpegVideoConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/ffmpeg/src/main/java/com/github/gtache/autosubtitle/ffmpeg/FFmpegVideoConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ffmpeg/src/main/java/module-info.java" beforeDir="false" afterPath="$PROJECT_DIR$/ffmpeg/src/main/java/module-info.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ffmpeg/src/test/java/com/github/gtache/autosubtitle/ffmpeg/TestFFmpegVideoConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/ffmpeg/src/test/java/com/github/gtache/autosubtitle/ffmpeg/TestFFmpegVideoConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ffmpeg/src/test/java/com/github/gtache/autosubtitle/setup/ffmpeg/TestFFmpegSetupManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/ffmpeg/src/test/java/com/github/gtache/autosubtitle/setup/ffmpeg/TestFFmpegSetupManager.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/api/src/main/java/com/github/gtache/autosubtitle/gui/parameters/ParametersModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/api/src/main/java/com/github/gtache/autosubtitle/gui/parameters/ParametersModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/api/src/main/java/com/github/gtache/autosubtitle/gui/subtitles/SubtitlesModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/api/src/main/java/com/github/gtache/autosubtitle/gui/subtitles/SubtitlesModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/api/src/main/java/com/github/gtache/autosubtitle/gui/work/WorkModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/api/src/main/java/com/github/gtache/autosubtitle/gui/work/WorkModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/CombinedResourceBundle.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/CombinedResourceBundle.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/spi/MainBundleProvider.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/spi/MainBundleProvider.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/spi/ParametersBundleProvider.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/spi/ParametersBundleProvider.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/spi/SetupBundleProvider.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/spi/SetupBundleProvider.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/spi/SubtitlesBundleProvider.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/spi/SubtitlesBundleProvider.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/spi/WorkBundleProvider.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/gui/impl/spi/WorkBundleProvider.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/modules/gui/impl/GuiCoreModule.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/core/src/main/java/com/github/gtache/autosubtitle/modules/gui/impl/GuiCoreModule.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/parameters/fx/FXParametersController.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/parameters/fx/FXParametersController.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/parameters/fx/FXParametersModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/parameters/fx/FXParametersModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/subtitles/fx/FXSubtitlesBinder.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/subtitles/fx/FXSubtitlesBinder.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/subtitles/fx/FXSubtitlesController.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/subtitles/fx/FXSubtitlesController.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/subtitles/fx/FXSubtitlesModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/subtitles/fx/FXSubtitlesModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/work/fx/FXWorkBinder.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/work/fx/FXWorkBinder.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/work/fx/FXWorkController.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/work/fx/FXWorkController.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/work/fx/FXWorkModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/main/java/com/github/gtache/autosubtitle/gui/work/fx/FXWorkModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/main/java/module-info.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/main/java/module-info.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/gui/parameters/fx/TestFXParametersModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/gui/parameters/fx/TestFXParametersModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/gui/subtitles/fx/TestFXSubtitlesBinder.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/gui/subtitles/fx/TestFXSubtitlesBinder.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/gui/subtitles/fx/TestFXSubtitlesModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/gui/subtitles/fx/TestFXSubtitlesModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/gui/work/fx/TestFXWorkBinder.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/gui/work/fx/TestFXWorkBinder.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/gui/work/fx/TestFXWorkModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/gui/work/fx/TestFXWorkModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/subtitle/gui/fx/TestObservableSubtitleCollectionImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/subtitle/gui/fx/TestObservableSubtitleCollectionImpl.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/subtitle/gui/fx/TestObservableSubtitleImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/test/java/com/github/gtache/autosubtitle/subtitle/gui/fx/TestObservableSubtitleImpl.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/run/src/main/java/com/github/gtache/autosubtitle/gui/run/Main.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/run/src/main/java/com/github/gtache/autosubtitle/gui/run/Main.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/gui/run/src/main/java/com/github/gtache/autosubtitle/modules/gui/run/RunComponent.java" beforeDir="false" afterPath="$PROJECT_DIR$/gui/run/src/main/java/com/github/gtache/autosubtitle/modules/gui/run/RunComponent.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/pom.xml" beforeDir="false" afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/base/pom.xml" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/base/pom.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/base/src/main/java/com/github/gtache/autosubtitle/modules/subtitle/parser/json/whisper/base/WhisperJsonModule.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/base/src/main/java/com/github/gtache/autosubtitle/modules/subtitle/parser/json/whisper/base/WhisperJsonModule.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/base/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/whisper/base/WhisperSubtitleExtractor.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/base/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/whisper/base/WhisperSubtitleExtractor.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/base/src/main/java/com/github/gtache/autosubtitle/subtitle/parser/json/whisper/base/JSONSubtitleConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/base/src/main/java/com/github/gtache/autosubtitle/subtitle/parser/json/whisper/base/JSONSubtitleConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/base/src/main/java/module-info.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/base/src/main/java/module-info.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/common/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/whisper/AbstractWhisperSubtitleExtractor.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/common/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/whisper/AbstractWhisperSubtitleExtractor.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/common/src/main/java/module-info.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/common/src/main/java/module-info.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/common/src/test/java/com/github/gtache/autosubtitle/subtitle/extractor/whisper/TestAbstractWhisperSubtitleExtractor.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/common/src/test/java/com/github/gtache/autosubtitle/subtitle/extractor/whisper/TestAbstractWhisperSubtitleExtractor.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/pom.xml" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/pom.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/whisperx/pom.xml" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/whisperx/pom.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/whisperx/src/main/java/com/github/gtache/autosubtitle/modules/subtitle/parser/json/whisperx/WhisperXJsonModule.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/whisperx/src/main/java/com/github/gtache/autosubtitle/modules/subtitle/parser/json/whisperx/WhisperXJsonModule.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/whisperx/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/whisperx/WhisperXSubtitleExtractor.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/whisperx/src/main/java/com/github/gtache/autosubtitle/subtitle/extractor/whisperx/WhisperXSubtitleExtractor.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/whisperx/src/main/java/com/github/gtache/autosubtitle/subtitle/parser/json/whisperx/JSONSubtitleConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/whisperx/src/main/java/com/github/gtache/autosubtitle/subtitle/parser/json/whisperx/JSONSubtitleConverter.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/whisperx/src/main/java/com/github/gtache/autosubtitle/subtitle/parser/json/whisperx/JSONSubtitles.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/whisperx/src/main/java/com/github/gtache/autosubtitle/subtitle/parser/json/whisperx/JSONSubtitles.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/whisperx/src/main/java/module-info.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/whisperx/src/main/java/module-info.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/whisperx/src/test/java/com/github/gtache/autosubtitle/modules/subtitle/parser/json/whisperx/TestWhisperXJsonModule.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/whisperx/src/test/java/com/github/gtache/autosubtitle/modules/subtitle/parser/json/whisperx/TestWhisperXJsonModule.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/whisperx/src/test/java/com/github/gtache/autosubtitle/subtitle/extractor/whisperx/TestWhisperXSubtitleExtractor.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/whisperx/src/test/java/com/github/gtache/autosubtitle/subtitle/extractor/whisperx/TestWhisperXSubtitleExtractor.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/whisper/whisperx/src/test/java/com/github/gtache/autosubtitle/subtitle/parser/json/whisperx/TestJSONSubtitleConverter.java" beforeDir="false" afterPath="$PROJECT_DIR$/whisper/whisperx/src/test/java/com/github/gtache/autosubtitle/subtitle/parser/json/whisperx/TestJSONSubtitleConverter.java" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Record" />
<option value="Interface" />
<option value="Class" />
</list>
</option>
</component>
<component name="FormatOnSaveOptions">
<option name="myRunOnSave" value="true" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="GradleLocalSettings">
<option name="myGradleUserHome" value="D:/.gradle" />
<option name="projectSyncType">
<map>
<entry key="D:/Projects/Android/Rooster" value="PREVIEW" />
<entry key="D:/Projects/Scala/scalajs-gradle/scalajs-plugin" value="PREVIEW" />
</map>
</option>
</component>
<component name="MavenImportPreferences">
<option name="generalSettings">
<MavenGeneralSettings>
<option name="alwaysUpdateSnapshots" value="true" />
<option name="customMavenHome" value="F:\Maven" />
<option name="localRepository" value="D:\caches\.m2\" />
<option name="mavenHomeTypeForPersistence" value="CUSTOM" />
</MavenGeneralSettings>
</option>
<option name="importingSettings">
<MavenImportingSettings>
<option name="downloadAnnotationsAutomatically" value="true" />
<option name="downloadDocsAutomatically" value="true" />
<option name="downloadSourcesAutomatically" value="true" />
</MavenImportingSettings>
</option>
</component>
<component name="OptimizeOnSaveOptions">
<option name="myRunOnSave" value="true" />
</component>
<component name="ProblemsViewState">
<option name="selectedTabId" value="QODANA_PROBLEMS_VIEW_TAB" />
</component>
<component name="ProjectColorInfo">{
&quot;customColor&quot;: &quot;&quot;,
&quot;associatedIndex&quot;: 4
}</component>
<component name="ProjectId" id="2mOTkDSFeKNrF2FBh5zobHeX11u" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"Application.Main.executor": "Run",
"JUnit.TestASSSubtitleConverter.executor": "Run",
"JUnit.TestAbstractSetupManager.executor": "Run",
"JUnit.TestFFmpegVideoConverter.executor": "Run",
"JUnit.TestFXSubtitlesBinder.executor": "Run",
"Maven.autosubtitle [clean,package,-DskipTests].executor": "Run",
"Maven.autosubtitle [clean,package].executor": "Run",
"Maven.autosubtitle [clean].executor": "Run",
"RunOnceActivity.ShowReadmeOnStart": "true",
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
"com.codeium.enabled": "true",
"git-widget-placeholder": "master",
"ignore.virus.scanning.warn.message": "true",
"kotlin-language-version-configured": "true",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"project.structure.last.edited": "Modules",
"project.structure.proportion": "0.0",
"project.structure.side.proportion": "0.0",
"run.code.analysis.last.selected.profile": "aDefault",
"settings.editor.selected.configurable": "actions.on.save",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="QodanaHighlightedReportService">
<option name="localRunNotPublishedPersistedInfo">
<LocalReportPersistedInfo>
<option name="path" value="C:\Temp\UserTemp\qodana_output\qodana.sarif.json" />
<option name="reportGuid" value="6c32d48e-3af1-4a39-9921-31ac1f556472" />
<option name="reportName" value="auto-subtitle/qodana/2024-09-22" />
</LocalReportPersistedInfo>
</option>
</component>
<component name="QodanaIsSelectedPersistenceService">
<option name="selectedOrLoading" value="true" />
</component>
<component name="QodanaReportsService">
<option name="descriptions">
<ReportDescription localRun="true" path="C:\Temp\UserTemp\qodana_output\qodana.sarif.json" reportGuid="6c32d48e-3af1-4a39-9921-31ac1f556472" reportId="auto-subtitle/qodana/2024-09-22" />
</option>
</component>
<component name="RecentsManager">
<key name="CopyClassDialog.RECENTS_KEY">
<recent name="com.github.gtache.autosubtitle.subtitle.impl" />
<recent name="com.github.gtache.autosubtitle.subtitle.extractor.impl" />
<recent name="com.github.gtache.autosubtitle.subtitle.converter.impl" />
<recent name="com.github.gtache.autosubtitle.subtitle" />
<recent name="com.github.gtache.autosubtitle.subtitle.converter" />
</key>
</component>
<component name="RunAnythingCache">
<option name="myCommands">
<command value="mvn clean" />
<command value="mvn clean package" />
<command value="mvn clean package -DskipTests" />
</option>
</component>
<component name="RunManager" selected="JUnit.TestFXSubtitlesBinder">
<configuration default="true" type="Applet">
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType">
<module name="" />
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
<option name="PROGRAM_PARAMETERS" />
<predefined_log_file enabled="true" id="idea.log" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="Main" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="com.github.gtache.autosubtitle.gui.run.Main" />
<module name="autosubtitle-gui-run" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.github.gtache.autosubtitle.gui.run.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="Application" factoryName="Application">
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="TestASSSubtitleConverter" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
<module name="autosubtitle-core" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.github.gtache.autosubtitle.subtitle.converter.impl.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<option name="PACKAGE_NAME" value="com.github.gtache.autosubtitle.subtitle.converter.impl" />
<option name="MAIN_CLASS_NAME" value="com.github.gtache.autosubtitle.subtitle.converter.impl.TestASSSubtitleConverter" />
<option name="TEST_OBJECT" value="class" />
<option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="TestAbstractSetupManager" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
<module name="autosubtitle-core" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.github.gtache.autosubtitle.setup.impl.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<option name="PACKAGE_NAME" value="com.github.gtache.autosubtitle.setup.impl" />
<option name="MAIN_CLASS_NAME" value="com.github.gtache.autosubtitle.setup.impl.TestAbstractSetupManager" />
<option name="TEST_OBJECT" value="class" />
<option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="TestFFmpegVideoConverter" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
<module name="autosubtitle-ffmpeg" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.github.gtache.autosubtitle.ffmpeg.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<option name="PACKAGE_NAME" value="com.github.gtache.autosubtitle.ffmpeg" />
<option name="MAIN_CLASS_NAME" value="com.github.gtache.autosubtitle.ffmpeg.TestFFmpegVideoConverter" />
<option name="TEST_OBJECT" value="class" />
<option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="TestFXSubtitlesBinder" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
<module name="autosubtitle-gui-fx" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="com.github.gtache.autosubtitle.gui.subtitles.fx.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<option name="PACKAGE_NAME" value="com.github.gtache.autosubtitle.gui.subtitles.fx" />
<option name="MAIN_CLASS_NAME" value="com.github.gtache.autosubtitle.gui.subtitles.fx.TestFXSubtitlesBinder" />
<option name="TEST_OBJECT" value="class" />
<option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="JUnit" factoryName="JUnit">
<option name="TEST_OBJECT" value="class" />
<option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="JetRunConfigurationType">
<module name="auto-subtitle" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="KotlinStandaloneScriptRunConfigurationType">
<module name="auto-subtitle" />
<option name="filePath" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="PythonConfigurationType" factoryName="Python">
<module name="auto-subtitle" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration default="true" type="Python.FlaskServer">
<module name="auto-subtitle" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="launchJavascriptDebuger" value="false" />
<method v="2" />
</configuration>
<configuration default="true" type="TestNG">
<option name="TEST_OBJECT" value="CLASS" />
<option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
<properties />
<listeners />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration default="true" type="Tox" factoryName="Tox">
<module name="auto-subtitle" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="JUnit.TestFXSubtitlesBinder" />
<item itemvalue="JUnit.TestFFmpegVideoConverter" />
<item itemvalue="JUnit.TestASSSubtitleConverter" />
<item itemvalue="JUnit.TestAbstractSetupManager" />
<item itemvalue="Application.Main" />
</list>
</recent_temporary>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-jdk-9823dce3aa75-28b599e66164-intellij.indexing.shared.core-IU-242.22855.74" />
<option value="bundled-js-predefined-d6986cc7102b-5c90d61e3bab-JavaScript-IU-242.22855.74" />
</set>
</attachedChunks>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="ff40425e-42c7-4b0e-a76a-6e50cecddb1a" name="Changes" comment="" />
<created>1726946764733</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1726946764733</updated>
<workItem from="1726946765439" duration="148000" />
<workItem from="1727010656600" duration="16634000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>

View File

@@ -8,6 +8,7 @@ import java.nio.file.Path;
/** /**
* Represents a file * Represents a file
*/ */
@FunctionalInterface
public interface File { public interface File {
/** /**
* @return The file input stream * @return The file input stream

View File

@@ -54,7 +54,7 @@ public enum Language {
static { static {
final Map<String, Language> map = new java.util.HashMap<>(); final Map<String, Language> map = new java.util.HashMap<>();
for (final var language : Language.values()) { for (final var language : values()) {
map.put(language.name().toLowerCase(), language); map.put(language.name().toLowerCase(), language);
map.put(language.englishName.toLowerCase(), language); map.put(language.englishName.toLowerCase(), language);
map.put(language.iso2, language); map.put(language.iso2, language);

View File

@@ -1,5 +1,6 @@
package com.github.gtache.autosubtitle; package com.github.gtache.autosubtitle;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import java.io.IOException; import java.io.IOException;
@@ -16,40 +17,44 @@ public interface VideoConverter {
* *
* @param video The video * @param video The video
* @param subtitles The subtitles collections to add * @param subtitles The subtitles collections to add
* @param options The export options for the subtitles
* @return The modified video * @return The modified video
* @throws IOException If an I/O error occurs * @throws IOException If an I/O error occurs
*/ */
Video addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles) throws IOException; Video addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles, final ExportOptions options) throws IOException;
/** /**
* Adds soft subtitles to the given video * Adds soft subtitles to the given video
* *
* @param video The video * @param video The video
* @param subtitles The subtitles collections to add * @param subtitles The subtitles collections to add
* @param options The export options for the subtitles
* @param path The output path * @param path The output path
* @throws IOException If an I/O error occurs * @throws IOException If an I/O error occurs
*/ */
void addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles, final Path path) throws IOException; void addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles, final ExportOptions options, final Path path) throws IOException;
/** /**
* Adds hard subtitles to the given video * Adds hard subtitles to the given video
* *
* @param video The video * @param video The video
* @param subtitles The subtitle collection to add * @param subtitles The subtitle collection to add
* @param options The export options for the subtitles
* @return The modified video * @return The modified video
* @throws IOException If an I/O error occurs * @throws IOException If an I/O error occurs
*/ */
Video addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles) throws IOException; Video addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final ExportOptions options) throws IOException;
/** /**
* Adds hard subtitles to the given video * Adds hard subtitles to the given video
* *
* @param video The video * @param video The video
* @param subtitles The subtitle collection to add * @param subtitles The subtitle collection to add
* @param options The export options for the subtitles
* @param path The output path * @param path The output path
* @throws IOException If an I/O error occurs * @throws IOException If an I/O error occurs
*/ */
void addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final Path path) throws IOException; void addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final ExportOptions options, final Path path) throws IOException;
/** /**
* Extracts the audio from the given video * Extracts the audio from the given video

View File

@@ -14,9 +14,8 @@ public interface Archiver {
* *
* @param files The files to zip * @param files The files to zip
* @param destination The zipped file * @param destination The zipped file
* @throws IOException if an error occurs
*/ */
void compress(final List<Path> files, final Path destination) throws IOException; void compress(final List<Path> files, final Path destination);
/** /**
* Unzips an archive to the given destination * Unzips an archive to the given destination

View File

@@ -26,7 +26,6 @@ public interface ProcessListener {
* *
* @param duration The maximum time to wait * @param duration The maximum time to wait
* @return The process result * @return The process result
* @throws IOException if an error occurs
*/ */
ProcessResult join(final Duration duration) throws IOException; ProcessResult join(final Duration duration);
} }

View File

@@ -17,9 +17,8 @@ public interface SetupManager {
/** /**
* @return whether the component is installed * @return whether the component is installed
* @throws SetupException if an error occurred
*/ */
boolean isInstalled() throws SetupException; boolean isInstalled();
/** /**
* Installs the component * Installs the component
@@ -46,9 +45,8 @@ public interface SetupManager {
* Checks if an update is available for the component * Checks if an update is available for the component
* *
* @return whether an update is available * @return whether an update is available
* @throws SetupException if an error occurred during the check
*/ */
boolean isUpdateAvailable() throws SetupException; boolean isUpdateAvailable();
/** /**
* Updates the component * Updates the component

View File

@@ -0,0 +1,19 @@
package com.github.gtache.autosubtitle.subtitle;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
/**
* Represents the subtitles export options
*/
public interface ExportOptions {
/**
* @return The output format
*/
OutputFormat outputFormat();
/**
* @return The subtitles format options
*/
FormatOptions formatOptions();
}

View File

@@ -0,0 +1,14 @@
package com.github.gtache.autosubtitle.subtitle;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
/**
* Represents the subtitles import options
*/
public interface ImportOptions {
/**
* @return The options for subtitle parsing
*/
ParseOptions parseOptions();
}

View File

@@ -1,7 +1,6 @@
package com.github.gtache.autosubtitle.subtitle; package com.github.gtache.autosubtitle.subtitle;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException; import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
import java.io.IOException; import java.io.IOException;
@@ -19,32 +18,33 @@ public interface SubtitleImporterExporter<T extends Subtitle> {
* Imports subtitles from a file * Imports subtitles from a file
* *
* @param file The path to the file * @param file The path to the file
* @return A mapping of langauge to collection * @param options The import options
* @return A mapping of language to collection
* @throws IOException If an error occurred * @throws IOException If an error occurred
* @throws ParseException If an error occurred while parsing a subtitle * @throws ParseException If an error occurred while parsing a subtitle
*/ */
Map<Language, SubtitleCollection<T>> importSubtitles(final Path file) throws IOException, ParseException; Map<Language, SubtitleCollection<T>> importSubtitles(final Path file, final ImportOptions options) throws IOException, ParseException;
/** /**
* Exports multiple collections to a file * Exports multiple collections to a file
* *
* @param collections The subtitle collections * @param collections The subtitle collections
* @param videoInfo The video info (e.g. ASS format uses it) * @param options The export options
* @param file The path to the file * @param file The path to the file
* @throws IOException If an error occurred * @throws IOException If an error occurred
*/ */
void exportSubtitles(final Collection<? extends SubtitleCollection<?>> collections, final VideoInfo videoInfo, final Path file) throws IOException; void exportSubtitles(final Collection<? extends SubtitleCollection<?>> collections, final ExportOptions options, final Path file) throws IOException;
/** /**
* Exports a single collection to a file * Exports a single collection to a file
* *
* @param collection The subtitle collection * @param collection The subtitle collection
* @param videoInfo The video info (e.g. ASS format uses it) * @param options The export options
* @param file The path to the file * @param file The path to the file
* @throws IOException If an error occurred * @throws IOException If an error occurred
*/ */
default void exportSubtitles(final SubtitleCollection<?> collection, final VideoInfo videoInfo, final Path file) throws IOException { default void exportSubtitles(final SubtitleCollection<?> collection, final ExportOptions options, final Path file) throws IOException {
exportSubtitles(List.of(collection), videoInfo, file); exportSubtitles(List.of(collection), options, file);
} }
/** /**

View File

@@ -0,0 +1,19 @@
package com.github.gtache.autosubtitle.subtitle.converter;
/**
* Exception thrown when an error occurs during subtitle formatting
*/
public class FormatException extends Exception {
public FormatException(final String message) {
super(message);
}
public FormatException(final String message, final Throwable cause) {
super(message, cause);
}
public FormatException(final Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,20 @@
package com.github.gtache.autosubtitle.subtitle.converter;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.subtitle.Font;
/**
* Represents the subtitle format options
*/
public interface FormatOptions {
/**
* @return the current video info
*/
VideoInfo videoInfo();
/**
* @return The default font to use when not specified
*/
Font defaultFont();
}

View File

@@ -0,0 +1,24 @@
package com.github.gtache.autosubtitle.subtitle.converter;
import com.github.gtache.autosubtitle.subtitle.Font;
/**
* Represents the parse options
*/
public interface ParseOptions {
/**
* @return The max length in characters for a subtitle line
*/
int maxLineLength();
/**
* @return The max number of lines for a subtitle
*/
int maxLines();
/**
* @return The default font to use when not specified
*/
Font defaultFont();
}

View File

@@ -1,6 +1,5 @@
package com.github.gtache.autosubtitle.subtitle.converter; package com.github.gtache.autosubtitle.subtitle.converter;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.subtitle.Subtitle; import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
@@ -9,7 +8,7 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
/** /**
* Converts subtitles to a specific format (e.g. srt, ssa, ass, ...) and vice-versa * Converts subtitles to a specific format (e.g. srt, ssa, ass, ...) and vice versa
*/ */
public interface SubtitleConverter<T extends Subtitle> { public interface SubtitleConverter<T extends Subtitle> {
@@ -17,22 +16,24 @@ public interface SubtitleConverter<T extends Subtitle> {
* Converts the subtitle collection * Converts the subtitle collection
* *
* @param collection The collection * @param collection The collection
* @param videoInfo The video info (e.g. ASS format uses it) * @param options The format options
* @return The converted subtitles as the content of a file * @return The converted subtitles as the content of a file
* @throws FormatException If an error occurred
*/ */
String format(final SubtitleCollection<?> collection, final VideoInfo videoInfo); String format(final SubtitleCollection<?> collection, final FormatOptions options) throws FormatException;
/** /**
* Parses a subtitle collection * Parses a subtitle collection
* *
* @param file The path to the file * @param file The path to the file
* @param options The parse options
* @return The subtitle collection * @return The subtitle collection
* @throws ParseException If an error occurred * @throws ParseException If an error occurred
*/ */
default SubtitleCollection<T> parse(final Path file) throws ParseException { default SubtitleCollection<T> parse(final Path file, final ParseOptions options) throws ParseException {
try { try {
final var content = Files.readString(file); final var content = Files.readString(file);
return parse(content); return parse(content, options);
} catch (final IOException e) { } catch (final IOException e) {
throw new ParseException(e); throw new ParseException(e);
} }
@@ -42,10 +43,11 @@ public interface SubtitleConverter<T extends Subtitle> {
* Parses a subtitle collection * Parses a subtitle collection
* *
* @param content The content of the file * @param content The content of the file
* @param options The conversion options
* @return The subtitle collection * @return The subtitle collection
* @throws ParseException If an error occurred * @throws ParseException If an error occurred
*/ */
SubtitleCollection<T> parse(String content) throws ParseException; SubtitleCollection<T> parse(String content, ParseOptions options) throws ParseException;
/** /**
* Check if the parser can parse the given file * Check if the parser can parse the given file

View File

@@ -1,5 +1,7 @@
package com.github.gtache.autosubtitle.subtitle.converter; package com.github.gtache.autosubtitle.subtitle.converter;
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import java.util.Collection; import java.util.Collection;
/** /**
@@ -19,4 +21,14 @@ public interface SubtitleConverterProvider {
* @return The converter (or null if not found) * @return The converter (or null if not found)
*/ */
SubtitleConverter<?> getConverter(final String format); SubtitleConverter<?> getConverter(final String format);
/**
* Returns the converter for the given format
*
* @param format The format
* @return The converter (or null if not found)
*/
default SubtitleConverter<?> getConverter(final OutputFormat format) {
return getConverter(format.name());
}
} }

View File

@@ -0,0 +1,25 @@
package com.github.gtache.autosubtitle.subtitle.extractor;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
/**
* Options for subtitle extraction
*/
public interface ExtractOptions {
/**
* @return The language of the subtitles
*/
Language language();
/**
* @return The extraction model
*/
ExtractionModel model();
/**
* @return The subtitles parsing options
*/
ParseOptions parseOptions();
}

View File

@@ -3,6 +3,7 @@ package com.github.gtache.autosubtitle.subtitle.extractor;
/** /**
* An extraction model * An extraction model
*/ */
@FunctionalInterface
public interface ExtractionModel { public interface ExtractionModel {
/** /**
* @return the name of the model * @return the name of the model

View File

@@ -1,7 +1,6 @@
package com.github.gtache.autosubtitle.subtitle.extractor; package com.github.gtache.autosubtitle.subtitle.extractor;
import com.github.gtache.autosubtitle.Audio; import com.github.gtache.autosubtitle.Audio;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Video; import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.subtitle.Subtitle; import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
@@ -34,45 +33,19 @@ public interface SubtitleExtractor<T extends Subtitle> {
* Extracts the subtitles from a video * Extracts the subtitles from a video
* *
* @param video The video * @param video The video
* @param model The model to use * @param options The language of the audio
* @return The extracted subtitle collection * @return The extracted subtitle collection
* @throws ExtractException If an error occurs * @throws ExtractException If an error occurs
*/ */
default SubtitleCollection<T> extract(final Video video, final ExtractionModel model) throws ExtractException { SubtitleCollection<T> extract(final Video video, final ExtractOptions options) throws ExtractException;
return extract(video, Language.AUTO, model);
}
/**
* Extracts the subtitles from a video
*
* @param video The video
* @param language The language of the audio
* @param model The model to use
* @return The extracted subtitle collection
* @throws ExtractException If an error occurs
*/
SubtitleCollection<T> extract(final Video video, final Language language, final ExtractionModel model) throws ExtractException;
/** /**
* Extracts the subtitles from an audio * Extracts the subtitles from an audio
* *
* @param audio The audio * @param audio The audio
* @param model The model to use * @param options The extraction options
* @return The extracted subtitle collection * @return The extracted subtitle collection
* @throws ExtractException If an error occurs * @throws ExtractException If an error occurs
*/ */
default SubtitleCollection<T> extract(final Audio audio, final ExtractionModel model) throws ExtractException { SubtitleCollection<T> extract(final Audio audio, final ExtractOptions options) throws ExtractException;
return extract(audio, Language.AUTO, model);
}
/**
* Extracts the subtitles from an audio
*
* @param audio The audio
* @param language The language of the audio
* @param model The model to use
* @return The extracted subtitle collection
* @throws ExtractException If an error occurs
*/
SubtitleCollection<T> extract(final Audio audio, final Language language, final ExtractionModel model) throws ExtractException;
} }

View File

@@ -1,36 +1,36 @@
package com.github.gtache.autosubtitle.subtitle; package com.github.gtache.autosubtitle.subtitle;
import com.github.gtache.autosubtitle.VideoInfo;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Paths;
import java.util.List; import java.util.List;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class TestSubtitleImporterExporter { class TestSubtitleImporterExporter {
private final SubtitleImporterExporter<Subtitle> importerExporter; private final SubtitleImporterExporter<Subtitle> importerExporter;
private final SubtitleCollection<Subtitle> subtitleCollection; private final SubtitleCollection<Subtitle> subtitleCollection;
private final ExportOptions options;
TestSubtitleImporterExporter(@Mock final SubtitleCollection<Subtitle> subtitleCollection) { TestSubtitleImporterExporter(@Mock final SubtitleCollection<Subtitle> subtitleCollection, @Mock final ExportOptions options) {
this.subtitleCollection = requireNonNull(subtitleCollection); this.subtitleCollection = requireNonNull(subtitleCollection);
this.options = requireNonNull(options);
this.importerExporter = spy(SubtitleImporterExporter.class); this.importerExporter = spy(SubtitleImporterExporter.class);
} }
@Test @Test
void testExportSubtitleCollection() throws IOException { void testExportSubtitleCollection() throws IOException {
final var videoInfo = Mockito.mock(VideoInfo.class); final var file = Paths.get("path");
final var file = mock(Path.class);
importerExporter.exportSubtitles(subtitleCollection, videoInfo, file); importerExporter.exportSubtitles(subtitleCollection, options, file);
verify(importerExporter).exportSubtitles(List.of(subtitleCollection), videoInfo, file); verify(importerExporter).exportSubtitles(List.of(subtitleCollection), options, file);
} }
} }

View File

@@ -11,11 +11,10 @@ import org.mockito.junit.jupiter.MockitoExtension;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Objects;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
@@ -23,11 +22,14 @@ class TestSubtitleConverter {
private final SubtitleConverter<Subtitle> subtitleConverter; private final SubtitleConverter<Subtitle> subtitleConverter;
private final SubtitleCollection<Subtitle> subtitleCollection; private final SubtitleCollection<Subtitle> subtitleCollection;
private final ParseOptions options;
TestSubtitleConverter(@Mock final SubtitleConverter<Subtitle> subtitleConverter, TestSubtitleConverter(@Mock final SubtitleConverter<Subtitle> subtitleConverter,
@Mock final SubtitleCollection<Subtitle> subtitleCollection) { @Mock final SubtitleCollection<Subtitle> subtitleCollection,
this.subtitleConverter = Objects.requireNonNull(subtitleConverter); @Mock final ParseOptions options) {
this.subtitleCollection = Objects.requireNonNull(subtitleCollection); this.subtitleConverter = requireNonNull(subtitleConverter);
this.subtitleCollection = requireNonNull(subtitleCollection);
this.options = requireNonNull(options);
} }
@Test @Test
@@ -35,19 +37,19 @@ class TestSubtitleConverter {
final var file = tempDir.resolve("test.srt"); final var file = tempDir.resolve("test.srt");
final var string = "test"; final var string = "test";
Files.writeString(file, string); Files.writeString(file, string);
when(subtitleConverter.parse(file)).thenCallRealMethod(); when(subtitleConverter.parse(file, options)).thenCallRealMethod();
when(subtitleConverter.parse(string)).thenReturn(subtitleCollection); when(subtitleConverter.parse(string, options)).thenReturn(subtitleCollection);
assertEquals(subtitleCollection, subtitleConverter.parse(file)); assertEquals(subtitleCollection, subtitleConverter.parse(file, options));
} }
@Test @Test
void testParseException(@TempDir final Path tempDir) throws ParseException { void testParseException(@TempDir final Path tempDir) throws ParseException {
final var file = tempDir.resolve("test.srt"); final var file = tempDir.resolve("test.srt");
when(subtitleConverter.parse(file)).thenCallRealMethod(); when(subtitleConverter.parse(file, options)).thenCallRealMethod();
when(subtitleConverter.parse(anyString())).thenReturn(subtitleCollection); when(subtitleConverter.parse(anyString(), eq(options))).thenReturn(subtitleCollection);
assertThrows(ParseException.class, () -> subtitleConverter.parse(file)); assertThrows(ParseException.class, () -> subtitleConverter.parse(file, options));
} }
@Test @Test

View File

@@ -0,0 +1,32 @@
package com.github.gtache.autosubtitle.subtitle.converter;
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class TestSubtitleConverterProvider {
private final SubtitleConverter<?> converter;
private final SubtitleConverterProvider provider;
TestSubtitleConverterProvider(@Mock final SubtitleConverter<?> converter) {
this.converter = Objects.requireNonNull(converter);
this.provider = spy(SubtitleConverterProvider.class);
}
@Test
void testGetConverter() {
final var format = OutputFormat.SRT;
when(provider.getConverter("SRT")).thenReturn((SubtitleConverter) converter);
assertEquals(converter, provider.getConverter(format));
verify(provider).getConverter("SRT");
}
}

View File

@@ -1,55 +0,0 @@
package com.github.gtache.autosubtitle.subtitle.extractor;
import com.github.gtache.autosubtitle.Audio;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class TestSubtitleExtractor {
private final SubtitleExtractor<Subtitle> subtitleExtractor;
private final SubtitleCollection<Subtitle> subtitleCollection;
private final Audio audio;
private final Video video;
private final ExtractionModel extractionModel;
TestSubtitleExtractor(@Mock final SubtitleExtractor<Subtitle> subtitleExtractor,
@Mock final SubtitleCollection<Subtitle> subtitleCollection,
@Mock final Audio audio,
@Mock final Video video,
@Mock final ExtractionModel extractionModel) {
this.subtitleExtractor = Objects.requireNonNull(subtitleExtractor);
this.subtitleCollection = Objects.requireNonNull(subtitleCollection);
this.audio = Objects.requireNonNull(audio);
this.video = Objects.requireNonNull(video);
this.extractionModel = Objects.requireNonNull(extractionModel);
}
@Test
void testExtractVideo() throws ExtractException {
when(subtitleExtractor.extract(any(Video.class), any())).thenCallRealMethod();
when(subtitleExtractor.extract(video, Language.AUTO, extractionModel)).thenReturn(subtitleCollection);
assertEquals(subtitleCollection, subtitleExtractor.extract(video, extractionModel));
}
@Test
void testExtractAudio() throws ExtractException {
when(subtitleExtractor.extract(any(Audio.class), any())).thenCallRealMethod();
when(subtitleExtractor.extract(audio, Language.AUTO, extractionModel)).thenReturn(subtitleCollection);
assertEquals(subtitleCollection, subtitleExtractor.extract(audio, extractionModel));
}
}

View File

@@ -23,7 +23,7 @@ public final class Cli implements Runnable {
private String subtitleConverter; private String subtitleConverter;
@CommandLine.Option(names = {"-c", "--video-converter"}, description = "The video converter to use [ffmpeg]", defaultValue = "ffmpeg") @CommandLine.Option(names = {"-c", "--video-converter"}, description = "The video converter to use [ffmpeg]", defaultValue = "ffmpeg")
private String videoConverter; private String videoConverter;
@CommandLine.Option(names = {"--translations"}, description = "The list of translations to create. Ignored if burn is specified", split = ",", arity = "0..*") @CommandLine.Option(names = "--translations", description = "The list of translations to create. Ignored if burn is specified", split = ",", arity = "0..*")
private Set<String> translations; private Set<String> translations;
@CommandLine.Option(names = {"-t", "--translator"}, description = "The translator to use [deepl]. Ignored if burn is specified", defaultValue = "deepl") @CommandLine.Option(names = {"-t", "--translator"}, description = "The translator to use [deepl]. Ignored if burn is specified", defaultValue = "deepl")
private String translator; private String translator;

View File

@@ -3,9 +3,9 @@ package com.github.gtache.autosubtitle.client;
import com.github.gtache.autosubtitle.Audio; import com.github.gtache.autosubtitle.Audio;
import com.github.gtache.autosubtitle.Video; import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.VideoConverter; import com.github.gtache.autosubtitle.VideoConverter;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Collection; import java.util.Collection;
@@ -14,27 +14,28 @@ import java.util.Collection;
*/ */
public class RemoteVideoConverter implements VideoConverter { public class RemoteVideoConverter implements VideoConverter {
@Override @Override
public Video addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles) throws IOException { public Video addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles, final ExportOptions options) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles, final Path path) throws IOException { public void addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles, final ExportOptions options, final Path path) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public Video addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles) throws IOException { public Video addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final ExportOptions options) {
throw new UnsupportedOperationException();
}
@Override
public void addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final ExportOptions options, final Path path) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public void addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final Path path) throws IOException { public Audio getAudio(final Video video) {
throw new UnsupportedOperationException();
}
@Override
public Audio getAudio(final Video video) throws IOException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }

View File

@@ -3,7 +3,6 @@ package com.github.gtache.autosubtitle.client;
import com.github.gtache.autosubtitle.Video; import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.VideoLoader; import com.github.gtache.autosubtitle.VideoLoader;
import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
/** /**
@@ -11,7 +10,7 @@ import java.nio.file.Path;
*/ */
public class RemoteVideoLoader implements VideoLoader { public class RemoteVideoLoader implements VideoLoader {
@Override @Override
public Video loadVideo(final Path path) throws IOException { public Video loadVideo(final Path path) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }

View File

@@ -1,9 +1,9 @@
package com.github.gtache.autosubtitle.subtitle.converter.client; package com.github.gtache.autosubtitle.subtitle.converter.client;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.subtitle.Subtitle; import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException; import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
/** /**
@@ -13,12 +13,12 @@ import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
*/ */
public class RemoteSubtitleConverter<T extends Subtitle> implements SubtitleConverter<T> { public class RemoteSubtitleConverter<T extends Subtitle> implements SubtitleConverter<T> {
@Override @Override
public String format(final SubtitleCollection<?> collection, final VideoInfo videoInfo) { public String format(final SubtitleCollection<?> collection, final FormatOptions options) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public SubtitleCollection<T> parse(final String content) throws ParseException { public SubtitleCollection<T> parse(final String content, final ParseOptions options) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View File

@@ -1,11 +1,9 @@
package com.github.gtache.autosubtitle.subtitle.extractor.client; package com.github.gtache.autosubtitle.subtitle.extractor.client;
import com.github.gtache.autosubtitle.Audio; import com.github.gtache.autosubtitle.Audio;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Video; import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractException; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor; import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
import com.github.gtache.autosubtitle.subtitle.extractor.impl.AbstractSubtitleExtractor; import com.github.gtache.autosubtitle.subtitle.extractor.impl.AbstractSubtitleExtractor;
@@ -15,12 +13,12 @@ import com.github.gtache.autosubtitle.subtitle.extractor.impl.AbstractSubtitleEx
public class RemoteSubtitleExtractor extends AbstractSubtitleExtractor { public class RemoteSubtitleExtractor extends AbstractSubtitleExtractor {
@Override @Override
public SubtitleCollection extract(final Video video, final Language language, final ExtractionModel model) throws ExtractException { public SubtitleCollection extract(final Video video, final ExtractOptions options) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public SubtitleCollection extract(final Audio audio, final Language language, final ExtractionModel model) throws ExtractException { public SubtitleCollection extract(final Audio audio, final ExtractOptions options) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }

View File

@@ -3,7 +3,6 @@ package com.github.gtache.autosubtitle.translation.client;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.subtitle.Subtitle; import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.translation.TranslationException;
import com.github.gtache.autosubtitle.translation.Translator; import com.github.gtache.autosubtitle.translation.Translator;
/** /**
@@ -18,17 +17,17 @@ public class RemoteTranslator<T extends Subtitle> implements Translator<T> {
} }
@Override @Override
public String translate(final String text, final Language from, final Language to) throws TranslationException { public String translate(final String text, final Language from, final Language to) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public T translate(final Subtitle subtitle, final Language from, final Language to) throws TranslationException { public T translate(final Subtitle subtitle, final Language from, final Language to) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public SubtitleCollection<T> translate(final SubtitleCollection<?> collection, final Language from, final Language to) throws TranslationException { public SubtitleCollection<T> translate(final SubtitleCollection<?> collection, final Language from, final Language to) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }

View File

@@ -70,8 +70,8 @@ public class CondaSetupManager extends AbstractSetupManager {
logger.info("Conda downloaded"); logger.info("Conda downloaded");
} }
switch (configuration.os()) { switch (configuration.os()) {
case OS.WINDOWS -> installWindows(); case WINDOWS -> installWindows();
case OS.MAC, OS.LINUX -> installLinux(); case MAC, LINUX -> installLinux();
default -> throw new SetupException("Unsupported OS: " + configuration.os()); default -> throw new SetupException("Unsupported OS: " + configuration.os());
} }
} }
@@ -106,9 +106,9 @@ public class CondaSetupManager extends AbstractSetupManager {
private void downloadConda() throws SetupException { private void downloadConda() throws SetupException {
switch (configuration.os()) { switch (configuration.os()) {
case OS.WINDOWS -> downloadCondaWindows(); case WINDOWS -> downloadCondaWindows();
case OS.MAC -> downloadCondaMac(); case MAC -> downloadCondaMac();
case OS.LINUX -> downloadCondaLinux(); case LINUX -> downloadCondaLinux();
default -> throw new SetupException("Unsupported OS: " + configuration.os()); default -> throw new SetupException("Unsupported OS: " + configuration.os());
} }
logger.info("Downloaded conda to {}", configuration.condaInstallerPath()); logger.info("Downloaded conda to {}", configuration.condaInstallerPath());

View File

@@ -43,7 +43,7 @@ class TestCondaSetupManager {
private final Path systemPath; private final Path systemPath;
TestCondaSetupManager(@Mock final CondaSetupConfiguration configuration, @Mock final ProcessRunner processRunner, TestCondaSetupManager(@Mock final CondaSetupConfiguration configuration, @Mock final ProcessRunner processRunner,
@Mock final HttpClient httpClient, @Mock final ProcessResult systemProcessResult, @Mock final HttpResponse<Path> response) throws IOException, InterruptedException { @Mock final HttpClient httpClient, @Mock final ProcessResult systemProcessResult, @Mock final HttpResponse<Path> response) {
this.configuration = requireNonNull(configuration); this.configuration = requireNonNull(configuration);
this.processRunner = requireNonNull(processRunner); this.processRunner = requireNonNull(processRunner);
this.httpClient = requireNonNull(httpClient); this.httpClient = requireNonNull(httpClient);
@@ -167,7 +167,7 @@ class TestCondaSetupManager {
} }
@Test @Test
void testInstallDownloadLinuxUnsupported(@TempDir final Path tempDir) throws IOException { void testInstallDownloadLinuxUnsupported(@TempDir final Path tempDir) {
final var installerPath = tempDir.resolve("conda"); final var installerPath = tempDir.resolve("conda");
when(configuration.condaInstallerPath()).thenReturn(installerPath); when(configuration.condaInstallerPath()).thenReturn(installerPath);
when(configuration.condaBundledPath()).thenReturn(tempDir); when(configuration.condaBundledPath()).thenReturn(tempDir);
@@ -221,7 +221,7 @@ class TestCondaSetupManager {
} }
@Test @Test
void testInstallDownloadMacUnsupported(@TempDir final Path tempDir) throws IOException { void testInstallDownloadMacUnsupported(@TempDir final Path tempDir) {
final var installerPath = tempDir.resolve("conda"); final var installerPath = tempDir.resolve("conda");
when(configuration.condaInstallerPath()).thenReturn(installerPath); when(configuration.condaInstallerPath()).thenReturn(installerPath);
when(configuration.condaBundledPath()).thenReturn(tempDir); when(configuration.condaBundledPath()).thenReturn(tempDir);
@@ -235,7 +235,7 @@ class TestCondaSetupManager {
} }
@Test @Test
void testInstallDownloadUnsupported(@TempDir final Path tempDir) throws IOException { void testInstallDownloadUnsupported(@TempDir final Path tempDir) {
final var installerPath = tempDir.resolve("conda"); final var installerPath = tempDir.resolve("conda");
when(configuration.condaInstallerPath()).thenReturn(installerPath); when(configuration.condaInstallerPath()).thenReturn(installerPath);
when(configuration.condaBundledPath()).thenReturn(tempDir); when(configuration.condaBundledPath()).thenReturn(tempDir);
@@ -258,7 +258,7 @@ class TestCondaSetupManager {
when(systemProcessResult.exitCode()).thenReturn(1); when(systemProcessResult.exitCode()).thenReturn(1);
when(configuration.condaRootPath()).thenReturn(tempDir); when(configuration.condaRootPath()).thenReturn(tempDir);
final var args = List.of(installerPath.toString(), "/InstallationType=JustMe", "/RegisterPython=0", "/S", "/D=" + tempDir.toString()); final var args = List.of(installerPath.toString(), "/InstallationType=JustMe", "/RegisterPython=0", "/S", "/D=" + tempDir);
final var result = mock(ProcessResult.class); final var result = mock(ProcessResult.class);
when(result.exitCode()).thenReturn(0); when(result.exitCode()).thenReturn(0);
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result); when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);

View File

@@ -14,15 +14,15 @@ import java.util.zip.ZipInputStream;
/** /**
* Zip implementation of {@link Archiver} * Zip implementation of {@link Archiver}
*/ */
public class ZipDecompresser implements Archiver { public class ZipArchiver implements Archiver {
@Inject @Inject
ZipDecompresser() { ZipArchiver() {
} }
@Override @Override
public void compress(final List<Path> files, final Path destination) throws IOException { public void compress(final List<Path> files, final Path destination) {
throw new UnsupportedOperationException("Not supported"); throw new UnsupportedOperationException("Not supported");
} }

View File

@@ -3,7 +3,7 @@ package com.github.gtache.autosubtitle.modules.archive.impl;
import com.github.gtache.autosubtitle.archive.Archiver; import com.github.gtache.autosubtitle.archive.Archiver;
import com.github.gtache.autosubtitle.archive.ArchiverProvider; import com.github.gtache.autosubtitle.archive.ArchiverProvider;
import com.github.gtache.autosubtitle.archive.impl.ArchiverProviderImpl; import com.github.gtache.autosubtitle.archive.impl.ArchiverProviderImpl;
import com.github.gtache.autosubtitle.archive.impl.ZipDecompresser; import com.github.gtache.autosubtitle.archive.impl.ZipArchiver;
import dagger.Binds; import dagger.Binds;
import dagger.Module; import dagger.Module;
import dagger.multibindings.IntoMap; import dagger.multibindings.IntoMap;
@@ -25,5 +25,5 @@ public abstract class ArchiveModule {
@Binds @Binds
@StringKey("zip") @StringKey("zip")
@IntoMap @IntoMap
abstract Archiver bindsZipDecompresser(final ZipDecompresser decompresser); abstract Archiver bindsZipDecompresser(final ZipArchiver decompresser);
} }

View File

@@ -9,7 +9,7 @@ import dagger.Module;
/** /**
* Dagger module for subtitles * Dagger module for subtitles
*/ */
@Module(includes = {SubtitleConverterModule.class}) @Module(includes = SubtitleConverterModule.class)
public abstract class SubtitleModule { public abstract class SubtitleModule {
private SubtitleModule() { private SubtitleModule() {

View File

@@ -1,12 +1,12 @@
package com.github.gtache.autosubtitle.subtitle.converter.impl; package com.github.gtache.autosubtitle.subtitle.converter.impl;
import com.github.gtache.autosubtitle.VideoInfo; import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.modules.impl.FontName;
import com.github.gtache.autosubtitle.modules.impl.FontSize;
import com.github.gtache.autosubtitle.subtitle.Font; import com.github.gtache.autosubtitle.subtitle.Font;
import com.github.gtache.autosubtitle.subtitle.Subtitle; import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException; import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import com.github.gtache.autosubtitle.subtitle.impl.FontImpl; import com.github.gtache.autosubtitle.subtitle.impl.FontImpl;
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl; import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl;
@@ -20,7 +20,7 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.prefs.Preferences; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
@@ -35,47 +35,38 @@ public class ASSSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
private static final String DIALOGUE = "Dialogue:"; private static final String DIALOGUE = "Dialogue:";
private static final String EVENTS_SECTION = "[Events]"; private static final String EVENTS_SECTION = "[Events]";
private static final String STYLES_SECTION = "[V4+ Styles]"; private static final String STYLES_SECTION = "[V4+ Styles]";
private static final Pattern NEWLINE_PATTERN = Pattern.compile("\\n");
private final Translator<?> translator; private final Translator<?> translator;
private final Preferences preferences;
private final String defaultFontName;
private final int defaultFontSize;
@Inject @Inject
ASSSubtitleConverter(final Translator translator, final Preferences preferences, ASSSubtitleConverter(final Translator translator) {
@FontName final String defaultFontName, @FontSize final int defaultFontSize) {
this.translator = requireNonNull(translator); this.translator = requireNonNull(translator);
this.preferences = requireNonNull(preferences);
this.defaultFontName = Objects.requireNonNull(defaultFontName);
if (defaultFontSize <= 0) {
throw new IllegalArgumentException("Font size must be positive : " + defaultFontSize);
}
this.defaultFontSize = defaultFontSize;
} }
@Override @Override
public String format(final SubtitleCollection<?> collection, final VideoInfo videoInfo) { public String format(final SubtitleCollection<?> collection, final FormatOptions options) {
final var subtitles = collection.subtitles().stream().sorted(Comparator.comparing(Subtitle::start).thenComparing(Subtitle::end)).toList(); final var subtitles = collection.subtitles().stream().sorted(Comparator.comparing(Subtitle::start).thenComparing(Subtitle::end)).toList();
final var scriptInfo = getScriptInfo(videoInfo); final var scriptInfo = getScriptInfo(options.videoInfo());
final var styles = getStyles(subtitles); final var styles = getStyles(subtitles, options.defaultFont());
final var events = getEvents(subtitles); final var events = getEvents(subtitles, options.defaultFont());
return scriptInfo + "\n\n" + styles + "\n\n" + events + "\n"; return scriptInfo + "\n\n" + styles + "\n\n" + events + "\n";
} }
private String getEvents(final Collection<? extends Subtitle> subtitles) { private static String getEvents(final Collection<? extends Subtitle> subtitles, final Font defaultFont) {
return EVENTS_SECTION + "\n" + "Format: Start, End, Style, Text\n" + return EVENTS_SECTION + "\n" + "Format: Start, End, Style, Text\n" +
subtitles.stream().map(this::getEvent).collect(Collectors.joining("\n")); subtitles.stream().map(s -> getEvent(s, defaultFont)).collect(Collectors.joining("\n"));
} }
private String getEvent(final Subtitle subtitle) { private static String getEvent(final Subtitle subtitle, final Font defaultFont) {
return DIALOGUE + " " + formatTime(subtitle.start()) + "," + formatTime(subtitle.end()) + "," + getName(subtitle.font()) + "," + subtitle.content(); return DIALOGUE + " " + formatTime(subtitle.start()) + "," + formatTime(subtitle.end()) + "," + getName(subtitle.font(), defaultFont) + "," + subtitle.content();
} }
private String getName(final Font font) { private static String getName(final Font font, final Font defaultFont) {
final String fontName; final String fontName;
final int fontSize; final int fontSize;
if (font == null) { if (font == null) {
fontName = preferences.get("fontName", defaultFontName); fontName = defaultFont.name();
fontSize = preferences.getInt("fontSize", defaultFontSize); fontSize = defaultFont.size();
} else { } else {
fontName = font.name(); fontName = font.name();
fontSize = font.size(); fontSize = font.size();
@@ -83,16 +74,16 @@ public class ASSSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
return fontName + fontSize; return fontName + fontSize;
} }
private String getStyles(final Collection<? extends Subtitle> subtitles) { private static String getStyles(final Collection<? extends Subtitle> subtitles, final Font defaultFont) {
return STYLES_SECTION + "\n" + "Format: Name, Fontname, Fontsize\n" + listStyles(subtitles); return STYLES_SECTION + "\n" + "Format: Name, Fontname, Fontsize\n" + listStyles(subtitles, defaultFont);
} }
private String listStyles(final Collection<? extends Subtitle> subtitles) { private static String listStyles(final Collection<? extends Subtitle> subtitles, final Font defaultFont) {
final var uniqueStyles = subtitles.stream().map(Subtitle::font).filter(Objects::nonNull).collect(Collectors.toSet()); final var uniqueStyles = subtitles.stream().map(Subtitle::font).filter(Objects::nonNull).collect(Collectors.toSet());
if (subtitles.stream().anyMatch(s -> s.font() == null)) { if (subtitles.stream().anyMatch(s -> s.font() == null)) {
uniqueStyles.add(new FontImpl(preferences.get("fontName", defaultFontName), preferences.getInt("fontSize", defaultFontSize))); uniqueStyles.add(defaultFont);
} }
return uniqueStyles.stream().map(f -> STYLE + " " + getName(f) + ", " + f.name() + ", " + f.size()).collect(Collectors.joining("\n")); return uniqueStyles.stream().map(f -> STYLE + " " + getName(f, defaultFont) + ", " + f.name() + ", " + f.size()).collect(Collectors.joining("\n"));
} }
private static String getScriptInfo(final VideoInfo videoInfo) { private static String getScriptInfo(final VideoInfo videoInfo) {
@@ -103,32 +94,21 @@ public class ASSSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
WrapStyle: 1""".formatted(videoInfo.width(), videoInfo.height()); WrapStyle: 1""".formatted(videoInfo.width(), videoInfo.height());
} }
private static String formatTime(final long time) {
final var millisPerHour = 3600000;
final var millisPerMinute = 60000;
final var hours = time / millisPerHour;
final var minutes = (time - hours * millisPerHour) / millisPerMinute;
final var seconds = (time - hours * millisPerHour - minutes * millisPerMinute) / 1000;
final var millis = time - hours * millisPerHour - minutes * millisPerMinute - seconds * 1000;
final var hundredths = millis / 10;
return String.format("%d:%02d:%02d.%02d", hours, minutes, seconds, hundredths);
}
@Override @Override
public SubtitleCollectionImpl<SubtitleImpl> parse(final String content) throws ParseException { public SubtitleCollectionImpl<SubtitleImpl> parse(final String content, final ParseOptions options) throws ParseException {
final var fonts = parseFonts(content); final var fonts = parseFonts(content, options.defaultFont());
final var subtitles = parseSubtitles(content, fonts); final var subtitles = parseSubtitles(content, fonts);
final var text = subtitles.stream().map(Subtitle::content).collect(Collectors.joining()); final var text = subtitles.stream().map(Subtitle::content).collect(Collectors.joining());
final var language = translator.getLanguage(text); final var language = translator.getLanguage(text);
return new SubtitleCollectionImpl<>(text, subtitles, language); return new SubtitleCollectionImpl<>(text, subtitles, language);
} }
private static List<SubtitleImpl> parseSubtitles(final String content, final Map<String, Font> fonts) throws ParseException { private static List<SubtitleImpl> parseSubtitles(final String content, final Map<String, ? extends Font> fonts) throws ParseException {
final var fontIndex = content.indexOf(EVENTS_SECTION); final var fontIndex = content.indexOf(EVENTS_SECTION);
if (fontIndex == -1) { if (fontIndex == -1) {
throw new ParseException("Events section not found in " + content); throw new ParseException("Events section not found in " + content);
} else { } else {
final var split = content.substring(fontIndex).split("\\n"); final var split = NEWLINE_PATTERN.split(content.substring(fontIndex));
final List<String> fields; final List<String> fields;
if (split[0].startsWith(EVENTS_SECTION)) { if (split[0].startsWith(EVENTS_SECTION)) {
fields = getFields(split[1]); fields = getFields(split[1]);
@@ -155,12 +135,12 @@ public class ASSSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
} }
} }
private Map<String, Font> parseFonts(final String content) throws ParseException { private static Map<String, Font> parseFonts(final String content, final Font defaultFont) throws ParseException {
final var fontIndex = content.indexOf(STYLES_SECTION); final var fontIndex = content.indexOf(STYLES_SECTION);
if (fontIndex == -1) { if (fontIndex == -1) {
throw new ParseException("Styles section not found in " + content); throw new ParseException("Styles section not found in " + content);
} else { } else {
final var split = content.substring(fontIndex).split("\\n"); final var split = NEWLINE_PATTERN.split(content.substring(fontIndex));
final List<String> fields; final List<String> fields;
if (split[0].startsWith(STYLES_SECTION)) { if (split[0].startsWith(STYLES_SECTION)) {
fields = getFields(split[1]); fields = getFields(split[1]);
@@ -178,7 +158,7 @@ public class ASSSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
final var name = values.get(fontNameIndex); final var name = values.get(fontNameIndex);
final var size = Integer.parseInt(values.get(fontSizeIndex)); final var size = Integer.parseInt(values.get(fontSizeIndex));
return new FontImpl(name, size); return new FontImpl(name, size);
}).collect(Collectors.toMap(this::getName, f -> f)); }).collect(Collectors.toMap(f -> getName(f, defaultFont), f -> f));
} }
} }
@@ -196,6 +176,16 @@ public class ASSSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
return (hours * 3600L + minutes * 60L + seconds) * 1000L + hundredths * 10L; return (hours * 3600L + minutes * 60L + seconds) * 1000L + hundredths * 10L;
} }
private static String formatTime(final long time) {
final var millisPerHour = 3600000;
final var millisPerMinute = 60000;
final var hours = time / millisPerHour;
final var minutes = (time - hours * millisPerHour) / millisPerMinute;
final var seconds = (time - hours * millisPerHour - minutes * millisPerMinute) / 1000;
final var hundredths = (time - hours * millisPerHour - minutes * millisPerMinute - seconds * 1000) / 10;
return String.format("%02d:%02d:%02d.%02d", hours, minutes, seconds, hundredths);
}
@Override @Override
public String formatName() { public String formatName() {
return "ass"; return "ass";

View File

@@ -0,0 +1,17 @@
package com.github.gtache.autosubtitle.subtitle.converter.impl;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.subtitle.Font;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import java.util.Objects;
/**
* Implementation of {@link FormatOptions}
*/
public record FormatOptionsImpl(VideoInfo videoInfo, Font defaultFont) implements FormatOptions {
public FormatOptionsImpl {
Objects.requireNonNull(videoInfo);
Objects.requireNonNull(defaultFont);
}
}

View File

@@ -0,0 +1,21 @@
package com.github.gtache.autosubtitle.subtitle.converter.impl;
import com.github.gtache.autosubtitle.subtitle.Font;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import java.util.Objects;
/**
* Implementation of {@link ParseOptions}
*/
public record ParseOptionsImpl(int maxLineLength, int maxLines, Font defaultFont) implements ParseOptions {
public ParseOptionsImpl {
if (maxLineLength <= 0) {
throw new IllegalArgumentException("maxLineLength must be > 0");
}
if (maxLines <= 0) {
throw new IllegalArgumentException("maxLines must be > 0");
}
Objects.requireNonNull(defaultFont);
}
}

View File

@@ -1,9 +1,10 @@
package com.github.gtache.autosubtitle.subtitle.converter.impl; package com.github.gtache.autosubtitle.subtitle.converter.impl;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.subtitle.Subtitle; import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException; import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl; import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl; import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl;
@@ -12,6 +13,7 @@ import com.github.gtache.autosubtitle.translation.Translator;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
@@ -22,6 +24,9 @@ import static java.util.Objects.requireNonNull;
*/ */
public class SRTSubtitleConverter implements SubtitleConverter<SubtitleImpl> { public class SRTSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
private static final Pattern ARROW_PATTERN = Pattern.compile(" --> ");
private static final Pattern DOUBLE_NEWLINE_PATTERN = Pattern.compile("\n\n");
private final Translator<?> translator; private final Translator<?> translator;
@Inject @Inject
@@ -30,7 +35,7 @@ public class SRTSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
} }
@Override @Override
public String format(final SubtitleCollection<?> collection, final VideoInfo videoInfo) { public String format(final SubtitleCollection<?> collection, final FormatOptions options) {
final var subtitles = collection.subtitles().stream().sorted(Comparator.comparing(Subtitle::start).thenComparing(Subtitle::end)).toList(); final var subtitles = collection.subtitles().stream().sorted(Comparator.comparing(Subtitle::start).thenComparing(Subtitle::end)).toList();
return IntStream.range(0, subtitles.size()).mapToObj(i -> { return IntStream.range(0, subtitles.size()).mapToObj(i -> {
final var subtitle = subtitles.get(i); final var subtitle = subtitles.get(i);
@@ -40,24 +45,14 @@ public class SRTSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
}).collect(Collectors.joining("\n\n")) + "\n"; }).collect(Collectors.joining("\n\n")) + "\n";
} }
private static String formatTime(final long time) {
final var millisPerHour = 3600000;
final var millisPerMinute = 60000;
final var hours = time / millisPerHour;
final var minutes = (time - hours * millisPerHour) / millisPerMinute;
final var seconds = (time - hours * millisPerHour - minutes * millisPerMinute) / 1000;
final var millis = time - hours * millisPerHour - minutes * millisPerMinute - seconds * 1000;
return String.format("%02d:%02d:%02d,%03d", hours, minutes, seconds, millis);
}
@Override @Override
public SubtitleCollectionImpl<SubtitleImpl> parse(final String content) throws ParseException { public SubtitleCollectionImpl<SubtitleImpl> parse(final String content, final ParseOptions options) throws ParseException {
try { try {
final var elements = content.split("\n\n"); final var elements = DOUBLE_NEWLINE_PATTERN.split(content);
final var subtitles = Arrays.stream(elements).filter(element -> !element.isBlank()).map(element -> { final var subtitles = Arrays.stream(elements).filter(element -> !element.isBlank()).map(element -> {
final var lines = element.split("\n"); final var lines = element.split("\n");
final var time = lines[1]; final var time = lines[1];
final var timeSplit = time.split(" --> "); final var timeSplit = ARROW_PATTERN.split(time);
final var startTimeStr = timeSplit[0]; final var startTimeStr = timeSplit[0];
final var endTimeStr = timeSplit[1]; final var endTimeStr = timeSplit[1];
final var start = parseTime(startTimeStr); final var start = parseTime(startTimeStr);
@@ -82,6 +77,16 @@ public class SRTSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
return (hours * 3600L + minutes * 60L + seconds) * 1000 + millis; return (hours * 3600L + minutes * 60L + seconds) * 1000 + millis;
} }
private static String formatTime(final long time) {
final var millisPerHour = 3600000;
final var millisPerMinute = 60000;
final var hours = time / millisPerHour;
final var minutes = (time - hours * millisPerHour) / millisPerMinute;
final var seconds = (time - hours * millisPerHour - minutes * millisPerMinute) / 1000;
final var millis = time - hours * millisPerHour - minutes * millisPerMinute - seconds * 1000;
return String.format("%02d:%02d:%02d,%03d", hours, minutes, seconds, millis);
}
@Override @Override
public String formatName() { public String formatName() {
return "srt"; return "srt";

View File

@@ -0,0 +1,21 @@
package com.github.gtache.autosubtitle.subtitle.extractor.impl;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
import java.util.Objects;
/**
* Implementation of {@link ExtractOptions}
*/
public record ExtractOptionsImpl(Language language, ExtractionModel model,
ParseOptions parseOptions) implements ExtractOptions {
public ExtractOptionsImpl {
Objects.requireNonNull(language);
Objects.requireNonNull(model);
Objects.requireNonNull(parseOptions);
}
}

View File

@@ -0,0 +1,18 @@
package com.github.gtache.autosubtitle.subtitle.impl;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import java.util.Objects;
/**
* Implementation of {@link ExportOptions}
*/
public record ExportOptionsImpl(OutputFormat outputFormat, FormatOptions formatOptions) implements ExportOptions {
public ExportOptionsImpl {
Objects.requireNonNull(outputFormat);
Objects.requireNonNull(formatOptions);
}
}

View File

@@ -0,0 +1,15 @@
package com.github.gtache.autosubtitle.subtitle.impl;
import com.github.gtache.autosubtitle.subtitle.ImportOptions;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import static java.util.Objects.requireNonNull;
/**
* Implementation of {@link ImportOptions}
*/
public record ImportOptionsImpl(ParseOptions parseOptions) implements ImportOptions {
public ImportOptionsImpl {
requireNonNull(parseOptions);
}
}

View File

@@ -6,7 +6,6 @@ import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Objects;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
@@ -17,7 +16,7 @@ public record SubtitleCollectionImpl<T extends Subtitle>(String text, Collection
Language language) implements SubtitleCollection<T> { Language language) implements SubtitleCollection<T> {
public SubtitleCollectionImpl { public SubtitleCollectionImpl {
Objects.requireNonNull(text); requireNonNull(text);
subtitles = List.copyOf(subtitles); subtitles = List.copyOf(subtitles);
requireNonNull(language); requireNonNull(language);
} }

View File

@@ -1,11 +1,13 @@
package com.github.gtache.autosubtitle.subtitle.impl; package com.github.gtache.autosubtitle.subtitle.impl;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.archive.Archiver; import com.github.gtache.autosubtitle.archive.Archiver;
import com.github.gtache.autosubtitle.archive.ArchiverProvider; import com.github.gtache.autosubtitle.archive.ArchiverProvider;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.ImportOptions;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.SubtitleImporterExporter; import com.github.gtache.autosubtitle.subtitle.SubtitleImporterExporter;
import com.github.gtache.autosubtitle.subtitle.converter.FormatException;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException; import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider;
@@ -40,19 +42,19 @@ public class SubtitleImporterExporterImpl implements SubtitleImporterExporter<Su
} }
@Override @Override
public Map<Language, SubtitleCollection<SubtitleImpl>> importSubtitles(final Path file) throws IOException, ParseException { public Map<Language, SubtitleCollection<SubtitleImpl>> importSubtitles(final Path file, final ImportOptions options) throws IOException, ParseException {
final var fileName = file.getFileName().toString(); final var fileName = file.getFileName().toString();
final var extension = fileName.substring(fileName.lastIndexOf('.') + 1); final var extension = fileName.substring(fileName.lastIndexOf('.') + 1);
if (archiverProvider.getArchiver(extension) == null) { if (archiverProvider.getArchiver(extension) == null) {
final var loaded = loadSingleFile(file); final var loaded = loadSingleFile(file, options);
logger.info("Loaded {}", file); logger.info("Loaded {}", file);
return Map.of(loaded.language(), loaded); return Map.of(loaded.language(), loaded);
} else { } else {
return loadArchive(file); return loadArchive(file, options);
} }
} }
private Map<Language, SubtitleCollection<SubtitleImpl>> loadArchive(final Path file) throws IOException, ParseException { private Map<Language, SubtitleCollection<SubtitleImpl>> loadArchive(final Path file, final ImportOptions options) throws IOException, ParseException {
final var fileName = file.getFileName().toString(); final var fileName = file.getFileName().toString();
final var extension = fileName.substring(fileName.lastIndexOf('.') + 1); final var extension = fileName.substring(fileName.lastIndexOf('.') + 1);
final var archiver = archiverProvider.getArchiver(extension); final var archiver = archiverProvider.getArchiver(extension);
@@ -64,7 +66,7 @@ public class SubtitleImporterExporterImpl implements SubtitleImporterExporter<Su
} }
final var map = new EnumMap<Language, SubtitleCollection<SubtitleImpl>>(Language.class); final var map = new EnumMap<Language, SubtitleCollection<SubtitleImpl>>(Language.class);
for (final var path : files) { for (final var path : files) {
final var loaded = loadSingleFile(path); final var loaded = loadSingleFile(path, options);
map.put(loaded.language(), loaded); map.put(loaded.language(), loaded);
Files.deleteIfExists(path); Files.deleteIfExists(path);
} }
@@ -73,39 +75,39 @@ public class SubtitleImporterExporterImpl implements SubtitleImporterExporter<Su
return map; return map;
} }
private SubtitleCollection<SubtitleImpl> loadSingleFile(final Path file) throws ParseException { private SubtitleCollection<SubtitleImpl> loadSingleFile(final Path file, final ImportOptions options) throws ParseException {
final var fileName = file.getFileName().toString(); final var fileName = file.getFileName().toString();
final var extension = fileName.substring(fileName.lastIndexOf('.') + 1); final var extension = fileName.substring(fileName.lastIndexOf('.') + 1);
final var parser = converterProvider.getConverter(extension); final var parser = converterProvider.getConverter(extension);
if (parser == null) { if (parser == null) {
throw new ParseException("No converter found for " + file); throw new ParseException("No converter found for " + file);
} else { } else {
final var parsed = parser.parse(file); final var parsed = parser.parse(file, options.parseOptions());
return new SubtitleCollectionImpl<>(parsed.text(), parsed.subtitles().stream().map(SubtitleImpl::new).toList(), parsed.language()); return new SubtitleCollectionImpl<>(parsed.text(), parsed.subtitles().stream().map(SubtitleImpl::new).toList(), parsed.language());
} }
} }
@Override @Override
public void exportSubtitles(final Collection<? extends SubtitleCollection<?>> collections, final VideoInfo videoInfo, final Path file) throws IOException { public void exportSubtitles(final Collection<? extends SubtitleCollection<?>> collections, final ExportOptions options, final Path file) throws IOException {
final var fileName = file.getFileName().toString(); final var fileName = file.getFileName().toString();
final var extension = fileName.substring(fileName.lastIndexOf('.') + 1); final var extension = fileName.substring(fileName.lastIndexOf('.') + 1);
if (archiverProvider.getArchiver(extension) != null) { if (archiverProvider.getArchiver(extension) != null) {
saveArchive(file, collections, videoInfo); saveArchive(file, collections, options);
} else if (collections.size() == 1) { } else if (collections.size() == 1) {
saveSingleFile(file, collections.iterator().next(), videoInfo); saveSingleFile(file, collections.iterator().next(), options);
} else { } else {
throw new IllegalArgumentException("Cannot export multiple collections to a non-archive file : " + file); throw new IllegalArgumentException("Cannot export multiple collections to a non-archive file : " + file);
} }
} }
private void saveArchive(final Path file, final Iterable<? extends SubtitleCollection<?>> collections, final VideoInfo videoInfo) throws IOException { private void saveArchive(final Path file, final Iterable<? extends SubtitleCollection<?>> collections, final ExportOptions options) throws IOException {
final var fileName = file.getFileName().toString(); final var fileName = file.getFileName().toString();
final var extension = fileName.substring(fileName.lastIndexOf('.') + 1); final var extension = fileName.substring(fileName.lastIndexOf('.') + 1);
final var archiver = archiverProvider.getArchiver(extension); final var archiver = archiverProvider.getArchiver(extension);
final var tempDir = Files.createTempDirectory("autosubtitle"); final var tempDir = Files.createTempDirectory("autosubtitle");
for (final var collection : collections) { for (final var collection : collections) {
final var subtitleFile = tempDir.resolve(collection.language().name().toLowerCase() + ".json"); final var subtitleFile = tempDir.resolve(collection.language().name().toLowerCase() + ".json");
saveSingleFile(subtitleFile, collection, videoInfo); saveSingleFile(subtitleFile, collection, options);
} }
final var files = new ArrayList<Path>(); final var files = new ArrayList<Path>();
try (final var stream = Files.list(tempDir)) { try (final var stream = Files.list(tempDir)) {
@@ -119,16 +121,20 @@ public class SubtitleImporterExporterImpl implements SubtitleImporterExporter<Su
logger.info("Saved {}", file); logger.info("Saved {}", file);
} }
private void saveSingleFile(final Path file, final SubtitleCollection<?> collection, final VideoInfo videoInfo) throws IOException { private void saveSingleFile(final Path file, final SubtitleCollection<?> collection, final ExportOptions options) throws IOException {
final var fileName = file.getFileName().toString(); final var fileName = file.getFileName().toString();
final var extension = fileName.substring(fileName.lastIndexOf('.') + 1); final var extension = fileName.substring(fileName.lastIndexOf('.') + 1);
final var converter = converterProvider.getConverter(extension); final var converter = converterProvider.getConverter(extension);
if (converter == null) { if (converter == null) {
throw new IOException("No converter found for " + file); throw new IOException("No converter found for " + file);
} else { } else {
final var string = converter.format(collection, videoInfo); try {
final var string = converter.format(collection, options.formatOptions());
Files.writeString(file, string); Files.writeString(file, string);
logger.info("Saved {}", file); logger.info("Saved {}", file);
} catch (final FormatException e) {
throw new IOException(e);
}
} }
} }

View File

@@ -11,27 +11,27 @@ import java.util.List;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
class TestZipDecompresser { class TestZipArchiver {
private final ZipDecompresser zipDecompresser; private final ZipArchiver zipArchiver;
TestZipDecompresser() { TestZipArchiver() {
this.zipDecompresser = new ZipDecompresser(); this.zipArchiver = new ZipArchiver();
} }
@Test @Test
void testIsPathSupported() { void testIsPathSupported() {
assertTrue(zipDecompresser.isPathSupported(Path.of("test.zip"))); assertTrue(zipArchiver.isPathSupported(Path.of("test.zip")));
assertFalse(zipDecompresser.isPathSupported(Path.of("test"))); assertFalse(zipArchiver.isPathSupported(Path.of("test")));
assertFalse(zipDecompresser.isPathSupported(Path.of("test.txt"))); assertFalse(zipArchiver.isPathSupported(Path.of("test.txt")));
assertFalse(zipDecompresser.isPathSupported(Path.of("test.zip2"))); assertFalse(zipArchiver.isPathSupported(Path.of("test.zip2")));
} }
@Test @Test
void testCompress() { void testCompress() {
final var paths = List.of(Paths.get("file.txt")); final var paths = List.of(Paths.get("file.txt"));
final var target = Paths.get("target"); final var target = Paths.get("target");
assertThrows(UnsupportedOperationException.class, () -> zipDecompresser.compress(paths, target)); assertThrows(UnsupportedOperationException.class, () -> zipArchiver.compress(paths, target));
} }
@Test @Test
@@ -43,7 +43,7 @@ class TestZipDecompresser {
} }
Files.copy(in, file); Files.copy(in, file);
} }
zipDecompresser.decompress(file, tempDir); zipArchiver.decompress(file, tempDir);
final var inTxt = tempDir.resolve("in.txt"); final var inTxt = tempDir.resolve("in.txt");
final var bin = tempDir.resolve("bin"); final var bin = tempDir.resolve("bin");
final var binTxt = bin.resolve("bin.txt"); final var binTxt = bin.resolve("bin.txt");
@@ -64,6 +64,6 @@ class TestZipDecompresser {
void testIllegal() { void testIllegal() {
final var source = Paths.get("source"); final var source = Paths.get("source");
final var target = Paths.get("target"); final var target = Paths.get("target");
assertThrows(IllegalArgumentException.class, () -> zipDecompresser.decompress(source, target)); assertThrows(IllegalArgumentException.class, () -> zipArchiver.decompress(source, target));
} }
} }

View File

@@ -26,25 +26,25 @@ class TestArchitecture {
@Test @Test
void testGetArchitecture() { void testGetArchitecture() {
for (final var value : Architecture.values()) { for (final var value : values()) {
System.setProperty("os.arch", value.name()); System.setProperty("os.arch", value.name());
assertEquals(value, Architecture.getArchitecture()); assertEquals(value, getArchitecture());
} }
System.setProperty("os.arch", "any"); System.setProperty("os.arch", "any");
assertEquals(UNKNOWN, Architecture.getArchitecture()); assertEquals(UNKNOWN, getArchitecture());
} }
@Test @Test
void testGetArchitectureName() { void testGetArchitectureName() {
assertEquals(I386, Architecture.getArchitecture("i386")); assertEquals(I386, getArchitecture("i386"));
assertEquals(I386, Architecture.getArchitecture("I386")); assertEquals(I386, getArchitecture("I386"));
} }
@Test @Test
void testIsAMD64() { void testIsAMD64() {
final var expectedAMD64 = Set.of(X86, X86_64, AMD64); final var expectedAMD64 = Set.of(X86, X86_64, AMD64);
expectedAMD64.forEach(a -> assertTrue(a.isAMD64())); expectedAMD64.forEach(a -> assertTrue(a.isAMD64()));
Arrays.stream(Architecture.values()).filter(a -> !expectedAMD64.contains(a)) Arrays.stream(values()).filter(a -> !expectedAMD64.contains(a))
.forEach(a -> assertFalse(a.isAMD64())); .forEach(a -> assertFalse(a.isAMD64()));
} }
@@ -52,7 +52,7 @@ class TestArchitecture {
void testIsARM64() { void testIsARM64() {
final var expectedARM64 = Set.of(ARM64, ARMV8, ARMV9, AARCH64); final var expectedARM64 = Set.of(ARM64, ARMV8, ARMV9, AARCH64);
expectedARM64.forEach(a -> assertTrue(a.isARM64())); expectedARM64.forEach(a -> assertTrue(a.isARM64()));
Arrays.stream(Architecture.values()).filter(a -> !expectedARM64.contains(a)) Arrays.stream(values()).filter(a -> !expectedARM64.contains(a))
.forEach(a -> assertFalse(a.isARM64())); .forEach(a -> assertFalse(a.isARM64()));
} }
} }

View File

@@ -3,7 +3,9 @@ package com.github.gtache.autosubtitle.subtitle.converter.impl;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.VideoInfo; import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.subtitle.Subtitle; import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException; import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import com.github.gtache.autosubtitle.subtitle.impl.FontImpl; import com.github.gtache.autosubtitle.subtitle.impl.FontImpl;
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl; import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl; import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl;
@@ -15,9 +17,8 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import java.util.prefs.Preferences;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
@@ -27,28 +28,28 @@ import static org.mockito.Mockito.when;
class TestASSSubtitleConverter { class TestASSSubtitleConverter {
private final Translator<Subtitle> translator; private final Translator<Subtitle> translator;
private final Preferences preferences; private final FormatOptions formatOptions;
private final ParseOptions parseOptions;
private final Language language; private final Language language;
private final VideoInfo videoInfo; private final VideoInfo videoInfo;
private final String defaultFontName;
private final int defaultFontSize;
private final ASSSubtitleConverter converter; private final ASSSubtitleConverter converter;
TestASSSubtitleConverter(@Mock final Translator<Subtitle> translator, TestASSSubtitleConverter(@Mock final Translator<Subtitle> translator,
@Mock final Preferences preferences,
@Mock final Language language, @Mock final Language language,
@Mock final FormatOptions formatOptions,
@Mock final ParseOptions parseOptions,
@Mock final VideoInfo videoInfo) { @Mock final VideoInfo videoInfo) {
this.translator = Objects.requireNonNull(translator); this.translator = requireNonNull(translator);
this.preferences = Objects.requireNonNull(preferences); this.language = requireNonNull(language);
this.language = Objects.requireNonNull(language); this.formatOptions = requireNonNull(formatOptions);
this.videoInfo = Objects.requireNonNull(videoInfo); this.parseOptions = requireNonNull(parseOptions);
this.defaultFontName = "Arial"; this.videoInfo = requireNonNull(videoInfo);
this.defaultFontSize = 12; this.converter = new ASSSubtitleConverter(translator);
this.converter = new ASSSubtitleConverter(translator, preferences, defaultFontName, defaultFontSize);
} }
@BeforeEach @BeforeEach
void beforeEach() { void beforeEach() {
when(formatOptions.videoInfo()).thenReturn(videoInfo);
when(videoInfo.width()).thenReturn(1920); when(videoInfo.width()).thenReturn(1920);
when(videoInfo.height()).thenReturn(1080); when(videoInfo.height()).thenReturn(1080);
when(translator.getLanguage(anyString())).thenReturn(language); when(translator.getLanguage(anyString())).thenReturn(language);
@@ -69,7 +70,7 @@ class TestASSSubtitleConverter {
[Events] [Events]
Format: Start, End, Style, Text Format: Start, End, Style, Text
Dialogue: 0:00:00.00,0:00:00.41,Arial12,Test ? Dialogue: 00:00:00.00,00:00:00.41,Arial12,Test ?
Dialogue: 123:45:54.32,124:00:00.00,Times New Roman13,Test2. Dialogue: 123:45:54.32,124:00:00.00,Times New Roman13,Test2.
"""; """;
@@ -82,8 +83,8 @@ class TestASSSubtitleConverter {
final var subtitle1 = new SubtitleImpl("Test ?", start1, end1, arial, null); final var subtitle1 = new SubtitleImpl("Test ?", start1, end1, arial, null);
final var subtitle2 = new SubtitleImpl("Test2.", start2, end2, times, null); final var subtitle2 = new SubtitleImpl("Test2.", start2, end2, times, null);
final var subtitles = new SubtitleCollectionImpl<>(subtitle1.content() + subtitle2.content(), Arrays.asList(subtitle1, subtitle2), language); final var subtitles = new SubtitleCollectionImpl<>(subtitle1.content() + subtitle2.content(), Arrays.asList(subtitle1, subtitle2), language);
assertEquals(subtitles, converter.parse(in)); assertEquals(subtitles, converter.parse(in, parseOptions));
assertEquals(in, converter.format(subtitles, videoInfo)); assertEquals(in, converter.format(subtitles, formatOptions));
} }
@Test @Test
@@ -114,7 +115,7 @@ class TestASSSubtitleConverter {
final var subtitle1 = new SubtitleImpl("Test ?", start1, end1, arial, null); final var subtitle1 = new SubtitleImpl("Test ?", start1, end1, arial, null);
final var subtitle2 = new SubtitleImpl("Test2.", start2, end2, times, null); final var subtitle2 = new SubtitleImpl("Test2.", start2, end2, times, null);
final var subtitles = new SubtitleCollectionImpl<>(subtitle1.content() + subtitle2.content(), Arrays.asList(subtitle1, subtitle2), language); final var subtitles = new SubtitleCollectionImpl<>(subtitle1.content() + subtitle2.content(), Arrays.asList(subtitle1, subtitle2), language);
assertEquals(subtitles, converter.parse(in)); assertEquals(subtitles, converter.parse(in, parseOptions));
} }
@Test @Test
@@ -125,7 +126,7 @@ class TestASSSubtitleConverter {
test1 test2 test1 test2
test3 test4 test3 test4
"""; """;
assertThrows(ParseException.class, () -> converter.parse(in)); assertThrows(ParseException.class, () -> converter.parse(in, parseOptions));
} }
@Test @Test
@@ -135,9 +136,6 @@ class TestASSSubtitleConverter {
@Test @Test
void testIllegal() { void testIllegal() {
assertThrows(NullPointerException.class, () -> new ASSSubtitleConverter(null, preferences, defaultFontName, defaultFontSize)); assertThrows(NullPointerException.class, () -> new ASSSubtitleConverter(null));
assertThrows(NullPointerException.class, () -> new ASSSubtitleConverter(translator, null, defaultFontName, defaultFontSize));
assertThrows(NullPointerException.class, () -> new ASSSubtitleConverter(translator, preferences, null, defaultFontSize));
assertThrows(IllegalArgumentException.class, () -> new ASSSubtitleConverter(translator, preferences, defaultFontName, 0));
} }
} }

View File

@@ -0,0 +1,40 @@
package com.github.gtache.autosubtitle.subtitle.converter.impl;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.subtitle.Font;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestFormatOptionsImpl {
private final VideoInfo videoInfo;
private final Font defaultFont;
private final FormatOptions formatOptions;
TestFormatOptionsImpl(@Mock final VideoInfo videoInfo, @Mock final Font defaultFont) {
this.videoInfo = Objects.requireNonNull(videoInfo);
this.defaultFont = Objects.requireNonNull(defaultFont);
this.formatOptions = new FormatOptionsImpl(videoInfo, defaultFont);
}
@Test
void testGetters() {
assertEquals(videoInfo, formatOptions.videoInfo());
assertEquals(defaultFont, formatOptions.defaultFont());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new FormatOptionsImpl(null, defaultFont));
assertThrows(NullPointerException.class, () -> new FormatOptionsImpl(videoInfo, null));
}
}

View File

@@ -0,0 +1,43 @@
package com.github.gtache.autosubtitle.subtitle.converter.impl;
import com.github.gtache.autosubtitle.subtitle.Font;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestParseOptionsImpl {
private final int maxLineLength;
private final int maxLines;
private final Font defaultFont;
private final ParseOptions parseOptions;
TestParseOptionsImpl(@Mock final Font defaultFont) {
this.defaultFont = Objects.requireNonNull(defaultFont);
this.maxLineLength = 1;
this.maxLines = 1;
this.parseOptions = new ParseOptionsImpl(maxLineLength, maxLines, defaultFont);
}
@Test
void testGetters() {
assertEquals(maxLineLength, parseOptions.maxLineLength());
assertEquals(maxLines, parseOptions.maxLines());
assertEquals(defaultFont, parseOptions.defaultFont());
}
@Test
void testIllegal() {
assertThrows(IllegalArgumentException.class, () -> new ParseOptionsImpl(0, 1, defaultFont));
assertThrows(IllegalArgumentException.class, () -> new ParseOptionsImpl(1, 0, defaultFont));
assertThrows(NullPointerException.class, () -> new ParseOptionsImpl(1, 1, null));
}
}

View File

@@ -1,9 +1,10 @@
package com.github.gtache.autosubtitle.subtitle.converter.impl; package com.github.gtache.autosubtitle.subtitle.converter.impl;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.subtitle.Subtitle; import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException; import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl; import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl; import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl;
import com.github.gtache.autosubtitle.translation.Translator; import com.github.gtache.autosubtitle.translation.Translator;
@@ -26,13 +27,16 @@ class TestSRTSubtitleConverter {
private final Translator<Subtitle> translator; private final Translator<Subtitle> translator;
private final Language language; private final Language language;
private final VideoInfo videoInfo; private final FormatOptions formatOptions;
private final ParseOptions parseOptions;
private final SRTSubtitleConverter converter; private final SRTSubtitleConverter converter;
TestSRTSubtitleConverter(@Mock final Translator<Subtitle> translator, @Mock final Language language, @Mock final VideoInfo videoInfo) { TestSRTSubtitleConverter(@Mock final Translator<Subtitle> translator, @Mock final Language language,
@Mock final FormatOptions formatOptions, @Mock final ParseOptions parseOptions) {
this.translator = Objects.requireNonNull(translator); this.translator = Objects.requireNonNull(translator);
this.language = Objects.requireNonNull(language); this.language = Objects.requireNonNull(language);
this.videoInfo = Objects.requireNonNull(videoInfo); this.formatOptions = Objects.requireNonNull(formatOptions);
this.parseOptions = Objects.requireNonNull(parseOptions);
this.converter = new SRTSubtitleConverter(translator); this.converter = new SRTSubtitleConverter(translator);
} }
@@ -62,8 +66,8 @@ class TestSRTSubtitleConverter {
final var subtitle1 = new SubtitleImpl("test5 test6\ntest7 test8", start1, end1, null, null); final var subtitle1 = new SubtitleImpl("test5 test6\ntest7 test8", start1, end1, null, null);
final var subtitle2 = new SubtitleImpl("test1 test2\ntest3 test4", start2, end2, null, null); final var subtitle2 = new SubtitleImpl("test1 test2\ntest3 test4", start2, end2, null, null);
final var subtitles = new SubtitleCollectionImpl<>(subtitle1.content() + " " + subtitle2.content(), Arrays.asList(subtitle1, subtitle2), language); final var subtitles = new SubtitleCollectionImpl<>(subtitle1.content() + " " + subtitle2.content(), Arrays.asList(subtitle1, subtitle2), language);
assertEquals(subtitles, converter.parse(in)); assertEquals(subtitles, converter.parse(in, parseOptions));
assertEquals(in, converter.format(subtitles, videoInfo)); assertEquals(in, converter.format(subtitles, formatOptions));
} }
@Test @Test
@@ -74,7 +78,7 @@ class TestSRTSubtitleConverter {
test1 test2 test1 test2
test3 test4 test3 test4
"""; """;
assertThrows(ParseException.class, () -> converter.parse(in)); assertThrows(ParseException.class, () -> converter.parse(in, parseOptions));
} }
@Test @Test

View File

@@ -1,12 +1,11 @@
package com.github.gtache.autosubtitle.subtitle.extractor.impl; package com.github.gtache.autosubtitle.subtitle.extractor.impl;
import com.github.gtache.autosubtitle.Audio; import com.github.gtache.autosubtitle.Audio;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Video; import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.subtitle.Subtitle; import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractEvent; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractEvent;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractorListener; import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractorListener;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@@ -56,12 +55,12 @@ class TestAbstractSubtitleExtractor {
private static final class DummySubtitleExtractor extends AbstractSubtitleExtractor { private static final class DummySubtitleExtractor extends AbstractSubtitleExtractor {
@Override @Override
public SubtitleCollection<Subtitle> extract(final Video video, final Language language, final ExtractionModel model) { public SubtitleCollection<Subtitle> extract(final Video video, final ExtractOptions options) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override @Override
public SubtitleCollection<Subtitle> extract(final Audio audio, final Language language, final ExtractionModel model) { public SubtitleCollection<Subtitle> extract(final Audio audio, final ExtractOptions options) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }

View File

@@ -0,0 +1,44 @@
package com.github.gtache.autosubtitle.subtitle.extractor.impl;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestExtractOptionsImpl {
private final Language language;
private final ExtractionModel model;
private final ParseOptions parseOptions;
private final ExtractOptions extractOptions;
TestExtractOptionsImpl(@Mock final Language language, @Mock final ExtractionModel model, @Mock final ParseOptions parseOptions) {
this.language = requireNonNull(language);
this.model = requireNonNull(model);
this.parseOptions = requireNonNull(parseOptions);
this.extractOptions = new ExtractOptionsImpl(language, model, parseOptions);
}
@Test
void testGetters() {
assertEquals(language, extractOptions.language());
assertEquals(model, extractOptions.model());
assertEquals(parseOptions, extractOptions.parseOptions());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new ExtractOptionsImpl(null, model, parseOptions));
assertThrows(NullPointerException.class, () -> new ExtractOptionsImpl(language, null, parseOptions));
assertThrows(NullPointerException.class, () -> new ExtractOptionsImpl(language, model, null));
}
}

View File

@@ -0,0 +1,39 @@
package com.github.gtache.autosubtitle.subtitle.impl;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestExportOptionsImpl {
private final OutputFormat outputFormat;
private final FormatOptions formatOptions;
private final ExportOptions exportOptions;
TestExportOptionsImpl(@Mock final OutputFormat outputFormat, @Mock final FormatOptions formatOptions) {
this.outputFormat = requireNonNull(outputFormat);
this.formatOptions = requireNonNull(formatOptions);
this.exportOptions = new ExportOptionsImpl(outputFormat, formatOptions);
}
@Test
void testGetters() {
assertEquals(outputFormat, exportOptions.outputFormat());
assertEquals(formatOptions, exportOptions.formatOptions());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new ExportOptionsImpl(null, formatOptions));
assertThrows(NullPointerException.class, () -> new ExportOptionsImpl(outputFormat, null));
}
}

View File

@@ -0,0 +1,36 @@
package com.github.gtache.autosubtitle.subtitle.impl;
import com.github.gtache.autosubtitle.subtitle.ImportOptions;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@ExtendWith(MockitoExtension.class)
class TestImportOptionsImpl {
private final ParseOptions parseOptions;
private final ImportOptions importOptions;
TestImportOptionsImpl(@Mock final ParseOptions parseOptions) {
this.parseOptions = requireNonNull(parseOptions);
this.importOptions = new ImportOptionsImpl(parseOptions);
}
@Test
void testGetters() {
assertEquals(parseOptions, importOptions.parseOptions());
}
@Test
void testIllegal() {
assertThrows(NullPointerException.class, () -> new ImportOptionsImpl(null));
}
}

View File

@@ -1,14 +1,19 @@
package com.github.gtache.autosubtitle.subtitle.impl; package com.github.gtache.autosubtitle.subtitle.impl;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.archive.Archiver; import com.github.gtache.autosubtitle.archive.Archiver;
import com.github.gtache.autosubtitle.archive.ArchiverProvider; import com.github.gtache.autosubtitle.archive.ArchiverProvider;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.ImportOptions;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.SubtitleImporterExporter; import com.github.gtache.autosubtitle.subtitle.SubtitleImporterExporter;
import com.github.gtache.autosubtitle.subtitle.converter.FormatException;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import com.github.gtache.autosubtitle.subtitle.converter.ParseException; import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.api.io.TempDir;
@@ -33,25 +38,38 @@ class TestSubtitleImporterExporterImpl {
private final ArchiverProvider archiverProvider; private final ArchiverProvider archiverProvider;
private final SubtitleConverterProvider converterProvider; private final SubtitleConverterProvider converterProvider;
private final SubtitleImporterExporter<SubtitleImpl> subtitleImporterExporter; private final SubtitleImporterExporter<SubtitleImpl> subtitleImporterExporter;
private final VideoInfo videoInfo; private final ExportOptions exportOptions;
private final FormatOptions formatOptions;
private final ImportOptions importOptions;
private final ParseOptions parseOptions;
private final Path path; private final Path path;
private final SubtitleCollection<SubtitleImpl> firstCollection; private final SubtitleCollection<SubtitleImpl> firstCollection;
private final SubtitleCollection<SubtitleImpl> secondCollection; private final SubtitleCollection<SubtitleImpl> secondCollection;
TestSubtitleImporterExporterImpl(@Mock final ArchiverProvider archiverProvider, TestSubtitleImporterExporterImpl(@Mock final ArchiverProvider archiverProvider,
@Mock final SubtitleConverterProvider converterProvider, @Mock final SubtitleConverterProvider converterProvider,
@Mock final VideoInfo videoInfo, @Mock final ExportOptions exportOptions, @Mock final FormatOptions formatOptions,
@Mock final ImportOptions importOptions, @Mock final ParseOptions parseOptions,
@Mock final SubtitleCollection<SubtitleImpl> firstCollection, @Mock final SubtitleCollection<SubtitleImpl> firstCollection,
@Mock final SubtitleCollection<SubtitleImpl> secondCollection) { @Mock final SubtitleCollection<SubtitleImpl> secondCollection) {
this.archiverProvider = requireNonNull(archiverProvider); this.archiverProvider = requireNonNull(archiverProvider);
this.converterProvider = requireNonNull(converterProvider); this.converterProvider = requireNonNull(converterProvider);
this.videoInfo = requireNonNull(videoInfo); this.exportOptions = requireNonNull(exportOptions);
this.formatOptions = requireNonNull(formatOptions);
this.importOptions = requireNonNull(importOptions);
this.parseOptions = requireNonNull(parseOptions);
this.subtitleImporterExporter = new SubtitleImporterExporterImpl(archiverProvider, converterProvider); this.subtitleImporterExporter = new SubtitleImporterExporterImpl(archiverProvider, converterProvider);
this.path = Paths.get("out.out"); this.path = Paths.get("out.out");
this.firstCollection = requireNonNull(firstCollection); this.firstCollection = requireNonNull(firstCollection);
this.secondCollection = requireNonNull(secondCollection); this.secondCollection = requireNonNull(secondCollection);
} }
@BeforeEach
void beforeEach() {
when(exportOptions.formatOptions()).thenReturn(formatOptions);
when(importOptions.parseOptions()).thenReturn(parseOptions);
}
@Test @Test
void testImportSubtitlesArchive() throws IOException, ParseException { void testImportSubtitlesArchive() throws IOException, ParseException {
final var archiver = mock(Archiver.class); final var archiver = mock(Archiver.class);
@@ -76,7 +94,7 @@ class TestSubtitleImporterExporterImpl {
when(firstCollection.subtitles()).thenReturn(subtitles); when(firstCollection.subtitles()).thenReturn(subtitles);
when(firstCollection.text()).thenReturn("text"); when(firstCollection.text()).thenReturn("text");
when(firstCollection.language()).thenReturn(Language.EN); when(firstCollection.language()).thenReturn(Language.EN);
when(converter1.parse(any(Path.class))).thenReturn(firstCollection); when(converter1.parse(any(Path.class), eq(parseOptions))).thenReturn(firstCollection);
final var s3 = new SubtitleImpl("test3", 0, 100, null, null); final var s3 = new SubtitleImpl("test3", 0, 100, null, null);
final var s4 = new SubtitleImpl("test4", 100, 200, null, null); final var s4 = new SubtitleImpl("test4", 100, 200, null, null);
@@ -84,9 +102,9 @@ class TestSubtitleImporterExporterImpl {
when(secondCollection.subtitles()).thenReturn(subtitles2); when(secondCollection.subtitles()).thenReturn(subtitles2);
when(secondCollection.text()).thenReturn("text2"); when(secondCollection.text()).thenReturn("text2");
when(secondCollection.language()).thenReturn(Language.FR); when(secondCollection.language()).thenReturn(Language.FR);
when(converter2.parse(any(Path.class))).thenReturn(secondCollection); when(converter2.parse(any(Path.class), eq(parseOptions))).thenReturn(secondCollection);
final var result = subtitleImporterExporter.importSubtitles(path); final var result = subtitleImporterExporter.importSubtitles(path, importOptions);
assertEquals(2, result.size()); assertEquals(2, result.size());
final var collection1 = result.get(Language.EN); final var collection1 = result.get(Language.EN);
@@ -103,7 +121,7 @@ class TestSubtitleImporterExporterImpl {
void testImportSubtitlesSingle() throws IOException, ParseException { void testImportSubtitlesSingle() throws IOException, ParseException {
final var converter = mock(SubtitleConverter.class); final var converter = mock(SubtitleConverter.class);
when(converterProvider.getConverter("out")).thenReturn(converter); when(converterProvider.getConverter("out")).thenReturn(converter);
when(converter.parse(path)).thenReturn(firstCollection); when(converter.parse(path, parseOptions)).thenReturn(firstCollection);
final var s1 = new SubtitleImpl("test", 0, 100, null, null); final var s1 = new SubtitleImpl("test", 0, 100, null, null);
final var s2 = new SubtitleImpl("test2", 100, 200, null, null); final var s2 = new SubtitleImpl("test2", 100, 200, null, null);
final var subtitles = List.of(s1, s2); final var subtitles = List.of(s1, s2);
@@ -111,7 +129,7 @@ class TestSubtitleImporterExporterImpl {
when(firstCollection.text()).thenReturn("text"); when(firstCollection.text()).thenReturn("text");
when(firstCollection.language()).thenReturn(Language.EN); when(firstCollection.language()).thenReturn(Language.EN);
final var result = subtitleImporterExporter.importSubtitles(path); final var result = subtitleImporterExporter.importSubtitles(path, importOptions);
assertEquals(1, result.size()); assertEquals(1, result.size());
final var collection = result.get(Language.EN); final var collection = result.get(Language.EN);
@@ -121,12 +139,12 @@ class TestSubtitleImporterExporterImpl {
} }
@Test @Test
void testImportSubtitlesSingleParseException() throws IOException, ParseException { void testImportSubtitlesSingleParseException() {
assertThrows(ParseException.class, () -> subtitleImporterExporter.importSubtitles(path)); assertThrows(ParseException.class, () -> subtitleImporterExporter.importSubtitles(path, importOptions));
} }
@Test @Test
void testExportSubtitlesArchive(@TempDir final Path outputDir) throws IOException, ParseException { void testExportSubtitlesArchive(@TempDir final Path outputDir) throws IOException, FormatException {
final var outputPath = outputDir.resolve("out.out"); final var outputPath = outputDir.resolve("out.out");
final var collection = List.of(firstCollection, secondCollection); final var collection = List.of(firstCollection, secondCollection);
final var archiver = mock(Archiver.class); final var archiver = mock(Archiver.class);
@@ -135,13 +153,13 @@ class TestSubtitleImporterExporterImpl {
when(converterProvider.getConverter("json")).thenReturn(converter); when(converterProvider.getConverter("json")).thenReturn(converter);
when(firstCollection.language()).thenReturn(Language.EN); when(firstCollection.language()).thenReturn(Language.EN);
when(secondCollection.language()).thenReturn(Language.FR); when(secondCollection.language()).thenReturn(Language.FR);
when(converter.format(firstCollection, videoInfo)).thenReturn("en"); when(converter.format(firstCollection, formatOptions)).thenReturn("en");
when(converter.format(secondCollection, videoInfo)).thenReturn("fr"); when(converter.format(secondCollection, formatOptions)).thenReturn("fr");
subtitleImporterExporter.exportSubtitles(collection, videoInfo, outputPath); subtitleImporterExporter.exportSubtitles(collection, exportOptions, outputPath);
verify(converter).format(collection.get(0), videoInfo); verify(converter).format(collection.get(0), formatOptions);
verify(converter).format(collection.get(1), videoInfo); verify(converter).format(collection.get(1), formatOptions);
final var captor = ArgumentCaptor.forClass(List.class); final var captor = ArgumentCaptor.forClass(List.class);
verify(archiver).compress(captor.capture(), eq(outputPath)); verify(archiver).compress(captor.capture(), eq(outputPath));
final var files = (List<Path>) captor.getValue(); final var files = (List<Path>) captor.getValue();
@@ -151,26 +169,26 @@ class TestSubtitleImporterExporterImpl {
} }
@Test @Test
void testExportSubtitlesSingle(@TempDir final Path outputDir) throws IOException { void testExportSubtitlesSingle(@TempDir final Path outputDir) throws IOException, FormatException {
final var outputPath = outputDir.resolve("out.out"); final var outputPath = outputDir.resolve("out.out");
final var collection = List.of(firstCollection); final var collection = List.of(firstCollection);
final var converter = mock(SubtitleConverter.class); final var converter = mock(SubtitleConverter.class);
when(converterProvider.getConverter("out")).thenReturn(converter); when(converterProvider.getConverter("out")).thenReturn(converter);
final var expected = "expected"; final var expected = "expected";
when(converter.format(collection.getFirst(), videoInfo)).thenReturn(expected); when(converter.format(collection.getFirst(), formatOptions)).thenReturn(expected);
subtitleImporterExporter.exportSubtitles(collection, videoInfo, outputPath); subtitleImporterExporter.exportSubtitles(collection, exportOptions, outputPath);
assertEquals(expected, Files.readString(outputPath)); assertEquals(expected, Files.readString(outputPath));
} }
@Test @Test
void testExportSubtitlesSingleException() { void testExportSubtitlesSingleException() {
final var collection = List.of(firstCollection); final var collection = List.of(firstCollection);
assertThrows(IOException.class, () -> subtitleImporterExporter.exportSubtitles(collection, videoInfo, path)); assertThrows(IOException.class, () -> subtitleImporterExporter.exportSubtitles(collection, exportOptions, path));
} }
@Test @Test
void testExportSubtitlesMultipleException() { void testExportSubtitlesMultipleException() {
assertThrows(IllegalArgumentException.class, () -> subtitleImporterExporter.exportSubtitles(List.of(firstCollection, secondCollection), videoInfo, path)); assertThrows(IllegalArgumentException.class, () -> subtitleImporterExporter.exportSubtitles(List.of(firstCollection, secondCollection), exportOptions, path));
} }
@Test @Test

View File

@@ -22,7 +22,7 @@ public class TarArchiver implements Archiver {
} }
@Override @Override
public void compress(final List<Path> files, final Path destination) throws IOException { public void compress(final List<Path> files, final Path destination) {
throw new UnsupportedOperationException("Not implemented yet"); throw new UnsupportedOperationException("Not implemented yet");
} }

View File

@@ -20,7 +20,7 @@ public class XZArchiver implements Archiver {
} }
@Override @Override
public void compress(final List<Path> files, final Path destination) throws IOException { public void compress(final List<Path> files, final Path destination) {
throw new UnsupportedOperationException("Not implemented"); throw new UnsupportedOperationException("Not implemented");
} }

View File

@@ -4,14 +4,15 @@ import com.github.gtache.autosubtitle.Audio;
import com.github.gtache.autosubtitle.File; import com.github.gtache.autosubtitle.File;
import com.github.gtache.autosubtitle.Video; import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.VideoConverter; import com.github.gtache.autosubtitle.VideoConverter;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.impl.AudioInfoImpl; import com.github.gtache.autosubtitle.impl.AudioInfoImpl;
import com.github.gtache.autosubtitle.impl.FileAudioImpl; import com.github.gtache.autosubtitle.impl.FileAudioImpl;
import com.github.gtache.autosubtitle.impl.FileVideoImpl; import com.github.gtache.autosubtitle.impl.FileVideoImpl;
import com.github.gtache.autosubtitle.modules.setup.ffmpeg.FFmpegBundledPath; import com.github.gtache.autosubtitle.modules.setup.ffmpeg.FFmpegBundledPath;
import com.github.gtache.autosubtitle.modules.setup.ffmpeg.FFmpegSystemPath; import com.github.gtache.autosubtitle.modules.setup.ffmpeg.FFmpegSystemPath;
import com.github.gtache.autosubtitle.process.ProcessRunner; import com.github.gtache.autosubtitle.process.ProcessRunner;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.converter.FormatException;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@@ -28,7 +29,6 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.SequencedMap; import java.util.SequencedMap;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.prefs.Preferences;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
@@ -41,31 +41,28 @@ public class FFmpegVideoConverter implements VideoConverter {
private final Path bundledPath; private final Path bundledPath;
private final Path systemPath; private final Path systemPath;
private final SubtitleConverterProvider converterProvider; private final SubtitleConverterProvider converterProvider;
private final Preferences preferences;
private final ProcessRunner processRunner; private final ProcessRunner processRunner;
@Inject @Inject
FFmpegVideoConverter(@FFmpegBundledPath final Path bundledPath, @FFmpegSystemPath final Path systemPath, FFmpegVideoConverter(@FFmpegBundledPath final Path bundledPath, @FFmpegSystemPath final Path systemPath,
final SubtitleConverterProvider converterProvider, final Preferences preferences, final SubtitleConverterProvider converterProvider, final ProcessRunner processRunner) {
final ProcessRunner processRunner) {
this.bundledPath = requireNonNull(bundledPath); this.bundledPath = requireNonNull(bundledPath);
this.systemPath = requireNonNull(systemPath); this.systemPath = requireNonNull(systemPath);
this.converterProvider = requireNonNull(converterProvider); this.converterProvider = requireNonNull(converterProvider);
this.preferences = requireNonNull(preferences);
this.processRunner = requireNonNull(processRunner); this.processRunner = requireNonNull(processRunner);
} }
@Override @Override
public Video addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles) throws IOException { public Video addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles, final ExportOptions options) throws IOException {
final var out = getTempFile(video.info().format()); final var out = getTempFile(video.info().format());
addSoftSubtitles(video, subtitles, out); addSoftSubtitles(video, subtitles, options, out);
return new FileVideoImpl(out, video.info()); return new FileVideoImpl(out, video.info());
} }
@Override @Override
public void addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles, final Path path) throws IOException { public void addSoftSubtitles(final Video video, final Collection<? extends SubtitleCollection<?>> subtitles, final ExportOptions options, final Path path) throws IOException {
final var videoPath = getPath(video); final var videoPath = getPath(video);
final var collectionMap = dumpCollections(subtitles, video.info()); final var collectionMap = dumpCollections(subtitles, options);
final var args = new ArrayList<String>(); final var args = new ArrayList<String>();
args.add(getFFmpegPath()); args.add(getFFmpegPath());
args.add("-y"); args.add("-y");
@@ -108,18 +105,18 @@ public class FFmpegVideoConverter implements VideoConverter {
} }
@Override @Override
public Video addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles) throws IOException { public Video addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final ExportOptions options) throws IOException {
final var out = getTempFile(video.info().format()); final var out = getTempFile(video.info().format());
addHardSubtitles(video, subtitles, out); addHardSubtitles(video, subtitles, options, out);
return new FileVideoImpl(out, video.info()); return new FileVideoImpl(out, video.info());
} }
@Override @Override
public void addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final Path path) throws IOException { public void addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final ExportOptions options, final Path path) throws IOException {
final var videoPath = getPath(video); final var videoPath = getPath(video);
final var subtitlesPath = dumpSubtitles(subtitles, video.info()); final var subtitlesPath = dumpSubtitles(subtitles, options);
final var escapedPath = escapeVF(subtitlesPath.toString()); final var escapedPath = escapeVF(subtitlesPath.toString());
final var subtitleArg = getSubtitleConverter().formatName().equalsIgnoreCase("ass") ? "ass='" + escapedPath + "'" : "subtitles='" + escapedPath + "'"; final var subtitleArg = getSubtitleConverter(options).formatName().equalsIgnoreCase("ass") ? "ass='" + escapedPath + "'" : "subtitles='" + escapedPath + "'";
final var args = List.of( final var args = List.of(
getFFmpegPath(), getFFmpegPath(),
"-y", "-y",
@@ -132,8 +129,8 @@ public class FFmpegVideoConverter implements VideoConverter {
runLog(args, Duration.ofHours(1)); runLog(args, Duration.ofHours(1));
} }
private SubtitleConverter<?> getSubtitleConverter() { private SubtitleConverter<?> getSubtitleConverter(final ExportOptions options) {
return converterProvider.getConverter(preferences.get("outputFormat", "srt")); return converterProvider.getConverter(options.outputFormat());
} }
private static String escapeVF(final String path) { private static String escapeVF(final String path) {
@@ -179,18 +176,22 @@ public class FFmpegVideoConverter implements VideoConverter {
return path; return path;
} }
private <T extends SubtitleCollection<?>> SequencedMap<T, Path> dumpCollections(final Collection<T> collections, final VideoInfo videoInfo) throws IOException { private <T extends SubtitleCollection<?>> SequencedMap<T, Path> dumpCollections(final Collection<? extends T> collections, final ExportOptions options) throws IOException {
final var ret = LinkedHashMap.<T, Path>newLinkedHashMap(collections.size()); final var ret = LinkedHashMap.<T, Path>newLinkedHashMap(collections.size());
for (final var subtitles : collections) { for (final var subtitles : collections) {
ret.put(subtitles, dumpSubtitles(subtitles, videoInfo)); ret.put(subtitles, dumpSubtitles(subtitles, options));
} }
return ret; return ret;
} }
private Path dumpSubtitles(final SubtitleCollection<?> subtitles, final VideoInfo videoInfo) throws IOException { private Path dumpSubtitles(final SubtitleCollection<?> subtitles, final ExportOptions options) throws IOException {
final var path = getTempFile(getSubtitleConverter().formatName().toLowerCase()); final var path = getTempFile(getSubtitleConverter(options).formatName().toLowerCase());
Files.writeString(path, getSubtitleConverter().format(subtitles, videoInfo)); try {
Files.writeString(path, getSubtitleConverter(options).format(subtitles, options.formatOptions()));
return path; return path;
} catch (final FormatException e) {
throw new IOException(e);
}
} }
private static Path getTempFile(final String extension) throws IOException { private static Path getTempFile(final String extension) throws IOException {

View File

@@ -9,7 +9,6 @@ module com.github.gtache.autosubtitle.ffmpeg {
requires org.apache.logging.log4j; requires org.apache.logging.log4j;
requires org.tukaani.xz; requires org.tukaani.xz;
requires org.apache.commons.compress; requires org.apache.commons.compress;
requires java.prefs;
exports com.github.gtache.autosubtitle.ffmpeg; exports com.github.gtache.autosubtitle.ffmpeg;
exports com.github.gtache.autosubtitle.setup.ffmpeg; exports com.github.gtache.autosubtitle.setup.ffmpeg;

View File

@@ -8,7 +8,11 @@ import com.github.gtache.autosubtitle.impl.FileVideoImpl;
import com.github.gtache.autosubtitle.process.ProcessListener; import com.github.gtache.autosubtitle.process.ProcessListener;
import com.github.gtache.autosubtitle.process.ProcessResult; import com.github.gtache.autosubtitle.process.ProcessResult;
import com.github.gtache.autosubtitle.process.ProcessRunner; import com.github.gtache.autosubtitle.process.ProcessRunner;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.converter.FormatException;
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@@ -28,7 +32,6 @@ import java.time.Duration;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.prefs.Preferences;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
@@ -40,29 +43,31 @@ class TestFFmpegVideoConverter {
private final ProcessRunner runner; private final ProcessRunner runner;
private final ProcessListener listener; private final ProcessListener listener;
private final ProcessResult result; private final ProcessResult processResult;
private final SubtitleConverter<?> subtitleConverter; private final SubtitleConverter<?> subtitleConverter;
private final SubtitleConverterProvider subtitleConverterProvider; private final SubtitleConverterProvider subtitleConverterProvider;
private final Video video; private final Video video;
private final InputStream in;
private final VideoInfo videoInfo; private final VideoInfo videoInfo;
private final InputStream in;
private final ExportOptions options;
private final FormatOptions formatOptions;
private final SubtitleCollection<?> frCollection; private final SubtitleCollection<?> frCollection;
private final SubtitleCollection<?> deCollection; private final SubtitleCollection<?> deCollection;
private final Preferences preferences;
private final Path systemPath; private final Path systemPath;
TestFFmpegVideoConverter(@Mock final SubtitleConverter<?> subtitleConverter, @Mock final ProcessRunner runner, TestFFmpegVideoConverter(@Mock final SubtitleConverter<?> subtitleConverter, @Mock final ProcessRunner runner,
@Mock final SubtitleConverterProvider subtitleConverterProvider, @Mock final Video video, @Mock final SubtitleConverterProvider subtitleConverterProvider, @Mock final Video video, @Mock final VideoInfo videoInfo,
@Mock final VideoInfo videoInfo, @Mock final SubtitleCollection<?> frCollection, @Mock final SubtitleCollection<?> deCollection, @Mock final ExportOptions options, @Mock final SubtitleCollection<?> frCollection,
@Mock final Preferences preferences, @Mock final ProcessListener listener, @Mock final InputStream in, @Mock final SubtitleCollection<?> deCollection, @Mock final ProcessListener listener, @Mock final InputStream in,
@Mock final ProcessResult result) { @Mock final ProcessResult processResult, @Mock final FormatOptions formatOptions) {
this.video = requireNonNull(video); this.video = requireNonNull(video);
this.runner = requireNonNull(runner);
this.result = requireNonNull(result);
this.videoInfo = requireNonNull(videoInfo); this.videoInfo = requireNonNull(videoInfo);
this.runner = requireNonNull(runner);
this.options = requireNonNull(options);
this.formatOptions = requireNonNull(formatOptions);
this.processResult = requireNonNull(processResult);
this.subtitleConverter = requireNonNull(subtitleConverter); this.subtitleConverter = requireNonNull(subtitleConverter);
this.subtitleConverterProvider = requireNonNull(subtitleConverterProvider); this.subtitleConverterProvider = requireNonNull(subtitleConverterProvider);
this.preferences = requireNonNull(preferences);
this.listener = requireNonNull(listener); this.listener = requireNonNull(listener);
this.in = requireNonNull(in); this.in = requireNonNull(in);
this.systemPath = Paths.get("system"); this.systemPath = Paths.get("system");
@@ -71,25 +76,26 @@ class TestFFmpegVideoConverter {
} }
@BeforeEach @BeforeEach
void beforeEach() throws IOException { void beforeEach() throws IOException, FormatException {
when(video.info()).thenReturn(videoInfo); when(video.info()).thenReturn(videoInfo);
when(subtitleConverterProvider.getConverter("srt")).thenReturn((SubtitleConverter) subtitleConverter); when(subtitleConverterProvider.getConverter(OutputFormat.SRT)).thenReturn((SubtitleConverter) subtitleConverter);
when(subtitleConverter.formatName()).thenReturn("srt"); when(subtitleConverter.formatName()).thenReturn("srt");
when(subtitleConverter.format(any(), any())).thenReturn(""); when(subtitleConverter.format(any(), any())).thenReturn("");
when(preferences.get("outputFormat", "srt")).thenReturn("srt"); when(options.outputFormat()).thenReturn(OutputFormat.SRT);
when(options.formatOptions()).thenReturn(formatOptions);
when(video.getInputStream()).thenReturn(in); when(video.getInputStream()).thenReturn(in);
when(frCollection.language()).thenReturn(Language.FR); when(frCollection.language()).thenReturn(Language.FR);
when(deCollection.language()).thenReturn(Language.DE); when(deCollection.language()).thenReturn(Language.DE);
when(runner.startListen(anyList())).thenReturn(listener); when(runner.startListen(anyList())).thenReturn(listener);
when(listener.join(Duration.ofHours(1))).thenReturn(result); when(listener.join(Duration.ofHours(1))).thenReturn(processResult);
when(result.exitCode()).thenReturn(0); when(processResult.exitCode()).thenReturn(0);
} }
@Test @Test
void testAddSoftSubtitlesMp4() throws IOException { void testAddSoftSubtitlesMp4() throws IOException, FormatException {
when(videoInfo.format()).thenReturn("mp4"); when(videoInfo.format()).thenReturn("mp4");
final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, preferences, runner); final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, runner);
final var result = converter.addSoftSubtitles(video, List.of(frCollection, deCollection)); final var result = converter.addSoftSubtitles(video, List.of(frCollection, deCollection), options);
assertEquals(videoInfo, result.info()); assertEquals(videoInfo, result.info());
@@ -125,8 +131,8 @@ class TestFFmpegVideoConverter {
assertTrue(args.get(5).endsWith(".srt")); assertTrue(args.get(5).endsWith(".srt"));
assertTrue(args.get(7).endsWith(".srt")); assertTrue(args.get(7).endsWith(".srt"));
assertTrue(args.get(26).endsWith(".mp4")); assertTrue(args.get(26).endsWith(".mp4"));
verify(subtitleConverter).format(frCollection, videoInfo); verify(subtitleConverter).format(frCollection, formatOptions);
verify(subtitleConverter).format(deCollection, videoInfo); verify(subtitleConverter).format(deCollection, formatOptions);
verify(in).transferTo(any()); verify(in).transferTo(any());
} }
@@ -135,19 +141,18 @@ class TestFFmpegVideoConverter {
} }
@Test @Test
void testAddSoftSubtitlesMkvPathFile() throws IOException { void testAddSoftSubtitlesMkvPathFile() throws IOException, FormatException {
when(videoInfo.format()).thenReturn("mkv"); when(videoInfo.format()).thenReturn("mkv");
doReturn(null).when(subtitleConverterProvider).getConverter("srt"); doReturn(null).when(subtitleConverterProvider).getConverter(OutputFormat.SRT);
when(subtitleConverterProvider.getConverter("ass")).thenReturn((SubtitleConverter) subtitleConverter); when(subtitleConverterProvider.getConverter(OutputFormat.ASS)).thenReturn((SubtitleConverter) subtitleConverter);
when(subtitleConverter.formatName()).thenReturn("ass"); when(subtitleConverter.formatName()).thenReturn("ass");
when(preferences.get("outputFormat", "srt")).thenReturn("ass"); when(options.outputFormat()).thenReturn(OutputFormat.ASS);
final var fileVideo = mock(FileVideoImpl.class); final var fileVideo = mock(FileVideoImpl.class);
when(fileVideo.info()).thenReturn(videoInfo);
final var path = Paths.get("path.mkv"); final var path = Paths.get("path.mkv");
when(fileVideo.path()).thenReturn(path); when(fileVideo.path()).thenReturn(path);
final var out = Paths.get("out.mkv"); final var out = Paths.get("out.mkv");
final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, preferences, runner); final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, runner);
converter.addSoftSubtitles(fileVideo, List.of(frCollection, deCollection), out); converter.addSoftSubtitles(fileVideo, List.of(frCollection, deCollection), options, out);
final var args = getArgs(); final var args = getArgs();
assertEquals(27, args.size()); assertEquals(27, args.size());
@@ -181,16 +186,16 @@ class TestFFmpegVideoConverter {
checkEquals(argMap, args); checkEquals(argMap, args);
assertTrue(args.get(5).endsWith(".ass")); assertTrue(args.get(5).endsWith(".ass"));
assertTrue(args.get(7).endsWith(".ass")); assertTrue(args.get(7).endsWith(".ass"));
verify(subtitleConverter).format(frCollection, videoInfo); verify(subtitleConverter).format(frCollection, formatOptions);
verify(subtitleConverter).format(deCollection, videoInfo); verify(subtitleConverter).format(deCollection, formatOptions);
verifyNoInteractions(in); verifyNoInteractions(in);
} }
@Test @Test
void testAddHardSubtitles() throws IOException { void testAddHardSubtitles() throws IOException, FormatException {
when(videoInfo.format()).thenReturn("mp4"); when(videoInfo.format()).thenReturn("mp4");
final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, preferences, runner); final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, runner);
final var result = converter.addHardSubtitles(video, frCollection); final var result = converter.addHardSubtitles(video, frCollection, options);
assertEquals(videoInfo, result.info()); assertEquals(videoInfo, result.info());
@@ -206,19 +211,19 @@ class TestFFmpegVideoConverter {
assertTrue(args.get(3).endsWith(".mp4")); assertTrue(args.get(3).endsWith(".mp4"));
assertTrue(args.get(5).startsWith("subtitles=")); assertTrue(args.get(5).startsWith("subtitles="));
assertTrue(args.get(6).endsWith(".mp4")); assertTrue(args.get(6).endsWith(".mp4"));
verify(subtitleConverter).format(frCollection, videoInfo); verify(subtitleConverter).format(frCollection, formatOptions);
verify(in).transferTo(any()); verify(in).transferTo(any());
} }
@Test @Test
void testAddHardAssSubtitles() throws IOException { void testAddHardAssSubtitles() throws IOException, FormatException {
doReturn(null).when(subtitleConverterProvider).getConverter("srt"); doReturn(null).when(subtitleConverterProvider).getConverter(OutputFormat.SRT);
when(subtitleConverterProvider.getConverter("ass")).thenReturn((SubtitleConverter) subtitleConverter); when(subtitleConverterProvider.getConverter(OutputFormat.ASS)).thenReturn((SubtitleConverter) subtitleConverter);
when(subtitleConverter.formatName()).thenReturn("ass"); when(subtitleConverter.formatName()).thenReturn("ass");
when(preferences.get("outputFormat", "srt")).thenReturn("ass"); when(options.outputFormat()).thenReturn(OutputFormat.ASS);
when(videoInfo.format()).thenReturn("mp4"); when(videoInfo.format()).thenReturn("mp4");
final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, preferences, runner); final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, runner);
final var result = converter.addHardSubtitles(video, frCollection); final var result = converter.addHardSubtitles(video, frCollection, options);
assertEquals(videoInfo, result.info()); assertEquals(videoInfo, result.info());
@@ -234,7 +239,7 @@ class TestFFmpegVideoConverter {
assertTrue(args.get(3).endsWith(".mp4")); assertTrue(args.get(3).endsWith(".mp4"));
assertTrue(args.get(5).startsWith("ass=")); assertTrue(args.get(5).startsWith("ass="));
assertTrue(args.get(6).endsWith(".mp4")); assertTrue(args.get(6).endsWith(".mp4"));
verify(subtitleConverter).format(frCollection, videoInfo); verify(subtitleConverter).format(frCollection, formatOptions);
verify(in).transferTo(any()); verify(in).transferTo(any());
} }
@@ -242,7 +247,7 @@ class TestFFmpegVideoConverter {
void testGetAudio() throws IOException { void testGetAudio() throws IOException {
when(videoInfo.format()).thenReturn("mp4"); when(videoInfo.format()).thenReturn("mp4");
when(videoInfo.duration()).thenReturn(25000L); when(videoInfo.duration()).thenReturn(25000L);
final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, preferences, runner); final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, runner);
final var result = converter.getAudio(video); final var result = converter.getAudio(video);
assertEquals(new AudioInfoImpl("wav", 25000L), result.info()); assertEquals(new AudioInfoImpl("wav", 25000L), result.info());
@@ -267,10 +272,10 @@ class TestFFmpegVideoConverter {
@Test @Test
void testGetAudioException() { void testGetAudioException() {
when(result.exitCode()).thenReturn(1); when(processResult.exitCode()).thenReturn(1);
when(videoInfo.format()).thenReturn("mp4"); when(videoInfo.format()).thenReturn("mp4");
when(videoInfo.duration()).thenReturn(25000L); when(videoInfo.duration()).thenReturn(25000L);
final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, preferences, runner); final var converter = new FFmpegVideoConverter(Paths.get("bundled"), systemPath, subtitleConverterProvider, runner);
assertThrows(IOException.class, () -> converter.getAudio(video)); assertThrows(IOException.class, () -> converter.getAudio(video));
} }
@@ -280,7 +285,7 @@ class TestFFmpegVideoConverter {
Files.createFile(bundled); Files.createFile(bundled);
when(videoInfo.format()).thenReturn("mp4"); when(videoInfo.format()).thenReturn("mp4");
when(videoInfo.duration()).thenReturn(25000L); when(videoInfo.duration()).thenReturn(25000L);
final var converter = new FFmpegVideoConverter(bundled, systemPath, subtitleConverterProvider, preferences, runner); final var converter = new FFmpegVideoConverter(bundled, systemPath, subtitleConverterProvider, runner);
final var result = converter.getAudio(video); final var result = converter.getAudio(video);
assertEquals(new AudioInfoImpl("wav", 25000L), result.info()); assertEquals(new AudioInfoImpl("wav", 25000L), result.info());

View File

@@ -95,7 +95,7 @@ class TestFFmpegSetupManager {
} }
@Test @Test
void testGetStatusSystemException() throws IOException, SetupException { void testGetStatusSystemException() throws IOException {
final var ffmpegPath = Paths.get("path"); final var ffmpegPath = Paths.get("path");
when(configuration.bundledFFmpegPath()).thenReturn(ffmpegPath); when(configuration.bundledFFmpegPath()).thenReturn(ffmpegPath);
when(processRunner.run(List.of(systemPath.toString(), "-version"), Duration.ofSeconds(5))).thenThrow(IOException.class); when(processRunner.run(List.of(systemPath.toString(), "-version"), Duration.ofSeconds(5))).thenThrow(IOException.class);

View File

@@ -1,5 +1,6 @@
package com.github.gtache.autosubtitle.gui.parameters; package com.github.gtache.autosubtitle.gui.parameters;
import com.github.gtache.autosubtitle.subtitle.Font;
import com.github.gtache.autosubtitle.subtitle.OutputFormat; import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
@@ -65,6 +66,11 @@ public interface ParametersModel {
*/ */
void setFontSize(int fontSize); void setFontSize(int fontSize);
/**
* @return The current font
*/
Font font();
/** /**
* @return The current max line length setting * @return The current max line length setting
*/ */

View File

@@ -1,7 +1,6 @@
package com.github.gtache.autosubtitle.gui.subtitles; package com.github.gtache.autosubtitle.gui.subtitles;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.subtitle.Subtitle; import com.github.gtache.autosubtitle.subtitle.Subtitle;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
@@ -33,18 +32,6 @@ public interface SubtitlesModel<T extends Subtitle, U extends SubtitleCollection
*/ */
void setVideoLanguage(Language language); void setVideoLanguage(Language language);
/**
* @return The video info
*/
VideoInfo videoInfo();
/**
* Sets the video info
*
* @param videoInfo The new video info
*/
void setVideoInfo(VideoInfo videoInfo);
/** /**
* @return The list of available translations languages * @return The list of available translations languages
*/ */

View File

@@ -1,8 +1,9 @@
package com.github.gtache.autosubtitle.gui.work; package com.github.gtache.autosubtitle.gui.work;
import com.github.gtache.autosubtitle.Video; import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
/** /**
* Model for the main view * Model for the main view
@@ -19,16 +20,6 @@ public interface WorkModel {
*/ */
void setVideo(Video video); void setVideo(Video video);
/**
* @return The current extraction model
*/
ExtractionModel extractionModel();
/**
* @param model The new extraction model
*/
void setExtractionModel(ExtractionModel model);
/** /**
* @return The current status * @return The current status
*/ */
@@ -80,4 +71,28 @@ public interface WorkModel {
* @param collection The last extracted collection * @param collection The last extracted collection
*/ */
void setExtractedCollection(SubtitleCollection<?> collection); void setExtractedCollection(SubtitleCollection<?> collection);
/**
* @return The current export options
*/
ExportOptions exportOptions();
/**
* Sets the export options
*
* @param options The options
*/
void setExportOptions(ExportOptions options);
/**
* @return The current extract options
*/
ExtractOptions extractOptions();
/**
* Sets the extract options
*
* @param options The options
*/
void setExtractOptions(ExtractOptions options);
} }

View File

@@ -14,13 +14,13 @@ public class CombinedResourceBundle extends ResourceBundle {
private final Map<String, String> resources; private final Map<String, String> resources;
private final Locale locale; private final Locale locale;
public CombinedResourceBundle(final ResourceBundle... resourceBundles) { public CombinedResourceBundle(final ResourceBundle... bundles) {
this(Arrays.asList(resourceBundles)); this(Arrays.asList(bundles));
} }
public CombinedResourceBundle(final List<ResourceBundle> resourceBundles) { public CombinedResourceBundle(final Collection<ResourceBundle> bundles) {
final var filteredBundles = resourceBundles.stream().filter(Objects::nonNull).toList(); final var filteredBundles = bundles.stream().filter(Objects::nonNull).toList();
if (filteredBundles.size() != resourceBundles.size()) { if (filteredBundles.size() != bundles.size()) {
logger.warn("There was one or more null bundles in the inner bundles"); logger.warn("There was one or more null bundles in the inner bundles");
} }
if (filteredBundles.isEmpty()) { if (filteredBundles.isEmpty()) {

View File

@@ -5,5 +5,6 @@ import java.util.spi.ResourceBundleProvider;
/** /**
* Provider for MainBundle * Provider for MainBundle
*/ */
@FunctionalInterface
public interface MainBundleProvider extends ResourceBundleProvider { public interface MainBundleProvider extends ResourceBundleProvider {
} }

View File

@@ -5,5 +5,6 @@ import java.util.spi.ResourceBundleProvider;
/** /**
* Provider for ParametersBundle * Provider for ParametersBundle
*/ */
@FunctionalInterface
public interface ParametersBundleProvider extends ResourceBundleProvider { public interface ParametersBundleProvider extends ResourceBundleProvider {
} }

View File

@@ -5,5 +5,6 @@ import java.util.spi.ResourceBundleProvider;
/** /**
* Provider for SetupBundle * Provider for SetupBundle
*/ */
@FunctionalInterface
public interface SetupBundleProvider extends ResourceBundleProvider { public interface SetupBundleProvider extends ResourceBundleProvider {
} }

View File

@@ -5,5 +5,6 @@ import java.util.spi.ResourceBundleProvider;
/** /**
* Provider for SubtitlesBundle * Provider for SubtitlesBundle
*/ */
@FunctionalInterface
public interface SubtitlesBundleProvider extends ResourceBundleProvider { public interface SubtitlesBundleProvider extends ResourceBundleProvider {
} }

View File

@@ -5,5 +5,6 @@ import java.util.spi.ResourceBundleProvider;
/** /**
* Provider for WorkBundle * Provider for WorkBundle
*/ */
@FunctionalInterface
public interface WorkBundleProvider extends ResourceBundleProvider { public interface WorkBundleProvider extends ResourceBundleProvider {
} }

View File

@@ -31,6 +31,9 @@ public final class GuiCoreModule {
@Play @Play
static byte[] providesPlayImage() { static byte[] providesPlayImage() {
try (final var in = GuiCoreModule.class.getResourceAsStream("/com/github/gtache/autosubtitle/gui/impl/play_64.png")) { try (final var in = GuiCoreModule.class.getResourceAsStream("/com/github/gtache/autosubtitle/gui/impl/play_64.png")) {
if (in == null) {
throw new UncheckedIOException(new IOException("Resource not found : /com/github/gtache/autosubtitle/gui/impl/play_64.png"));
}
return in.readAllBytes(); return in.readAllBytes();
} catch (final IOException e) { } catch (final IOException e) {
throw new UncheckedIOException(e); throw new UncheckedIOException(e);
@@ -41,6 +44,9 @@ public final class GuiCoreModule {
@Pause @Pause
static byte[] providesPauseImage() { static byte[] providesPauseImage() {
try (final var in = GuiCoreModule.class.getResourceAsStream("/com/github/gtache/autosubtitle/gui/impl/pause_64.png")) { try (final var in = GuiCoreModule.class.getResourceAsStream("/com/github/gtache/autosubtitle/gui/impl/pause_64.png")) {
if (in == null) {
throw new UncheckedIOException(new IOException("Resource not found : /com/github/gtache/autosubtitle/gui/impl/pause_64.png"));
}
return in.readAllBytes(); return in.readAllBytes();
} catch (final IOException e) { } catch (final IOException e) {
throw new UncheckedIOException(e); throw new UncheckedIOException(e);

View File

@@ -20,6 +20,7 @@ import javax.inject.Singleton;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
import java.util.prefs.BackingStoreException; import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
import java.util.regex.Pattern;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
@@ -30,6 +31,7 @@ import static java.util.Objects.requireNonNull;
public class FXParametersController extends AbstractFXController implements ParametersController { public class FXParametersController extends AbstractFXController implements ParametersController {
private static final Logger logger = LogManager.getLogger(FXParametersController.class); private static final Logger logger = LogManager.getLogger(FXParametersController.class);
private static final Pattern INTEGER_PATTERN = Pattern.compile("[1-9]\\d*");
@FXML @FXML
private PrefixSelectionComboBox<ExtractionModel> extractionModelCombobox; private PrefixSelectionComboBox<ExtractionModel> extractionModelCombobox;
@FXML @FXML
@@ -67,7 +69,7 @@ public class FXParametersController extends AbstractFXController implements Para
final UnaryOperator<TextFormatter.Change> integerFilter = change -> { final UnaryOperator<TextFormatter.Change> integerFilter = change -> {
final var newText = change.getControlNewText(); final var newText = change.getControlNewText();
if (newText.matches("[1-9]\\d*")) { if (INTEGER_PATTERN.matcher(newText).matches()) {
return change; return change;
} }
return null; return null;

View File

@@ -5,11 +5,16 @@ import com.github.gtache.autosubtitle.modules.impl.FontName;
import com.github.gtache.autosubtitle.modules.impl.FontSize; import com.github.gtache.autosubtitle.modules.impl.FontSize;
import com.github.gtache.autosubtitle.modules.impl.MaxLineLength; import com.github.gtache.autosubtitle.modules.impl.MaxLineLength;
import com.github.gtache.autosubtitle.modules.impl.MaxLines; import com.github.gtache.autosubtitle.modules.impl.MaxLines;
import com.github.gtache.autosubtitle.subtitle.Font;
import com.github.gtache.autosubtitle.subtitle.OutputFormat; import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider;
import com.github.gtache.autosubtitle.subtitle.impl.FontImpl;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty; import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
@@ -33,6 +38,7 @@ public class FXParametersModel implements ParametersModel {
private final ObservableList<String> availableFontFamilies; private final ObservableList<String> availableFontFamilies;
private final StringProperty fontName; private final StringProperty fontName;
private final IntegerProperty fontSize; private final IntegerProperty fontSize;
private final ReadOnlyObjectWrapper<Font> font;
private final IntegerProperty maxLineLength; private final IntegerProperty maxLineLength;
private final IntegerProperty maxLines; private final IntegerProperty maxLines;
@@ -46,8 +52,11 @@ public class FXParametersModel implements ParametersModel {
this.availableFontFamilies = FXCollections.unmodifiableObservableList(FXCollections.observableArrayList("Arial")); this.availableFontFamilies = FXCollections.unmodifiableObservableList(FXCollections.observableArrayList("Arial"));
this.fontName = new SimpleStringProperty(defaultFontFamily); this.fontName = new SimpleStringProperty(defaultFontFamily);
this.fontSize = new SimpleIntegerProperty(defaultFontSize); this.fontSize = new SimpleIntegerProperty(defaultFontSize);
this.font = new ReadOnlyObjectWrapper<>();
this.maxLineLength = new SimpleIntegerProperty(defaultMaxLineLength); this.maxLineLength = new SimpleIntegerProperty(defaultMaxLineLength);
this.maxLines = new SimpleIntegerProperty(defaultMaxLines); this.maxLines = new SimpleIntegerProperty(defaultMaxLines);
font.bind(Bindings.createObjectBinding(() -> new FontImpl(fontName(), fontSize()), fontName, fontSize));
} }
@Override @Override
@@ -84,7 +93,7 @@ public class FXParametersModel implements ParametersModel {
outputFormat.set(format); outputFormat.set(format);
} }
ObjectProperty<OutputFormat> outputFormatProperty() { public ObjectProperty<OutputFormat> outputFormatProperty() {
return outputFormat; return outputFormat;
} }
@@ -121,6 +130,15 @@ public class FXParametersModel implements ParametersModel {
return fontSize; return fontSize;
} }
@Override
public Font font() {
return font.get();
}
public ReadOnlyObjectProperty<Font> fontProperty() {
return font.getReadOnlyProperty();
}
@Override @Override
public int maxLineLength() { public int maxLineLength() {
return maxLineLength.get(); return maxLineLength.get();
@@ -131,7 +149,7 @@ public class FXParametersModel implements ParametersModel {
this.maxLineLength.set(maxLineLength); this.maxLineLength.set(maxLineLength);
} }
IntegerProperty maxLineLengthProperty() { public IntegerProperty maxLineLengthProperty() {
return maxLineLength; return maxLineLength;
} }
@@ -145,7 +163,7 @@ public class FXParametersModel implements ParametersModel {
this.maxLines.set(maxLines); this.maxLines.set(maxLines);
} }
IntegerProperty maxLinesProperty() { public IntegerProperty maxLinesProperty() {
return maxLines; return maxLines;
} }
} }

View File

@@ -1,11 +1,15 @@
package com.github.gtache.autosubtitle.gui.subtitles.fx; package com.github.gtache.autosubtitle.gui.subtitles.fx;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.gui.fx.FXBinder; import com.github.gtache.autosubtitle.gui.fx.FXBinder;
import com.github.gtache.autosubtitle.gui.work.fx.FXWorkModel; import com.github.gtache.autosubtitle.gui.parameters.fx.FXParametersModel;
import com.github.gtache.autosubtitle.gui.work.WorkStatus; import com.github.gtache.autosubtitle.gui.work.WorkStatus;
import com.github.gtache.autosubtitle.gui.work.fx.FXWorkModel;
import com.github.gtache.autosubtitle.subtitle.converter.impl.FormatOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.converter.impl.ParseOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.impl.ExportOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.impl.ImportOptionsImpl;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javax.inject.Inject; import javax.inject.Inject;
@@ -19,11 +23,13 @@ import java.util.Objects;
public class FXSubtitlesBinder implements FXBinder { public class FXSubtitlesBinder implements FXBinder {
private final FXWorkModel workModel; private final FXWorkModel workModel;
private final FXParametersModel parametersModel;
private final FXSubtitlesModel subtitlesModel; private final FXSubtitlesModel subtitlesModel;
@Inject @Inject
FXSubtitlesBinder(final FXWorkModel workModel, final FXSubtitlesModel subtitlesModel) { FXSubtitlesBinder(final FXWorkModel workModel, final FXParametersModel parametersModel, final FXSubtitlesModel subtitlesModel) {
this.workModel = Objects.requireNonNull(workModel); this.workModel = Objects.requireNonNull(workModel);
this.parametersModel = Objects.requireNonNull(parametersModel);
this.subtitlesModel = Objects.requireNonNull(subtitlesModel); this.subtitlesModel = Objects.requireNonNull(subtitlesModel);
} }
@@ -36,11 +42,9 @@ public class FXSubtitlesBinder implements FXBinder {
workModel.selectedSubtitleProperty().bind(subtitlesModel.selectedSubtitleProperty()); workModel.selectedSubtitleProperty().bind(subtitlesModel.selectedSubtitleProperty());
workModel.canExportProperty().bind(Bindings.isNotEmpty(subtitlesModel.collections()).and(workModel.statusProperty().isEqualTo(WorkStatus.IDLE))); workModel.canExportProperty().bind(Bindings.isNotEmpty(subtitlesModel.collections()).and(workModel.statusProperty().isEqualTo(WorkStatus.IDLE)));
workModel.videoLanguageProperty().bind(subtitlesModel.videoLanguageProperty());
subtitlesModel.videoInfoProperty().bind(workModel.videoProperty().map(Video::info));
subtitlesModel.translatingProperty().addListener((observable, oldValue, newValue) -> { subtitlesModel.translatingProperty().addListener((observable, oldValue, newValue) -> {
if (newValue) { if (Boolean.TRUE.equals(newValue)) {
workModel.statusProperty().set(WorkStatus.TRANSLATING); workModel.statusProperty().set(WorkStatus.TRANSLATING);
} else { } else {
workModel.statusProperty().set(WorkStatus.IDLE); workModel.statusProperty().set(WorkStatus.IDLE);
@@ -55,5 +59,20 @@ public class FXSubtitlesBinder implements FXBinder {
Bindings.bindContent(workModel.collections(), subtitlesModel.collections()); Bindings.bindContent(workModel.collections(), subtitlesModel.collections());
Bindings.bindContent(workModel.subtitles(), subtitlesModel.selectedSubtitles()); Bindings.bindContent(workModel.subtitles(), subtitlesModel.selectedSubtitles());
subtitlesModel.exportOptionsProperty().bind(Bindings.createObjectBinding(() -> {
if (workModel.video() == null) {
return null;
} else {
final var format = parametersModel.outputFormat();
final var formatOptions = new FormatOptionsImpl(workModel.video().info(), parametersModel.font());
return new ExportOptionsImpl(format, formatOptions);
}
}, parametersModel.outputFormatProperty(), workModel.videoProperty(), parametersModel.fontProperty()));
subtitlesModel.importOptionsProperty().bind(Bindings.createObjectBinding(() -> {
final var parseOptions = new ParseOptionsImpl(parametersModel.maxLineLength(), parametersModel.maxLines(), parametersModel.font());
return new ImportOptionsImpl(parseOptions);
}, parametersModel.maxLineLengthProperty(), parametersModel.maxLinesProperty(), parametersModel.fontProperty()));
} }
} }

View File

@@ -114,9 +114,7 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
bindComboboxes(); bindComboboxes();
bindTable(); bindTable();
mainSubtitlesTab.textProperty().bind(Bindings.createStringBinding(() -> model.videoLanguage().iso2(), model.videoLanguageProperty())); mainSubtitlesTab.textProperty().bind(Bindings.createStringBinding(() -> model.videoLanguage().iso2(), model.videoLanguageProperty()));
model.collections().addListener((MapChangeListener<Language, ObservableSubtitleCollectionImpl>) change -> { model.collections().addListener((MapChangeListener<Language, ObservableSubtitleCollectionImpl>) change -> manageTabs());
manageTabs();
});
tabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { tabPane.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if (newValue != null) { if (newValue != null) {
model.setSelectedCollection(model.collections().get(Language.getLanguage(newValue.getText()))); model.setSelectedCollection(model.collections().get(Language.getLanguage(newValue.getText())));
@@ -293,10 +291,11 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
try { try {
final var filename = file.getFileName().toString(); final var filename = file.getFileName().toString();
final var extension = filename.substring(filename.lastIndexOf('.') + 1); final var extension = filename.substring(filename.lastIndexOf('.') + 1);
final var options = model.exportOptions();
if (subtitleExtensions.contains(extension)) { if (subtitleExtensions.contains(extension)) {
importerExporter.exportSubtitles(model.selectedCollection(), model.videoInfo(), file); importerExporter.exportSubtitles(model.selectedCollection(), options, file);
} else { } else {
importerExporter.exportSubtitles(model.collections().values(), model.videoInfo(), file); importerExporter.exportSubtitles(model.collections().values(), options, file);
} }
} catch (final IOException e) { } catch (final IOException e) {
logger.error("Error saving subtitles {}", file, e); logger.error("Error saving subtitles {}", file, e);
@@ -307,7 +306,8 @@ public class FXSubtitlesController extends AbstractFXController implements Subti
@Override @Override
public void loadSubtitles(final Path file) { public void loadSubtitles(final Path file) {
try { try {
final var map = importerExporter.importSubtitles(file); final var importOptions = model.importOptions();
final var map = importerExporter.importSubtitles(file, importOptions);
if (model.videoLanguage() == Language.AUTO) { if (model.videoLanguage() == Language.AUTO) {
model.setVideoLanguage(map.keySet().stream().findFirst().orElse(Language.AUTO)); model.setVideoLanguage(map.keySet().stream().findFirst().orElse(Language.AUTO));
} }

View File

@@ -1,8 +1,9 @@
package com.github.gtache.autosubtitle.gui.subtitles.fx; package com.github.gtache.autosubtitle.gui.subtitles.fx;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.gui.subtitles.SubtitlesModel; import com.github.gtache.autosubtitle.gui.subtitles.SubtitlesModel;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.ImportOptions;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
@@ -30,7 +31,6 @@ public class FXSubtitlesModel implements SubtitlesModel<ObservableSubtitleImpl,
private final ObservableList<Language> availableVideoLanguages; private final ObservableList<Language> availableVideoLanguages;
private final ObjectProperty<Language> videoLanguage; private final ObjectProperty<Language> videoLanguage;
private final ObjectProperty<VideoInfo> videoInfo;
private final ObservableList<Language> availableTranslationLanguages; private final ObservableList<Language> availableTranslationLanguages;
private final ObservableList<Language> selectedTranslationsLanguages; private final ObservableList<Language> selectedTranslationsLanguages;
private final ObjectProperty<Language> selectedLanguage; private final ObjectProperty<Language> selectedLanguage;
@@ -46,6 +46,8 @@ public class FXSubtitlesModel implements SubtitlesModel<ObservableSubtitleImpl,
private final BooleanProperty canEditTable; private final BooleanProperty canEditTable;
private final ReadOnlyBooleanWrapper canSaveSubtitles; private final ReadOnlyBooleanWrapper canSaveSubtitles;
private final BooleanProperty isTranslating; private final BooleanProperty isTranslating;
private final ObjectProperty<ExportOptions> exportOptions;
private final ObjectProperty<ImportOptions> importOptions;
@Inject @Inject
FXSubtitlesModel() { FXSubtitlesModel() {
@@ -61,7 +63,6 @@ public class FXSubtitlesModel implements SubtitlesModel<ObservableSubtitleImpl,
}).toList())); }).toList()));
this.availableTranslationLanguages = FXCollections.observableArrayList(Arrays.stream(Language.values()).filter(l -> l != Language.AUTO).toList()); this.availableTranslationLanguages = FXCollections.observableArrayList(Arrays.stream(Language.values()).filter(l -> l != Language.AUTO).toList());
this.videoLanguage = new SimpleObjectProperty<>(Language.AUTO); this.videoLanguage = new SimpleObjectProperty<>(Language.AUTO);
this.videoInfo = new SimpleObjectProperty<>();
this.selectedTranslationsLanguages = FXCollections.observableArrayList(); this.selectedTranslationsLanguages = FXCollections.observableArrayList();
this.selectedLanguage = new SimpleObjectProperty<>(Language.AUTO); this.selectedLanguage = new SimpleObjectProperty<>(Language.AUTO);
this.collections = FXCollections.observableHashMap(); this.collections = FXCollections.observableHashMap();
@@ -75,6 +76,8 @@ public class FXSubtitlesModel implements SubtitlesModel<ObservableSubtitleImpl,
this.canSaveSubtitles = new ReadOnlyBooleanWrapper(false); this.canSaveSubtitles = new ReadOnlyBooleanWrapper(false);
this.canEditTable = new SimpleBooleanProperty(false); this.canEditTable = new SimpleBooleanProperty(false);
this.isTranslating = new SimpleBooleanProperty(false); this.isTranslating = new SimpleBooleanProperty(false);
this.exportOptions = new SimpleObjectProperty<>();
this.importOptions = new SimpleObjectProperty<>();
canSaveSubtitles.bind(Bindings.isNotEmpty(collections)); canSaveSubtitles.bind(Bindings.isNotEmpty(collections));
collections.addListener((MapChangeListener<Language, ObservableSubtitleCollectionImpl>) change -> collections.addListener((MapChangeListener<Language, ObservableSubtitleCollectionImpl>) change ->
@@ -107,24 +110,10 @@ public class FXSubtitlesModel implements SubtitlesModel<ObservableSubtitleImpl,
videoLanguage.set(language); videoLanguage.set(language);
} }
ObjectProperty<Language> videoLanguageProperty() { public ObjectProperty<Language> videoLanguageProperty() {
return videoLanguage; return videoLanguage;
} }
@Override
public VideoInfo videoInfo() {
return videoInfo.get();
}
@Override
public void setVideoInfo(final VideoInfo videoInfo) {
this.videoInfo.set(videoInfo);
}
ObjectProperty<VideoInfo> videoInfoProperty() {
return videoInfo;
}
@Override @Override
public ObservableList<Language> availableTranslationsLanguage() { public ObservableList<Language> availableTranslationsLanguage() {
return FXCollections.unmodifiableObservableList(availableTranslationLanguages); return FXCollections.unmodifiableObservableList(availableTranslationLanguages);
@@ -270,4 +259,20 @@ public class FXSubtitlesModel implements SubtitlesModel<ObservableSubtitleImpl,
public BooleanProperty canEditTableProperty() { public BooleanProperty canEditTableProperty() {
return canEditTable; return canEditTable;
} }
ExportOptions exportOptions() {
return exportOptions.get();
}
public ObjectProperty<ExportOptions> exportOptionsProperty() {
return exportOptions;
}
ImportOptions importOptions() {
return importOptions.get();
}
public ObjectProperty<ImportOptions> importOptionsProperty() {
return importOptions;
}
} }

View File

@@ -2,10 +2,17 @@ package com.github.gtache.autosubtitle.gui.work.fx;
import com.github.gtache.autosubtitle.gui.fx.FXBinder; import com.github.gtache.autosubtitle.gui.fx.FXBinder;
import com.github.gtache.autosubtitle.gui.parameters.fx.FXParametersModel; import com.github.gtache.autosubtitle.gui.parameters.fx.FXParametersModel;
import com.github.gtache.autosubtitle.gui.subtitles.fx.FXSubtitlesModel;
import com.github.gtache.autosubtitle.subtitle.converter.impl.FormatOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.converter.impl.ParseOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.extractor.impl.ExtractOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.impl.ExportOptionsImpl;
import javafx.beans.binding.Bindings;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import java.util.Objects;
import static java.util.Objects.requireNonNull;
/** /**
* {@link FXBinder} for {@link FXWorkModel} * {@link FXBinder} for {@link FXWorkModel}
@@ -15,15 +22,29 @@ public class FXWorkBinder implements FXBinder {
private final FXWorkModel workModel; private final FXWorkModel workModel;
private final FXParametersModel parametersModel; private final FXParametersModel parametersModel;
private final FXSubtitlesModel subtitlesModel;
@Inject @Inject
FXWorkBinder(final FXWorkModel workModel, final FXParametersModel parametersModel) { FXWorkBinder(final FXWorkModel workModel, final FXParametersModel parametersModel, final FXSubtitlesModel subtitlesModel) {
this.workModel = Objects.requireNonNull(workModel); this.workModel = requireNonNull(workModel);
this.parametersModel = Objects.requireNonNull(parametersModel); this.parametersModel = requireNonNull(parametersModel);
this.subtitlesModel = requireNonNull(subtitlesModel);
} }
@Override @Override
public void createBindings() { public void createBindings() {
workModel.extractionModelProperty().bind(parametersModel.extractionModelProperty()); workModel.exportOptionsProperty().bind(Bindings.createObjectBinding(() -> {
if (workModel.video() == null) {
return null;
} else {
return new ExportOptionsImpl(parametersModel.outputFormat(), new FormatOptionsImpl(workModel.video().info(), parametersModel.font()));
}
}, workModel.videoProperty(), parametersModel.outputFormatProperty(), parametersModel.fontProperty()));
workModel.extractOptionsProperty().bind(Bindings.createObjectBinding(() ->
new ExtractOptionsImpl(subtitlesModel.videoLanguage(), parametersModel.extractionModel(),
new ParseOptionsImpl(parametersModel.maxLineLength(), parametersModel.maxLines(), parametersModel.font())),
subtitlesModel.videoLanguageProperty(), parametersModel.extractionModelProperty(),
parametersModel.maxLineLengthProperty(), parametersModel.maxLinesProperty(), parametersModel.fontProperty()));
} }
} }

View File

@@ -75,7 +75,7 @@ public class FXWorkController extends AbstractFXController implements WorkContro
private final FXWorkModel model; private final FXWorkModel model;
private final FXWorkBinder binder; private final FXWorkBinder binder;
private final SubtitleExtractor subtitleExtractor; private final SubtitleExtractor<?> subtitleExtractor;
private final VideoConverter videoConverter; private final VideoConverter videoConverter;
private final VideoLoader videoLoader; private final VideoLoader videoLoader;
@@ -142,7 +142,7 @@ public class FXWorkController extends AbstractFXController implements WorkContro
private SubtitleCollection<?> extractAsync() { private SubtitleCollection<?> extractAsync() {
try { try {
return subtitleExtractor.extract(model.video(), model.videoLanguageProperty().get(), model.extractionModel()); return subtitleExtractor.extract(model.video(), model.extractOptions());
} catch (final ExtractException e) { } catch (final ExtractException e) {
throw new CompletionException(e); throw new CompletionException(e);
} }
@@ -182,7 +182,7 @@ public class FXWorkController extends AbstractFXController implements WorkContro
model.setStatus(WorkStatus.EXPORTING); model.setStatus(WorkStatus.EXPORTING);
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
try { try {
videoConverter.addSoftSubtitles(model.video(), model.collections().values(), file.toPath()); videoConverter.addSoftSubtitles(model.video(), model.collections().values(), model.exportOptions(), file.toPath());
} catch (final IOException e) { } catch (final IOException e) {
throw new CompletionException(e); throw new CompletionException(e);
} }
@@ -207,7 +207,7 @@ public class FXWorkController extends AbstractFXController implements WorkContro
model.setStatus(WorkStatus.EXPORTING); model.setStatus(WorkStatus.EXPORTING);
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() -> {
try { try {
videoConverter.addHardSubtitles(model.video(), model.collections().get(model.videoLanguageProperty().get()), file.toPath()); videoConverter.addHardSubtitles(model.video(), model.collections().get(model.extractOptions().language()), model.exportOptions(), file.toPath());
} catch (final IOException e) { } catch (final IOException e) {
throw new CompletionException(e); throw new CompletionException(e);
} }

View File

@@ -5,8 +5,9 @@ import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.gui.work.WorkModel; import com.github.gtache.autosubtitle.gui.work.WorkModel;
import com.github.gtache.autosubtitle.gui.work.WorkStatus; import com.github.gtache.autosubtitle.gui.work.WorkStatus;
import com.github.gtache.autosubtitle.subtitle.EditableSubtitle; import com.github.gtache.autosubtitle.subtitle.EditableSubtitle;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
@@ -31,7 +32,6 @@ import javax.inject.Singleton;
public class FXWorkModel implements WorkModel { public class FXWorkModel implements WorkModel {
private final ObjectProperty<Video> video; private final ObjectProperty<Video> video;
private final ObjectProperty<ExtractionModel> extractionModel;
private final ObjectProperty<WorkStatus> workStatus; private final ObjectProperty<WorkStatus> workStatus;
private final DoubleProperty progress; private final DoubleProperty progress;
private final ObjectProperty<EditableSubtitle> selectedSubtitle; private final ObjectProperty<EditableSubtitle> selectedSubtitle;
@@ -42,12 +42,13 @@ public class FXWorkModel implements WorkModel {
private final BooleanProperty canExport; private final BooleanProperty canExport;
private final ReadOnlyBooleanWrapper isProgressVisible; private final ReadOnlyBooleanWrapper isProgressVisible;
private final ObjectProperty<SubtitleCollection<?>> extractedCollection; private final ObjectProperty<SubtitleCollection<?>> extractedCollection;
private final ObjectProperty<ExportOptions> exportOptions;
private final ObjectProperty<ExtractOptions> extractOptions;
@Inject @Inject
FXWorkModel() { FXWorkModel() {
this.video = new SimpleObjectProperty<>(); this.video = new SimpleObjectProperty<>();
this.workStatus = new SimpleObjectProperty<>(WorkStatus.IDLE); this.workStatus = new SimpleObjectProperty<>(WorkStatus.IDLE);
this.extractionModel = new SimpleObjectProperty<>();
this.progress = new SimpleDoubleProperty(-1); this.progress = new SimpleDoubleProperty(-1);
this.selectedSubtitle = new SimpleObjectProperty<>(); this.selectedSubtitle = new SimpleObjectProperty<>();
this.subtitles = FXCollections.observableArrayList(); this.subtitles = FXCollections.observableArrayList();
@@ -57,6 +58,8 @@ public class FXWorkModel implements WorkModel {
this.canExport = new SimpleBooleanProperty(false); this.canExport = new SimpleBooleanProperty(false);
this.isProgressVisible = new ReadOnlyBooleanWrapper(false); this.isProgressVisible = new ReadOnlyBooleanWrapper(false);
this.extractedCollection = new SimpleObjectProperty<>(); this.extractedCollection = new SimpleObjectProperty<>();
this.exportOptions = new SimpleObjectProperty<>();
this.extractOptions = new SimpleObjectProperty<>();
isProgressVisible.bind(workStatus.isNotEqualTo(WorkStatus.IDLE)); isProgressVisible.bind(workStatus.isNotEqualTo(WorkStatus.IDLE));
canExtract.bind(video.isNotNull().and(workStatus.isEqualTo(WorkStatus.IDLE))); canExtract.bind(video.isNotNull().and(workStatus.isEqualTo(WorkStatus.IDLE)));
@@ -76,20 +79,6 @@ public class FXWorkModel implements WorkModel {
return video; return video;
} }
@Override
public ExtractionModel extractionModel() {
return extractionModel.get();
}
@Override
public void setExtractionModel(final ExtractionModel model) {
extractionModel.set(model);
}
ObjectProperty<ExtractionModel> extractionModelProperty() {
return extractionModel;
}
@Override @Override
public WorkStatus status() { public WorkStatus status() {
return workStatus.get(); return workStatus.get();
@@ -176,7 +165,31 @@ public class FXWorkModel implements WorkModel {
return collections; return collections;
} }
public ObjectProperty<Language> videoLanguageProperty() { @Override
return videoLanguage; public ExportOptions exportOptions() {
return exportOptions.get();
}
@Override
public void setExportOptions(final ExportOptions options) {
exportOptions.set(options);
}
public ObjectProperty<ExportOptions> exportOptionsProperty() {
return exportOptions;
}
@Override
public ExtractOptions extractOptions() {
return extractOptions.get();
}
@Override
public void setExtractOptions(final ExtractOptions options) {
extractOptions.set(options);
}
public ObjectProperty<ExtractOptions> extractOptionsProperty() {
return extractOptions;
} }
} }

View File

@@ -9,7 +9,6 @@ module com.github.gtache.autosubtitle.gui.fx {
requires transitive javafx.fxml; requires transitive javafx.fxml;
requires org.controlsfx.controls; requires org.controlsfx.controls;
requires org.apache.logging.log4j; requires org.apache.logging.log4j;
requires java.desktop;
requires transitive java.prefs; requires transitive java.prefs;
exports com.github.gtache.autosubtitle.gui.fx; exports com.github.gtache.autosubtitle.gui.fx;

View File

@@ -3,6 +3,7 @@ package com.github.gtache.autosubtitle.gui.parameters.fx;
import com.github.gtache.autosubtitle.subtitle.OutputFormat; import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider;
import com.github.gtache.autosubtitle.subtitle.impl.FontImpl;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@@ -101,6 +102,18 @@ class TestFXParametersModel {
assertEquals(fontSize, model.fontSizeProperty().get()); assertEquals(fontSize, model.fontSizeProperty().get());
} }
@Test
void testFont() {
assertEquals(new FontImpl(DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE), model.font());
assertEquals(new FontImpl(DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE), model.fontProperty().get());
model.setFontName("TT");
assertEquals(new FontImpl("TT", DEFAULT_FONT_SIZE), model.font());
assertEquals(new FontImpl("TT", DEFAULT_FONT_SIZE), model.fontProperty().get());
model.setFontSize(1);
assertEquals(new FontImpl("TT", 1), model.font());
assertEquals(new FontImpl("TT", 1), model.fontProperty().get());
}
@Test @Test
void testMaxLineLength() { void testMaxLineLength() {
assertEquals(DEFAULT_MAX_LINE_LENGTH, model.maxLineLength()); assertEquals(DEFAULT_MAX_LINE_LENGTH, model.maxLineLength());

View File

@@ -3,15 +3,26 @@ package com.github.gtache.autosubtitle.gui.subtitles.fx;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Video; import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.VideoInfo; import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.gui.parameters.fx.FXParametersModel;
import com.github.gtache.autosubtitle.gui.work.WorkStatus; import com.github.gtache.autosubtitle.gui.work.WorkStatus;
import com.github.gtache.autosubtitle.gui.work.fx.FXWorkModel; import com.github.gtache.autosubtitle.gui.work.fx.FXWorkModel;
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import com.github.gtache.autosubtitle.subtitle.converter.impl.FormatOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.converter.impl.ParseOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
import com.github.gtache.autosubtitle.subtitle.impl.ExportOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.impl.FontImpl;
import com.github.gtache.autosubtitle.subtitle.impl.ImportOptionsImpl;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -19,16 +30,28 @@ import java.util.Map;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class TestFXSubtitlesBinder { class TestFXSubtitlesBinder {
private final FXWorkModel workModel; private final FXWorkModel workModel;
private final FXSubtitlesModel subtitlesModel; private final FXSubtitlesModel subtitlesModel;
private final FXParametersModel parametersModel;
private final FXSubtitlesBinder binder; private final FXSubtitlesBinder binder;
private final String defaultFontFamily;
private final int defaultFontSize;
private final int defaultMaxLineLength;
private final int defaultMaxLines;
TestFXSubtitlesBinder() { TestFXSubtitlesBinder(@Mock final ExtractionModelProvider extractionModelProvider) {
this.workModel = spy(FXWorkModel.class); this.workModel = spy(FXWorkModel.class);
this.defaultFontFamily = "Arial";
this.defaultFontSize = 12;
this.defaultMaxLineLength = 40;
this.defaultMaxLines = 2;
this.parametersModel = mock(FXParametersModel.class, withSettings().defaultAnswer(CALLS_REAL_METHODS)
.useConstructor(extractionModelProvider, defaultFontFamily, defaultFontSize, defaultMaxLineLength, defaultMaxLines));
this.subtitlesModel = new FXSubtitlesModel(); this.subtitlesModel = new FXSubtitlesModel();
this.binder = new FXSubtitlesBinder(workModel, subtitlesModel); this.binder = new FXSubtitlesBinder(workModel, parametersModel, subtitlesModel);
} }
@BeforeEach @BeforeEach
@@ -93,23 +116,6 @@ class TestFXSubtitlesBinder {
assertFalse(workModel.canExport()); assertFalse(workModel.canExport());
} }
@Test
void testVideoLanguageBinding() {
assertEquals(Language.AUTO, workModel.videoLanguageProperty().get());
subtitlesModel.setVideoLanguage(Language.EN);
assertEquals(Language.EN, workModel.videoLanguageProperty().get());
}
@Test
void testVideoInfoBinding() {
assertNull(subtitlesModel.videoInfo());
final var video = mock(Video.class);
final var info = mock(VideoInfo.class);
when(video.info()).thenReturn(info);
workModel.setVideo(video);
assertEquals(info, subtitlesModel.videoInfo());
}
@Test @Test
void testTranslatingBinding() { void testTranslatingBinding() {
assertEquals(WorkStatus.IDLE, workModel.status()); assertEquals(WorkStatus.IDLE, workModel.status());
@@ -145,4 +151,33 @@ class TestFXSubtitlesBinder {
subtitlesModel.selectedSubtitles().add(subtitle); subtitlesModel.selectedSubtitles().add(subtitle);
assertEquals(List.of(subtitle), workModel.subtitles()); assertEquals(List.of(subtitle), workModel.subtitles());
} }
@Test
void testExportOptionsBinding() {
assertNull(subtitlesModel.exportOptions());
final var video = mock(Video.class);
final var info = mock(VideoInfo.class);
when(video.info()).thenReturn(info);
workModel.setVideo(video);
assertEquals(new ExportOptionsImpl(OutputFormat.SRT, new FormatOptionsImpl(info, new FontImpl(defaultFontFamily, defaultFontSize))), subtitlesModel.exportOptions());
parametersModel.setFontSize(14);
parametersModel.setFontName("TT");
assertEquals(new ExportOptionsImpl(OutputFormat.SRT, new FormatOptionsImpl(info, new FontImpl("TT", 14))), subtitlesModel.exportOptions());
parametersModel.setOutputFormat(OutputFormat.ASS);
assertEquals(new ExportOptionsImpl(OutputFormat.ASS, new FormatOptionsImpl(info, new FontImpl("TT", 14))), subtitlesModel.exportOptions());
workModel.setVideo(null);
assertNull(subtitlesModel.exportOptions());
}
@Test
void testImportOptionsBinding() {
assertEquals(new ImportOptionsImpl(new ParseOptionsImpl(defaultMaxLineLength, defaultMaxLines, new FontImpl(defaultFontFamily, defaultFontSize))), subtitlesModel.importOptions());
parametersModel.setFontSize(14);
parametersModel.setFontName("TT");
assertEquals(new ImportOptionsImpl(new ParseOptionsImpl(defaultMaxLineLength, defaultMaxLines, new FontImpl("TT", 14))), subtitlesModel.importOptions());
parametersModel.setMaxLineLength(1);
assertEquals(new ImportOptionsImpl(new ParseOptionsImpl(1, defaultMaxLines, new FontImpl("TT", 14))), subtitlesModel.importOptions());
parametersModel.setMaxLines(4);
assertEquals(new ImportOptionsImpl(new ParseOptionsImpl(1, 4, new FontImpl("TT", 14))), subtitlesModel.importOptions());
}
} }

View File

@@ -1,7 +1,8 @@
package com.github.gtache.autosubtitle.gui.subtitles.fx; package com.github.gtache.autosubtitle.gui.subtitles.fx;
import com.github.gtache.autosubtitle.Language; import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.VideoInfo; import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.ImportOptions;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
@@ -56,16 +57,6 @@ class TestFXSubtitlesModel {
assertEquals(Language.DE, model.videoLanguageProperty().get()); assertEquals(Language.DE, model.videoLanguageProperty().get());
} }
@Test
void testVideoInfo() {
assertNull(model.videoInfo());
assertNull(model.videoInfoProperty().get());
final var videoInfo = mock(VideoInfo.class);
model.setVideoInfo(videoInfo);
assertEquals(videoInfo, model.videoInfo());
assertEquals(videoInfo, model.videoInfoProperty().get());
}
@Test @Test
void testSelectedTranslationsLanguages() { void testSelectedTranslationsLanguages() {
assertEquals(List.of(), model.selectedTranslationsLanguages()); assertEquals(List.of(), model.selectedTranslationsLanguages());
@@ -197,4 +188,18 @@ class TestFXSubtitlesModel {
assertTrue(model.isTranslating()); assertTrue(model.isTranslating());
assertTrue(model.translatingProperty().get()); assertTrue(model.translatingProperty().get());
} }
@Test
void testExportOptions() {
assertNull(model.exportOptionsProperty().get());
final var options = mock(ExportOptions.class);
assertDoesNotThrow(() -> model.exportOptionsProperty().set(options));
}
@Test
void testImportOptions() {
assertNull(model.importOptionsProperty().get());
final var options = mock(ImportOptions.class);
assertDoesNotThrow(() -> model.importOptionsProperty().set(options));
}
} }

View File

@@ -1,24 +1,56 @@
package com.github.gtache.autosubtitle.gui.work.fx; package com.github.gtache.autosubtitle.gui.work.fx;
import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.VideoInfo;
import com.github.gtache.autosubtitle.gui.parameters.fx.FXParametersModel; import com.github.gtache.autosubtitle.gui.parameters.fx.FXParametersModel;
import com.github.gtache.autosubtitle.gui.subtitles.fx.FXSubtitlesModel;
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
import com.github.gtache.autosubtitle.subtitle.converter.impl.FormatOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.converter.impl.ParseOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModelProvider;
import com.github.gtache.autosubtitle.subtitle.extractor.impl.ExtractOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.impl.ExportOptionsImpl;
import com.github.gtache.autosubtitle.subtitle.impl.FontImpl;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.*; import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
@ExtendWith(MockitoExtension.class)
class TestFXWorkBinder { class TestFXWorkBinder {
private final FXWorkModel workModel; private final FXWorkModel workModel;
private final FXParametersModel parametersModel; private final FXParametersModel parametersModel;
private final FXSubtitlesModel subtitlesModel;
private final FXWorkBinder binder; private final FXWorkBinder binder;
private final String defaultFontFamily;
private final int defaultFontSize;
private final int defaultMaxLineLength;
private final int defaultMaxLines;
private final ExtractionModelProvider extractionModelProvider;
private final ExtractionModel extractionModel;
TestFXWorkBinder() { TestFXWorkBinder(@Mock final ExtractionModelProvider extractionModelProvider, @Mock final ExtractionModel extractionModel) {
this.extractionModelProvider = Objects.requireNonNull(extractionModelProvider);
this.extractionModel = Objects.requireNonNull(extractionModel);
when(extractionModelProvider.getDefaultExtractionModel()).thenReturn(extractionModel);
this.defaultFontFamily = "Arial";
this.defaultFontSize = 12;
this.defaultMaxLineLength = 40;
this.defaultMaxLines = 1;
this.parametersModel = mock(FXParametersModel.class, withSettings().defaultAnswer(CALLS_REAL_METHODS).useConstructor(extractionModelProvider, defaultFontFamily, defaultFontSize, defaultMaxLineLength, defaultMaxLines));
this.subtitlesModel = spy(FXSubtitlesModel.class);
this.workModel = new FXWorkModel(); this.workModel = new FXWorkModel();
this.parametersModel = mock(FXParametersModel.class, withSettings().defaultAnswer(CALLS_REAL_METHODS).useConstructor(mock(ExtractionModelProvider.class), "Arial", 12, 40, 1)); this.binder = new FXWorkBinder(workModel, parametersModel, subtitlesModel);
this.binder = new FXWorkBinder(workModel, parametersModel);
} }
@BeforeEach @BeforeEach
@@ -27,14 +59,36 @@ class TestFXWorkBinder {
} }
@Test @Test
void testBindings() { void testExportOptionsBinding() {
assertNull(workModel.extractionModel()); assertNull(workModel.exportOptions());
assertNull(parametersModel.extractionModel()); final var video = mock(Video.class);
final var info = mock(VideoInfo.class);
when(video.info()).thenReturn(info);
workModel.setVideo(video);
assertEquals(new ExportOptionsImpl(OutputFormat.SRT, new FormatOptionsImpl(info, new FontImpl(defaultFontFamily, defaultFontSize))), workModel.exportOptions());
parametersModel.setFontSize(14);
parametersModel.setFontName("TT");
assertEquals(new ExportOptionsImpl(OutputFormat.SRT, new FormatOptionsImpl(info, new FontImpl("TT", 14))), workModel.exportOptions());
parametersModel.setOutputFormat(OutputFormat.ASS);
assertEquals(new ExportOptionsImpl(OutputFormat.ASS, new FormatOptionsImpl(info, new FontImpl("TT", 14))), workModel.exportOptions());
workModel.setVideo(null);
assertNull(workModel.exportOptions());
}
final var extractionModel = mock(ExtractionModel.class); @Test
parametersModel.setExtractionModel(extractionModel); void testExtractOptionsBinding() {
assertEquals(extractionModel, workModel.extractionModel()); assertEquals(new ExtractOptionsImpl(Language.AUTO, extractionModel, new ParseOptionsImpl(defaultMaxLineLength, defaultMaxLines, new FontImpl(defaultFontFamily, defaultFontSize))), workModel.extractOptions());
parametersModel.setFontSize(14);
assertThrows(RuntimeException.class, () -> workModel.setExtractionModel(mock(ExtractionModel.class))); parametersModel.setFontName("TT");
assertEquals(new ExtractOptionsImpl(Language.AUTO, extractionModel, new ParseOptionsImpl(defaultMaxLineLength, defaultMaxLines, new FontImpl("TT", 14))), workModel.extractOptions());
parametersModel.setMaxLineLength(1);
assertEquals(new ExtractOptionsImpl(Language.AUTO, extractionModel, new ParseOptionsImpl(1, defaultMaxLines, new FontImpl("TT", 14))), workModel.extractOptions());
parametersModel.setMaxLines(4);
assertEquals(new ExtractOptionsImpl(Language.AUTO, extractionModel, new ParseOptionsImpl(1, 4, new FontImpl("TT", 14))), workModel.extractOptions());
final var newModel = mock(ExtractionModel.class);
parametersModel.setExtractionModel(newModel);
assertEquals(new ExtractOptionsImpl(Language.AUTO, newModel, new ParseOptionsImpl(1, 4, new FontImpl("TT", 14))), workModel.extractOptions());
subtitlesModel.setVideoLanguage(Language.EN);
assertEquals(new ExtractOptionsImpl(Language.EN, newModel, new ParseOptionsImpl(1, 4, new FontImpl("TT", 14))), workModel.extractOptions());
} }
} }

View File

@@ -4,8 +4,9 @@ import com.github.gtache.autosubtitle.Language;
import com.github.gtache.autosubtitle.Video; import com.github.gtache.autosubtitle.Video;
import com.github.gtache.autosubtitle.gui.work.WorkStatus; import com.github.gtache.autosubtitle.gui.work.WorkStatus;
import com.github.gtache.autosubtitle.subtitle.EditableSubtitle; import com.github.gtache.autosubtitle.subtitle.EditableSubtitle;
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection; import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleCollectionImpl;
import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl; import com.github.gtache.autosubtitle.subtitle.gui.fx.ObservableSubtitleImpl;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -43,16 +44,6 @@ class TestFXWorkModel {
assertEquals(WorkStatus.TRANSLATING, model.statusProperty().get()); assertEquals(WorkStatus.TRANSLATING, model.statusProperty().get());
} }
@Test
void testExtractionModel() {
assertNull(model.extractionModel());
assertNull(model.extractionModelProperty().get());
final var extractionModel = mock(ExtractionModel.class);
model.setExtractionModel(extractionModel);
assertEquals(extractionModel, model.extractionModel());
assertEquals(extractionModel, model.extractionModelProperty().get());
}
@Test @Test
void testProgress() { void testProgress() {
assertEquals(-1.0, model.progress()); assertEquals(-1.0, model.progress());
@@ -80,12 +71,6 @@ class TestFXWorkModel {
assertDoesNotThrow(() -> model.collections().put(Language.FR, mock(ObservableSubtitleCollectionImpl.class))); assertDoesNotThrow(() -> model.collections().put(Language.FR, mock(ObservableSubtitleCollectionImpl.class)));
} }
@Test
void testVideoLanguage() {
assertEquals(Language.AUTO, model.videoLanguageProperty().get());
assertDoesNotThrow(() -> model.videoLanguageProperty().set(Language.FR));
}
@Test @Test
void testCanExtract() { void testCanExtract() {
assertFalse(model.canExtract()); assertFalse(model.canExtract());
@@ -123,4 +108,24 @@ class TestFXWorkModel {
assertNotNull(model.extractedCollection()); assertNotNull(model.extractedCollection());
assertNotNull(model.extractedCollectionProperty().get()); assertNotNull(model.extractedCollectionProperty().get());
} }
@Test
void testExportOptions() {
assertNull(model.exportOptions());
assertNull(model.exportOptionsProperty().get());
final var options = mock(ExportOptions.class);
model.setExportOptions(options);
assertEquals(options, model.exportOptions());
assertEquals(options, model.exportOptionsProperty().get());
}
@Test
void testExtractOptions() {
assertNull(model.extractOptions());
assertNull(model.extractOptionsProperty().get());
final var options = mock(ExtractOptions.class);
model.setExtractOptions(options);
assertEquals(options, model.extractOptions());
assertEquals(options, model.extractOptionsProperty().get());
}
} }

View File

@@ -30,10 +30,10 @@ class TestObservableSubtitleCollectionImpl {
@Test @Test
void testEmptyConstructor() { void testEmptyConstructor() {
final var collection = new ObservableSubtitleCollectionImpl(); final var emptyCollection = new ObservableSubtitleCollectionImpl();
assertEquals("", collection.text()); assertEquals("", emptyCollection.text());
assertEquals(List.of(), collection.subtitles()); assertEquals(List.of(), emptyCollection.subtitles());
assertEquals(Language.AUTO, collection.language()); assertEquals(Language.AUTO, emptyCollection.language());
} }
@Test @Test

View File

@@ -79,28 +79,28 @@ class TestObservableSubtitleImpl {
@Test @Test
void testStringConstructor() { void testStringConstructor() {
final var subtitle = new ObservableSubtitleImpl(content); final var observable = new ObservableSubtitleImpl(content);
assertEquals(content, subtitle.content()); assertEquals(content, observable.content());
} }
@Test @Test
void testWholeConstructor() { void testWholeConstructor() {
final var subtitle = new ObservableSubtitleImpl(content, start, end, font, bounds); final var observable = new ObservableSubtitleImpl(content, start, end, font, bounds);
assertEquals(content, subtitle.content()); assertEquals(content, observable.content());
assertEquals(start, subtitle.start()); assertEquals(start, observable.start());
assertEquals(end, subtitle.end()); assertEquals(end, observable.end());
assertEquals(font, subtitle.font()); assertEquals(font, observable.font());
assertEquals(bounds, subtitle.bounds()); assertEquals(bounds, observable.bounds());
} }
@Test @Test
void testCopyConstructor() { void testCopyConstructor() {
final var originalSubtitle = new SubtitleImpl(content, start, end, font, bounds); final var originalSubtitle = new SubtitleImpl(content, start, end, font, bounds);
final var subtitle = new ObservableSubtitleImpl(originalSubtitle); final var observable = new ObservableSubtitleImpl(originalSubtitle);
assertEquals(content, subtitle.content()); assertEquals(content, observable.content());
assertEquals(start, subtitle.start()); assertEquals(start, observable.start());
assertEquals(end, subtitle.end()); assertEquals(end, observable.end());
assertEquals(font, subtitle.font()); assertEquals(font, observable.font());
assertEquals(bounds, subtitle.bounds()); assertEquals(bounds, observable.bounds());
} }
} }

View File

@@ -24,6 +24,6 @@ public final class Main extends Application {
} }
public static void main(final String[] args) { public static void main(final String[] args) {
Application.launch(args); launch(args);
} }
} }

View File

@@ -14,6 +14,7 @@ import javax.inject.Singleton;
/** /**
* Main component * Main component
*/ */
@FunctionalInterface
@Singleton @Singleton
@Component(modules = {CoreModule.class, GuiCoreModule.class, FXModule.class, FFmpegModule.class, @Component(modules = {CoreModule.class, GuiCoreModule.class, FXModule.class, FFmpegModule.class,
WhisperXModule.class, DeepLModule.class}) WhisperXModule.class, DeepLModule.class})

View File

@@ -28,7 +28,7 @@
<commons.compress.version>1.27.0</commons.compress.version> <commons.compress.version>1.27.0</commons.compress.version>
<dagger.version>2.51.1</dagger.version> <dagger.version>2.51.1</dagger.version>
<gson.version>2.11.0</gson.version> <jackson.version>2.17.2</jackson.version>
<junit.version>5.10.3</junit.version> <junit.version>5.10.3</junit.version>
<log4j.version>2.23.1</log4j.version> <log4j.version>2.23.1</log4j.version>
<mockito.version>5.12.0</mockito.version> <mockito.version>5.12.0</mockito.version>
@@ -94,9 +94,9 @@
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>gson</artifactId> <artifactId>jackson-databind</artifactId>
<version>${gson.version}</version> <version>${jackson.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.dagger</groupId> <groupId>com.google.dagger</groupId>

View File

@@ -15,5 +15,9 @@
<groupId>com.github.gtache.autosubtitle</groupId> <groupId>com.github.gtache.autosubtitle</groupId>
<artifactId>autosubtitle-whisper-common</artifactId> <artifactId>autosubtitle-whisper-common</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -1,8 +1,8 @@
package com.github.gtache.autosubtitle.modules.subtitle.parser.json.whisper.base; package com.github.gtache.autosubtitle.modules.subtitle.parser.json.whisper.base;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
import com.github.gtache.autosubtitle.subtitle.parser.json.whisper.base.JSONSubtitleConverter; import com.github.gtache.autosubtitle.subtitle.parser.json.whisper.base.JSONSubtitleConverter;
import com.google.gson.Gson;
import dagger.Binds; import dagger.Binds;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
@@ -25,7 +25,7 @@ public abstract class WhisperJsonModule {
@Provides @Provides
@Singleton @Singleton
static Gson providesGson() { static ObjectMapper providesObjectMapper() {
return new Gson(); return new ObjectMapper();
} }
} }

View File

@@ -5,7 +5,7 @@ import com.github.gtache.autosubtitle.impl.OS;
import com.github.gtache.autosubtitle.modules.setup.whisper.WhisperVenvPath; import com.github.gtache.autosubtitle.modules.setup.whisper.WhisperVenvPath;
import com.github.gtache.autosubtitle.process.ProcessRunner; import com.github.gtache.autosubtitle.process.ProcessRunner;
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider; import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider;
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractionModel; import com.github.gtache.autosubtitle.subtitle.extractor.ExtractOptions;
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor; import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
import com.github.gtache.autosubtitle.subtitle.extractor.whisper.AbstractWhisperSubtitleExtractor; import com.github.gtache.autosubtitle.subtitle.extractor.whisper.AbstractWhisperSubtitleExtractor;
import com.github.gtache.autosubtitle.whisper.WhisperModels; import com.github.gtache.autosubtitle.whisper.WhisperModels;
@@ -30,7 +30,9 @@ public class WhisperSubtitleExtractor extends AbstractWhisperSubtitleExtractor {
} }
@Override @Override
protected List<String> createArgs(final Path path, final Language language, final ExtractionModel model, final Path outputDir) { protected List<String> createArgs(final Path path, final ExtractOptions options, final Path outputDir) {
final var model = options.model();
final var language = options.language();
final var args = new ArrayList<String>(14); final var args = new ArrayList<String>(14);
args.add(getPythonPath().toString()); args.add(getPythonPath().toString());
args.add("-m"); args.add("-m");

Some files were not shown because too many files have changed in this diff Show More