From bdcf1bee006e046851a4dcbd8d642542b9b8481b Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Sun, 23 Aug 2020 13:37:59 +0200 Subject: [PATCH] Implement Renamer post-processor --- .../ui/settings/RenamerPaneFactory.java | 24 ++++ .../postprocessing/RecordingRenamer.java | 16 --- .../recorder/postprocessing/Renamer.java | 116 ++++++++++++++++++ 3 files changed, 140 insertions(+), 16 deletions(-) create mode 100644 client/src/main/java/ctbrec/ui/settings/RenamerPaneFactory.java delete mode 100644 common/src/main/java/ctbrec/recorder/postprocessing/RecordingRenamer.java create mode 100644 common/src/main/java/ctbrec/recorder/postprocessing/Renamer.java diff --git a/client/src/main/java/ctbrec/ui/settings/RenamerPaneFactory.java b/client/src/main/java/ctbrec/ui/settings/RenamerPaneFactory.java new file mode 100644 index 00000000..2140b75a --- /dev/null +++ b/client/src/main/java/ctbrec/ui/settings/RenamerPaneFactory.java @@ -0,0 +1,24 @@ +package ctbrec.ui.settings; + +import ctbrec.recorder.postprocessing.PostProcessor; +import ctbrec.recorder.postprocessing.Renamer; +import ctbrec.ui.settings.api.Category; +import ctbrec.ui.settings.api.Preferences; +import ctbrec.ui.settings.api.Setting; +import javafx.beans.property.SimpleStringProperty; + +public class RenamerPaneFactory extends AbstractPostProcessingPaneFactory { + + @Override + public Preferences doCreatePostProcessorPane(PostProcessor pp) { + SimpleStringProperty fileTemplate = new SimpleStringProperty(null, Renamer.FILE_NAME_TEMPLATE, pp.getConfig().getOrDefault(Renamer.FILE_NAME_TEMPLATE, Renamer.DEFAULT)); + properties.add(fileTemplate); + + return Preferences.of(new MapPreferencesStorage(), + Category.of(pp.getName(), + Setting.of("File name", fileTemplate) + ) + ); + } + +} diff --git a/common/src/main/java/ctbrec/recorder/postprocessing/RecordingRenamer.java b/common/src/main/java/ctbrec/recorder/postprocessing/RecordingRenamer.java deleted file mode 100644 index ed771e0d..00000000 --- a/common/src/main/java/ctbrec/recorder/postprocessing/RecordingRenamer.java +++ /dev/null @@ -1,16 +0,0 @@ -package ctbrec.recorder.postprocessing; - -import ctbrec.Recording; - -public class RecordingRenamer extends AbstractPostProcessor { - - @Override - public String getName() { - return "rename"; - } - - @Override - public void postprocess(Recording rec) { - // TODO rename - } -} diff --git a/common/src/main/java/ctbrec/recorder/postprocessing/Renamer.java b/common/src/main/java/ctbrec/recorder/postprocessing/Renamer.java new file mode 100644 index 00000000..af98ad55 --- /dev/null +++ b/common/src/main/java/ctbrec/recorder/postprocessing/Renamer.java @@ -0,0 +1,116 @@ +package ctbrec.recorder.postprocessing; +import static java.util.Optional.*; + +import java.io.File; +import java.io.IOException; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.Files; + +import ctbrec.Recording; + +public class Renamer extends AbstractPostProcessor { + + private static final Logger LOG = LoggerFactory.getLogger(Renamer.class); + public static final String FILE_NAME_TEMPLATE = "filename.template"; + public static final String DEFAULT = "${modelSanitizedName}_${localDateTime}.${fileSuffix}"; + + @SuppressWarnings("unused") + private String[] placeHolders = { + "${modelName}", + "${modelDisplayName}", + "${modelSanitizedName}", + "${siteName}", + "${siteSanitizedName}", + "${utcDateTime}", + "${localDateTime}", + "${epochSeconds}", + "${fileSuffix}", + "${modelNotes}" + }; + + @Override + public String getName() { + return "rename"; + } + + @Override + public void postprocess(Recording rec) throws IOException { + String filenameTemplate = getConfig().getOrDefault(FILE_NAME_TEMPLATE, DEFAULT); + String filename = filenameTemplate + .replace("${modelName}", ofNullable(rec.getModel().getName()).orElse("modelName")) + .replace("${modelDisplayName}", ofNullable(rec.getModel().getDisplayName()).orElse("displayName")) + .replace("${modelSanitizedName}", ofNullable(rec.getModel().getSanitizedNamed()).orElse("sanitizedName")) + .replace("${siteName}", rec.getModel().getSite().getName()) + .replace("${siteSanitizedName}", getSanitizedSiteName(rec)) + .replace("${fileSuffix}", getFileSuffix(rec)) + .replace("${epochSeconds}", Long.toString(rec.getStartDate().getEpochSecond())) + ; + + filename = replaceUtcDateTime(rec, filename); + filename = replaceLocalDateTime(rec, filename); + + File src = rec.getPostProcessedFile(); + File target = new File(src.getParentFile(), filename); + LOG.info("Renaming {} to {}", src.getName(), target.getName()); + Files.copy(rec.getPostProcessedFile(), target); + //Files.move(rec.getPostProcessedFile(), target); + rec.setPostProcessedFile(target); + rec.getAssociatedFiles().add(target.getAbsolutePath()); + } + + private String replaceUtcDateTime(Recording rec, String filename) { + return replaceDateTime(rec, filename, "utcDateTime", ZoneOffset.UTC); + } + + private String replaceLocalDateTime(Recording rec, String filename) { + return replaceDateTime(rec, filename, "localDateTime", ZoneId.systemDefault()); + } + + private String replaceDateTime(Recording rec, String filename, String placeHolder, ZoneId zone) { + String pattern = "yyyy-mm-dd_HH-mm-ss"; + Matcher m = Pattern.compile("\\$\\{" + placeHolder + "(?:\\((.*?)\\))?\\}").matcher(filename); + if (m.find()) { + String p = m.group(1); + if (p != null) { + pattern = p; + } + } + String formattedDate = getDateTime(rec, pattern, zone); + return m.replaceAll(formattedDate); + } + + private String getDateTime(Recording rec, String pattern, ZoneId zone) { + return DateTimeFormatter.ofPattern(pattern) + .withLocale(Locale.getDefault()) + .withZone(zone) + .format(rec.getStartDate()); + } + + private CharSequence getFileSuffix(Recording rec) { + String filename = rec.getPostProcessedFile().getName(); + return filename.substring(filename.lastIndexOf('.') + 1); + } + + + private CharSequence getSanitizedSiteName(Recording rec) { + return rec.getModel().getSite().getName().replace(' ', '_').replace('\\', '_').replace('/', '_'); + } + + @Override + public String toString() { + String s = getName(); + if (getConfig().containsKey(FILE_NAME_TEMPLATE)) { + s += " [" + getConfig().get(FILE_NAME_TEMPLATE) + ']'; + } + return s; + } +}