diff --git a/common/src/main/antlr4/ctbrec/variableexpansion/antlr/PostProcessing.g4 b/common/src/main/antlr4/ctbrec/variableexpansion/antlr/PostProcessing.g4 index ed95603b..ca25c780 100644 --- a/common/src/main/antlr4/ctbrec/variableexpansion/antlr/PostProcessing.g4 +++ b/common/src/main/antlr4/ctbrec/variableexpansion/antlr/PostProcessing.g4 @@ -7,9 +7,7 @@ functionCall: '$' identifier '(' (expression (',' expression)*)? ')'; text: CH+?; identifier: CH+?; -parameter: text; - -variable: '${' identifier ('(' parameter ')')? ('?' expression)? '}'; +variable: '${' identifier '}'; expression : text diff --git a/common/src/main/java/ctbrec/Settings.java b/common/src/main/java/ctbrec/Settings.java index 5b28e39f..6e8503c4 100644 --- a/common/src/main/java/ctbrec/Settings.java +++ b/common/src/main/java/ctbrec/Settings.java @@ -66,7 +66,7 @@ public class Settings { public int defaultPriority = 50; public boolean determineResolution = false; public List disabledSites = new ArrayList<>(); - public String downloadFilename = "${modelSanitizedName}-${localDateTime}"; + public String downloadFilename = "${modelSanitizedName}-$format(${localDateTime})"; public List eventHandlers = new ArrayList<>(); public boolean eventsSuspended = false; public boolean fastScrollSpeed = true; diff --git a/common/src/main/java/ctbrec/recorder/postprocessing/Move.java b/common/src/main/java/ctbrec/recorder/postprocessing/Move.java index 1633400a..c8f6b6c4 100644 --- a/common/src/main/java/ctbrec/recorder/postprocessing/Move.java +++ b/common/src/main/java/ctbrec/recorder/postprocessing/Move.java @@ -1,22 +1,22 @@ package ctbrec.recorder.postprocessing; -import static ctbrec.io.IoUtils.*; + +import ctbrec.Recording; +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.Objects; -import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ctbrec.Recording; +import static ctbrec.io.IoUtils.deleteEmptyParents; public class Move extends AbstractPlaceholderAwarePostProcessor { private static final Logger LOG = LoggerFactory.getLogger(Move.class); public static final String PATH_TEMPLATE = "path.template"; - public static final String DEFAULT = "${modelSanitizedName}" + File.separatorChar + "${localDateTime}"; + public static final String DEFAULT = "${modelSanitizedName}" + File.separatorChar + "$format(${localDateTime})"; @Override public String getName() { diff --git a/common/src/main/java/ctbrec/recorder/postprocessing/Rename.java b/common/src/main/java/ctbrec/recorder/postprocessing/Rename.java index 298e3653..a9a2bd82 100644 --- a/common/src/main/java/ctbrec/recorder/postprocessing/Rename.java +++ b/common/src/main/java/ctbrec/recorder/postprocessing/Rename.java @@ -1,20 +1,20 @@ package ctbrec.recorder.postprocessing; + +import ctbrec.Recording; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.Objects; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import ctbrec.Recording; - public class Rename extends AbstractPlaceholderAwarePostProcessor { private static final Logger LOG = LoggerFactory.getLogger(Rename.class); public static final String FILE_NAME_TEMPLATE = "filename.template"; - public static final String DEFAULT = "${modelSanitizedName}_${localDateTime}.${fileSuffix}"; - public static final String DEFAULT_DIR = "${modelSanitizedName}_${localDateTime}"; + public static final String DEFAULT = "${modelSanitizedName}_$format(${localDateTime}).${fileSuffix}"; + public static final String DEFAULT_DIR = "${modelSanitizedName}_$format(${localDateTime})"; @Override public String getName() { diff --git a/common/src/main/java/ctbrec/variableexpansion/ParserVisitor.java b/common/src/main/java/ctbrec/variableexpansion/ParserVisitor.java index 9939e830..b77eed7a 100644 --- a/common/src/main/java/ctbrec/variableexpansion/ParserVisitor.java +++ b/common/src/main/java/ctbrec/variableexpansion/ParserVisitor.java @@ -22,6 +22,7 @@ public class ParserVisitor extends PostProcessingBaseVisitor { functions.put("format", new Format()); functions.put("capitalize", new Capitalize()); functions.put("sanitize", new Sanitize()); + functions.put("orElse", new OrElse()); } @Override @@ -44,11 +45,7 @@ public class ParserVisitor extends PostProcessingBaseVisitor { if (value != null && value.isPresent()) { // NOSONAR return value.get().toString(); } else { - if (ctx.expression() != null) { - return visitExpression(ctx.expression()); - } else { - return ""; - } + return ""; } } diff --git a/common/src/main/java/ctbrec/variableexpansion/functions/Format.java b/common/src/main/java/ctbrec/variableexpansion/functions/Format.java index b0c6ae88..20839d23 100644 --- a/common/src/main/java/ctbrec/variableexpansion/functions/Format.java +++ b/common/src/main/java/ctbrec/variableexpansion/functions/Format.java @@ -4,6 +4,7 @@ import ctbrec.variableexpansion.VarArgsFunction; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.Optional; public class Format implements VarArgsFunction { @@ -16,7 +17,11 @@ public class Format implements VarArgsFunction { } ZonedDateTime zdt; if (p[0] instanceof String date) { - zdt = ZonedDateTime.parse(date); + try { + zdt = ZonedDateTime.parse(date); + } catch (DateTimeParseException e) { + return ""; + } } else { zdt = (ZonedDateTime) p[0]; } diff --git a/common/src/main/java/ctbrec/variableexpansion/functions/OrElse.java b/common/src/main/java/ctbrec/variableexpansion/functions/OrElse.java new file mode 100644 index 00000000..5fa0e4b5 --- /dev/null +++ b/common/src/main/java/ctbrec/variableexpansion/functions/OrElse.java @@ -0,0 +1,22 @@ +package ctbrec.variableexpansion.functions; + +import ctbrec.StringUtil; +import ctbrec.variableexpansion.VarArgsFunction; + +import java.util.Optional; + +public class OrElse implements VarArgsFunction { + @Override + public String apply(Object... params) { + if (params.length < 2) { + throw new IllegalArgumentException("OrElse needs two parameters"); + } + + Optional result = Optional.ofNullable(params[0]).map(String::valueOf); + if (result.isPresent() && StringUtil.isNotBlank(result.get())) { + return result.get(); + } else { + return String.valueOf(params[1]); + } + } +} diff --git a/common/src/test/java/ctbrec/recorder/postprocessing/AbstractPlaceholderAwarePostProcessorTest.java b/common/src/test/java/ctbrec/recorder/postprocessing/AbstractPlaceholderAwarePostProcessorTest.java index b3336321..46c9a153 100644 --- a/common/src/test/java/ctbrec/recorder/postprocessing/AbstractPlaceholderAwarePostProcessorTest.java +++ b/common/src/test/java/ctbrec/recorder/postprocessing/AbstractPlaceholderAwarePostProcessorTest.java @@ -137,20 +137,20 @@ class AbstractPlaceholderAwarePostProcessorTest extends AbstractPpTest { @Test void testPlaceholderDefaultValues() { - String input = "asdf_${modelGroupName?${modelSanitizedName?anonymous}}_asdf"; + String input = "asdf_$orElse(${modelGroupName},$orElse(${modelSanitizedName},anonymous))_asdf"; PostProcessingContext ctx = createPostProcessingContext(rec, null, config); ctx.getRecording().getModel().setName(null); assertEquals("asdf_anonymous_asdf", placeHolderAwarePp.fillInPlaceHolders(input, ctx)); - input = "asdf_${modelGroupName?$format(${utcDateTime},yyyy)}_asdf"; + input = "asdf_$orElse(${modelGroupName},$format(${utcDateTime},yyyy))_asdf"; int year = LocalDate.now().getYear(); assertEquals("asdf_" + year + "_asdf", placeHolderAwarePp.fillInPlaceHolders(input, ctx)); ctx.getRecording().setStartDate(null); - input = "asdf_${modelGroupName?${utcDateTime(yyyy)?anonymous}}_asdf"; + input = "asdf_$orElse(${modelGroupName},$orElse($format(${utcDateTime},yyyy),anonymous))_asdf"; assertEquals("asdf_anonymous_asdf", placeHolderAwarePp.fillInPlaceHolders(input, ctx)); - input = "asdf_${modelGroupName?${utcDateTime?anonymous}}_asdf"; + input = "asdf_$orElse(${modelGroupName},$orElse($format(${utcDateTime}),anonymous))_asdf"; assertEquals("asdf_anonymous_asdf", placeHolderAwarePp.fillInPlaceHolders(input, ctx)); } @@ -166,7 +166,7 @@ class AbstractPlaceholderAwarePostProcessorTest extends AbstractPpTest { String input = "$upper(${modelName})"; assertEquals("MOCKITA BOOBILICIOUS", placeHolderAwarePp.fillInPlaceHolders(input, createPostProcessingContext(rec, null, config))); - input = "$upper(${doesNotExist?mockita boobilicious})"; + input = "$upper($orElse(${doesNotExist},mockita boobilicious))"; assertEquals("MOCKITA BOOBILICIOUS", placeHolderAwarePp.fillInPlaceHolders(input, createPostProcessingContext(rec, null, config))); } } diff --git a/common/src/test/java/ctbrec/recorder/postprocessing/AbstractPpTest.java b/common/src/test/java/ctbrec/recorder/postprocessing/AbstractPpTest.java index 9f29abfc..36bc9462 100644 --- a/common/src/test/java/ctbrec/recorder/postprocessing/AbstractPpTest.java +++ b/common/src/test/java/ctbrec/recorder/postprocessing/AbstractPpTest.java @@ -1,21 +1,5 @@ package ctbrec.recorder.postprocessing; -import static java.nio.charset.StandardCharsets.*; -import static java.nio.file.StandardOpenOption.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.Instant; - -import org.apache.commons.io.FileUtils; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.mockito.MockedStatic; - import ctbrec.Config; import ctbrec.Model; import ctbrec.Recording; @@ -24,6 +8,20 @@ import ctbrec.recorder.Recorder; import ctbrec.recorder.RecordingManager; import ctbrec.sites.Site; import ctbrec.sites.chaturbate.Chaturbate; +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.mockito.MockedStatic; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; + +import static java.nio.file.StandardOpenOption.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; public abstract class AbstractPpTest { Path baseDir; @@ -46,8 +44,8 @@ public abstract class AbstractPpTest { originalDir = new File(recDir.toFile(), "original"); postProcessedDir = new File(recDir.toFile(), "postProcessed"); Files.createDirectories(original.getParentFile().toPath()); - Files.write(original.toPath(), "foobar".getBytes(UTF_8), CREATE_NEW, WRITE, TRUNCATE_EXISTING); - Files.write(postProcessed.toPath(), "foobar".getBytes(UTF_8), CREATE_NEW, WRITE, TRUNCATE_EXISTING); + Files.writeString(original.toPath(), "foobar", CREATE_NEW, WRITE, TRUNCATE_EXISTING); + Files.writeString(postProcessed.toPath(), "foobar", CREATE_NEW, WRITE, TRUNCATE_EXISTING); Files.createDirectories(originalDir.toPath()); FileUtils.touch(new File(originalDir, "playlist.m3u8")); } diff --git a/common/src/test/java/ctbrec/recorder/postprocessing/RenameSingleFileTest.java b/common/src/test/java/ctbrec/recorder/postprocessing/RenameSingleFileTest.java index b2bc4708..42943ed4 100644 --- a/common/src/test/java/ctbrec/recorder/postprocessing/RenameSingleFileTest.java +++ b/common/src/test/java/ctbrec/recorder/postprocessing/RenameSingleFileTest.java @@ -1,18 +1,17 @@ package ctbrec.recorder.postprocessing; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; +import ctbrec.Config; +import ctbrec.Model; +import ctbrec.Recording; +import org.junit.jupiter.api.Test; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.junit.jupiter.api.Test; - -import ctbrec.Config; -import ctbrec.Model; -import ctbrec.Recording; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; class RenameSingleFileTest extends AbstractPpTest { @@ -68,6 +67,6 @@ class RenameSingleFileTest extends AbstractPpTest { assertEquals("rename", pp.toString()); pp.getConfig().put(Rename.FILE_NAME_TEMPLATE, Rename.DEFAULT); - assertEquals("rename [${modelSanitizedName}_${localDateTime}.${fileSuffix}]", pp.toString()); + assertEquals("rename [" + Rename.DEFAULT + "]", pp.toString()); } }