import static java.util.Arrays.asList;
import static net.pterodactylus.xdcc.data.Download.BY_NAME;
import static net.pterodactylus.xdcc.data.Download.BY_RUNNING;
+import static net.pterodactylus.xdcc.data.Download.SECONDS_LEFT;
import static net.pterodactylus.xdcc.ui.stdin.CommandReader.f;
+import static net.pterodactylus.xdcc.ui.stdin.CommandReader.t;
import java.io.IOException;
import java.io.Writer;
import net.pterodactylus.xdcc.core.Core;
import net.pterodactylus.xdcc.data.Download;
+import com.google.common.collect.FluentIterable;
import com.google.common.collect.Ordering;
/**
*/
public class ListDownloadsCommand implements Command {
+ private static final int PROGRESS_BAR_WIDTH = 10;
+
/** The core to operate on. */
private final Core core;
outputWriter.write(String.format("[%d] %s requested from %s (not started yet)\n", counter++, download.pack().name(), download.bot().name()));
continue;
}
- outputWriter.write(String.format("[%d] %s from %s (%s, ", counter++, dccReceiver.filename(), download.bot().name(), f(dccReceiver.size())));
+ outputWriter.write(String.format("[%d] %s %s from %s (%s, ", counter++, getProgressBar(dccReceiver, PROGRESS_BAR_WIDTH), dccReceiver.filename(), download.bot().name(), f(dccReceiver.size())));
if (dccReceiver.isRunning()) {
- outputWriter.write(String.format("%.1f%%, %s/s, %s", dccReceiver.progress() * 100.0 / dccReceiver.size(), f(dccReceiver.currentRate()), getTimeLeft(dccReceiver)));
+ outputWriter.write(String.format("%.1f%%, %s/s, %s", dccReceiver.progress() * 100.0 / dccReceiver.size(), f(dccReceiver.currentRate()), t(SECONDS_LEFT.apply(download))));
} else {
if (dccReceiver.progress() >= dccReceiver.size()) {
outputWriter.write(String.format("complete, %s/s", f(dccReceiver.overallRate())));
return state.setLastDownloads(downloads);
}
- //
- // PRIVATE METHODS
- //
-
/**
- * Returns the estimated time left for the given transfer.
+ * Creates a progress bar for the given DCC receiver.
*
* @param dccReceiver
- * The DCC receiver to get the time left for
- * @return The time left for the transfer, or “unknown” if the time can not be
- * estimated
+ * The DCC receiver to create the progress bar for
+ * @param progressBarWidth
+ * The width of the progress bar (in characters)
+ * @return The progress bar for the given DCC receiver
*/
- private static String getTimeLeft(DccReceiver dccReceiver) {
- if ((dccReceiver.size() == -1) || (dccReceiver.currentRate() == 0)) {
- return "unknown";
- }
- long secondsLeft = (dccReceiver.size() - dccReceiver.progress()) / dccReceiver.currentRate();
- if (secondsLeft > 3600) {
- return String.format("%02d:%02d:%02d", secondsLeft / 3600, (secondsLeft / 60) % 60, secondsLeft % 60);
+ private static String getProgressBar(DccReceiver dccReceiver, int progressBarWidth) {
+ FluentIterable<Character> partialProgressCharacters = from(asList(' ', '\u258f', '\u258e', '\u258d', '\u258c', '\u258b', '\u258a', '\u2589', '\u2588'));
+ double progress = dccReceiver.progress() * 100.0 / dccReceiver.size();
+ double singleBlockWidth = 100.0 / progressBarWidth;
+ int fullProgressBlocks = (int) (progress / singleBlockWidth);
+ double lastBlockProgress = (progress - fullProgressBlocks * singleBlockWidth) / singleBlockWidth;
+ StringBuilder progressBar = new StringBuilder(progressBarWidth);
+ for (int i = 0; i < progressBarWidth; ++i) {
+ if (i < fullProgressBlocks) {
+ progressBar.append(partialProgressCharacters.last().get());
+ } else if (i > fullProgressBlocks) {
+ progressBar.append(partialProgressCharacters.first().get());
+ } else {
+ progressBar.append(partialProgressCharacters.get((int) (lastBlockProgress * (partialProgressCharacters.size() - 1))));
+ }
}
- return String.format("%02d:%02d", (secondsLeft / 60) % 60, secondsLeft % 60);
+ return progressBar.toString();
}
}