From df6d0608637abe0fdbc5b201a0fa2e9b1c0506ff Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Sun, 12 Mar 2023 05:32:07 +0100 Subject: [PATCH] Added a command to get suggestion data into excel --- build.gradle.kts | 7 +- .../alttd/commandManager/CommandManager.java | 1 + .../commands/CommandDataSuggestions.java | 120 ++++++++++++++++++ src/main/java/com/alttd/util/ExcelWriter.java | 57 +++++++++ 4 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/alttd/commandManager/commands/CommandDataSuggestions.java create mode 100644 src/main/java/com/alttd/util/ExcelWriter.java diff --git a/build.gradle.kts b/build.gradle.kts index c3f603e..b268bce 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -53,7 +53,7 @@ tasks { } dependencies { -// JDA + // JDA implementation("net.dv8tion:JDA:5.0.0-alpha.20") { exclude("opus-java") // exclude audio } @@ -64,7 +64,10 @@ dependencies { // Configurate implementation("org.spongepowered:configurate-yaml:4.1.2") - + // Excel + implementation("org.apache.poi:poi:5.2.0") + implementation("org.apache.poi:poi-ooxml:5.2.0") + // Other stuff? compileOnly("org.projectlombok:lombok:1.18.24") annotationProcessor("org.projectlombok:lombok:1.18.24") } \ No newline at end of file diff --git a/src/main/java/com/alttd/commandManager/CommandManager.java b/src/main/java/com/alttd/commandManager/CommandManager.java index a78f17e..3a21ce2 100644 --- a/src/main/java/com/alttd/commandManager/CommandManager.java +++ b/src/main/java/com/alttd/commandManager/CommandManager.java @@ -51,6 +51,7 @@ public class CommandManager extends ListenerAdapter { new CommandToggleRole(commandSetToggleableRoles, jda, this), new CommandRemindMe(jda, this, modalManager), new CommandSoftLock(jda, this, lockedChannel), + new CommandDataSuggestions(jda, this), new CommandAuction(jda, this, selectMenuManager)); } diff --git a/src/main/java/com/alttd/commandManager/commands/CommandDataSuggestions.java b/src/main/java/com/alttd/commandManager/commands/CommandDataSuggestions.java new file mode 100644 index 0000000..58afe7e --- /dev/null +++ b/src/main/java/com/alttd/commandManager/commands/CommandDataSuggestions.java @@ -0,0 +1,120 @@ +package com.alttd.commandManager.commands; + +import com.alttd.commandManager.CommandManager; +import com.alttd.commandManager.DiscordCommand; +import com.alttd.util.ExcelWriter; +import com.alttd.util.Util; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.MessageReaction; +import net.dv8tion.jda.api.entities.channel.concrete.ForumChannel; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; +import net.dv8tion.jda.api.entities.channel.forums.ForumTag; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.InteractionHook; +import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions; +import net.dv8tion.jda.api.interactions.commands.build.CommandData; +import net.dv8tion.jda.api.interactions.commands.build.Commands; + +import java.util.HashSet; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public class CommandDataSuggestions extends DiscordCommand { + + private final CommandData commandData; + private final CommandManager commandManager; + + public CommandDataSuggestions(JDA jda, CommandManager commandManager) { + this.commandManager = commandManager; + this.commandData = Commands.slash(getName(), "Get data about suggestions from the forum channel") + .setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.ADMINISTRATOR)) + .setGuildOnly(true); + Util.registerCommand(commandManager, jda, commandData, getName()); + } + + @Override + public String getName() { + return "data_suggestions"; + } + + private void filterAndStoreActiveSuggestions(InteractionHook reply, HashSet activeSuggestions) { + ExcelWriter excelWriter = new ExcelWriter(); + long waitSeconds = 0; + for (ThreadChannel activeSuggestion : activeSuggestions) { + activeSuggestion.getHistoryFromBeginning(1).queueAfter(waitSeconds, TimeUnit.SECONDS, hist -> { + List retrievedHistory = hist.getRetrievedHistory(); + if (retrievedHistory.size() != 1) { + return; + } + Message message = retrievedHistory.get(0); + MessageReaction thumbsUp = message.getReaction(Emoji.fromUnicode("\uD83D\uDC4D")); + MessageReaction thumbsDown = message.getReaction(Emoji.fromUnicode("\uD83D\uDC4E")); + excelWriter.addRow( + message.getJumpUrl(), + activeSuggestion.getName(), + thumbsUp == null ? "err" : String.valueOf(thumbsUp.getCount()), + thumbsDown == null ? "err" : String.valueOf(thumbsDown.getCount())); + }); + waitSeconds += 5; + } + ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); + executor.schedule(() -> excelWriter.saveAndSend(reply), waitSeconds, TimeUnit.SECONDS); + } + + private void processSuggestionThreads(SlashCommandInteractionEvent event, ForumChannel forumChannel, ForumTag unansweredTag, List activeSuggestions) { + activeSuggestions.addAll(forumChannel.getThreadChannels()); + activeSuggestions = activeSuggestions.stream() + .filter(threadChannel -> !threadChannel.isLocked()) + .filter(threadChannel -> threadChannel.getAppliedTags().contains(unansweredTag)) + .toList(); + HashSet activeSuggestionsSet = new HashSet<>(activeSuggestions); + + event.deferReply(true).queue(reply -> filterAndStoreActiveSuggestions(reply, activeSuggestionsSet)); + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + Guild guild = event.getGuild(); + if (guild == null) { + event.replyEmbeds(Util.genericErrorEmbed("Error", "This command needs to be executed from a guild")).queue(); + return; + } + ForumChannel forumChannel = guild.getForumChannelById(1019660718867488768L); + if (forumChannel == null) { + event.replyEmbeds(Util.genericErrorEmbed("Error", "Can't find the forum channel in this guild")).queue(); + return; + } + List tagList = forumChannel.getAvailableTagsByName("unanswered", true); + if (tagList.size() != 1) { + event.replyEmbeds(Util.genericErrorEmbed("Error", "Expected one unanswered tag found: " + tagList.size())).queue(); + return; + } + + ForumTag unansweredTag = tagList.get(0); + forumChannel.retrieveArchivedPublicThreadChannels().queue(threads -> { + processSuggestionThreads(event, forumChannel, unansweredTag, threads); + }); + } + + @Override + public void suggest(CommandAutoCompleteInteractionEvent event) { + event.replyChoices(List.of()).queue(); + } + + @Override + public String getHelpMessage() { + return null; + } + + @Override + public CommandData getCommandData() { + return commandData; + } +} diff --git a/src/main/java/com/alttd/util/ExcelWriter.java b/src/main/java/com/alttd/util/ExcelWriter.java new file mode 100644 index 0000000..41a0d80 --- /dev/null +++ b/src/main/java/com/alttd/util/ExcelWriter.java @@ -0,0 +1,57 @@ +package com.alttd.util; + +import net.dv8tion.jda.api.interactions.InteractionHook; +import net.dv8tion.jda.api.utils.FileUpload; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; + +public class ExcelWriter { + + private final String fileName = "suggestions.xlsx"; + private final String sheetName = "Sheet1"; + private final Workbook workbook; + private final Sheet sheet; + private int currentRow = 0; + private boolean done = false; + + public ExcelWriter() { + this.workbook = new XSSFWorkbook(); + + // Create a new sheet in the workbook + this.sheet = workbook.createSheet(sheetName); + } + + public synchronized void addRow(String... data) { + if (done) { + Logger.warning("Tried to write to finished excel file"); + return; + } + Row row = sheet.createRow(currentRow++); + int curCel = 0; + for (String entry : data) { + Cell cell = row.createCell(curCel++); + cell.setCellValue(entry); + } + } + + public synchronized void saveAndSend(InteractionHook reply) { + done = true; + try { + File file = new File(fileName); + FileOutputStream outputStream = new FileOutputStream(file); + workbook.write(outputStream); + workbook.close(); + reply.sendFiles(FileUpload.fromData(file)).queue(done -> { + //noinspection ResultOfMethodCallIgnored + file.delete(); + }); + } catch (IOException e) { + reply.sendMessageEmbeds(Util.genericErrorEmbed("Error", "Error while uploading excel file")).queue(); + } + } +}