diff --git a/core/src/main/groovy/com/muwire/core/Core.groovy b/core/src/main/groovy/com/muwire/core/Core.groovy index 541668e2..facdb6c5 100644 --- a/core/src/main/groovy/com/muwire/core/Core.groovy +++ b/core/src/main/groovy/com/muwire/core/Core.groovy @@ -54,7 +54,8 @@ public class Core { final EventBus eventBus final Persona me - + final File home + private final TrustService trustService private final PersisterService persisterService private final HostCache hostCache @@ -64,7 +65,8 @@ public class Core { private final ConnectionEstablisher connectionEstablisher private final HasherService hasherService - public Core(MuWireSettings props, File home) { + public Core(MuWireSettings props, File home) { + this.home = home log.info "Initializing I2P context" I2PAppContext.getGlobalContext().logManager() I2PAppContext.getGlobalContext()._logManager = new MuWireLogManager() @@ -164,7 +166,7 @@ public class Core { eventBus.register(ResultsEvent.class, searchManager) log.info("initializing download manager") - DownloadManager downloadManager = new DownloadManager(eventBus, i2pConnector) + DownloadManager downloadManager = new DownloadManager(eventBus, i2pConnector, new File(home, "incompletes")) eventBus.register(UIDownloadEvent.class, downloadManager) log.info("initializing upload manager") diff --git a/core/src/main/groovy/com/muwire/core/download/DownloadManager.groovy b/core/src/main/groovy/com/muwire/core/download/DownloadManager.groovy index 835bff44..50805f7d 100644 --- a/core/src/main/groovy/com/muwire/core/download/DownloadManager.groovy +++ b/core/src/main/groovy/com/muwire/core/download/DownloadManager.groovy @@ -11,10 +11,13 @@ public class DownloadManager { private final EventBus eventBus private final I2PConnector connector private final Executor executor + private final File incompletes - public DownloadManager(EventBus eventBus, I2PConnector connector) { + public DownloadManager(EventBus eventBus, I2PConnector connector, File incompletes) { this.eventBus = eventBus this.connector = connector + this.incompletes = incompletes + incompletes.mkdir() this.executor = Executors.newCachedThreadPool({ r -> Thread rv = new Thread(r) rv.setName("download-worker") @@ -26,7 +29,8 @@ public class DownloadManager { public void onUIDownloadEvent(UIDownloadEvent e) { def downloader = new Downloader(e.target, e.result.size, - e.result.infohash, e.result.pieceSize, connector, e.result.sender.destination) + e.result.infohash, e.result.pieceSize, connector, e.result.sender.destination, + incompletes) executor.execute({downloader.download()} as Runnable) eventBus.publish(new DownloadStartedEvent(downloader : downloader)) } diff --git a/core/src/main/groovy/com/muwire/core/download/Downloader.groovy b/core/src/main/groovy/com/muwire/core/download/Downloader.groovy index c527d614..332cb2f2 100644 --- a/core/src/main/groovy/com/muwire/core/download/Downloader.groovy +++ b/core/src/main/groovy/com/muwire/core/download/Downloader.groovy @@ -23,6 +23,7 @@ public class Downloader { private final I2PConnector connector private final Destination destination private final int nPieces + private final File piecesFile private Endpoint endpoint private volatile DownloadSession currentSession @@ -30,12 +31,14 @@ public class Downloader { private volatile boolean cancelled private volatile Thread downloadThread - public Downloader(File file, long length, InfoHash infoHash, int pieceSizePow2, I2PConnector connector, Destination destination) { + public Downloader(File file, long length, InfoHash infoHash, int pieceSizePow2, I2PConnector connector, Destination destination, + File incompletes) { this.file = file this.infoHash = infoHash this.length = length this.connector = connector this.destination = destination + this.piecesFile = new File(incompletes, file.getName()+".pieces") this.pieceSize = 1 << pieceSizePow2 int nPieces @@ -50,6 +53,7 @@ public class Downloader { } void download() { + readPieces() downloadThread = Thread.currentThread() Endpoint endpoint = null try { @@ -58,8 +62,10 @@ public class Downloader { while(!pieces.isComplete()) { currentSession = new DownloadSession(pieces, infoHash, endpoint, file, pieceSize, length) currentSession.request() + writePieces() } currentState = DownloadState.FINISHED + piecesFile.delete() } catch (Exception bad) { log.log(Level.WARNING,"Exception while downloading",bad) if (cancelled) @@ -71,6 +77,23 @@ public class Downloader { } } + void readPieces() { + if (!piecesFile.exists()) + return + piecesFile.withReader { + int piece = Integer.parseInt(it.readLine()) + pieces.markDownloaded(piece) + } + } + + void writePieces() { + piecesFile.withPrintWriter { writer -> + pieces.getDownloaded().each { piece -> + writer.println(piece) + } + } + } + public long donePieces() { pieces.donePieces() } diff --git a/core/src/main/groovy/com/muwire/core/download/Pieces.groovy b/core/src/main/groovy/com/muwire/core/download/Pieces.groovy index 64705e32..71749c58 100644 --- a/core/src/main/groovy/com/muwire/core/download/Pieces.groovy +++ b/core/src/main/groovy/com/muwire/core/download/Pieces.groovy @@ -33,6 +33,14 @@ class Pieces { } } + def getDownloaded() { + def rv = [] + for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet.nextSetBit(i+1)) { + rv << i + } + rv + } + synchronized void markDownloaded(int piece) { bitSet.set(piece) }