Compare commits
10 Commits
dcadbcaf36
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aab2e2a486 | ||
|
|
c58a8b0588 | ||
|
|
df58cf4585 | ||
|
|
0a2f9e0c31 | ||
|
|
c59619da2d | ||
|
|
7f99c48e2c | ||
|
|
703a4c71ae | ||
|
|
17086a87ef | ||
|
|
233b4bdb77 | ||
|
|
3cc2f7a0c9 |
8
.idea/.gitignore
generated
vendored
8
.idea/.gitignore
generated
vendored
@@ -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
|
||||
7
.idea/codeStyles/Project.xml
generated
7
.idea/codeStyles/Project.xml
generated
@@ -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>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
5
.idea/codeStyles/codeStyleConfig.xml
generated
@@ -1,5 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
||||
109
.idea/inspectionProfiles/Project_Default.xml
generated
109
.idea/inspectionProfiles/Project_Default.xml
generated
@@ -1,30 +1,53 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<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="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="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="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="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="AnonymousInnerClassMayBeStatic" 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="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="AssignmentToFunctionParameterJS" 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">
|
||||
<option name="ignoreAssignmentsToFields" value="true" />
|
||||
</inspection_tool>
|
||||
<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">
|
||||
<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 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="BadExceptionCaught" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<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" />
|
||||
</inspection_tool>
|
||||
<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="BreakStatementJS" 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="BulkFileAttributesRead" 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">
|
||||
<option name="ignoreSetterCallsOnOtherObjects" 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="ComparatorNotSerializable" 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="ConditionalExpressionWithIdenticalBranchesJS" 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="ConstantAssertArgument" 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="ConstantMathCall" 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="CovariantEquals" 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">
|
||||
<option name="ignoreLocalVariables" value="false" />
|
||||
<option name="ignorePrivateMethodsAndFields" value="false" />
|
||||
</inspection_tool>
|
||||
<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="DisjointPackage" 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="DuplicateConditionJS" 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="EmptyCatchBlockJS" 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="commentsAreContent" value="true" />
|
||||
</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="EnhancedSwitchBackwardMigration" enabled="false" level="INFORMATION" enabled_by_default="false" />
|
||||
<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">
|
||||
<option name="insideTryAllowed" value="false" />
|
||||
</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">
|
||||
<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" />
|
||||
@@ -195,6 +229,7 @@
|
||||
<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="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="InconsistentLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="IncorrectFormatting" enabled="false" level="WEAK WARNING" enabled_by_default="false">
|
||||
@@ -203,6 +238,9 @@
|
||||
</scope>
|
||||
<option name="reportPerFile" value="true" />
|
||||
</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="InnerClassVariableHidesOuterClassVariable" enabled="true" level="WARNING" enabled_by_default="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="InstanceofThis" 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">
|
||||
<option name="ignoreInterfacesThatOnlyDeclareConstants" value="false" />
|
||||
</inspection_tool>
|
||||
@@ -328,6 +367,10 @@
|
||||
<option name="REPORT_VARIABLES" value="true" />
|
||||
<option name="REPORT_PARAMETERS" value="true" />
|
||||
</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">
|
||||
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
|
||||
</inspection_tool>
|
||||
@@ -349,9 +392,11 @@
|
||||
<option name="ignoreStaticMethodsFromNonStaticInnerClass" value="false" />
|
||||
<option name="onlyReportStaticMethods" value="false" />
|
||||
</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="MethodOverridesStaticMethod" 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="MissingDeprecatedAnnotation" 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="MisspelledMethodName" 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="NegatedConditional" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="m_ignoreNegatedNullComparison" value="false" />
|
||||
@@ -415,6 +461,7 @@
|
||||
</inspection_tool>
|
||||
<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="NegatedEqualityExpression" 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_ignoreNegatedZeroComparison" value="false" />
|
||||
@@ -441,6 +488,7 @@
|
||||
</inspection_tool>
|
||||
<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="NonShortCircuitBoolean" 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">
|
||||
<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="NonThreadSafeLazyInitialization" 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="ObjectNotify" 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">
|
||||
<option name="ignoreInMatchingInstanceof" value="true" />
|
||||
</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="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">
|
||||
<option name="m_ignoreInvisibleFields" 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="ParameterizedParametersStaticCollection" 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="ProblematicVarargsMethodOverride" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="ProblematicWhitespace" enabled="true" level="WARNING" enabled_by_default="false">
|
||||
<scope name="Project Files" level="WARNING" enabled="true" />
|
||||
</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="PublicFieldAccessedInSynchronizedContext" 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 name="onlyWarnIfContainingClassImplementsAnInterface" value="false" />
|
||||
</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="RandomDoubleForRandomInteger" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="ReadObjectAndWriteObjectPrivate" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
@@ -507,6 +578,9 @@
|
||||
<option name="ignoreObscureOperators" value="false" />
|
||||
</inspection_tool>
|
||||
<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" />
|
||||
</inspection_tool>
|
||||
<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="ReuseOfLocalVariableJS" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
@@ -524,15 +598,20 @@
|
||||
<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="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="SocketResource" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="insideTryAllowed" value="false" />
|
||||
</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="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="StaticInheritance" 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="StringBufferField" 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="StringConcatenationInMessageFormatCall" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
@@ -544,13 +623,20 @@
|
||||
<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="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="SuspiciousLiteralUnderscore" 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">
|
||||
<option name="m_includeNativeMethods" value="true" />
|
||||
<option name="ignoreSynchronizedSuperMethods" value="true" />
|
||||
</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">
|
||||
<option name="ignoreInMainMethod" value="true" />
|
||||
</inspection_tool>
|
||||
@@ -571,9 +657,12 @@
|
||||
<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="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">
|
||||
<option name="ignoreRethrownExceptions" value="false" />
|
||||
</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="TransientFieldNotInitialized" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="TsLint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
@@ -586,6 +675,12 @@
|
||||
</inspection_tool>
|
||||
<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="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="UnnecessaryConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="UnnecessaryExplicitNumericCast" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
@@ -593,6 +688,9 @@
|
||||
<inspection_tool class="UnnecessaryJavaDocLink" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoreInlineLinkToSuper" value="false" />
|
||||
</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="UnusedCatchParameterJS" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="m_ignoreCatchBlocksWithComments" value="false" />
|
||||
@@ -601,6 +699,10 @@
|
||||
<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="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="UseOfJDBCDriverClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="UseOfObsoleteAssert" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
@@ -622,6 +724,7 @@
|
||||
<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="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="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />
|
||||
|
||||
4
.idea/misc.xml
generated
4
.idea/misc.xml
generated
@@ -11,7 +11,5 @@
|
||||
<component name="NodePackageJsonFileManager">
|
||||
<packageJsonPaths />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
|
||||
</project>
|
||||
6
.idea/scala_compiler.xml
generated
6
.idea/scala_compiler.xml
generated
@@ -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
11
.idea/sonarlint.xml
generated
@@ -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
2
.idea/vcs.xml
generated
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
337
.idea/workspace.xml
generated
Normal file
337
.idea/workspace.xml
generated
Normal file
@@ -0,0 +1,337 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="b9d7e333-acad-414e-8be1-4685e71ee4fe" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" 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/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$/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/resources/com/github/gtache/autosubtitle/gui/setup/fx/setupView.fxml" beforeDir="false" afterPath="$PROJECT_DIR$/gui/fx/src/main/resources/com/github/gtache/autosubtitle/gui/setup/fx/setupView.fxml" 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="CoverageOptionsProvider">
|
||||
<option name="myAddOrReplace" value="0" />
|
||||
</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="localRepository" value="D:\caches\.m2\" />
|
||||
</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="ProjectColorInfo">{
|
||||
"customColor": "",
|
||||
"associatedIndex": 4
|
||||
}</component>
|
||||
<component name="ProjectId" id="2mwO59xISTvRVmoGPPwWN1oEXCt" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"Application.Main.executor": "Run",
|
||||
"JUnit.All in autosubtitle-core.executor": "Run",
|
||||
"JUnit.TestASSSubtitleConverter.executor": "Coverage",
|
||||
"JUnit.TestASSSubtitleConverter.testFormatDefaultFont.executor": "Run",
|
||||
"JUnit.TestASSSubtitleConverter.testParseFormat.executor": "Debug",
|
||||
"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",
|
||||
"settings.editor.selected.configurable": "reference.projectsettings.compiler.annotationProcessors",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RecentsManager">
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="I:\Projects\Java\auto-subtitle\gui\fx\src\main\resources\com\github\gtache\autosubtitle\gui\work\fx" />
|
||||
<recent name="I:\Projects\Java\auto-subtitle\gui\fx\src\main\resources\com\github\gtache\autosubtitle\gui\subtitles\fx" />
|
||||
<recent name="I:\Projects\Java\auto-subtitle\gui\fx\src\main\resources\com\github\gtache\autosubtitle\gui\setup\fx" />
|
||||
<recent name="I:\Projects\Java\auto-subtitle\gui\fx\src\main\resources\com\github\gtache\autosubtitle\gui\parameters\fx" />
|
||||
<recent name="I:\Projects\Java\auto-subtitle\gui\core\src\main\resources\com\github\gtache\autosubtitle\gui\work\impl" />
|
||||
</key>
|
||||
<key name="MoveClassesOrPackagesDialog.RECENTS_KEY">
|
||||
<recent name="com.github.gtache.autosubtitle.gui.work.impl.spi" />
|
||||
<recent name="com.github.gtache.autosubtitle.gui.subtitles.impl.spi" />
|
||||
<recent name="com.github.gtache.autosubtitle.gui.setup.impl.spi" />
|
||||
<recent name="com.github.gtache.autosubtitle.gui.parameters.impl.spi" />
|
||||
<recent name="com.github.gtache.autosubtitle.gui.fx" />
|
||||
</key>
|
||||
<key name="CopyClassDialog.RECENTS_KEY">
|
||||
<recent name="com.github.gtache.autosubtitle.modules.setup.impl" />
|
||||
<recent name="com.github.gtache.autosubtitle.modules.impl" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunAnythingCache">
|
||||
<option name="myCommands">
|
||||
<command value="mvn clean package" />
|
||||
<command value="mvn clean" />
|
||||
<command value="mvn clean package -DskipTests" />
|
||||
</option>
|
||||
</component>
|
||||
<component name="RunManager" selected="JUnit.TestASSSubtitleConverter">
|
||||
<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="All in autosubtitle-core" type="JUnit" factoryName="JUnit" temporary="true" nameIsGenerated="true">
|
||||
<module name="autosubtitle-core" />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="package" />
|
||||
<option name="WORKING_DIRECTORY" value="%MODULE_WORKING_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="TestASSSubtitleConverter.testFormatDefaultFont" 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="METHOD_NAME" value="testFormatDefaultFont" />
|
||||
<option name="TEST_OBJECT" value="method" />
|
||||
<option name="WORKING_DIRECTORY" value="%MODULE_WORKING_DIR%" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
<configuration name="TestASSSubtitleConverter.testParseFormat" 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="METHOD_NAME" value="testParseFormat" />
|
||||
<option name="TEST_OBJECT" value="method" />
|
||||
<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.TestASSSubtitleConverter" />
|
||||
<item itemvalue="JUnit.TestASSSubtitleConverter.testFormatDefaultFont" />
|
||||
<item itemvalue="JUnit.TestASSSubtitleConverter.testParseFormat" />
|
||||
<item itemvalue="Application.Main" />
|
||||
<item itemvalue="JUnit.All in autosubtitle-core" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-jdk-9823dce3aa75-28b599e66164-intellij.indexing.shared.core-IU-242.23339.11" />
|
||||
<option value="bundled-js-predefined-d6986cc7102b-5c90d61e3bab-JavaScript-IU-242.23339.11" />
|
||||
</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="b9d7e333-acad-414e-8be1-4685e71ee4fe" name="Changes" comment="" />
|
||||
<created>1727983986841</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1727983986841</updated>
|
||||
<workItem from="1727983987865" duration="45000" />
|
||||
<workItem from="1727984039387" duration="1480000" />
|
||||
<workItem from="1728066754302" duration="4620000" />
|
||||
<workItem from="1728153813144" duration="6710000" />
|
||||
<workItem from="1728207088557" duration="675000" />
|
||||
<workItem from="1728227281845" duration="2280000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
||||
<SUITE FILE_PATH="coverage/auto_subtitle$TestASSSubtitleConverter.ic" NAME="TestASSSubtitleConverter Coverage Results" MODIFIED="1728229568706" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="idea" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="true">
|
||||
<FILTER>com.github.gtache.autosubtitle.subtitle.converter.impl.*</FILTER>
|
||||
</SUITE>
|
||||
<SUITE FILE_PATH="coverage/auto_subtitle$All_in_autosubtitle_core.ic" NAME="All in autosubtitle-core Coverage Results" MODIFIED="1728070687799" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="idea" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="true" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -9,7 +9,7 @@ import java.io.InputStream;
|
||||
public interface Audio {
|
||||
|
||||
/**
|
||||
* @return The audio input stream
|
||||
* @return The input stream
|
||||
* @throws IOException If an I/O error occurs
|
||||
*/
|
||||
InputStream getInputStream() throws IOException;
|
||||
|
||||
@@ -4,13 +4,14 @@ package com.github.gtache.autosubtitle;
|
||||
* Represents info about an audio
|
||||
*/
|
||||
public interface AudioInfo {
|
||||
/**
|
||||
* @return The audio extension (mp3, etc.)
|
||||
*/
|
||||
String audioFormat();
|
||||
|
||||
/**
|
||||
* @return The audio duration in milliseconds
|
||||
* @return The extension (mp3, etc.)
|
||||
*/
|
||||
String format();
|
||||
|
||||
/**
|
||||
* @return The duration in milliseconds
|
||||
*/
|
||||
long duration();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.nio.file.Path;
|
||||
/**
|
||||
* Represents a file
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface File {
|
||||
/**
|
||||
* @return The file input stream
|
||||
|
||||
@@ -54,7 +54,7 @@ public enum Language {
|
||||
|
||||
static {
|
||||
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.englishName.toLowerCase(), language);
|
||||
map.put(language.iso2, language);
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.github.gtache.autosubtitle;
|
||||
|
||||
/**
|
||||
* Type of a tool
|
||||
*/
|
||||
public enum ToolType {
|
||||
/**
|
||||
* The subtitle extractor (used to extract subtitles from a video)
|
||||
*/
|
||||
SUBTITLE_EXTRACTOR,
|
||||
/**
|
||||
* The subtitle translator (used to translate subtitles from one language to another)
|
||||
*/
|
||||
TRANSLATOR,
|
||||
/**
|
||||
* The video converter (used to add subtitles)
|
||||
*/
|
||||
VIDEO_CONVERTER,
|
||||
/**
|
||||
* The video loader (used to load videos)w
|
||||
*/
|
||||
VIDEO_LOADER
|
||||
}
|
||||
@@ -7,9 +7,8 @@ import java.io.InputStream;
|
||||
* Represents a video
|
||||
*/
|
||||
public interface Video {
|
||||
|
||||
/**
|
||||
* @return The video input stream
|
||||
* @return The input stream
|
||||
* @throws IOException If an I/O error occurs
|
||||
*/
|
||||
InputStream getInputStream() throws IOException;
|
||||
@@ -18,5 +17,4 @@ public interface Video {
|
||||
* @return The video info
|
||||
*/
|
||||
VideoInfo info();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.gtache.autosubtitle;
|
||||
|
||||
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -16,40 +17,44 @@ public interface VideoConverter {
|
||||
*
|
||||
* @param video The video
|
||||
* @param subtitles The subtitles collections to add
|
||||
* @param options The export options for the subtitles
|
||||
* @return The modified video
|
||||
* @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
|
||||
*
|
||||
* @param video The video
|
||||
* @param subtitles The subtitles collections to add
|
||||
* @param options The export options for the subtitles
|
||||
* @param path The output path
|
||||
* @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
|
||||
*
|
||||
* @param video The video
|
||||
* @param subtitles The subtitle collection to add
|
||||
* @param options The export options for the subtitles
|
||||
* @return The modified video
|
||||
* @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
|
||||
*
|
||||
* @param video The video
|
||||
* @param subtitles The subtitle collection to add
|
||||
* @param options The export options for the subtitles
|
||||
* @param path The output path
|
||||
* @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
|
||||
|
||||
@@ -3,11 +3,7 @@ package com.github.gtache.autosubtitle;
|
||||
/**
|
||||
* Info about a video
|
||||
*/
|
||||
public interface VideoInfo {
|
||||
/**
|
||||
* @return The video extension (mp4, etc.)
|
||||
*/
|
||||
String videoFormat();
|
||||
public interface VideoInfo extends AudioInfo {
|
||||
|
||||
/**
|
||||
* @return The video width in pixels
|
||||
@@ -19,11 +15,6 @@ public interface VideoInfo {
|
||||
*/
|
||||
int height();
|
||||
|
||||
/**
|
||||
* @return The video duration in milliseconds
|
||||
*/
|
||||
long duration();
|
||||
|
||||
/**
|
||||
* @return The aspect ratio of the video
|
||||
*/
|
||||
|
||||
@@ -14,9 +14,8 @@ public interface Archiver {
|
||||
*
|
||||
* @param files The files to zip
|
||||
* @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
|
||||
|
||||
@@ -26,7 +26,6 @@ public interface ProcessListener {
|
||||
*
|
||||
* @param duration The maximum time to wait
|
||||
* @return The process result
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
ProcessResult join(final Duration duration) throws IOException;
|
||||
ProcessResult join(final Duration duration);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.setup;
|
||||
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
|
||||
/**
|
||||
* Manages the setup of a component
|
||||
*/
|
||||
@@ -10,6 +12,11 @@ public interface SetupManager {
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* @return the type of the component
|
||||
*/
|
||||
ToolType type();
|
||||
|
||||
/**
|
||||
* @return the status of the component setup
|
||||
*/
|
||||
@@ -17,9 +24,8 @@ public interface SetupManager {
|
||||
|
||||
/**
|
||||
* @return whether the component is installed
|
||||
* @throws SetupException if an error occurred
|
||||
*/
|
||||
boolean isInstalled() throws SetupException;
|
||||
boolean isInstalled();
|
||||
|
||||
/**
|
||||
* Installs the component
|
||||
@@ -46,9 +52,8 @@ public interface SetupManager {
|
||||
* Checks if an update is available for the component
|
||||
*
|
||||
* @return whether an update is available
|
||||
* @throws SetupException if an error occurred during the check
|
||||
*/
|
||||
boolean isUpdateAvailable() throws SetupException;
|
||||
boolean isUpdateAvailable();
|
||||
|
||||
/**
|
||||
* Updates the component
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.github.gtache.autosubtitle.subtitle;
|
||||
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
import com.github.gtache.autosubtitle.VideoInfo;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -19,32 +18,33 @@ public interface SubtitleImporterExporter<T extends Subtitle> {
|
||||
* Imports subtitles from a 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 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
|
||||
*
|
||||
* @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
|
||||
* @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
|
||||
*
|
||||
* @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
|
||||
* @throws IOException If an error occurred
|
||||
*/
|
||||
default void exportSubtitles(final SubtitleCollection<?> collection, final VideoInfo videoInfo, final Path file) throws IOException {
|
||||
exportSubtitles(List.of(collection), videoInfo, file);
|
||||
default void exportSubtitles(final SubtitleCollection<?> collection, final ExportOptions options, final Path file) throws IOException {
|
||||
exportSubtitles(List.of(collection), options, 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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
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.SubtitleCollection;
|
||||
|
||||
@@ -9,7 +8,7 @@ import java.nio.file.Files;
|
||||
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> {
|
||||
|
||||
@@ -17,22 +16,24 @@ public interface SubtitleConverter<T extends Subtitle> {
|
||||
* Converts the subtitle 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
|
||||
* @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
|
||||
*
|
||||
* @param file The path to the file
|
||||
* @param options The parse options
|
||||
* @return The subtitle collection
|
||||
* @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 {
|
||||
final var content = Files.readString(file);
|
||||
return parse(content);
|
||||
return parse(content, options);
|
||||
} catch (final IOException e) {
|
||||
throw new ParseException(e);
|
||||
}
|
||||
@@ -42,10 +43,11 @@ public interface SubtitleConverter<T extends Subtitle> {
|
||||
* Parses a subtitle collection
|
||||
*
|
||||
* @param content The content of the file
|
||||
* @param options The conversion options
|
||||
* @return The subtitle collection
|
||||
* @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
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.subtitle.converter;
|
||||
|
||||
import com.github.gtache.autosubtitle.subtitle.OutputFormat;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@@ -19,4 +21,14 @@ public interface SubtitleConverterProvider {
|
||||
* @return The converter (or null if not found)
|
||||
*/
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.github.gtache.autosubtitle.subtitle.extractor;
|
||||
/**
|
||||
* An extraction model
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ExtractionModel {
|
||||
/**
|
||||
* @return the name of the model
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
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;
|
||||
@@ -34,45 +33,19 @@ public interface SubtitleExtractor<T extends Subtitle> {
|
||||
* Extracts the subtitles from a video
|
||||
*
|
||||
* @param video The video
|
||||
* @param model The model to use
|
||||
* @param options The language of the audio
|
||||
* @return The extracted subtitle collection
|
||||
* @throws ExtractException If an error occurs
|
||||
*/
|
||||
default SubtitleCollection<T> extract(final Video video, final ExtractionModel model) throws ExtractException {
|
||||
return extract(video, Language.AUTO, model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the subtitles from a video
|
||||
*
|
||||
* @param video The video
|
||||
* @param language The language of the video
|
||||
* @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;
|
||||
SubtitleCollection<T> extract(final Video video, final ExtractOptions options) throws ExtractException;
|
||||
|
||||
/**
|
||||
* Extracts the subtitles from an audio
|
||||
*
|
||||
* @param audio The audio
|
||||
* @param model The model to use
|
||||
* @param options The extraction options
|
||||
* @return The extracted subtitle collection
|
||||
* @throws ExtractException If an error occurs
|
||||
*/
|
||||
default SubtitleCollection<T> extract(final Audio audio, final ExtractionModel model) 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;
|
||||
SubtitleCollection<T> extract(final Audio audio, final ExtractOptions options) throws ExtractException;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
package com.github.gtache.autosubtitle;
|
||||
|
||||
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.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestVideoInfo {
|
||||
|
||||
private final VideoInfo videoInfo;
|
||||
|
||||
TestVideoInfo(@Mock final VideoInfo videoInfo) {
|
||||
this.videoInfo = Objects.requireNonNull(videoInfo);
|
||||
TestVideoInfo() {
|
||||
this.videoInfo = spy(VideoInfo.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -11,9 +11,14 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
class TestArchiver {
|
||||
|
||||
private final Archiver archiver;
|
||||
|
||||
TestArchiver() {
|
||||
this.archiver = spy(Archiver.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsSupported() {
|
||||
final var archiver = spy(Archiver.class);
|
||||
when(archiver.archiveExtension()).thenReturn("test");
|
||||
assertTrue(archiver.isPathSupported(Paths.get("x.test")));
|
||||
assertFalse(archiver.isPathSupported(Paths.get("tes")));
|
||||
|
||||
@@ -1,26 +1,36 @@
|
||||
package com.github.gtache.autosubtitle.subtitle;
|
||||
|
||||
import com.github.gtache.autosubtitle.VideoInfo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestSubtitleImporterExporter {
|
||||
|
||||
private final SubtitleImporterExporter<Subtitle> importerExporter;
|
||||
private final SubtitleCollection<Subtitle> subtitleCollection;
|
||||
private final ExportOptions options;
|
||||
|
||||
TestSubtitleImporterExporter(@Mock final SubtitleCollection<Subtitle> subtitleCollection, @Mock final ExportOptions options) {
|
||||
this.subtitleCollection = requireNonNull(subtitleCollection);
|
||||
this.options = requireNonNull(options);
|
||||
this.importerExporter = spy(SubtitleImporterExporter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExportSubtitleCollection() throws IOException {
|
||||
final var importExporter = spy(SubtitleImporterExporter.class);
|
||||
final var collection = mock(SubtitleCollection.class);
|
||||
final var videoInfo = Mockito.mock(VideoInfo.class);
|
||||
final var file = mock(Path.class);
|
||||
final var file = Paths.get("path");
|
||||
|
||||
importExporter.exportSubtitles(collection, videoInfo, file);
|
||||
verify(importExporter).exportSubtitles(List.of(collection), videoInfo, file);
|
||||
importerExporter.exportSubtitles(subtitleCollection, options, file);
|
||||
verify(importerExporter).exportSubtitles(List.of(subtitleCollection), options, file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,23 +11,25 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
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.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class TestSubtitleConverter {
|
||||
|
||||
private final SubtitleConverter subtitleConverter;
|
||||
private final SubtitleConverter<Subtitle> subtitleConverter;
|
||||
private final SubtitleCollection<Subtitle> subtitleCollection;
|
||||
private final ParseOptions options;
|
||||
|
||||
TestSubtitleConverter(@Mock final SubtitleConverter subtitleConverter,
|
||||
@Mock final SubtitleCollection<Subtitle> subtitleCollection) {
|
||||
this.subtitleConverter = Objects.requireNonNull(subtitleConverter);
|
||||
this.subtitleCollection = Objects.requireNonNull(subtitleCollection);
|
||||
TestSubtitleConverter(@Mock final SubtitleConverter<Subtitle> subtitleConverter,
|
||||
@Mock final SubtitleCollection<Subtitle> subtitleCollection,
|
||||
@Mock final ParseOptions options) {
|
||||
this.subtitleConverter = requireNonNull(subtitleConverter);
|
||||
this.subtitleCollection = requireNonNull(subtitleCollection);
|
||||
this.options = requireNonNull(options);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -35,19 +37,19 @@ class TestSubtitleConverter {
|
||||
final var file = tempDir.resolve("test.srt");
|
||||
final var string = "test";
|
||||
Files.writeString(file, string);
|
||||
when(subtitleConverter.parse(file)).thenCallRealMethod();
|
||||
when(subtitleConverter.parse(string)).thenReturn(subtitleCollection);
|
||||
when(subtitleConverter.parse(file, options)).thenCallRealMethod();
|
||||
when(subtitleConverter.parse(string, options)).thenReturn(subtitleCollection);
|
||||
|
||||
assertEquals(subtitleCollection, subtitleConverter.parse(file));
|
||||
assertEquals(subtitleCollection, subtitleConverter.parse(file, options));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testParseException(@TempDir final Path tempDir) throws ParseException {
|
||||
final var file = tempDir.resolve("test.srt");
|
||||
when(subtitleConverter.parse(file)).thenCallRealMethod();
|
||||
when(subtitleConverter.parse(anyString())).thenReturn(subtitleCollection);
|
||||
when(subtitleConverter.parse(file, options)).thenCallRealMethod();
|
||||
when(subtitleConverter.parse(anyString(), eq(options))).thenReturn(subtitleCollection);
|
||||
|
||||
assertThrows(ParseException.class, () -> subtitleConverter.parse(file));
|
||||
assertThrows(ParseException.class, () -> subtitleConverter.parse(file, options));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -1,54 +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.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 subtitleExtractor;
|
||||
private final SubtitleCollection subtitleCollection;
|
||||
private final Audio audio;
|
||||
private final Video video;
|
||||
private final ExtractionModel extractionModel;
|
||||
|
||||
TestSubtitleExtractor(@Mock final SubtitleExtractor subtitleExtractor,
|
||||
@Mock final SubtitleCollection 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));
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,15 @@ import picocli.CommandLine;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Main class for CLI
|
||||
*/
|
||||
@CommandLine.Command(name = "autosubtitle", mixinStandardHelpOptions = true, version = "autosubtitle 1.0-SNAPSHOT", description = "CLI for auto-subtitle")
|
||||
public final class Cli implements Runnable {
|
||||
|
||||
@CommandLine.Option(names = {"-b", "--burn"}, description = "Burn the subtitles. Otherwise, adds them to the video", defaultValue = "false")
|
||||
@CommandLine.Option(names = {"-b", "--burn"}, description = "Burns the subtitles. Otherwise, adds them to the video", defaultValue = "false")
|
||||
private boolean burn;
|
||||
@CommandLine.Option(names = {"-e", "--extractor"}, description = "The subtitle extractor to use [whisper]", defaultValue = "whisper")
|
||||
@CommandLine.Option(names = {"-e", "--extractor"}, description = "The subtitle extractor to use [whisperx]", defaultValue = "whisperx")
|
||||
private String extractor;
|
||||
@CommandLine.Option(names = {"-i", "--input"}, description = "The input file", required = true)
|
||||
private String input;
|
||||
@@ -23,7 +26,7 @@ public final class Cli implements Runnable {
|
||||
private String subtitleConverter;
|
||||
@CommandLine.Option(names = {"-c", "--video-converter"}, description = "The video converter to use [ffmpeg]", defaultValue = "ffmpeg")
|
||||
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;
|
||||
@CommandLine.Option(names = {"-t", "--translator"}, description = "The translator to use [deepl]. Ignored if burn is specified", defaultValue = "deepl")
|
||||
private String translator;
|
||||
|
||||
@@ -6,4 +6,5 @@ module com.github.gtache.autosubtitle.cli {
|
||||
requires com.github.gtache.autosubtitle.ffmpeg;
|
||||
requires com.github.gtache.autosubtitle.whisperx;
|
||||
requires info.picocli;
|
||||
requires guava;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package com.github.gtache.autosubtitle.archive.client;
|
||||
|
||||
import com.github.gtache.autosubtitle.archive.Archiver;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link Archiver} using a remote API
|
||||
*/
|
||||
public class RemoteArchiver implements Archiver {
|
||||
@Override
|
||||
public void compress(final List<Path> files, final Path destination) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decompress(final Path archive, final Path destination) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String archiveExtension() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.client;
|
||||
|
||||
public abstract class AbstractClient {
|
||||
}
|
||||
@@ -3,9 +3,9 @@ package com.github.gtache.autosubtitle.client;
|
||||
import com.github.gtache.autosubtitle.Audio;
|
||||
import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.VideoConverter;
|
||||
import com.github.gtache.autosubtitle.subtitle.ExportOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -14,27 +14,28 @@ import java.util.Collection;
|
||||
*/
|
||||
public class RemoteVideoConverter implements VideoConverter {
|
||||
@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();
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHardSubtitles(final Video video, final SubtitleCollection<?> subtitles, final Path path) throws IOException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Audio getAudio(final Video video) throws IOException {
|
||||
public Audio getAudio(final Video video) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.github.gtache.autosubtitle.client;
|
||||
import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.VideoLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
@@ -11,7 +10,7 @@ import java.nio.file.Path;
|
||||
*/
|
||||
public class RemoteVideoLoader implements VideoLoader {
|
||||
@Override
|
||||
public Video loadVideo(final Path path) throws IOException {
|
||||
public Video loadVideo(final Path path) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
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.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;
|
||||
|
||||
/**
|
||||
@@ -13,12 +13,12 @@ import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
*/
|
||||
public class RemoteSubtitleConverter<T extends Subtitle> implements SubtitleConverter<T> {
|
||||
@Override
|
||||
public String format(final SubtitleCollection<?> collection, final VideoInfo videoInfo) {
|
||||
public String format(final SubtitleCollection<?> collection, final FormatOptions options) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubtitleCollection<T> parse(final String content) throws ParseException {
|
||||
public SubtitleCollection<T> parse(final String content, final ParseOptions options) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,25 @@
|
||||
package com.github.gtache.autosubtitle.subtitle.extractor.client;
|
||||
|
||||
import com.github.gtache.autosubtitle.Audio;
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
import com.github.gtache.autosubtitle.Video;
|
||||
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractException;
|
||||
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.impl.AbstractSubtitleExtractor;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl;
|
||||
|
||||
/**
|
||||
* {@link SubtitleExtractor} using a remote API
|
||||
*/
|
||||
public class RemoteSubtitleExtractor extends AbstractSubtitleExtractor {
|
||||
public class RemoteSubtitleExtractor extends AbstractSubtitleExtractor<SubtitleImpl> {
|
||||
|
||||
@Override
|
||||
public SubtitleCollection extract(final Video video, final Language language, final ExtractionModel model) throws ExtractException {
|
||||
public SubtitleCollection<SubtitleImpl> extract(final Video video, final ExtractOptions options) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubtitleCollection extract(final Audio audio, final Language language, final ExtractionModel model) throws ExtractException {
|
||||
public SubtitleCollection<SubtitleImpl> extract(final Audio audio, final ExtractOptions options) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.github.gtache.autosubtitle.translation.client;
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
import com.github.gtache.autosubtitle.subtitle.Subtitle;
|
||||
import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
import com.github.gtache.autosubtitle.translation.TranslationException;
|
||||
import com.github.gtache.autosubtitle.translation.Translator;
|
||||
|
||||
/**
|
||||
@@ -18,17 +17,17 @@ public class RemoteTranslator<T extends Subtitle> implements Translator<T> {
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.conda;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.conda;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.conda;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.conda;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.conda;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.conda;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
package com.github.gtache.autosubtitle.setup.conda;
|
||||
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
import com.github.gtache.autosubtitle.impl.OS;
|
||||
import com.github.gtache.autosubtitle.process.ProcessRunner;
|
||||
import com.github.gtache.autosubtitle.setup.SetupException;
|
||||
import com.github.gtache.autosubtitle.setup.SetupStatus;
|
||||
import com.github.gtache.autosubtitle.setup.impl.AbstractSetupManager;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.http.HttpClient;
|
||||
import java.nio.file.Files;
|
||||
@@ -42,6 +45,11 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
return "conda";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ToolType type() {
|
||||
return null; //Just an intermediary tool
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SetupStatus getStatus() throws SetupException {
|
||||
if (isSystemCondaInstalled()) {
|
||||
@@ -70,8 +78,8 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
logger.info("Conda downloaded");
|
||||
}
|
||||
switch (configuration.os()) {
|
||||
case OS.WINDOWS -> installWindows();
|
||||
case OS.MAC, OS.LINUX -> installLinux();
|
||||
case WINDOWS -> installWindows();
|
||||
case MAC, LINUX -> installLinux();
|
||||
default -> throw new SetupException("Unsupported OS: " + configuration.os());
|
||||
}
|
||||
}
|
||||
@@ -106,9 +114,9 @@ public class CondaSetupManager extends AbstractSetupManager {
|
||||
|
||||
private void downloadConda() throws SetupException {
|
||||
switch (configuration.os()) {
|
||||
case OS.WINDOWS -> downloadCondaWindows();
|
||||
case OS.MAC -> downloadCondaMac();
|
||||
case OS.LINUX -> downloadCondaLinux();
|
||||
case WINDOWS -> downloadCondaWindows();
|
||||
case MAC -> downloadCondaMac();
|
||||
case LINUX -> downloadCondaLinux();
|
||||
default -> throw new SetupException("Unsupported OS: " + configuration.os());
|
||||
}
|
||||
logger.info("Downloaded conda to {}", configuration.condaInstallerPath());
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.github.gtache.autosubtitle.process.ProcessResult;
|
||||
import com.github.gtache.autosubtitle.process.ProcessRunner;
|
||||
import com.github.gtache.autosubtitle.setup.SetupException;
|
||||
import com.github.gtache.autosubtitle.setup.SetupStatus;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -36,26 +37,30 @@ class TestCondaSetupManager {
|
||||
private final CondaSetupConfiguration configuration;
|
||||
private final ProcessRunner processRunner;
|
||||
private final HttpClient httpClient;
|
||||
private final HttpResponse<Path> response;
|
||||
private final CondaSetupManager condaSetupManager;
|
||||
private final ProcessResult systemProcessResult;
|
||||
private final Path systemPath;
|
||||
private final HttpResponse<Path> response;
|
||||
|
||||
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.processRunner = requireNonNull(processRunner);
|
||||
this.httpClient = requireNonNull(httpClient);
|
||||
this.condaSetupManager = new CondaSetupManager(configuration, processRunner, httpClient);
|
||||
this.systemProcessResult = requireNonNull(systemProcessResult);
|
||||
this.systemPath = Paths.get("system");
|
||||
this.response = requireNonNull(response);
|
||||
when(response.statusCode()).thenReturn(200);
|
||||
this.condaSetupManager = new CondaSetupManager(configuration, processRunner, httpClient);
|
||||
this.systemPath = Paths.get("system");
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() throws IOException, InterruptedException {
|
||||
when(configuration.condaSystemPath()).thenReturn(systemPath);
|
||||
when(systemProcessResult.output()).thenReturn(List.of("conda 99.99.99"));
|
||||
when(systemProcessResult.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(List.of(systemPath.toString(), "--version"), Duration.ofSeconds(5))).thenReturn(systemProcessResult);
|
||||
when(httpClient.send(any(HttpRequest.class), any(HttpResponse.BodyHandler.class))).thenReturn(response);
|
||||
when(response.statusCode()).thenReturn(200);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -63,6 +68,11 @@ class TestCondaSetupManager {
|
||||
assertEquals("conda", condaSetupManager.name());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testType() {
|
||||
assertNull(condaSetupManager.type());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetStatusIsSystemInstalled() throws SetupException {
|
||||
assertEquals(SetupStatus.SYSTEM_INSTALLED, condaSetupManager.getStatus());
|
||||
@@ -117,10 +127,7 @@ class TestCondaSetupManager {
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals("https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe", request.uri().toString());
|
||||
checkURLRequested("https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe");
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
}
|
||||
|
||||
@@ -140,10 +147,7 @@ class TestCondaSetupManager {
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals("https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh", request.uri().toString());
|
||||
checkURLRequested("https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh");
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
}
|
||||
|
||||
@@ -163,15 +167,12 @@ class TestCondaSetupManager {
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals("https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh", request.uri().toString());
|
||||
checkURLRequested("https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh");
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadLinuxUnsupported(@TempDir final Path tempDir) throws IOException {
|
||||
void testInstallDownloadLinuxUnsupported(@TempDir final Path tempDir) {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
@@ -200,10 +201,7 @@ class TestCondaSetupManager {
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals("https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh", request.uri().toString());
|
||||
checkURLRequested("https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh");
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
}
|
||||
|
||||
@@ -223,15 +221,12 @@ class TestCondaSetupManager {
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
|
||||
assertDoesNotThrow(condaSetupManager::install);
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals("https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh", request.uri().toString());
|
||||
checkURLRequested("https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh");
|
||||
verify(processRunner).run(args, Duration.ofMinutes(15));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadMacUnsupported(@TempDir final Path tempDir) throws IOException {
|
||||
void testInstallDownloadMacUnsupported(@TempDir final Path tempDir) {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
@@ -245,7 +240,7 @@ class TestCondaSetupManager {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInstallDownloadUnsupported(@TempDir final Path tempDir) throws IOException {
|
||||
void testInstallDownloadUnsupported(@TempDir final Path tempDir) {
|
||||
final var installerPath = tempDir.resolve("conda");
|
||||
when(configuration.condaInstallerPath()).thenReturn(installerPath);
|
||||
when(configuration.condaBundledPath()).thenReturn(tempDir);
|
||||
@@ -268,7 +263,7 @@ class TestCondaSetupManager {
|
||||
when(systemProcessResult.exitCode()).thenReturn(1);
|
||||
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);
|
||||
when(result.exitCode()).thenReturn(0);
|
||||
when(processRunner.run(args, Duration.ofMinutes(15))).thenReturn(result);
|
||||
@@ -510,4 +505,11 @@ class TestCondaSetupManager {
|
||||
assertThrows(NullPointerException.class, () -> new CondaSetupManager(configuration, processRunner, null));
|
||||
}
|
||||
|
||||
private void checkURLRequested(final String url) throws IOException, InterruptedException {
|
||||
final var requestCapture = ArgumentCaptor.forClass(HttpRequest.class);
|
||||
verify(httpClient).send(requestCapture.capture(), any(HttpResponse.BodyHandler.class));
|
||||
final var request = requestCapture.getValue();
|
||||
assertEquals(url, request.uri().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.github.gtache.autosubtitle.archive.Archiver;
|
||||
import com.github.gtache.autosubtitle.archive.ArchiverProvider;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.github.gtache.autosubtitle.archive.impl;
|
||||
import com.github.gtache.autosubtitle.archive.Archiver;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -14,15 +15,15 @@ import java.util.zip.ZipInputStream;
|
||||
/**
|
||||
* Zip implementation of {@link Archiver}
|
||||
*/
|
||||
public class ZipDecompresser implements Archiver {
|
||||
public class ZipArchiver implements Archiver {
|
||||
|
||||
@Inject
|
||||
ZipDecompresser() {
|
||||
ZipArchiver() {
|
||||
|
||||
}
|
||||
|
||||
@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");
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ import java.util.Objects;
|
||||
/**
|
||||
* Implementation of {@link AudioInfo}
|
||||
*/
|
||||
public record AudioInfoImpl(String audioFormat, long duration) implements AudioInfo {
|
||||
public record AudioInfoImpl(String format, long duration) implements AudioInfo {
|
||||
|
||||
public AudioInfoImpl {
|
||||
Objects.requireNonNull(audioFormat);
|
||||
Objects.requireNonNull(format);
|
||||
if (duration < 0) {
|
||||
throw new IllegalArgumentException("Duration must be positive");
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ import java.util.Objects;
|
||||
/**
|
||||
* Implementation of {@link VideoInfo}
|
||||
*/
|
||||
public record VideoInfoImpl(String videoFormat, int width, int height, long duration) implements VideoInfo {
|
||||
public record VideoInfoImpl(String format, int width, int height, long duration) implements VideoInfo {
|
||||
|
||||
public VideoInfoImpl {
|
||||
Objects.requireNonNull(videoFormat);
|
||||
Objects.requireNonNull(format);
|
||||
if (width <= 0) {
|
||||
throw new IllegalArgumentException("Width must be greater than 0 : " + width);
|
||||
}
|
||||
|
||||
@@ -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.ArchiverProvider;
|
||||
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.Module;
|
||||
import dagger.multibindings.IntoMap;
|
||||
@@ -25,5 +25,5 @@ public abstract class ArchiveModule {
|
||||
@Binds
|
||||
@StringKey("zip")
|
||||
@IntoMap
|
||||
abstract Archiver bindsZipDecompresser(final ZipDecompresser decompresser);
|
||||
abstract Archiver bindsZipDecompresser(final ZipArchiver decompresser);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.github.gtache.autosubtitle.modules.impl;
|
||||
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
import dagger.MapKey;
|
||||
|
||||
/**
|
||||
* Used for injection
|
||||
*/
|
||||
@MapKey
|
||||
public @interface ToolTypeKey {
|
||||
|
||||
/**
|
||||
* @return the tool type
|
||||
*/
|
||||
ToolType value();
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.impl;
|
||||
|
||||
import com.github.gtache.autosubtitle.ToolType;
|
||||
import com.github.gtache.autosubtitle.setup.SetupManager;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
import java.net.http.HttpClient;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Dagger core module for setup
|
||||
@@ -32,4 +35,14 @@ public final class SetupModule {
|
||||
static HttpClient providesHttpClient() {
|
||||
return HttpClient.newHttpClient();
|
||||
}
|
||||
|
||||
|
||||
@Provides
|
||||
static Map<ToolType, Map<String, SetupManager>> providesSetupManagers(@VideoConverterSetup final Map<String, SetupManager> convertersManagers,
|
||||
@SubtitleExtractorSetup final Map<String, SetupManager> extractorsManagers,
|
||||
@TranslatorSetup final Map<String, SetupManager> translatorsManagers) {
|
||||
return Map.of(ToolType.VIDEO_CONVERTER, convertersManagers,
|
||||
ToolType.SUBTITLE_EXTRACTOR, extractorsManagers,
|
||||
ToolType.TRANSLATOR, translatorsManagers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.github.gtache.autosubtitle.modules.setup.whisper;
|
||||
package com.github.gtache.autosubtitle.modules.setup.impl;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -12,5 +12,5 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
|
||||
public @interface PythonVersion {
|
||||
public @interface VideoLoaderSetup {
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.gtache.autosubtitle.modules.subtitle.converter.impl;
|
||||
|
||||
import com.github.gtache.autosubtitle.modules.subtitle.converter.json.impl.JSONConverterModule;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.impl.ASSSubtitleConverter;
|
||||
@@ -13,7 +14,7 @@ import dagger.multibindings.StringKey;
|
||||
/**
|
||||
* Dagger module for the subtitle converters
|
||||
*/
|
||||
@Module
|
||||
@Module(includes = JSONConverterModule.class)
|
||||
public abstract class SubtitleConverterModule {
|
||||
|
||||
private SubtitleConverterModule() {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.github.gtache.autosubtitle.modules.subtitle.converter.json.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.json.impl.JSONSubtitleConverter;
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.IntoMap;
|
||||
import dagger.multibindings.StringKey;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Dagger module for the json subtitle converter
|
||||
*/
|
||||
@Module
|
||||
public abstract class JSONConverterModule {
|
||||
|
||||
private JSONConverterModule() {
|
||||
}
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@StringKey("json")
|
||||
abstract SubtitleConverter bindsJsonSubtitleConverter(final JSONSubtitleConverter converter);
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
static ObjectMapper providesObjectMapper() {
|
||||
return new ObjectMapper();
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import dagger.Module;
|
||||
/**
|
||||
* Dagger module for subtitles
|
||||
*/
|
||||
@Module(includes = {SubtitleConverterModule.class})
|
||||
@Module(includes = SubtitleConverterModule.class)
|
||||
public abstract class SubtitleModule {
|
||||
|
||||
private SubtitleModule() {
|
||||
|
||||
@@ -3,10 +3,12 @@ package com.github.gtache.autosubtitle.process.impl;
|
||||
import com.github.gtache.autosubtitle.process.ProcessListener;
|
||||
import com.github.gtache.autosubtitle.process.ProcessResult;
|
||||
import com.github.gtache.autosubtitle.process.ProcessRunner;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
package com.github.gtache.autosubtitle.subtitle.converter.impl;
|
||||
|
||||
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.Bounds;
|
||||
import com.github.gtache.autosubtitle.subtitle.Font;
|
||||
import com.github.gtache.autosubtitle.subtitle.Subtitle;
|
||||
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.ParseOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.BoundsImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.FontImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl;
|
||||
import com.github.gtache.autosubtitle.translation.Translator;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.prefs.Preferences;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Converts subtitles to SRT format
|
||||
*/
|
||||
@@ -35,47 +37,71 @@ public class ASSSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
|
||||
private static final String DIALOGUE = "Dialogue:";
|
||||
private static final String EVENTS_SECTION = "[Events]";
|
||||
private static final String STYLES_SECTION = "[V4+ Styles]";
|
||||
private final Translator<?> translator;
|
||||
private final Preferences preferences;
|
||||
private final String defaultFontName;
|
||||
private final int defaultFontSize;
|
||||
private static final String START_FIELD = "Start";
|
||||
private static final String END_FIELD = "End";
|
||||
private static final String STYLE_FIELD = "Style";
|
||||
private static final String TEXT_FIELD = "Text";
|
||||
private static final String NAME_FIELD = "Name";
|
||||
private static final String FONTNAME_FIELD = "Fontname";
|
||||
private static final String FONTSIZE_FIELD = "Fontsize";
|
||||
private static final String MARGIN_L_FIELD = "MarginL";
|
||||
private static final String MARGIN_R_FIELD = "MarginR";
|
||||
private static final String MARGIN_V_FIELD = "MarginV";
|
||||
private static final List<String> STYLE_FIELDS = List.of(NAME_FIELD, FONTNAME_FIELD, FONTSIZE_FIELD, "PrimaryColour",
|
||||
"SecondaryColour", "OutlineColour", "BackColour", "Bold", "Italic",
|
||||
"Underline", "StrikeOut", "ScaleX", "ScaleY", "Spacing", "Angle", "BorderStyle", "Outline", "Shadow", "Alignment",
|
||||
MARGIN_L_FIELD, MARGIN_R_FIELD, MARGIN_V_FIELD, "AlphaLevel", "Encoding");
|
||||
private static final Set<String> REQUIRED_STYLE_FIELDS = Set.of(NAME_FIELD, FONTNAME_FIELD, FONTSIZE_FIELD);
|
||||
private static final List<String> EVENT_FIELDS = List.of("Layer", START_FIELD, END_FIELD, STYLE_FIELD, "Name", MARGIN_L_FIELD, MARGIN_R_FIELD, MARGIN_V_FIELD, "Effect", TEXT_FIELD);
|
||||
private static final Set<String> REQUIRED_EVENT_FIELDS = Set.of(START_FIELD, END_FIELD, STYLE_FIELD, TEXT_FIELD);
|
||||
|
||||
private static final Pattern NEWLINE_PATTERN = Pattern.compile("\\n");
|
||||
private static final Pattern POS_PATTERN = Pattern.compile("^\\{\\\\pos\\((?<x>\\d+),(?<y>\\d+)\\)}");
|
||||
private static final Pattern START_DIALOG_PATTERN = Pattern.compile("^Dialogue: ");
|
||||
private static final Pattern START_ZERO_PATTERN = Pattern.compile("^0+");
|
||||
private static final Pattern PLAY_RES_Y_PATTERN = Pattern.compile("^PlayResY: (?<height>\\d+)", Pattern.MULTILINE);
|
||||
|
||||
private final Map<String, Translator<?>> translators;
|
||||
|
||||
@Inject
|
||||
ASSSubtitleConverter(final Translator translator, final Preferences preferences,
|
||||
@FontName final String defaultFontName, @FontSize final int defaultFontSize) {
|
||||
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;
|
||||
ASSSubtitleConverter(final Map<String, Translator<?>> translators) {
|
||||
this.translators = Map.copyOf(translators);
|
||||
}
|
||||
|
||||
@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 scriptInfo = getScriptInfo(videoInfo);
|
||||
final var styles = getStyles(subtitles);
|
||||
final var events = getEvents(subtitles);
|
||||
final var scriptInfo = writeScriptInfo(options.videoInfo());
|
||||
final var styles = writeStyles(subtitles, options.defaultFont());
|
||||
final var events = writeEvents(subtitles, options.defaultFont());
|
||||
return scriptInfo + "\n\n" + styles + "\n\n" + events + "\n";
|
||||
}
|
||||
|
||||
private String getEvents(final Collection<? extends Subtitle> subtitles) {
|
||||
return EVENTS_SECTION + "\n" + "Format: Start, End, Style, Text\n" +
|
||||
subtitles.stream().map(this::getEvent).collect(Collectors.joining("\n"));
|
||||
private static String writeEvents(final Collection<? extends Subtitle> subtitles, final Font defaultFont) {
|
||||
return EVENTS_SECTION + "\n" + "Format: " + String.join(", ", EVENT_FIELDS) + "\n" +
|
||||
subtitles.stream().map(s -> writeEvent(s, defaultFont)).collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
private String getEvent(final Subtitle subtitle) {
|
||||
return DIALOGUE + " " + formatTime(subtitle.start()) + "," + formatTime(subtitle.end()) + "," + getName(subtitle.font()) + "," + subtitle.content();
|
||||
private static String writeEvent(final Subtitle subtitle, final Font defaultFont) {
|
||||
return DIALOGUE + " 0," +
|
||||
formatTime(subtitle.start()) + "," +
|
||||
formatTime(subtitle.end()) + "," +
|
||||
getStyleName(subtitle.font(), defaultFont) + "," +
|
||||
"X," +
|
||||
"0000," +
|
||||
"0000," +
|
||||
"0000," +
|
||||
"," +
|
||||
(subtitle.bounds() == null ? "" : "{\\pos(" + (long) subtitle.bounds().x() + "," + (long) subtitle.bounds().y() + ")}") +
|
||||
subtitle.content();
|
||||
}
|
||||
|
||||
private String getName(final Font font) {
|
||||
private static String getStyleName(final Font font, final Font defaultFont) {
|
||||
final String fontName;
|
||||
final int fontSize;
|
||||
if (font == null) {
|
||||
fontName = preferences.get("fontName", defaultFontName);
|
||||
fontSize = preferences.getInt("fontSize", defaultFontSize);
|
||||
fontName = defaultFont.name();
|
||||
fontSize = defaultFont.size();
|
||||
} else {
|
||||
fontName = font.name();
|
||||
fontSize = font.size();
|
||||
@@ -83,19 +109,19 @@ public class ASSSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
|
||||
return fontName + fontSize;
|
||||
}
|
||||
|
||||
private String getStyles(final Collection<? extends Subtitle> subtitles) {
|
||||
return STYLES_SECTION + "\n" + "Format: Name, Fontname, Fontsize\n" + listStyles(subtitles);
|
||||
private static String writeStyles(final Collection<? extends Subtitle> subtitles, final Font defaultFont) {
|
||||
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());
|
||||
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 + " " + getStyleName(f, defaultFont) + ", " + f.name() + ", " + f.size()).collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
private static String getScriptInfo(final VideoInfo videoInfo) {
|
||||
private static String writeScriptInfo(final VideoInfo videoInfo) {
|
||||
return """
|
||||
[Script Info]
|
||||
PlayResX: %d
|
||||
@@ -103,85 +129,129 @@ public class ASSSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
|
||||
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
|
||||
public SubtitleCollectionImpl<SubtitleImpl> parse(final String content) throws ParseException {
|
||||
public SubtitleCollectionImpl<SubtitleImpl> parse(final String content, final ParseOptions options) throws ParseException {
|
||||
final var videoHeight = parseVideoHeight(content);
|
||||
final var fonts = parseFonts(content);
|
||||
final var subtitles = parseSubtitles(content, fonts);
|
||||
final var subtitles = parseSubtitles(content, fonts, options.defaultFont(), videoHeight);
|
||||
final var text = subtitles.stream().map(Subtitle::content).collect(Collectors.joining());
|
||||
final var language = translator.getLanguage(text);
|
||||
final var language = translators.values().iterator().next().getLanguage(text); //Use any translator for now
|
||||
return new SubtitleCollectionImpl<>(text, subtitles, language);
|
||||
}
|
||||
|
||||
private static List<SubtitleImpl> parseSubtitles(final String content, final Map<String, Font> fonts) throws ParseException {
|
||||
final var fontIndex = content.indexOf(EVENTS_SECTION);
|
||||
if (fontIndex == -1) {
|
||||
private static int parseVideoHeight(final CharSequence content) {
|
||||
final var matcher = PLAY_RES_Y_PATTERN.matcher(content);
|
||||
if (matcher.find()) {
|
||||
return Integer.parseInt(matcher.group("height"));
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<SubtitleImpl> parseSubtitles(final String content, final Map<String, Font> fonts, final Font defaultFont, final int videoHeight) throws ParseException {
|
||||
final var eventsIndex = content.indexOf(EVENTS_SECTION);
|
||||
if (eventsIndex == -1) {
|
||||
throw new ParseException("Events section not found in " + content);
|
||||
} else {
|
||||
final var split = content.substring(fontIndex).split("\\n");
|
||||
final List<String> fields;
|
||||
if (split[0].startsWith(EVENTS_SECTION)) {
|
||||
fields = getFields(split[1]);
|
||||
} else {
|
||||
throw new ParseException("Couldn't parse events : " + content);
|
||||
final var split = NEWLINE_PATTERN.split(content.substring(eventsIndex));
|
||||
final var fields = getFields(split[1]);
|
||||
final var fieldsMapping = EVENT_FIELDS.stream().collect(Collectors.toMap(e -> e, fields::indexOf));
|
||||
if (REQUIRED_EVENT_FIELDS.stream().anyMatch(s -> fieldsMapping.get(s) == -1)) {
|
||||
throw new ParseException("Missing required fields : " + content);
|
||||
}
|
||||
final var startIndex = fields.indexOf("Start");
|
||||
final var endIndex = fields.indexOf("End");
|
||||
final var styleIndex = fields.indexOf("Style");
|
||||
final var textIndex = fields.indexOf("Text");
|
||||
if (startIndex == -1 || endIndex == -1 || styleIndex == -1 || textIndex == -1) {
|
||||
throw new ParseException("Couldn't parse events : " + content);
|
||||
if (fieldsMapping.get("Text") != fields.size() - 1) {
|
||||
throw new ParseException("Text field should be the last field : " + content);
|
||||
}
|
||||
//Ignore effect for now
|
||||
return Arrays.stream(split).filter(s -> s.startsWith(DIALOGUE))
|
||||
.map(s -> {
|
||||
final var values = Arrays.stream(s.replace(DIALOGUE, "").split(",")).map(String::trim).filter(w -> !w.isBlank()).toList();
|
||||
final var start = parseTime(values.get(startIndex));
|
||||
final var end = parseTime(values.get(endIndex));
|
||||
final var style = values.get(styleIndex);
|
||||
final var font = fonts.get(style);
|
||||
final var text = values.stream().skip(textIndex).collect(Collectors.joining(", "));
|
||||
return new SubtitleImpl(text, start, end, font, null); //TODO pos style overrides
|
||||
final var values = parseValues(s, fields.size());
|
||||
final var start = parseTime(values.get(fieldsMapping.get(START_FIELD)));
|
||||
final var end = parseTime(values.get(fieldsMapping.get(END_FIELD)));
|
||||
final var style = values.get(fieldsMapping.get(STYLE_FIELD));
|
||||
final var marginBounds = getMarginBounds(values, fieldsMapping, videoHeight);
|
||||
final var font = fonts.getOrDefault(style, defaultFont);
|
||||
final var rawText = values.get(fieldsMapping.get(TEXT_FIELD));
|
||||
final var matcher = POS_PATTERN.matcher(rawText);
|
||||
if (matcher.find()) {
|
||||
final var x = Integer.parseInt(matcher.group("x"));
|
||||
final var y = Integer.parseInt(matcher.group("y"));
|
||||
final var bounds = new BoundsImpl(x, y, 0, 0);
|
||||
final var text = matcher.replaceAll("");
|
||||
return new SubtitleImpl(text, start, end, font, bounds);
|
||||
} else {
|
||||
return new SubtitleImpl(rawText, start, end, font, marginBounds);
|
||||
}
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Font> parseFonts(final String content) throws ParseException {
|
||||
final var fontIndex = content.indexOf(STYLES_SECTION);
|
||||
if (fontIndex == -1) {
|
||||
private static List<String> parseValues(final CharSequence value, final int size) {
|
||||
final var trimmed = START_DIALOG_PATTERN.matcher(value).replaceAll("").trim();
|
||||
final var values = new ArrayList<String>(EVENT_FIELDS.size());
|
||||
var substring = trimmed;
|
||||
while (!substring.isEmpty()) {
|
||||
final var index = substring.indexOf(',');
|
||||
if (index == -1 || values.size() == size - 1) {
|
||||
values.add(substring);
|
||||
substring = "";
|
||||
} else {
|
||||
values.add(substring.substring(0, index));
|
||||
substring = substring.substring(index + 1);
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private static Bounds getMarginBounds(final List<String> values, final Map<String, Integer> fieldsMapping, final int videoHeight) {
|
||||
final var marginLIndex = fieldsMapping.get(MARGIN_L_FIELD);
|
||||
final var marginRIndex = fieldsMapping.get(MARGIN_R_FIELD);
|
||||
final var marginVIndex = fieldsMapping.get(MARGIN_V_FIELD);
|
||||
if (marginLIndex == -1 || marginRIndex == -1 || marginVIndex == -1) {
|
||||
return null;
|
||||
} else {
|
||||
final var marginL = parseMargin(values.get(marginLIndex));
|
||||
final var marginR = parseMargin(values.get(marginRIndex));
|
||||
final var marginV = parseMargin(values.get(marginVIndex));
|
||||
if (marginL == -1 || marginR == -1 || marginV == -1) {
|
||||
return null;
|
||||
} else {
|
||||
final var y = videoHeight <= 0 ? 0 : videoHeight - marginV;
|
||||
return new BoundsImpl(marginL, y, marginR - (double) marginL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int parseMargin(final CharSequence margin) {
|
||||
final var removedZero = START_ZERO_PATTERN.matcher(margin).replaceAll("");
|
||||
return removedZero.isEmpty() ? -1 : Integer.parseInt(removedZero);
|
||||
}
|
||||
|
||||
private static Map<String, Font> parseFonts(final String content) throws ParseException {
|
||||
final var stylesIndex = content.indexOf(STYLES_SECTION);
|
||||
if (stylesIndex == -1) {
|
||||
throw new ParseException("Styles section not found in " + content);
|
||||
} else {
|
||||
final var split = content.substring(fontIndex).split("\\n");
|
||||
final List<String> fields;
|
||||
if (split[0].startsWith(STYLES_SECTION)) {
|
||||
fields = getFields(split[1]);
|
||||
} else {
|
||||
throw new ParseException("Couldn't parse styles : " + content);
|
||||
}
|
||||
final var fontNameIndex = fields.indexOf("Fontname");
|
||||
final var fontSizeIndex = fields.indexOf("Fontsize");
|
||||
if (fontNameIndex == -1 || fontSizeIndex == -1) {
|
||||
throw new ParseException("Couldn't parse styles : " + content);
|
||||
final var split = NEWLINE_PATTERN.split(content.substring(stylesIndex));
|
||||
final var fields = getFields(split[1]);
|
||||
final var fieldsMapping = STYLE_FIELDS.stream().collect(Collectors.toMap(e -> e, fields::indexOf));
|
||||
if (REQUIRED_STYLE_FIELDS.stream().anyMatch(s -> fieldsMapping.get(s) == -1)) {
|
||||
throw new ParseException("Missing required fields : " + content);
|
||||
}
|
||||
return Arrays.stream(split).filter(s -> s.startsWith(STYLE))
|
||||
.map(s -> {
|
||||
final var values = Arrays.stream(s.replace(STYLE, "").split(",")).map(String::trim).filter(w -> !w.isBlank()).toList();
|
||||
final var name = values.get(fontNameIndex);
|
||||
final var size = Integer.parseInt(values.get(fontSizeIndex));
|
||||
return new FontImpl(name, size);
|
||||
}).collect(Collectors.toMap(this::getName, f -> f));
|
||||
final var name = values.get(fieldsMapping.get(NAME_FIELD));
|
||||
final var fontName = values.get(fieldsMapping.get(FONTNAME_FIELD));
|
||||
final var fontSize = Integer.parseInt(values.get(fieldsMapping.get(FONTSIZE_FIELD)));
|
||||
return new NamedFont(name, new FontImpl(fontName, fontSize));
|
||||
}).collect(Collectors.toMap(f -> f.name, f -> f.font));
|
||||
}
|
||||
}
|
||||
|
||||
private record NamedFont(String name, Font font) {
|
||||
}
|
||||
|
||||
private static List<String> getFields(final String string) {
|
||||
return Arrays.stream(string.replace(FORMAT, "").split(",")).map(String::trim).filter(s -> !s.isBlank()).toList();
|
||||
}
|
||||
@@ -196,6 +266,16 @@ public class ASSSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
|
||||
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
|
||||
public String formatName() {
|
||||
return "ass";
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
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.SubtitleCollection;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.FormatOptions;
|
||||
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.impl.SubtitleCollectionImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl;
|
||||
@@ -12,25 +13,28 @@ import com.github.gtache.autosubtitle.translation.Translator;
|
||||
import javax.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Converts subtitles to SRT format
|
||||
*/
|
||||
public class SRTSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
|
||||
|
||||
private final Translator<?> translator;
|
||||
private static final Pattern ARROW_PATTERN = Pattern.compile(" --> ");
|
||||
private static final Pattern DOUBLE_NEWLINE_PATTERN = Pattern.compile("\n\n");
|
||||
|
||||
private final Map<String, Translator<?>> translators;
|
||||
|
||||
@Inject
|
||||
SRTSubtitleConverter(final Translator translator) {
|
||||
this.translator = requireNonNull(translator);
|
||||
SRTSubtitleConverter(final Map<String, Translator<?>> translators) {
|
||||
this.translators = Map.copyOf(translators);
|
||||
}
|
||||
|
||||
@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();
|
||||
return IntStream.range(0, subtitles.size()).mapToObj(i -> {
|
||||
final var subtitle = subtitles.get(i);
|
||||
@@ -40,24 +44,14 @@ public class SRTSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
|
||||
}).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
|
||||
public SubtitleCollectionImpl<SubtitleImpl> parse(final String content) throws ParseException {
|
||||
public SubtitleCollectionImpl<SubtitleImpl> parse(final String content, final ParseOptions options) throws ParseException {
|
||||
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 lines = element.split("\n");
|
||||
final var time = lines[1];
|
||||
final var timeSplit = time.split(" --> ");
|
||||
final var timeSplit = ARROW_PATTERN.split(time);
|
||||
final var startTimeStr = timeSplit[0];
|
||||
final var endTimeStr = timeSplit[1];
|
||||
final var start = parseTime(startTimeStr);
|
||||
@@ -66,7 +60,7 @@ public class SRTSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
|
||||
return new SubtitleImpl(text, start, end, null, null);
|
||||
}).toList();
|
||||
final var text = subtitles.stream().map(Subtitle::content).collect(Collectors.joining(" "));
|
||||
return new SubtitleCollectionImpl<>(text, subtitles, translator.getLanguage(text));
|
||||
return new SubtitleCollectionImpl<>(text, subtitles, translators.values().iterator().next().getLanguage(text)); //Use any translator for now
|
||||
} catch (final Exception e) {
|
||||
throw new ParseException(e);
|
||||
}
|
||||
@@ -82,6 +76,16 @@ public class SRTSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
|
||||
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
|
||||
public String formatName() {
|
||||
return "srt";
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.github.gtache.autosubtitle.subtitle.converter.json.impl;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.gtache.autosubtitle.subtitle.Subtitle;
|
||||
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.ParseException;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.ParseOptions;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleCollectionImpl;
|
||||
import com.github.gtache.autosubtitle.subtitle.impl.SubtitleImpl;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* {@link SubtitleConverter} implementation for JSON files
|
||||
*/
|
||||
@Singleton
|
||||
public class JSONSubtitleConverter implements SubtitleConverter<SubtitleImpl> {
|
||||
|
||||
private final ObjectMapper mapper;
|
||||
|
||||
@Inject
|
||||
JSONSubtitleConverter(final ObjectMapper mapper) {
|
||||
this.mapper = Objects.requireNonNull(mapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String format(final SubtitleCollection<?> collection, final FormatOptions options) throws FormatException {
|
||||
final var segments = collection.subtitles().stream().map(s -> new JSONSubtitleSegment(s.start(),
|
||||
s.end(), s.content())).toList();
|
||||
final var subtitles = new JSONSubtitles(segments, collection.language());
|
||||
try {
|
||||
return mapper.writeValueAsString(subtitles);
|
||||
} catch (final JsonProcessingException e) {
|
||||
throw new FormatException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubtitleCollectionImpl<SubtitleImpl> parse(final String content, final ParseOptions options) throws ParseException {
|
||||
try {
|
||||
final var json = mapper.readValue(content, JSONSubtitles.class);
|
||||
final var subtitles = json.segments().stream().flatMap(s -> {
|
||||
final var start = s.start();
|
||||
final var end = s.end();
|
||||
return Stream.of(new SubtitleImpl(s.text(), start, end, null, null));
|
||||
}).sorted(Comparator.comparing(Subtitle::start).thenComparing(Subtitle::end)).toList();
|
||||
final var language = json.language();
|
||||
final var subtitlesText = subtitles.stream().map(s -> s.content().trim()).collect(Collectors.joining(" "));
|
||||
return new SubtitleCollectionImpl<>(subtitlesText, subtitles, language);
|
||||
} catch (final Exception e) {
|
||||
throw new ParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canParse(final Path file) {
|
||||
return file.getFileName().toString().endsWith(".json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatName() {
|
||||
return "json";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.github.gtache.autosubtitle.subtitle.converter.json.impl;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* A subtitle segment as a JSON
|
||||
*
|
||||
* @param start The start in milliseconds
|
||||
* @param end The end in milliseconds
|
||||
* @param text The text
|
||||
*/
|
||||
public record JSONSubtitleSegment(long start, long end, String text) {
|
||||
|
||||
public JSONSubtitleSegment {
|
||||
if (start < 0) {
|
||||
throw new IllegalArgumentException("start must be >= 0 : " + start);
|
||||
}
|
||||
if (end < 0) {
|
||||
throw new IllegalArgumentException("end must be >= 0 : " + end);
|
||||
}
|
||||
if (start > end) {
|
||||
throw new IllegalArgumentException("start must be <= end : " + start + " > " + end);
|
||||
}
|
||||
requireNonNull(text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.github.gtache.autosubtitle.subtitle.converter.json.impl;
|
||||
|
||||
import com.github.gtache.autosubtitle.Language;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* Root json object for subtitles
|
||||
*
|
||||
* @param segments The list of subtitle segments
|
||||
* @param language The subtitles language
|
||||
*/
|
||||
public record JSONSubtitles(List<JSONSubtitleSegment> segments, Language language) {
|
||||
|
||||
public JSONSubtitles {
|
||||
segments = List.copyOf(segments);
|
||||
requireNonNull(language);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.gtache.autosubtitle.subtitle.extractor.impl;
|
||||
|
||||
import com.github.gtache.autosubtitle.subtitle.Subtitle;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.ExtractEvent;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractor;
|
||||
import com.github.gtache.autosubtitle.subtitle.extractor.SubtitleExtractorListener;
|
||||
@@ -10,7 +11,7 @@ import java.util.Set;
|
||||
/**
|
||||
* Base implementation of {@link SubtitleExtractor}
|
||||
*/
|
||||
public abstract class AbstractSubtitleExtractor implements SubtitleExtractor {
|
||||
public abstract class AbstractSubtitleExtractor<T extends Subtitle> implements SubtitleExtractor<T> {
|
||||
|
||||
private final Set<SubtitleExtractorListener> listeners;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import com.github.gtache.autosubtitle.subtitle.SubtitleCollection;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@@ -17,7 +16,7 @@ public record SubtitleCollectionImpl<T extends Subtitle>(String text, Collection
|
||||
Language language) implements SubtitleCollection<T> {
|
||||
|
||||
public SubtitleCollectionImpl {
|
||||
Objects.requireNonNull(text);
|
||||
requireNonNull(text);
|
||||
subtitles = List.copyOf(subtitles);
|
||||
requireNonNull(language);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
package com.github.gtache.autosubtitle.subtitle.impl;
|
||||
|
||||
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.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.SubtitleImporterExporter;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.FormatException;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.ParseException;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverter;
|
||||
import com.github.gtache.autosubtitle.subtitle.converter.SubtitleConverterProvider;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@@ -40,19 +44,19 @@ public class SubtitleImporterExporterImpl implements SubtitleImporterExporter<Su
|
||||
}
|
||||
|
||||
@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 extension = fileName.substring(fileName.lastIndexOf('.') + 1);
|
||||
if (archiverProvider.getArchiver(extension) == null) {
|
||||
final var loaded = loadSingleFile(file);
|
||||
final var loaded = loadSingleFile(file, options);
|
||||
logger.info("Loaded {}", file);
|
||||
return Map.of(loaded.language(), loaded);
|
||||
} 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 extension = fileName.substring(fileName.lastIndexOf('.') + 1);
|
||||
final var archiver = archiverProvider.getArchiver(extension);
|
||||
@@ -64,7 +68,7 @@ public class SubtitleImporterExporterImpl implements SubtitleImporterExporter<Su
|
||||
}
|
||||
final var map = new EnumMap<Language, SubtitleCollection<SubtitleImpl>>(Language.class);
|
||||
for (final var path : files) {
|
||||
final var loaded = loadSingleFile(path);
|
||||
final var loaded = loadSingleFile(path, options);
|
||||
map.put(loaded.language(), loaded);
|
||||
Files.deleteIfExists(path);
|
||||
}
|
||||
@@ -73,39 +77,39 @@ public class SubtitleImporterExporterImpl implements SubtitleImporterExporter<Su
|
||||
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 extension = fileName.substring(fileName.lastIndexOf('.') + 1);
|
||||
final var parser = converterProvider.getConverter(extension);
|
||||
if (parser == null) {
|
||||
throw new ParseException("No converter found for " + file);
|
||||
} 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());
|
||||
}
|
||||
}
|
||||
|
||||
@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 extension = fileName.substring(fileName.lastIndexOf('.') + 1);
|
||||
if (archiverProvider.getArchiver(extension) != null) {
|
||||
saveArchive(file, collections, videoInfo);
|
||||
saveArchive(file, collections, options);
|
||||
} else if (collections.size() == 1) {
|
||||
saveSingleFile(file, collections.iterator().next(), videoInfo);
|
||||
saveSingleFile(file, collections.iterator().next(), options);
|
||||
} else {
|
||||
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 extension = fileName.substring(fileName.lastIndexOf('.') + 1);
|
||||
final var archiver = archiverProvider.getArchiver(extension);
|
||||
final var tempDir = Files.createTempDirectory("autosubtitle");
|
||||
for (final var collection : collections) {
|
||||
final var subtitleFile = tempDir.resolve(collection.language().name().toLowerCase() + ".json");
|
||||
saveSingleFile(subtitleFile, collection, videoInfo);
|
||||
saveSingleFile(subtitleFile, collection, options);
|
||||
}
|
||||
final var files = new ArrayList<Path>();
|
||||
try (final var stream = Files.list(tempDir)) {
|
||||
@@ -119,16 +123,20 @@ public class SubtitleImporterExporterImpl implements SubtitleImporterExporter<Su
|
||||
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 extension = fileName.substring(fileName.lastIndexOf('.') + 1);
|
||||
final var converter = converterProvider.getConverter(extension);
|
||||
if (converter == null) {
|
||||
throw new IOException("No converter found for " + file);
|
||||
} else {
|
||||
final var string = converter.format(collection, videoInfo);
|
||||
try {
|
||||
final var string = converter.format(collection, options.formatOptions());
|
||||
Files.writeString(file, string);
|
||||
logger.info("Saved {}", file);
|
||||
} catch (final FormatException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,18 +6,22 @@ module com.github.gtache.autosubtitle.core {
|
||||
requires transitive dagger;
|
||||
requires transitive java.net.http;
|
||||
requires transitive javax.inject;
|
||||
requires transitive java.prefs;
|
||||
requires transitive com.fasterxml.jackson.databind;
|
||||
requires org.apache.logging.log4j;
|
||||
requires java.prefs;
|
||||
|
||||
exports com.github.gtache.autosubtitle.impl;
|
||||
exports com.github.gtache.autosubtitle.archive.impl;
|
||||
exports com.github.gtache.autosubtitle.process.impl;
|
||||
exports com.github.gtache.autosubtitle.setup.impl;
|
||||
exports com.github.gtache.autosubtitle.subtitle.impl;
|
||||
exports com.github.gtache.autosubtitle.subtitle.converter.impl;
|
||||
exports com.github.gtache.autosubtitle.subtitle.converter.json.impl;
|
||||
exports com.github.gtache.autosubtitle.subtitle.extractor.impl;
|
||||
|
||||
exports com.github.gtache.autosubtitle.modules.impl;
|
||||
exports com.github.gtache.autosubtitle.modules.setup.impl;
|
||||
exports com.github.gtache.autosubtitle.subtitle.extractor.impl;
|
||||
exports com.github.gtache.autosubtitle.subtitle.converter.impl;
|
||||
exports com.github.gtache.autosubtitle.modules.subtitle.impl;
|
||||
exports com.github.gtache.autosubtitle.modules.subtitle.converter.impl;
|
||||
exports com.github.gtache.autosubtitle.modules.subtitle.converter.json.impl;
|
||||
}
|
||||
@@ -2,12 +2,12 @@ package com.github.gtache.autosubtitle.archive.impl;
|
||||
|
||||
import com.github.gtache.autosubtitle.archive.Archiver;
|
||||
import com.github.gtache.autosubtitle.archive.ArchiverProvider;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
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.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -22,16 +22,20 @@ class TestArchiverProviderImpl {
|
||||
private final ArchiverProvider archiverProvider;
|
||||
|
||||
TestArchiverProviderImpl(@Mock final Archiver zipArchiver, @Mock final Archiver rarArchiver) {
|
||||
when(zipArchiver.archiveExtension()).thenReturn("zip");
|
||||
when(rarArchiver.archiveExtension()).thenReturn("rar");
|
||||
this.zipArchiver = Objects.requireNonNull(zipArchiver);
|
||||
this.rarArchiver = Objects.requireNonNull(rarArchiver);
|
||||
this.archiverProvider = new ArchiverProviderImpl(Map.of("zip", zipArchiver, "rar", rarArchiver));
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void beforeEach() {
|
||||
when(zipArchiver.archiveExtension()).thenReturn("zip");
|
||||
when(rarArchiver.archiveExtension()).thenReturn("rar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAllArchivers() {
|
||||
final Collection<Archiver> allArchivers = archiverProvider.allArchivers();
|
||||
final var allArchivers = archiverProvider.allArchivers();
|
||||
assertEquals(2, allArchivers.size());
|
||||
assertTrue(allArchivers.contains(zipArchiver));
|
||||
assertTrue(allArchivers.contains(rarArchiver));
|
||||
|
||||
@@ -11,34 +11,39 @@ import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class TestZipDecompresser {
|
||||
class TestZipArchiver {
|
||||
|
||||
private final ZipDecompresser zipDecompresser;
|
||||
private final ZipArchiver zipArchiver;
|
||||
|
||||
TestZipDecompresser() {
|
||||
this.zipDecompresser = new ZipDecompresser();
|
||||
TestZipArchiver() {
|
||||
this.zipArchiver = new ZipArchiver();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsPathSupported() {
|
||||
assertTrue(zipDecompresser.isPathSupported(Path.of("test.zip")));
|
||||
assertFalse(zipDecompresser.isPathSupported(Path.of("test")));
|
||||
assertFalse(zipDecompresser.isPathSupported(Path.of("test.txt")));
|
||||
assertFalse(zipDecompresser.isPathSupported(Path.of("test.zip2")));
|
||||
assertTrue(zipArchiver.isPathSupported(Path.of("test.zip")));
|
||||
assertFalse(zipArchiver.isPathSupported(Path.of("test")));
|
||||
assertFalse(zipArchiver.isPathSupported(Path.of("test.txt")));
|
||||
assertFalse(zipArchiver.isPathSupported(Path.of("test.zip2")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCompress() {
|
||||
assertThrows(UnsupportedOperationException.class, () -> zipDecompresser.compress(List.of(Paths.get("file.txt")), Paths.get("target")));
|
||||
final var paths = List.of(Paths.get("file.txt"));
|
||||
final var target = Paths.get("target");
|
||||
assertThrows(UnsupportedOperationException.class, () -> zipArchiver.compress(paths, target));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDecompress(@TempDir final Path tempDir) throws IOException {
|
||||
final var file = tempDir.resolve("test.zip");
|
||||
try (final var in = getClass().getResourceAsStream("in.zip")) {
|
||||
if (in == null) {
|
||||
throw new IOException("in.zip not found");
|
||||
}
|
||||
Files.copy(in, file);
|
||||
}
|
||||
zipDecompresser.decompress(file, tempDir);
|
||||
zipArchiver.decompress(file, tempDir);
|
||||
final var inTxt = tempDir.resolve("in.txt");
|
||||
final var bin = tempDir.resolve("bin");
|
||||
final var binTxt = bin.resolve("bin.txt");
|
||||
@@ -57,6 +62,8 @@ class TestZipDecompresser {
|
||||
|
||||
@Test
|
||||
void testIllegal() {
|
||||
assertThrows(IllegalArgumentException.class, () -> zipDecompresser.decompress(Paths.get("file.txt"), Paths.get("target")));
|
||||
final var source = Paths.get("source");
|
||||
final var target = Paths.get("target");
|
||||
assertThrows(IllegalArgumentException.class, () -> zipArchiver.decompress(source, target));
|
||||
}
|
||||
}
|
||||
@@ -26,25 +26,25 @@ class TestArchitecture {
|
||||
|
||||
@Test
|
||||
void testGetArchitecture() {
|
||||
for (final var value : Architecture.values()) {
|
||||
for (final var value : values()) {
|
||||
System.setProperty("os.arch", value.name());
|
||||
assertEquals(value, Architecture.getArchitecture());
|
||||
assertEquals(value, getArchitecture());
|
||||
}
|
||||
System.setProperty("os.arch", "any");
|
||||
assertEquals(UNKNOWN, Architecture.getArchitecture());
|
||||
assertEquals(UNKNOWN, getArchitecture());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetArchitectureName() {
|
||||
assertEquals(I386, Architecture.getArchitecture("i386"));
|
||||
assertEquals(I386, Architecture.getArchitecture("I386"));
|
||||
assertEquals(I386, getArchitecture("i386"));
|
||||
assertEquals(I386, getArchitecture("I386"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIsAMD64() {
|
||||
final var expectedAMD64 = Set.of(X86, X86_64, AMD64);
|
||||
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()));
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class TestArchitecture {
|
||||
void testIsARM64() {
|
||||
final var expectedARM64 = Set.of(ARM64, ARMV8, ARMV9, AARCH64);
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@ class TestAudioInfoImpl {
|
||||
private final long duration;
|
||||
|
||||
TestAudioInfoImpl() {
|
||||
this.audioFormat = "audioFormat";
|
||||
this.audioFormat = "format";
|
||||
this.duration = 1000L;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetters() {
|
||||
final var audioInfo = new AudioInfoImpl(audioFormat, duration);
|
||||
assertEquals(audioFormat, audioInfo.audioFormat());
|
||||
assertEquals(audioFormat, audioInfo.format());
|
||||
assertEquals(duration, audioInfo.duration());
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class TestFileAudioImpl {
|
||||
private final Path path;
|
||||
private final AudioInfo info;
|
||||
|
||||
TestFileAudioImpl(@Mock final Path path, @Mock final AudioInfo info) throws IOException {
|
||||
TestFileAudioImpl(@Mock final Path path, @Mock final AudioInfo info) {
|
||||
this.path = requireNonNull(path);
|
||||
this.info = requireNonNull(info);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class TestMemoryAudioImpl {
|
||||
private final Supplier<InputStream> supplier;
|
||||
private final AudioInfo info;
|
||||
|
||||
TestMemoryAudioImpl(@Mock InputStream inputStream, @Mock AudioInfo info) {
|
||||
TestMemoryAudioImpl(@Mock final InputStream inputStream, @Mock final AudioInfo info) {
|
||||
this.supplier = () -> requireNonNull(inputStream);
|
||||
this.info = requireNonNull(info);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class TestMemoryVideoImpl {
|
||||
private final Supplier<InputStream> supplier;
|
||||
private final VideoInfo info;
|
||||
|
||||
TestMemoryVideoImpl(@Mock InputStream inputStream, @Mock VideoInfo info) {
|
||||
TestMemoryVideoImpl(@Mock final InputStream inputStream, @Mock final VideoInfo info) {
|
||||
this.supplier = () -> requireNonNull(inputStream);
|
||||
this.info = requireNonNull(info);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user