Flush output after every command.
[xudocci.git] / src / main / java / net / pterodactylus / xdcc / ui / stdin / CommandReader.java
index 01d0051..2d0a352 100644 (file)
@@ -19,12 +19,16 @@ package net.pterodactylus.xdcc.ui.stdin;
 
 import static com.google.common.collect.FluentIterable.from;
 import static java.util.Arrays.asList;
+import static net.pterodactylus.xdcc.ui.stdin.Ansi.bold;
+import static net.pterodactylus.xdcc.ui.stdin.Ansi.green;
+import static net.pterodactylus.xdcc.ui.stdin.Ansi.red;
 import static net.pterodactylus.xdcc.ui.stdin.Command.TO_NAME;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.Reader;
 import java.io.Writer;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
@@ -36,6 +40,7 @@ import net.pterodactylus.xdcc.core.event.DownloadStarted;
 import net.pterodactylus.xdcc.core.event.GenericMessage;
 import net.pterodactylus.xdcc.core.event.MessageReceived;
 import net.pterodactylus.xdcc.data.Download;
+import net.pterodactylus.xdcc.util.io.DuplicateLineSuppressingWriter;
 
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
@@ -58,7 +63,8 @@ public class CommandReader extends AbstractExecutionThreadService {
        private final BufferedReader reader;
 
        /** The writer to write the results to. */
-       private final Writer writer;
+       private final DuplicateLineSuppressingWriter writer;
+       private final Collection<Download> failedDownloads;
 
        /**
         * Creates a new command reader.
@@ -70,9 +76,10 @@ public class CommandReader extends AbstractExecutionThreadService {
         * @param writer
         *              The write to write results to
         */
-       public CommandReader(Core core, Reader reader, Writer writer) {
+       public CommandReader(Core core, Reader reader, Writer writer, Collection<Download> failedDownloads) {
                this.reader = new BufferedReader(reader);
-               this.writer = writer;
+               this.writer = new DuplicateLineSuppressingWriter(writer);
+               this.failedDownloads = failedDownloads;
 
                /* initialize commands. */
                ImmutableList.Builder<Command> commandBuilder = ImmutableList.builder();
@@ -83,6 +90,9 @@ public class CommandReader extends AbstractExecutionThreadService {
                commandBuilder.add(new ListConnectionsCommand(core));
                commandBuilder.add(new AbortDownloadCommand(core));
                commandBuilder.add(new DisconnectCommand(core));
+               commandBuilder.add(new FailedDownloadsCommand(failedDownloads));
+               commandBuilder.add(new RestartCommand(core, failedDownloads));
+               commandBuilder.add(new ResearchCommand(core));
                commands = commandBuilder.build();
        }
 
@@ -100,6 +110,7 @@ public class CommandReader extends AbstractExecutionThreadService {
                        if (line.equals("")) {
                                line = lastLine;
                        }
+                       writer.reset();
                        String[] words = line.split(" +");
                        String commandName = words[0];
                        Collection<Command> eligibleCommands = findEligibleCommands(commandName);
@@ -111,6 +122,7 @@ public class CommandReader extends AbstractExecutionThreadService {
                                Command command = eligibleCommands.iterator().next();
                                List<String> parameters = from(asList(words)).skip(1).toList();
                                state = command.execute(state, parameters, writer);
+                               writer.flush();
                        }
 
                        lastLine = line;
@@ -131,7 +143,7 @@ public class CommandReader extends AbstractExecutionThreadService {
        public void downloadStarted(DownloadStarted downloadStarted) {
                Download download = downloadStarted.download();
                try {
-                       writeLine(String.format("Download of %s (from %s, %s) has started.", download.pack().name(), download.bot().name(), download.bot().network().name()));
+                       writeLine(String.format("Download of %s (from %s, %s) has started.", bold(download.pack().name()), download.bot().name(), download.bot().network().name()));
                } catch (IOException ioe1) {
                        /* ignore. */
                }
@@ -146,13 +158,24 @@ public class CommandReader extends AbstractExecutionThreadService {
        @Subscribe
        public void downloadFinished(DownloadFinished downloadFinished) {
                Download download = downloadFinished.download();
+               removeFailedDownloads(download.pack().name());
                try {
-                       writeLine(String.format("Download of %s (from %s, %s) has finished, at %s/s.", download.pack().name(), download.bot().name(), download.bot().network().name(), f(download.dccReceiver().overallRate())));
+                       writeLine(green(String.format("Download of %s (from %s, %s) has finished, at %s/s.", download.pack().name(), download.bot().name(), download.bot().network().name(), f(download.dccReceiver().overallRate()))));
                } catch (IOException ioe1) {
                        /* ignore. */
                }
        }
 
+       private void removeFailedDownloads(String name) {
+               List<Download> failedDownloadsToRemove = new ArrayList<>();
+               for (Download failedDownload : failedDownloads) {
+                       if (failedDownload.pack().name().equals(name)) {
+                               failedDownloadsToRemove.add(failedDownload);
+                       }
+               }
+               failedDownloads.removeAll(failedDownloadsToRemove);
+       }
+
        /**
         * Called when a download fails.
         *
@@ -162,8 +185,9 @@ public class CommandReader extends AbstractExecutionThreadService {
        @Subscribe
        public void downloadFailed(DownloadFailed downloadFailed) {
                Download download = downloadFailed.download();
+               failedDownloads.add(download);
                try {
-                       writeLine(String.format("Download of %s (from %s, %s) has failed at %.1f%% and %s/s.", download.filename(), download.bot().name(), download.bot().network().name(), download.dccReceiver().progress() * 100.0 / download.dccReceiver().size(), f(download.dccReceiver().overallRate())));
+                       writeLine(red(String.format("Download of %s (from %s, %s) has failed at %.1f%% and %s/s.", download.filename(), download.bot().name(), download.bot().network().name(), download.dccReceiver().progress() * 100.0 / download.dccReceiver().size(), f(download.dccReceiver().overallRate()))));
                } catch (IOException ioe1) {
                        /* ignore. */
                }