From f1880790acc61fad2adbd9a9ecc8af89053d4932 Mon Sep 17 00:00:00 2001 From: arisnguyenit97 Date: Thu, 4 Jul 2024 22:36:17 +0700 Subject: [PATCH] :sparkles: feat: add Html builder for telegram message #5 --- .../bot4j/telegram/message/HtmlBuilder.java | 342 ++++++++++++++++++ .../model/rd/AbstractTelegramClass.java | 10 +- .../groovy/org/bot4j/HtmlBuilderTest.java | 99 +++++ 3 files changed, 450 insertions(+), 1 deletion(-) create mode 100644 plugin/src/main/groovy/org/bot4j/telegram/message/HtmlBuilder.java create mode 100644 plugin/src/test/groovy/org/bot4j/HtmlBuilderTest.java diff --git a/plugin/src/main/groovy/org/bot4j/telegram/message/HtmlBuilder.java b/plugin/src/main/groovy/org/bot4j/telegram/message/HtmlBuilder.java new file mode 100644 index 0000000..601e74a --- /dev/null +++ b/plugin/src/main/groovy/org/bot4j/telegram/message/HtmlBuilder.java @@ -0,0 +1,342 @@ +package org.bot4j.telegram.message; + +import org.unify4j.common.Class4j; +import org.unify4j.common.Json4j; +import org.unify4j.common.String4j; +import org.unify4j.model.c.Ascii; + +public class HtmlBuilder { + protected final StringBuilder message; + + public HtmlBuilder() { + this.message = new StringBuilder(); + } + + public HtmlBuilder vertical(String text) { + message.append(String4j.repeat(Ascii.Symbol.VERTICAL_LINE, 2)) + .append(text) + .append(String4j.repeat(Ascii.Symbol.VERTICAL_LINE, 2)); + return this.space(); + } + + public HtmlBuilder vertical(Object value) { + if (value == null) { + return this; + } + return this.vertical(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder bold(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Lowercase.LATIN_SMALL_LETTER_B) + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append(Ascii.Lowercase.LATIN_SMALL_LETTER_B) + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder bold(Object value) { + if (value == null) { + return this; + } + return this.bold(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder strong(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append("strong") + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append("strong") + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder strong(Object value) { + if (value == null) { + return this; + } + return this.strong(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder italic(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Lowercase.LATIN_SMALL_LETTER_I) + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append(Ascii.Lowercase.LATIN_SMALL_LETTER_I) + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder italic(Object value) { + if (value == null) { + return this; + } + return this.italic(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder em(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append("em") + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append("em") + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder em(Object value) { + if (value == null) { + return this; + } + return this.em(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder underline(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Lowercase.LATIN_SMALL_LETTER_U) + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append(Ascii.Lowercase.LATIN_SMALL_LETTER_U) + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder underline(Object value) { + if (value == null) { + return this; + } + return this.underline(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder ins(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append("ins") + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append("ins") + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder ins(Object value) { + if (value == null) { + return this; + } + return this.ins(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder strikethrough(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Lowercase.LATIN_SMALL_LETTER_S) + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append(Ascii.Lowercase.LATIN_SMALL_LETTER_S) + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder strikethrough(Object value) { + if (value == null) { + return this; + } + return this.strikethrough(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder strike(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append("strike") + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append("strike") + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder strike(Object value) { + if (value == null) { + return this; + } + return this.strike(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder delete(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append("del") + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append("del") + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder delete(Object value) { + if (value == null) { + return this; + } + return this.delete(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder spoiler(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append("tg-spoiler") + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append("tg-spoiler") + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder spoiler(Object value) { + if (value == null) { + return this; + } + return this.spoiler(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder inlineUrl(String text, String url) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Lowercase.LATIN_SMALL_LETTER_A) + .append(Ascii.Punctuation.SPACE) + .append("href=") + .append(Ascii.Punctuation.REVERSE_SOLIDUS) + .append(Ascii.Punctuation.QUOTATION_MARK) + .append(url) + .append(Ascii.Punctuation.REVERSE_SOLIDUS) + .append(Ascii.Punctuation.QUOTATION_MARK) + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append(Ascii.Lowercase.LATIN_SMALL_LETTER_A) + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder code(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append("code") + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append("code") + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder code(Object value) { + if (value == null) { + return this; + } + return this.code(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder preformatted(String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append("pre") + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append("pre") + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder preformatted(Object value) { + if (value == null) { + return this; + } + return this.preformatted(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder preformatted(String lang, String text) { + message.append(Ascii.Symbol.LESS_THAN_SIGN) + .append("pre") + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append("code class=") + .append(Ascii.Punctuation.REVERSE_SOLIDUS) + .append(Ascii.Punctuation.QUOTATION_MARK) + .append("language-") + .append(lang) + .append(Ascii.Punctuation.REVERSE_SOLIDUS) + .append(Ascii.Punctuation.QUOTATION_MARK) + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(text) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append("code") + .append(Ascii.Symbol.GREATER_THAN_SIGN) + .append(Ascii.Symbol.LESS_THAN_SIGN) + .append(Ascii.Punctuation.SOLIDUS) + .append("pre") + .append(Ascii.Symbol.GREATER_THAN_SIGN); + return this.space(); + } + + public HtmlBuilder preformatted(String lang, Object value) { + if (value == null) { + return this; + } + return this.preformatted(lang, Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder text(String text) { + message.append(text); + return this.space(); + } + + public HtmlBuilder text(Object value) { + if (value == null) { + return this; + } + return this.text(Class4j.isPrimitive(value.getClass()) ? value.toString() : Json4j.toJson(value)); + } + + public HtmlBuilder line() { + return this.text(System.lineSeparator()); + } + + public HtmlBuilder line(int repeat) { + return this.text(String4j.repeat(System.lineSeparator(), repeat)); + } + + public HtmlBuilder space() { + message.append(Ascii.Punctuation.SPACE); + return this; + } + + public HtmlBuilder space(int repeat) { + message.append(String4j.repeat(Ascii.Punctuation.SPACE, repeat)); + return this; + } + + @Override + public String toString() { + return this.message.toString(); + } +} diff --git a/plugin/src/main/groovy/org/bot4j/telegram/model/rd/AbstractTelegramClass.java b/plugin/src/main/groovy/org/bot4j/telegram/model/rd/AbstractTelegramClass.java index 8c6cbe5..96de884 100644 --- a/plugin/src/main/groovy/org/bot4j/telegram/model/rd/AbstractTelegramClass.java +++ b/plugin/src/main/groovy/org/bot4j/telegram/model/rd/AbstractTelegramClass.java @@ -1,5 +1,6 @@ package org.bot4j.telegram.model.rd; +import org.bot4j.telegram.message.HtmlBuilder; import org.bot4j.telegram.message.MarkdownBuilder; import org.bot4j.telegram.model.builder.TelegramConnectionBuilder; import org.bot4j.telegram.model.builder.TelegramOptionBuilder; @@ -98,13 +99,20 @@ public T text(MarkdownBuilder builder) { return this.text(builder.toString()); } + public T text(HtmlBuilder builder) { + if (builder == null) { + return this.self(); + } + return this.text(builder.toString()); + } + public T parseMode(String mode) { this.parseMode = mode; return this.self(); } public T parseMode(TelegramTextMode mode) { - return this.parseMode(mode.name()); + return this.parseMode(mode.name().toLowerCase()); } public T markdownSettings() { diff --git a/plugin/src/test/groovy/org/bot4j/HtmlBuilderTest.java b/plugin/src/test/groovy/org/bot4j/HtmlBuilderTest.java new file mode 100644 index 0000000..55ab2a9 --- /dev/null +++ b/plugin/src/test/groovy/org/bot4j/HtmlBuilderTest.java @@ -0,0 +1,99 @@ +package org.bot4j; + +import org.bot4j.telegram.message.HtmlBuilder; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class HtmlBuilderTest { + + @Test + public void testBold() { + HtmlBuilder builder = new HtmlBuilder(); + builder.bold("bold text"); + assertEquals("bold text ", builder.toString()); + } + + @Test + public void testItalic() { + HtmlBuilder builder = new HtmlBuilder(); + builder.italic("italic text"); + assertEquals("italic text ", builder.toString()); + } + + @Test + public void testUnderline() { + HtmlBuilder builder = new HtmlBuilder(); + builder.underline("underline text"); + assertEquals("underline text ", builder.toString()); + } + + @Test + public void testPreformatted() { + HtmlBuilder builder = new HtmlBuilder(); + builder.preformatted("preformatted text"); + assertEquals("
preformatted text
", builder.toString()); + } + + @Test + public void testPreformattedWithLang() { + HtmlBuilder builder = new HtmlBuilder(); + builder.preformatted("java", "import org.bot4j.telegram.message.HtmlBuilder;"); + assertEquals("
import org.bot4j.telegram.message.HtmlBuilder;
", builder.toString()); + } + + @Test + public void testVertical() { + HtmlBuilder builder = new HtmlBuilder(); + builder.vertical("vertical text"); + assertEquals("||vertical text|| ", builder.toString()); + } + + @Test + public void testInlineUrl() { + HtmlBuilder builder = new HtmlBuilder().inlineUrl("OpenAI", "https://www.openai.com"); + assertEquals("OpenAI ", builder.toString()); + } + + @Test + public void testStrong() { + HtmlBuilder builder = new HtmlBuilder(); + builder.strong("strong text"); + assertEquals("strong text ", builder.toString()); + } + + @Test + public void testStrikethrough() { + HtmlBuilder builder = new HtmlBuilder(); + builder.strikethrough("strikethrough text"); + assertEquals("strikethrough text ", builder.toString()); + } + + @Test + public void testText() { + HtmlBuilder builder = new HtmlBuilder(); + builder.text("simple text"); + assertEquals("simple text ", builder.toString()); + } + + @Test + public void testCode() { + HtmlBuilder builder = new HtmlBuilder(); + builder.code("code text"); + assertEquals("code text ", builder.toString()); + } + + @Test + public void testDelete() { + HtmlBuilder builder = new HtmlBuilder(); + builder.delete("delete text"); + assertEquals("delete text ", builder.toString()); + } + + @Test + public void testSpoiler() { + HtmlBuilder builder = new HtmlBuilder(); + builder.spoiler("spoiler text"); + assertEquals("spoiler text ", builder.toString()); + } +}