From 417c5f140cb38374ef2dba4af71dca85cb8198fd Mon Sep 17 00:00:00 2001 From: patsh Date: Wed, 6 Jul 2022 14:53:32 +0200 Subject: [PATCH 1/2] Add support for multiple tags in chapter naming feature #415 Add support for naming chapters by using suggested convention, using mix of special tokens and normal strings, like %title% - my book" --- app/path.properties | 8 +- pom.xml | 10 +- .../audiobookconverter/book/Chapter.java | 3 +- .../audiobookconverter/fx/ChapterEditor.java | 44 +++++-- .../fx/StringToContext.java | 121 ++++++++++++++++++ 5 files changed, 166 insertions(+), 20 deletions(-) create mode 100644 src/main/java/uk/yermak/audiobookconverter/fx/StringToContext.java diff --git a/app/path.properties b/app/path.properties index 854320fd..8032e4d2 100644 --- a/app/path.properties +++ b/app/path.properties @@ -1,5 +1,5 @@ -ffmpeg=external/x64/mac/ffmpeg -ffprobe=external/x64/mac/ffprobe -mp4art=external/x64/mac/mp4art -mp4info=external/x64/mac/mp4info +ffmpeg=external/x64/linux/ffmpeg +ffprobe=external/x64/linux/ffprobe +mp4art=external/x64/linux/mp4art +mp4info=external/x64/linux/mp4info platform=steam \ No newline at end of file diff --git a/pom.xml b/pom.xml index a1021f6f..f0f5fc2a 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ off 700m on - --enable-preview + 17.0.1 UTF-8 @@ -188,7 +188,7 @@ true true false - ${compiler.args.main} + @@ -196,9 +196,9 @@ org.apache.maven.plugins maven-surefire-plugin 2.19.1 - - --enable-preview - + + + diff --git a/src/main/java/uk/yermak/audiobookconverter/book/Chapter.java b/src/main/java/uk/yermak/audiobookconverter/book/Chapter.java index c5684081..00427862 100644 --- a/src/main/java/uk/yermak/audiobookconverter/book/Chapter.java +++ b/src/main/java/uk/yermak/audiobookconverter/book/Chapter.java @@ -4,6 +4,7 @@ import javafx.collections.ObservableList; import org.apache.commons.io.FilenameUtils; import uk.yermak.audiobookconverter.*; +import uk.yermak.audiobookconverter.fx.StringToContext; import java.time.Duration; import java.util.*; @@ -71,7 +72,7 @@ private void initRenderMap() { } if (context.contains("CUSTOM_TITLE")) { this.setCustomTitle(AppSetting.getProperty(AppSetting.CHAPTER_CUSTOM_TITLE, "")); - renderMap.put("CUSTOM_TITLE", chapter -> customTitle); + renderMap.put("CUSTOM_TITLE", StringToContext.getFunction(this.getCustomTitle())); } } diff --git a/src/main/java/uk/yermak/audiobookconverter/fx/ChapterEditor.java b/src/main/java/uk/yermak/audiobookconverter/fx/ChapterEditor.java index 82eb6b3a..10e4a21c 100644 --- a/src/main/java/uk/yermak/audiobookconverter/fx/ChapterEditor.java +++ b/src/main/java/uk/yermak/audiobookconverter/fx/ChapterEditor.java @@ -9,8 +9,8 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import uk.yermak.audiobookconverter.AppSetting; -import uk.yermak.audiobookconverter.book.Chapter; import uk.yermak.audiobookconverter.Utils; +import uk.yermak.audiobookconverter.book.Chapter; import java.util.HashMap; import java.util.List; @@ -158,10 +158,27 @@ void editChapter() { // } else if (context.containsKey("CUSTOM_TITLE")) { // customTitle.setText(AppSetting.getProperty(AppSetting.CHAPTER_CUSTOM_TITLE, "")); // } +// StringToContext stringToContext = new StringToContext(); + String formattingStringExplanation = "Special tokens\n" + + "%BOOK_NUMBER%\n" + + "%comment-0%\n" + + "%year%\n" + + "%genre%\n" + + "%album%\n" + + "%album_artist%\n" + + "%title%\n" + + "%BOOK_TITLE%\n" + + "%DURATION%\n" + + "%file_name%\n" + + "%CHAPTER_TEXT%\n" + + "%CHAPTER_NUMBER%\n"; + customTitle.setTooltip(new Tooltip(formattingStringExplanation)); + customTitle.textProperty().addListener((observable, oldValue, newValue) -> { // chapter.setCustomTitle(newValue); if (StringUtils.trimToNull(newValue) != null) { - context.put("CUSTOM_TITLE", c -> newValue); + StringToContext.updateContextUsingPrintf(context,newValue); +// context.put("CUSTOM_TITLE", c -> newValue); } else{ context.remove("CUSTOM_TITLE"); } @@ -194,13 +211,14 @@ void editChapter() { Optional result = dialog.showAndWait(); + if (result.isPresent() && result.get() == ButtonType.OK) { chapter.getRenderMap().clear(); chapter.getRenderMap().putAll(context); - chapter.setCustomTitle(StringUtils.trimToEmpty(customTitle.getText())); - if (StringUtils.isNotEmpty(customTitle.getText())) { - chapter.getRenderMap().put("CUSTOM_TITLE", Chapter::getCustomTitle); - } +// chapter.setCustomTitle(StringUtils.trimToEmpty(customTitle.getText())); +// if (StringUtils.isNotEmpty(customTitle.getText())) { +// chapter.getRenderMap().put("CUSTOM_TITLE", Chapter::getCustomTitle); +// } if (applyForAllChapters.isSelected() || saveAsDefault.isSelected()) { applyForAllChapters(context, customTitle); } @@ -209,7 +227,13 @@ void editChapter() { AppSetting.setProperty(AppSetting.CHAPTER_CONTEXT, defaultChapterContext); AppSetting.setProperty(AppSetting.CHAPTER_CUSTOM_TITLE, StringUtils.trimToNull(customTitle.getText())); } + + String t = AppSetting.getProperty(AppSetting.CHAPTER_CUSTOM_TITLE,"default"); + if(t.length()>1) + StringToContext.updateContextUsingPrintf(context, t); } + + } private void applyForAllChapters(Map> context, TextField customTitle) { @@ -217,10 +241,10 @@ private void applyForAllChapters(Map> context, for (Chapter c : chapters) { c.getRenderMap().clear(); c.getRenderMap().putAll(context); - if (StringUtils.isNotEmpty(customTitle.getText())) { - c.getRenderMap().put("CUSTOM_TITLE", Chapter::getCustomTitle); - } - c.setCustomTitle(customTitle.getText()); +// if (StringUtils.isNotEmpty(customTitle.getText())) { +// c.getRenderMap().put("CUSTOM_TITLE", Chapter::getCustomTitle); +// } +// c.setCustomTitle(customTitle.getText()); } } } diff --git a/src/main/java/uk/yermak/audiobookconverter/fx/StringToContext.java b/src/main/java/uk/yermak/audiobookconverter/fx/StringToContext.java new file mode 100644 index 00000000..365fb5e0 --- /dev/null +++ b/src/main/java/uk/yermak/audiobookconverter/fx/StringToContext.java @@ -0,0 +1,121 @@ +package uk.yermak.audiobookconverter.fx; + +import org.apache.commons.io.FilenameUtils; +import uk.yermak.audiobookconverter.book.Chapter; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + + +/** + * Util class which function is updating context in {@link ChapterEditor#editChapter()} method, + * so we can use printf like syntax for template naming chapter names. + * + * @author patsh + */ +public class StringToContext { + + /** + * Special tokens used in creating chapter naming template. + */ + public final static Set SPECIAL_TOKENS; + + /** + * Mapping between specials tokens at functions that map chapter object to some string. + */ + public final static Map> SPECIAL_TOKEN_TO_FUNCTION; + + static { + SPECIAL_TOKEN_TO_FUNCTION = new HashMap<>(); + SPECIAL_TOKEN_TO_FUNCTION.put("%BOOK_NUMBER%", + c -> String.valueOf(c.getPart().getBook().getBookInfo().bookNumber())); + SPECIAL_TOKEN_TO_FUNCTION.put("%comment-0%", + chapter -> chapter.getMedia().get(0).getBookInfo().comment()); + SPECIAL_TOKEN_TO_FUNCTION.put("%year%", + chapter -> chapter.getMedia().get(0).getBookInfo().year()); + SPECIAL_TOKEN_TO_FUNCTION.put("%genre%", + chapter -> chapter.getMedia().get(0).getBookInfo().genre()); + SPECIAL_TOKEN_TO_FUNCTION.put("%album%", + chapter -> chapter.getMedia().get(0).getBookInfo().series()); + SPECIAL_TOKEN_TO_FUNCTION.put("%album_artist%", + chapter -> chapter.getMedia().get(0).getBookInfo().narrator()); + SPECIAL_TOKEN_TO_FUNCTION.put("%artist%", + chapter -> chapter.getMedia().get(0).getBookInfo().writer()); + SPECIAL_TOKEN_TO_FUNCTION.put("%title%", + chapter -> chapter.getMedia().get(0).getBookInfo().title()); + SPECIAL_TOKEN_TO_FUNCTION.put("%BOOK_TITLE%", + c -> c.getPart().getBook().getBookInfo().title()); + SPECIAL_TOKEN_TO_FUNCTION.put("%DURATION%", + c -> Duration.ofMillis(c.getDuration())); + SPECIAL_TOKEN_TO_FUNCTION.put("%file_name%", + c -> FilenameUtils.getBaseName(c.getMedia().get(0).getFileName())); + SPECIAL_TOKEN_TO_FUNCTION.put("%CHAPTER_TEXT%", + c -> "Chapter"); + SPECIAL_TOKEN_TO_FUNCTION.put("%CHAPTER_NUMBER%", + c -> c.getNumber()); + + SPECIAL_TOKENS = SPECIAL_TOKEN_TO_FUNCTION.keySet(); + } + + + + public static Map> updateContextUsingPrintf(Map> context, String printf) { + Function exp = getFunction(printf); + + context.put("CUSTOM_TITLE", exp); + return context; + } + + /** + * Main method for generating function from string with special tokens. + *

+ * For example string - "%title% - chapter" will + * construct function that combines function mapped in {@link #SPECIAL_TOKEN_TO_FUNCTION} with string "- chapter". + * And put it in "CUSTOM_TITLE" value in context object. + * + * @param printf String for formatting chapter title. For example - "%title% - chapter" + * @return Function combining functions and strings + */ + + public static Function getFunction(String printf){ + String[] tokens = printf.split(" "); + ArrayList> functions = new ArrayList<>(); + ArrayList values = new ArrayList<>(); + values.add(""); + for (String token : tokens) { + if (SPECIAL_TOKENS.contains(token)) { + functions.add(SPECIAL_TOKEN_TO_FUNCTION.get(token)); + } else { + values.add(token); + } + } + + Function exp = chapter -> { + int n = Math.min(functions.size(), values.size()); + int i = 0; + StringBuilder sb = new StringBuilder(); + while (i < n) { + sb.append(values.get(i)); + sb.append(" "); + sb.append(functions.get(i).apply(chapter)); + sb.append(" "); + i++; + } + + while (i < functions.size()) { + sb.append(functions.get(i).apply(chapter)); + i++; + } + while (i < values.size()) { + sb.append(values.get(i)); + i++; + } + return sb.toString(); + }; + return exp; + } +} From 8148b889f08222e82a29baa031bfc3f0affd5e37 Mon Sep 17 00:00:00 2001 From: patsh Date: Mon, 1 Aug 2022 13:22:57 +0200 Subject: [PATCH 2/2] Restore configuration files to orginal version Without this modifications development on linux is impossible for me. --- app/path.properties | 8 ++++---- pom.xml | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/path.properties b/app/path.properties index 8032e4d2..854320fd 100644 --- a/app/path.properties +++ b/app/path.properties @@ -1,5 +1,5 @@ -ffmpeg=external/x64/linux/ffmpeg -ffprobe=external/x64/linux/ffprobe -mp4art=external/x64/linux/mp4art -mp4info=external/x64/linux/mp4info +ffmpeg=external/x64/mac/ffmpeg +ffprobe=external/x64/mac/ffprobe +mp4art=external/x64/mac/mp4art +mp4info=external/x64/mac/mp4info platform=steam \ No newline at end of file diff --git a/pom.xml b/pom.xml index f0f5fc2a..a1021f6f 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ off 700m on - + --enable-preview 17.0.1 UTF-8 @@ -188,7 +188,7 @@ true true false - + ${compiler.args.main}
@@ -196,9 +196,9 @@ org.apache.maven.plugins maven-surefire-plugin 2.19.1 - - - + + --enable-preview +