Search in sources :

Example 1 with WorkerStatus

use of com.gamebuster19901.excite.bot.command.ArchiveCommand.WorkerStatus in project ExciteBot by TheGameCommunity.

the class ArchiveCommand method archive.

private static int archive(MessageContext source, String argument) {
    if (source.isAdmin()) {
        if (source.isGuildMessage()) {
            if (argument.isEmpty()) {
                source.sendMessage("Usage: archive <TextChannels>");
                return 1;
            }
            DiscordServer server = source.getServer();
            Guild guild = server.getGuild();
            Member member = DiscordUser.getMember(source.getDiscordAuthor(), server);
            HashSet<TextChannel> channelsToArchive = getChannels(source, guild, Arrays.asList(argument.split(" ")));
            for (TextChannel channel : channelsToArchive) {
                if (!member.hasPermission(channel, Permission.MANAGE_CHANNEL, Permission.MESSAGE_MANAGE)) {
                    source.sendMessage("You must have the `MANAGE_CHANNEL` and `MESSAGE_MANAGE` permission in " + channel.getAsMention() + " in order to archive it.");
                    return 1;
                }
            }
            Thread workerThread = ThreadService.run("Archiver thread", new Thread() {

                private final Thread workerThread = this;

                private final int newlineSize = System.lineSeparator().length();

                public volatile WorkerStatus status = NOT_STARTED;

                public volatile byte updates = 0;

                public volatile int messagesArchived = 0;

                public volatile int wiiMessagesArchived = 0;

                public volatile int attachmentsArchived = 0;

                public volatile long estimatedSize = 0;

                private volatile Throwable error;

                @Override
                public void run() {
                    Thread monitorThread = ThreadService.run("Archive monitor", new Thread() {

                        public void run() {
                            Instant start = Instant.now();
                            EmbedBuilder embed = new EmbedBuilder();
                            embed.setTitle("Archive in progress...");
                            Field archivedDiscordMessagesField = new Field("Discord Messages archived:", "0", true, true);
                            Field archivedDiscordAttachmentsField = new Field("Discord Attachments archived:", "0", true, true);
                            Field emailsArchivedField = new Field("Wii Mails archived:", "0", true, true);
                            Field estimatedSizeField = new Field("Estimated size:", FileUtils.humanReadableByteCount(0), true, true);
                            Field timeElapsedField = new Field("Time elapsed:", "0 seconds", true, true);
                            embed.setTimestamp(start);
                            WorkerStatus currentStatus = status;
                            embed.addField(archivedDiscordMessagesField);
                            embed.addField(archivedDiscordAttachmentsField);
                            embed.addField(emailsArchivedField);
                            embed.addField(estimatedSizeField);
                            embed.addField(timeElapsedField);
                            Message message = source.sendMessage(embed.build());
                            while (!currentStatus.finished()) {
                                try {
                                    Thread.sleep(2500);
                                    currentStatus = status;
                                    Instant now = Instant.now();
                                    embed = new EmbedBuilder();
                                    if (currentStatus == NOT_STARTED) {
                                        embed.setColor(Color.DARK_GRAY);
                                    }
                                    if (currentStatus == WORKING) {
                                        if (updates++ % 2 == 0) {
                                            embed.setColor(Color.YELLOW);
                                        } else {
                                            // dark yellow
                                            embed.setColor(new Color(204, 204, 0));
                                        }
                                        embed.setTitle("Archive in progress...");
                                        embed.addField(archivedDiscordMessagesField = new Field("Discord Messages archived:", messagesArchived + "", true, true));
                                        embed.addField(archivedDiscordAttachmentsField = new Field("Discord Attachments archived:", attachmentsArchived + "", true, true));
                                        embed.addField(emailsArchivedField = new Field("Wii Messages archived:", wiiMessagesArchived + "", true, true));
                                        embed.addField(estimatedSizeField = new Field("Estimated size:", FileUtils.humanReadableByteCount(estimatedSize), true, true));
                                        embed.addField(timeElapsedField = new Field("Time elapsed:", TimeUtils.readableDuration(Duration.between(start, now)), true, true));
                                        embed.setTimestamp(now);
                                        message.editMessage(embed.build()).complete();
                                    }
                                    Thread.sleep(2500);
                                } catch (InterruptedException e) {
                                    currentStatus = ERRORED;
                                    embed.setTitle("Archive failed");
                                    embed.setColor(Color.RED);
                                    message.editMessage(embed.build()).complete();
                                    System.out.println("Monitor thread interrupted... stopping!");
                                    return;
                                }
                            }
                            Instant now = Instant.now();
                            embed.addField(archivedDiscordMessagesField = new Field("Discord Messages archived:", messagesArchived + "", true, true));
                            embed.addField(archivedDiscordAttachmentsField = new Field("Discord Attachments archived:", attachmentsArchived + "", true, true));
                            embed.addField(emailsArchivedField = new Field("Wii Messages archived:", wiiMessagesArchived + "", true, true));
                            embed.addField(estimatedSizeField = new Field("Estimated size:", FileUtils.humanReadableByteCount(estimatedSize), true, true));
                            embed.addField(timeElapsedField = new Field("Time elapsed:", TimeUtils.readableDuration(Duration.between(start, now)), true, true));
                            embed.setTimestamp(now);
                            message.editMessage(embed.build()).complete();
                            if (currentStatus == COMPLETE) {
                                embed.setColor(Color.GREEN);
                                embed.setTitle("Archive complete");
                                source.sendMessage(source.getDiscordAuthor().getJDAUser().getAsMention() + " Archive complete.");
                            } else {
                                embed.setColor(Color.RED);
                                embed.setTitle("Archive failed");
                                source.sendMessage(source.getDiscordAuthor().getJDAUser().getAsMention() + " Archive FAILED.");
                            }
                            message.editMessage(embed.build()).complete();
                        }
                    });
                    String date = TimeUtils.getDBDate(Instant.now());
                    try {
                        status = WORKING;
                        for (File f : org.apache.commons.io.FileUtils.listFiles(Mailbox.MAILBOX, null, true)) {
                            File archive = new File(".archive/" + date + "/" + f.getPath().replace("/run", ""));
                            if (!archive.getParentFile().mkdirs() && !archive.getParentFile().exists()) {
                                throw new IOException("Could not create " + archive.getAbsolutePath());
                            }
                            org.apache.commons.io.FileUtils.copyFile(f, archive);
                            wiiMessagesArchived++;
                            estimatedSize += archive.length();
                        }
                        for (TextChannel channel : channelsToArchive) {
                            try {
                                File file = new File(".archive/" + date + "/" + channel.getName() + "/" + channel.getName() + ".arc");
                                if (!file.getParentFile().mkdirs()) {
                                    throw new IOException("Could not create " + file.getAbsolutePath());
                                }
                                System.out.println(file.getAbsolutePath());
                                file.createNewFile();
                                MessagePaginationAction action = channel.getIterableHistory();
                                BufferedWriter fileWriter = new BufferedWriter(new FileWriter(file));
                                action.forEach((message) -> {
                                    try {
                                        List<Attachment> attachments = message.getAttachments();
                                        write(fileWriter, "==========START " + message.getIdLong() + " USER:" + message.getAuthor().getAsTag());
                                        write(fileWriter, message.getContentRaw());
                                        if (!attachments.isEmpty()) {
                                            write(fileWriter, "==========ATTACHMENTS " + message.getIdLong());
                                            for (Attachment attachment : attachments) {
                                                File attachmentFile = new File(file.getParentFile().getPath() + "/attach" + attachment.getIdLong() + attachment.getFileName());
                                                CompletableFuture<File> future = attachment.downloadToFile(attachmentFile);
                                                future.exceptionally(error -> {
                                                    int i = 0;
                                                    source.sendMessage("Encountered " + error.getClass().getSimpleName() + " while downloading " + attachmentFile + " retrying... (" + i++ + "/4)");
                                                    while (i < 4) {
                                                        try {
                                                            future.get();
                                                            i++;
                                                        } catch (Throwable t) {
                                                            if (t instanceof InterruptedException) {
                                                                throw new ThreadDeath();
                                                            }
                                                            if (i < 4) {
                                                                source.sendMessage("Encountered " + t.getClass().getSimpleName() + " while downloading " + attachmentFile + " retrying... (" + i + "/4)");
                                                            }
                                                        }
                                                    }
                                                    return null;
                                                }).get();
                                                write(fileWriter, attachment.getId() + attachmentFile.getName());
                                                estimatedSize += attachment.getSize();
                                                attachmentsArchived++;
                                            }
                                        }
                                        write(fileWriter, "==========END " + message.getIdLong());
                                        messagesArchived++;
                                    } catch (IOException | InterruptedException | ExecutionException e) {
                                        throw new RuntimeException(e);
                                    }
                                });
                                fileWriter.close();
                            } catch (Throwable t) {
                                source.sendMessage("Could not back up channel " + channel.getAsMention());
                                throw t;
                            }
                        }
                        status = COMPLETE;
                    } catch (Throwable t) {
                        source.sendMessage(StacktraceUtil.getStackTrace(t));
                        status = ERRORED;
                    }
                }

                private void write(BufferedWriter writer, String text) throws IOException {
                    estimatedSize += text.length() + newlineSize;
                    writer.write(text);
                    writer.newLine();
                }
            });
        } else {
            source.sendMessage("You must execute this command in a server");
        }
    } else {
        source.sendMessage("You must be an administator to execute this command");
    }
    return 1;
}
Also used : Color(java.awt.Color) ThreadService(com.gamebuster19901.excite.util.ThreadService) Arrays(java.util.Arrays) CommandDispatcher(com.mojang.brigadier.CommandDispatcher) Permission(net.dv8tion.jda.api.Permission) CompletableFuture(java.util.concurrent.CompletableFuture) Member(net.dv8tion.jda.api.entities.Member) Field(net.dv8tion.jda.api.entities.MessageEmbed.Field) TextChannel(net.dv8tion.jda.api.entities.TextChannel) MessagePaginationAction(net.dv8tion.jda.api.requests.restaction.pagination.MessagePaginationAction) HashSet(java.util.HashSet) StringArgumentType(com.mojang.brigadier.arguments.StringArgumentType) WorkerStatus(com.gamebuster19901.excite.bot.command.ArchiveCommand.WorkerStatus) Guild(net.dv8tion.jda.api.entities.Guild) Duration(java.time.Duration) Mailbox(com.gamebuster19901.excite.bot.mail.Mailbox) StacktraceUtil(com.gamebuster19901.excite.util.StacktraceUtil) Message(net.dv8tion.jda.api.entities.Message) Attachment(net.dv8tion.jda.api.entities.Message.Attachment) BufferedWriter(java.io.BufferedWriter) FileUtils(com.gamebuster19901.excite.util.file.FileUtils) FileWriter(java.io.FileWriter) DiscordUser(com.gamebuster19901.excite.bot.user.DiscordUser) IOException(java.io.IOException) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) Instant(java.time.Instant) File(java.io.File) ExecutionException(java.util.concurrent.ExecutionException) DiscordServer(com.gamebuster19901.excite.bot.server.DiscordServer) List(java.util.List) TimeUtils(com.gamebuster19901.excite.util.TimeUtils) Message(net.dv8tion.jda.api.entities.Message) FileWriter(java.io.FileWriter) Attachment(net.dv8tion.jda.api.entities.Message.Attachment) Guild(net.dv8tion.jda.api.entities.Guild) BufferedWriter(java.io.BufferedWriter) Field(net.dv8tion.jda.api.entities.MessageEmbed.Field) TextChannel(net.dv8tion.jda.api.entities.TextChannel) CompletableFuture(java.util.concurrent.CompletableFuture) WorkerStatus(com.gamebuster19901.excite.bot.command.ArchiveCommand.WorkerStatus) List(java.util.List) Member(net.dv8tion.jda.api.entities.Member) Instant(java.time.Instant) Color(java.awt.Color) IOException(java.io.IOException) EmbedBuilder(net.dv8tion.jda.api.EmbedBuilder) DiscordServer(com.gamebuster19901.excite.bot.server.DiscordServer) File(java.io.File) MessagePaginationAction(net.dv8tion.jda.api.requests.restaction.pagination.MessagePaginationAction)

Aggregations

WorkerStatus (com.gamebuster19901.excite.bot.command.ArchiveCommand.WorkerStatus)1 Mailbox (com.gamebuster19901.excite.bot.mail.Mailbox)1 DiscordServer (com.gamebuster19901.excite.bot.server.DiscordServer)1 DiscordUser (com.gamebuster19901.excite.bot.user.DiscordUser)1 StacktraceUtil (com.gamebuster19901.excite.util.StacktraceUtil)1 ThreadService (com.gamebuster19901.excite.util.ThreadService)1 TimeUtils (com.gamebuster19901.excite.util.TimeUtils)1 FileUtils (com.gamebuster19901.excite.util.file.FileUtils)1 CommandDispatcher (com.mojang.brigadier.CommandDispatcher)1 StringArgumentType (com.mojang.brigadier.arguments.StringArgumentType)1 Color (java.awt.Color)1 BufferedWriter (java.io.BufferedWriter)1 File (java.io.File)1 FileWriter (java.io.FileWriter)1 IOException (java.io.IOException)1 Duration (java.time.Duration)1 Instant (java.time.Instant)1 Arrays (java.util.Arrays)1 HashSet (java.util.HashSet)1 List (java.util.List)1