Merge branch 'source-tracking'

pull/5/head
Zlatin Balevsky 2019-06-18 12:22:46 +01:00
commit e85a0c7b2c
10 changed files with 55 additions and 6 deletions

View File

@ -58,6 +58,8 @@ public class DownloadManager {
e.result.each {
destinations.add(it.sender.destination)
}
destinations.addAll(e.sources)
destinations.remove(me.destination)
def downloader = new Downloader(eventBus, this, me, e.target, size,
infohash, pieceSize, connector, destinations,

View File

@ -85,7 +85,7 @@ class DownloadSession {
if (code.startsWith("404 ")) {
log.warning("file not found")
endpoint.close()
return
return false
}
if (code.startsWith("416 ")) {

View File

@ -21,6 +21,7 @@ import com.muwire.core.files.FileDownloadedEvent
import groovy.util.logging.Log
import net.i2p.data.Destination
import net.i2p.util.ConcurrentHashSet
@Log
public class Downloader {
@ -49,6 +50,7 @@ public class Downloader {
private final File incompleteFile
final int pieceSizePow2
private final Map<Destination, DownloadWorker> activeWorkers = new ConcurrentHashMap<>()
private final Set<Destination> successfulDestinations = new ConcurrentHashSet<>()
private volatile boolean cancelled
@ -249,6 +251,7 @@ public class Downloader {
requestPerformed = currentSession.request()
if (!requestPerformed)
break
successfulDestinations.add(endpoint.destination)
writePieces()
}
} catch (Exception bad) {
@ -268,7 +271,7 @@ public class Downloader {
}
eventBus.publish(
new FileDownloadedEvent(
downloadedFile : new DownloadedFile(file, getInfoHash(), pieceSizePow2, Collections.emptySet()),
downloadedFile : new DownloadedFile(file, getInfoHash(), pieceSizePow2, successfulDestinations),
downloader : Downloader.this))
}

View File

@ -3,8 +3,11 @@ package com.muwire.core.download
import com.muwire.core.Event
import com.muwire.core.search.UIResultEvent
import net.i2p.data.Destination
class UIDownloadEvent extends Event {
UIResultEvent[] result
Set<Destination> sources
File target
}

View File

@ -1,5 +1,7 @@
package com.muwire.core.search
import java.util.stream.Collectors
import javax.naming.directory.InvalidSearchControlsException
import com.muwire.core.InfoHash
@ -7,6 +9,7 @@ import com.muwire.core.Persona
import com.muwire.core.util.DataUtil
import net.i2p.data.Base64
import net.i2p.data.Destination
class ResultsParser {
public static UIResultEvent parse(Persona p, UUID uuid, def json) throws InvalidSearchResultException {
@ -58,6 +61,7 @@ class ResultsParser {
size : size,
infohash : parsedIH,
pieceSize : pieceSize,
sources : Collections.emptySet(),
uuid : uuid)
} catch (Exception e) {
throw new InvalidSearchResultException("parsing search result failed",e)
@ -82,11 +86,17 @@ class ResultsParser {
if (infoHash.length != InfoHash.SIZE)
throw new InvalidSearchResultException("invalid infohash size $infoHash.length")
int pieceSize = json.pieceSize
Set<Destination> sources = Collections.emptySet()
if (json.sources != null)
sources = json.sources.stream().map({new Destination(it)}).collect(Collectors.toSet())
return new UIResultEvent( sender : p,
name : name,
size : size,
infohash : new InfoHash(infoHash),
pieceSize : pieceSize,
sources : sources,
uuid: uuid)
} catch (Exception e) {
throw new InvalidSearchResultException("parsing search result failed",e)

View File

@ -11,7 +11,9 @@ import java.util.concurrent.Executor
import java.util.concurrent.Executors
import java.util.concurrent.ThreadFactory
import java.util.concurrent.atomic.AtomicInteger
import java.util.stream.Collectors
import com.muwire.core.DownloadedFile
import com.muwire.core.EventBus
import com.muwire.core.InfoHash
@ -54,12 +56,16 @@ class ResultsSender {
int pieceSize = it.getPieceSize()
if (pieceSize == 0)
pieceSize = FileHasher.getPieceSize(length)
Set<Destination> suggested = Collections.emptySet()
if (it instanceof DownloadedFile)
suggested = it.sources
def uiResultEvent = new UIResultEvent( sender : me,
name : it.getFile().getName(),
size : length,
infohash : it.getInfoHash(),
pieceSize : pieceSize,
uuid : uuid
uuid : uuid,
sources : suggested
)
eventBus.publish(uiResultEvent)
}
@ -110,6 +116,10 @@ class ResultsSender {
}
obj.hashList = hashListB64
}
if (it instanceof DownloadedFile)
obj.sources = it.sources.stream().map({dest -> dest.toBase64()}).collect(Collectors.toSet())
def json = jsonOutput.toJson(obj)
os.writeShort((short)json.length())
os.write(json.getBytes(StandardCharsets.US_ASCII))

View File

@ -4,8 +4,11 @@ import com.muwire.core.Event
import com.muwire.core.InfoHash
import com.muwire.core.Persona
import net.i2p.data.Destination
class UIResultEvent extends Event {
Persona sender
Set<Destination> sources
UUID uuid
String name
long size

View File

@ -129,8 +129,9 @@ class MainFrameController {
def group = selected.getClientProperty("mvc-group")
def resultsBucket = group.model.hashBucket[result.infohash]
def sources = group.model.sourcesBucket[result.infohash]
core.eventBus.publish(new UIDownloadEvent(result : resultsBucket, target : file))
core.eventBus.publish(new UIDownloadEvent(result : resultsBucket, sources: sources, target : file))
}
@ControllerAction

View File

@ -23,6 +23,7 @@ class SearchTabModel {
String uuid
def results = []
def hashBucket = [:]
def sourcesBucket = [:]
void mvcGroupInit(Map<String, String> args) {
@ -46,6 +47,13 @@ class SearchTabModel {
hashBucket[e.infohash] = bucket
}
bucket << e
Set sourceBucket = sourcesBucket.get(e.infohash)
if (sourceBucket == null) {
sourceBucket = new HashSet()
sourcesBucket.put(e.infohash, sourceBucket)
}
sourceBucket.addAll(e.sources)
results << e
JTable table = builder.getVariable("results-table")
@ -63,6 +71,14 @@ class SearchTabModel {
bucket = []
hashBucket[it.infohash] = bucket
}
Set sourceBucket = sourcesBucket.get(it.infohash)
if (sourceBucket == null) {
sourceBucket = new HashSet()
sourcesBucket.put(it.infohash, sourceBucket)
}
sourceBucket.addAll(it.sources)
bucket << it
results << it
}

View File

@ -47,8 +47,9 @@ class SearchTabView {
resultsTable = table(id : "results-table", autoCreateRowSorter : true) {
tableModel(list: model.results) {
closureColumn(header: "Name", preferredWidth: 350, type: String, read : {row -> row.name.replace('<','_')})
closureColumn(header: "Size", preferredWidth: 50, type: Long, read : {row -> row.size})
closureColumn(header: "Sources", preferredWidth: 10, type : Integer, read : { row -> model.hashBucket[row.infohash].size()})
closureColumn(header: "Size", preferredWidth: 20, type: Long, read : {row -> row.size})
closureColumn(header: "Direct Sources", preferredWidth: 50, type : Integer, read : { row -> model.hashBucket[row.infohash].size()})
closureColumn(header: "Possible Sources", preferredWidth : 50, type : Integer, read : {row -> model.sourcesBucket[row.infohash].size()})
closureColumn(header: "Sender", preferredWidth: 170, type: String, read : {row -> row.sender.getHumanReadableName()})
closureColumn(header: "Trust", preferredWidth: 50, type: String, read : {row ->
model.core.trustService.getLevel(row.sender.destination).toString()