diff --git a/src/main/java/.idea/.gitignore b/src/main/java/.idea/.gitignore
new file mode 100644
index 0000000..ab1f416
--- /dev/null
+++ b/src/main/java/.idea/.gitignore
@@ -0,0 +1,10 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Ignored default folder with query files
+/queries/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/src/main/java/.idea/misc.xml b/src/main/java/.idea/misc.xml
new file mode 100644
index 0000000..a20905f
--- /dev/null
+++ b/src/main/java/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/.idea/modules.xml b/src/main/java/.idea/modules.xml
new file mode 100644
index 0000000..122a905
--- /dev/null
+++ b/src/main/java/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/.idea/vcs.xml b/src/main/java/.idea/vcs.xml
new file mode 100644
index 0000000..c2365ab
--- /dev/null
+++ b/src/main/java/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/DownloadWorker.java b/src/main/java/DownloadWorker.java
index aab6865..ccd6620 100644
--- a/src/main/java/DownloadWorker.java
+++ b/src/main/java/DownloadWorker.java
@@ -24,8 +24,6 @@ public class DownloadWorker implements Runnable {
chunkStatus.setStartTimeMs(System.currentTimeMillis());
double downloaded = 0.0;
- System.out.println("Chunk " + chunkStatus.getChunkId() + " started downloading.");
-
while (downloaded < chunkStatus.getChunkSizeMB()) {
try {
int delay = config.getMinStepDelayMs()
@@ -50,7 +48,6 @@ public class DownloadWorker implements Runnable {
}
chunkStatus.setCompleted(true);
chunkStatus.setEndTimeMs(System.currentTimeMillis());
- System.out.println("[Worker-" + chunkStatus.getChunkId() + "] Download completed.");
}
}
diff --git a/src/main/java/ProgressMonitor.java b/src/main/java/ProgressMonitor.java
index 4a50402..7cf598d 100644
--- a/src/main/java/ProgressMonitor.java
+++ b/src/main/java/ProgressMonitor.java
@@ -16,16 +16,7 @@ public class ProgressMonitor implements Runnable {
@Override
public void run() {
- // TODO:
- // Repeatedly check chunk progress until all chunks are completed.
- // In each loop:
- // 1. Read the downloaded size from every chunk
- // 2. Add all downloaded amounts to totalDownloadedMB
- // 3. Count completed chunks
- // 4. Print a progress message
- // 5. If completedChunks == chunks.size(), print a final monitor message and stop
- // 6. Otherwise sleep for monitorDelayMs and continue
-
+ long startTimeMs = System.currentTimeMillis();
while (true) {
double totalDownloadedMB = 0.0;
@@ -33,29 +24,49 @@ public class ProgressMonitor implements Runnable {
for (ChunkStatus chunk : chunks) {
totalDownloadedMB += chunk.getDownloadedMB();
-
if (chunk.isCompleted()) {
completedChunks++;
}
}
- double percent = 0.0;
- if (totalSizeMB > 0) {
- percent = (totalDownloadedMB * 100.0) / totalSizeMB;
- }
+ long elapsedMs = System.currentTimeMillis() - startTimeMs;
+ double elapsedSeconds = elapsedMs / 1000.0;
+
+ double speedMBps = elapsedSeconds > 0.0
+ ? totalDownloadedMB / elapsedSeconds
+ : 0.0;
+
+ double percent = totalSizeMB > 0
+ ? totalDownloadedMB * 100.0 / totalSizeMB
+ : 100.0;
+ percent = Math.max(0.0, Math.min(100.0, percent));
+
+ double remainingMB = Math.max(0.0, totalSizeMB - totalDownloadedMB);
+ long etaSeconds = speedMBps > 0.0
+ ? (long) Math.ceil(remainingMB / speedMBps)
+ : 0L;
+
+ int barWidth = 40;
+ int filled = (int) Math.round(percent / 100.0 * barWidth);
+ filled = Math.max(0, Math.min(barWidth, filled));
+
+ String bar = "#".repeat(filled) + "-".repeat(barWidth - filled);
System.out.printf(
- "Progress for %s: %.1f/%.1f MB (%.2f%%), completed chunks: %d/%d%n",
- fileName,
- totalDownloadedMB,
- (double) totalSizeMB,
+ "\r[%s] %6.2f%% %7.1f/%d MB | %6.2f MB/s | ETA %s | chunks %d/%d",
+ bar,
percent,
+ totalDownloadedMB,
+ totalSizeMB,
+ speedMBps,
+ formatEta(etaSeconds),
completedChunks,
chunks.size()
);
-
+ System.out.flush();
if (completedChunks == chunks.size()) {
+ System.out.println();
System.out.println("All chunks completed.");
break;
}
@@ -63,9 +74,22 @@ public class ProgressMonitor implements Runnable {
try {
Thread.sleep(monitorDelayMs);
} catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ System.out.println();
System.out.println("Progress monitor interrupted.");
return;
}
}
}
+
+ private String formatEta(long totalSeconds) {
+ long minutes = totalSeconds / 60;
+ long seconds = totalSeconds % 60;
+
+ if (minutes > 0) {
+ return String.format("%dm %02ds", minutes, seconds);
+ }
+
+ return String.format("%ds", seconds);
+ }
}