From 08a98d9e4f3c93c14e454613c82a90dc3ccd4162 Mon Sep 17 00:00:00 2001 From: test Date: Mon, 5 Aug 2024 15:22:06 +1000 Subject: [PATCH] markdown adapter --- build.gradle | 2 +- .../commands/info/optimal/CityBranch.java | 6 -- .../manager/v2/command/AMessageBuilder.java | 22 +++--- .../v2/impl/pw/commands/IACommands.java | 12 ++-- .../link/locutus/discord/util/MarkupUtil.java | 69 +++++++++++++++---- 5 files changed, 76 insertions(+), 35 deletions(-) diff --git a/build.gradle b/build.gradle index 46ca06f9..7de86573 100644 --- a/build.gradle +++ b/build.gradle @@ -90,7 +90,7 @@ def currentArchitecture = DefaultNativePlatform.getCurrentArchitecture() dependencies { implementation 'org.lz4:lz4-java:1.8.0' - + implementation 'com.vladsch.flexmark:flexmark-all:0.64.8' implementation 'org.jgrapht:jgrapht-core:1.5.2' implementation 'org.jgrapht:jgrapht-ext:1.5.2' implementation 'com.amazonaws:aws-java-sdk-bom:1.12.649' diff --git a/src/main/java/link/locutus/discord/commands/info/optimal/CityBranch.java b/src/main/java/link/locutus/discord/commands/info/optimal/CityBranch.java index 22c2620e..d55816df 100644 --- a/src/main/java/link/locutus/discord/commands/info/optimal/CityBranch.java +++ b/src/main/java/link/locutus/discord/commands/info/optimal/CityBranch.java @@ -92,9 +92,6 @@ public CityBranch(CityNode.CachedCity cached) { }); resortList(rssSorted); } - for (Building building : rssSorted) { - System.out.println("rmv:|| " + building.name() + " " + rssBuildings.get(building) + " profit"); - } List allBuildings = new ArrayList<>(rssSorted); for (Building building : Buildings.values()) { @@ -104,9 +101,6 @@ public CityBranch(CityNode.CachedCity cached) { if (building instanceof ServiceBuilding) allBuildings.add(building); } this.buildings = allBuildings.toArray(new Building[0]); - for (Building building : buildings) { - System.out.println("rmv:|| All " + building.name()); - } } private static void resortList(List rssSorted) { diff --git a/src/main/java/link/locutus/discord/commands/manager/v2/command/AMessageBuilder.java b/src/main/java/link/locutus/discord/commands/manager/v2/command/AMessageBuilder.java index 13a3f8c1..cdb5cfcf 100644 --- a/src/main/java/link/locutus/discord/commands/manager/v2/command/AMessageBuilder.java +++ b/src/main/java/link/locutus/discord/commands/manager/v2/command/AMessageBuilder.java @@ -18,6 +18,9 @@ import java.util.*; import java.util.concurrent.CompletableFuture; +import static link.locutus.discord.util.MarkupUtil.formatDiscordMarkdown; +import static link.locutus.discord.util.MarkupUtil.markdownToHTML; + public abstract class AMessageBuilder implements IMessageBuilder { public final StringBuilder content = new StringBuilder(); public final Map buttons = new LinkedHashMap<>(); @@ -194,9 +197,9 @@ public void appendJson(JsonObject json) { for (var buttonJson : json.getAsJsonArray("buttons")) { JsonObject buttonObj = buttonJson.getAsJsonObject(); if (buttonObj.has("cmd")) { - this.buttons.put(buttonObj.get("cmd").getAsString(), buttonObj.get("label").getAsString()); + commandButton(buttonObj.get("cmd").getAsString(), buttonObj.get("label").getAsString()); } else if (buttonObj.has("href")) { - this.links.put(buttonObj.get("href").getAsString(), buttonObj.get("label").getAsString()); + linkButton(buttonObj.get("href").getAsString(), buttonObj.get("label").getAsString()); } } } @@ -251,14 +254,14 @@ private Guild getGuildOrNull() { public String toSimpleHtml(boolean includeFiles, boolean includeButtons) { StringBuilder html = new StringBuilder(); - html.append("

").append(MarkupUtil.formatDiscordMarkdown(content.toString(), getGuildOrNull())).append("

"); + html.append("

").append(markdownToHTML(formatDiscordMarkdown(content.toString(), getGuildOrNull()))).append("

"); for (MessageEmbed embed : embeds) { String title = embed.getTitle(); - String description = MarkupUtil.formatDiscordMarkdown(embed.getDescription(), getGuildOrNull()); + String description = markdownToHTML(formatDiscordMarkdown(embed.getDescription(), getGuildOrNull())); String footerText = null; MessageEmbed.Footer footer = embed.getFooter(); if (footer != null) { - footerText = MarkupUtil.formatDiscordMarkdown(footer.getText(), getGuildOrNull()); + footerText = markdownToHTML(formatDiscordMarkdown(footer.getText(), getGuildOrNull())); } List fields = embed.getFields(); StringBuilder embedHtml = new StringBuilder(); @@ -278,6 +281,7 @@ public String toSimpleHtml(boolean includeFiles, boolean includeButtons) { embedHtml.append("").append(footerText).append(""); } embedHtml.append(""); + html.append(embedHtml); } @@ -292,7 +296,7 @@ public String toSimpleHtml(boolean includeFiles, boolean includeButtons) { String name = entry.getKey(); // use
                 html.append("

").append(name).append("

"); - html.append("
").append(new String(entry.getValue())).append("
\n"); + html.append("
").append(new String(entry.getValue())).append("

"); } } if (includeButtons) { @@ -325,13 +329,13 @@ public String toSimpleHtml(boolean includeFiles, boolean includeButtons) { public IMessageBuilder writeTo(IMessageBuilder output) { if (!content.isEmpty()) output.append(content.toString()); for (MessageEmbed embed : embeds) { - embed(embed); + output.embed(embed); } for (Map.Entry entry : buttons.entrySet()) { - output.commandButton(entry.getValue(), entry.getKey()); + output.commandButton(entry.getKey(), entry.getValue()); } for (Map.Entry entry : links.entrySet()) { - output.linkButton(entry.getValue(), entry.getKey()); + output.linkButton(entry.getKey(), entry.getValue()); } for (Map.Entry entry : images.entrySet()) { output.image(entry.getKey(), entry.getValue()); diff --git a/src/main/java/link/locutus/discord/commands/manager/v2/impl/pw/commands/IACommands.java b/src/main/java/link/locutus/discord/commands/manager/v2/impl/pw/commands/IACommands.java index 87523754..f28d808c 100644 --- a/src/main/java/link/locutus/discord/commands/manager/v2/impl/pw/commands/IACommands.java +++ b/src/main/java/link/locutus/discord/commands/manager/v2/impl/pw/commands/IACommands.java @@ -1834,11 +1834,10 @@ public String mailCommandOutput(NationPlaceholders placeholders, ValueStore stor if (sheet == null) { sheet = SpreadSheet.create(db, SheetKey.MAIL_RESPONSES_SHEET); } - if (body != null) { - GPTUtil.checkThrowModeration(body + "\n" + command); - } else { - GPTUtil.checkThrowModeration(command); - } + String checkModMsg = command; + if (subject != null) checkModMsg += subject; + if (body != null) checkModMsg += body; + GPTUtil.checkThrowModeration(checkModMsg); List header = new ArrayList<>(Arrays.asList( "nation", @@ -1893,7 +1892,7 @@ public String mailCommandOutput(NationPlaceholders placeholders, ValueStore stor if (respType == CommandResult.SUCCESS) { if (!bodyFormat.isEmpty()) { - bodyFormat = MarkupUtil.markdownToHTML(bodyFormat) + "
"; + bodyFormat = bodyFormat + "\n"; } header.set(0, MarkupUtil.sheetUrl(nation.getNation(), nation.getUrl())); @@ -2069,6 +2068,7 @@ public String mailSheet(@Me GuildDB db, @Me JSONObject command, @Me IMessageIO i msg.send(); result.add("\n- **dm**: Sent dm"); } catch (Throwable e) { + e.printStackTrace(); result.add("\n- **dm**: Failed to send dm (`" + e.getMessage() + "`)"); } } diff --git a/src/main/java/link/locutus/discord/util/MarkupUtil.java b/src/main/java/link/locutus/discord/util/MarkupUtil.java index b1a56359..a4495c3f 100644 --- a/src/main/java/link/locutus/discord/util/MarkupUtil.java +++ b/src/main/java/link/locutus/discord/util/MarkupUtil.java @@ -1,6 +1,11 @@ package link.locutus.discord.util; import com.overzealous.remark.Remark; +import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension; +import com.vladsch.flexmark.html.HtmlRenderer; +import com.vladsch.flexmark.parser.Parser; +import com.vladsch.flexmark.util.ast.Node; +import com.vladsch.flexmark.util.data.MutableDataSet; import link.locutus.discord.Locutus; import link.locutus.discord.commands.external.guild.KeyStore; import link.locutus.discord.commands.manager.v2.command.CommandCallable; @@ -26,11 +31,8 @@ import org.primeframework.transformer.service.BBCodeToHTMLTransformer; import org.primeframework.transformer.service.Transformer; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.text.SimpleDateFormat; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -44,6 +46,25 @@ public static String markdownUrl(String name, String url) { private static final Pattern MENTIONED_ROLE = Pattern.compile("<@&([0-9]{11,21})>"); private static final Pattern MENTIONED_CHANNEL = Pattern.compile("<#([0-9]{11,21})>"); private static final Pattern MENTIONED_USER = Pattern.compile("<@!?([0-9]{11,21})>"); + private static final Pattern MENTIONED_TIMESTAMP = Pattern.compile(""); + + public static String formatQuotedTimestamps(String input) { + Matcher m = MENTIONED_TIMESTAMP.matcher(input); + StringBuffer sb = new StringBuffer(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss 'UTC'"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + String url = "https://www.epochconverter.com/countdown?q="; // Plus the time in either millis or seconds + + while (m.find()) { + long timestamp = Long.parseLong(m.group(1)) * 1000; // Convert seconds to milliseconds + Date date = new Date(timestamp); + String formattedDate = dateFormat.format(date); + String urlDate = "" + formattedDate + ""; + m.appendReplacement(sb, formattedDate); + } + m.appendTail(sb); + return sb.toString(); + } public static String formatQuotedCommands(String input) { Matcher m = QUOTED_COMMAND.matcher(input); @@ -139,6 +160,7 @@ public static String formatDiscordMarkdown(String input, Guild guild) { input = formatQuotedCommands(input); input = formatMentionedCommands(input); input = formatMentionedUsers(input); + input = formatQuotedTimestamps(input); if (guild != null) { input = formatMentionedRoles(input, guild); input = formatMentionedChannels(input, guild); @@ -299,15 +321,36 @@ public static String transformURLIntoMarkup(String text){ return sb.toString(); } + private static final MutableDataSet MARKDOWN_TO_HTML = new MutableDataSet(); + private static final Parser MARKDOWN_PARSER; + private static final HtmlRenderer MARKDOWN_RENDERER; + static { + MARKDOWN_TO_HTML.set(Parser.EXTENSIONS, Arrays.asList(StrikethroughExtension.create())); + MARKDOWN_PARSER = Parser.builder(MARKDOWN_TO_HTML).build(); + MARKDOWN_RENDERER = HtmlRenderer.builder(MARKDOWN_TO_HTML).build(); + } + public static String markdownToHTML(String source) { - source = source.replace("_", "\u200B\t").replace(" * ", "\u200B\r"); - source = source.replaceAll("```", "`"); - TextProcessor processor = BBProcessorFactory.getInstance() - .createFromResource(ConfigurationFactory.MARKDOWN_CONFIGURATION_FILE); - source = processor.process(source); - source = source.replace("\n", "
").replace("\u200B\r", " * ").replace("\u200B\t", "_"); - source = transformURLIntoLinks(source); - return source; + source = source.replaceAll("``` ", "```\n"); + Node document = MARKDOWN_PARSER.parse(source); + String html = MARKDOWN_RENDERER.render(document).trim(); + if (html.startsWith("

") && html.endsWith("

")) { + int lastIndex = html.lastIndexOf("

"); + if (lastIndex == 0) { + html = html.substring(3, html.length() - 4); + } + html = transformURLIntoLinks(html); + } + return html.replaceAll("\n", ""); +// +// source = source.replace("_", "\u200B\t").replace(" * ", "\u200B\r"); +// source = source.replaceAll("```", "`"); +// TextProcessor processor = BBProcessorFactory.getInstance() +// .createFromResource(ConfigurationFactory.MARKDOWN_CONFIGURATION_FILE); +// source = processor.process(source); +// source = source.replace("\n", "
").replace("\u200B\r", " * ").replace("\u200B\t", "_"); +// source = transformURLIntoLinks(source); +// return source; } public static String htmlToBBCode(String source) {