pause/resume downloads

This commit is contained in:
Zlatin Balevsky
2019-06-23 06:59:52 +01:00
parent a3a91050c8
commit bd12a1de3d
4 changed files with 52 additions and 4 deletions

View File

@@ -25,7 +25,7 @@ import net.i2p.util.ConcurrentHashSet
@Log @Log
public class Downloader { public class Downloader {
public enum DownloadState { CONNECTING, HASHLIST, DOWNLOADING, FAILED, CANCELLED, FINISHED } public enum DownloadState { CONNECTING, HASHLIST, DOWNLOADING, FAILED, CANCELLED, PAUSED, FINISHED }
private enum WorkerState { CONNECTING, HASHLIST, DOWNLOADING, FINISHED} private enum WorkerState { CONNECTING, HASHLIST, DOWNLOADING, FINISHED}
private static final ExecutorService executorService = Executors.newCachedThreadPool({r -> private static final ExecutorService executorService = Executors.newCachedThreadPool({r ->
@@ -53,7 +53,7 @@ public class Downloader {
private final Set<Destination> successfulDestinations = new ConcurrentHashSet<>() private final Set<Destination> successfulDestinations = new ConcurrentHashSet<>()
private volatile boolean cancelled private volatile boolean cancelled, paused
private final AtomicBoolean eventFired = new AtomicBoolean() private final AtomicBoolean eventFired = new AtomicBoolean()
private boolean piecesFileClosed private boolean piecesFileClosed
@@ -136,6 +136,9 @@ public class Downloader {
public DownloadState getCurrentState() { public DownloadState getCurrentState() {
if (cancelled) if (cancelled)
return DownloadState.CANCELLED return DownloadState.CANCELLED
if (paused)
return DownloadState.PAUSED
boolean allFinished = true boolean allFinished = true
activeWorkers.values().each { activeWorkers.values().each {
allFinished &= it.currentState == WorkerState.FINISHED allFinished &= it.currentState == WorkerState.FINISHED
@@ -183,6 +186,11 @@ public class Downloader {
pieces.clearAll() pieces.clearAll()
} }
public void pause() {
paused = true
stop()
}
void stop() { void stop() {
activeWorkers.values().each { activeWorkers.values().each {
it.cancel() it.cancel()
@@ -203,6 +211,7 @@ public class Downloader {
def worker = activeWorkers.get(destination) def worker = activeWorkers.get(destination)
if (worker != null) { if (worker != null) {
if (worker.currentState == WorkerState.FINISHED) { if (worker.currentState == WorkerState.FINISHED) {
paused = false
def newWorker = new DownloadWorker(destination) def newWorker = new DownloadWorker(destination)
activeWorkers.put(destination, newWorker) activeWorkers.put(destination, newWorker)
executorService.submit(newWorker) executorService.submit(newWorker)

View File

@@ -165,6 +165,12 @@ class MainFrameController {
def downloader = model.downloads[selectedDownload()].downloader def downloader = model.downloads[selectedDownload()].downloader
downloader.resume() downloader.resume()
} }
@ControllerAction
void pause() {
def downloader = model.downloads[selectedDownload()].downloader
downloader.pause()
}
private void markTrust(String tableName, TrustLevel level, def list) { private void markTrust(String tableName, TrustLevel level, def list) {
int row = builder.getVariable(tableName).getSelectedRow() int row = builder.getVariable(tableName).getSelectedRow()

View File

@@ -68,6 +68,8 @@ class MainFrameModel {
@Observable boolean trustButtonsEnabled @Observable boolean trustButtonsEnabled
@Observable boolean cancelButtonEnabled @Observable boolean cancelButtonEnabled
@Observable boolean retryButtonEnabled @Observable boolean retryButtonEnabled
@Observable boolean pauseButtonEnabled
@Observable String resumeButtonText
private final Set<InfoHash> infoHashes = new HashSet<>() private final Set<InfoHash> infoHashes = new HashSet<>()
@@ -168,6 +170,8 @@ class MainFrameModel {
watched.addAll(core.muOptions.watchedDirectories) watched.addAll(core.muOptions.watchedDirectories)
builder.getVariable("watched-directories-table").model.fireTableDataChanged() builder.getVariable("watched-directories-table").model.fireTableDataChanged()
watched.each { core.eventBus.publish(new FileSharedEvent(file : new File(it))) } watched.each { core.eventBus.publish(new FileSharedEvent(file : new File(it))) }
resumeButtonText = "Retry"
} }
}) })

View File

@@ -135,8 +135,9 @@ class MainFrameView {
} }
} }
panel (constraints : BorderLayout.SOUTH) { panel (constraints : BorderLayout.SOUTH) {
button(text: "Pause", enabled : bind {model.pauseButtonEnabled}, pauseAction)
button(text: "Cancel", enabled : bind {model.cancelButtonEnabled }, cancelAction ) button(text: "Cancel", enabled : bind {model.cancelButtonEnabled }, cancelAction )
button(text: "Retry", enabled : bind {model.retryButtonEnabled}, resumeAction) button(text: bind { model.resumeButtonText }, enabled : bind {model.retryButtonEnabled}, resumeAction)
} }
} }
} }
@@ -295,6 +296,7 @@ class MainFrameView {
if (selectedRow < 0) { if (selectedRow < 0) {
model.cancelButtonEnabled = false model.cancelButtonEnabled = false
model.retryButtonEnabled = false model.retryButtonEnabled = false
model.pauseButtonEnabled = false
return return
} }
def downloader = model.downloads[selectedRow]?.downloader def downloader = model.downloads[selectedRow]?.downloader
@@ -305,15 +307,25 @@ class MainFrameView {
case Downloader.DownloadState.DOWNLOADING : case Downloader.DownloadState.DOWNLOADING :
case Downloader.DownloadState.HASHLIST: case Downloader.DownloadState.HASHLIST:
model.cancelButtonEnabled = true model.cancelButtonEnabled = true
model.pauseButtonEnabled = true
model.retryButtonEnabled = false model.retryButtonEnabled = false
break break
case Downloader.DownloadState.FAILED: case Downloader.DownloadState.FAILED:
model.cancelButtonEnabled = true model.cancelButtonEnabled = true
model.retryButtonEnabled = true model.retryButtonEnabled = true
model.resumeButtonText = "Retry"
model.pauseButtonEnabled = false
break
case Downloader.DownloadState.PAUSED:
model.cancelButtonEnabled = true
model.retryButtonEnabled = true
model.resumeButtonText = "Resume"
model.pauseButtonEnabled = false
break break
default: default:
model.cancelButtonEnabled = false model.cancelButtonEnabled = false
model.retryButtonEnabled = false model.retryButtonEnabled = false
model.pauseButtonEnabled = false
} }
}) })
@@ -421,21 +433,32 @@ class MainFrameView {
int selected = selectedDownloaderRow() int selected = selectedDownloaderRow()
if (selected < 0) if (selected < 0)
return return
boolean pauseEnabled = false
boolean cancelEnabled = false boolean cancelEnabled = false
boolean retryEnabled = false boolean retryEnabled = false
String resumeText = "Retry"
Downloader downloader = model.downloads[selected].downloader Downloader downloader = model.downloads[selected].downloader
switch(downloader.currentState) { switch(downloader.currentState) {
case Downloader.DownloadState.DOWNLOADING: case Downloader.DownloadState.DOWNLOADING:
case Downloader.DownloadState.HASHLIST: case Downloader.DownloadState.HASHLIST:
case Downloader.DownloadState.CONNECTING: case Downloader.DownloadState.CONNECTING:
pauseEnabled = true
cancelEnabled = true cancelEnabled = true
retryEnabled = false retryEnabled = false
break break
case Downloader.DownloadState.FAILED: case Downloader.DownloadState.FAILED:
pauseEnabled = false
cancelEnabled = true cancelEnabled = true
retryEnabled = true retryEnabled = true
break break
case Downloader.DownloadState.PAUSED:
pauseEnabled = false
cancelEnabled = true
retryEnabled = true
resumeText = "Resume"
break
default : default :
pauseEnabled = false
cancelEnabled = false cancelEnabled = false
retryEnabled = false retryEnabled = false
} }
@@ -450,6 +473,12 @@ class MainFrameView {
}) })
menu.add(copyHashToClipboard) menu.add(copyHashToClipboard)
if (pauseEnabled) {
JMenuItem pause = new JMenuItem("Pause")
pause.addActionListener({mvcGroup.controller.pause()})
menu.add(pause)
}
if (cancelEnabled) { if (cancelEnabled) {
JMenuItem cancel = new JMenuItem("Cancel") JMenuItem cancel = new JMenuItem("Cancel")
cancel.addActionListener({mvcGroup.controller.cancel()}) cancel.addActionListener({mvcGroup.controller.cancel()})
@@ -457,7 +486,7 @@ class MainFrameView {
} }
if (retryEnabled) { if (retryEnabled) {
JMenuItem retry = new JMenuItem("Retry") JMenuItem retry = new JMenuItem(resumeText)
retry.addActionListener({mvcGroup.controller.resume()}) retry.addActionListener({mvcGroup.controller.resume()})
menu.add(retry) menu.add(retry)
} }