diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesModel.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesModel.groovy index dc7b2788..a00a6e03 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesModel.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesModel.groovy @@ -17,7 +17,7 @@ class FilesModel { private final TextGUIThread guiThread private final Core core private final List sharedFiles = new ArrayList<>() - private final TableModel model = new TableModel("Name","Size","Comment") + private final TableModel model = new TableModel("Name","Size","Comment","Search Hits","Downloaders") FilesModel(TextGUIThread guiThread, Core core) { this.guiThread = guiThread @@ -71,7 +71,9 @@ class FilesModel { sharedFiles.each { long size = it.getCachedLength() boolean comment = it.comment != null - model.addRow(new SharedFileWrapper(it), DataHelper.formatSize2(size, false)+"B", comment) + String hits = String.valueOf(it.getHits()) + String downloaders = String.valueOf(it.getDownloaders().size()) + model.addRow(new SharedFileWrapper(it), DataHelper.formatSize2(size, false)+"B", comment, hits, downloaders) } } } diff --git a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesView.groovy b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesView.groovy index 4860964f..3985c716 100644 --- a/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesView.groovy +++ b/cli-lanterna/src/main/groovy/com/muwire/clilanterna/FilesView.groovy @@ -42,7 +42,7 @@ class FilesView extends BasicWindow { contentPanel.setLayoutManager(new GridLayout(1)) LayoutData layoutData = GridLayout.createLayoutData(Alignment.CENTER, Alignment.CENTER, true, false) - table = new Table("Name","Size","Comment") + table = new Table("Name","Size","Comment","Search Hits","Downloaders") table.setCellSelection(false) table.setTableModel(model.model) table.setSelectAction({rowSelected()}) diff --git a/core/src/main/groovy/com/muwire/core/files/FileManager.groovy b/core/src/main/groovy/com/muwire/core/files/FileManager.groovy index 7df2ffb3..6f6691a5 100644 --- a/core/src/main/groovy/com/muwire/core/files/FileManager.groovy +++ b/core/src/main/groovy/com/muwire/core/files/FileManager.groovy @@ -158,8 +158,10 @@ class FileManager { Set found found = rootToFiles.get new InfoHash(e.searchHash) found = filter(found, e.oobInfohash) - if (found != null && !found.isEmpty()) + if (found != null && !found.isEmpty()) { + found.each { it.hit() } re = new ResultsEvent(results: found.asList(), uuid: e.uuid, searchEvent: e) + } } else { def names = index.search e.searchTerms Set files = new HashSet<>() @@ -172,8 +174,10 @@ class FileManager { files.each { sharedFiles.add fileToSharedFile[it] } files = filter(sharedFiles, e.oobInfohash) - if (!sharedFiles.isEmpty()) + if (!sharedFiles.isEmpty()) { + sharedFiles.each { it.hit() } re = new ResultsEvent(results: sharedFiles.asList(), uuid: e.uuid, searchEvent: e) + } } diff --git a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy index f31da894..251577cb 100644 --- a/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy +++ b/core/src/main/groovy/com/muwire/core/files/PersisterService.groovy @@ -129,9 +129,15 @@ class PersisterService extends Service { return new FileLoadedEvent(loadedFile : df) } + int hits = 0 + if (json.hits != null) + hits = json.hits SharedFile sf = new SharedFile(file, ih, pieceSize) sf.setComment(json.comment) + sf.hits = hits + if (json.downloaders != null) + sf.getDownloaders().addAll(json.downloaders) return new FileLoadedEvent(loadedFile: sf) } @@ -163,6 +169,8 @@ class PersisterService extends Service { json.pieceSize = sf.getPieceSize() json.hashList = sf.getB64EncodedHashList() json.comment = sf.getComment() + json.hits = sf.getHits() + json.downloaders = sf.getDownloaders() if (sf instanceof DownloadedFile) { json.sources = sf.sources.stream().map( {d -> d.toBase64()}).collect(Collectors.toList()) diff --git a/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy b/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy index ed157beb..46540218 100644 --- a/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy +++ b/core/src/main/groovy/com/muwire/core/upload/UploadManager.groovy @@ -91,6 +91,7 @@ public class UploadManager { file = downloader.incompleteFile pieceSize = downloader.pieceSizePow2 } else { + sharedFiles.each { it.getDownloaders().add(request.downloader.getHumanReadableName()) } SharedFile sharedFile = sharedFiles.iterator().next(); mesh = meshManager.getOrCreate(request.infoHash, sharedFile.NPieces, false) file = sharedFile.file @@ -216,6 +217,7 @@ public class UploadManager { file = downloader.incompleteFile pieceSize = downloader.pieceSizePow2 } else { + sharedFiles.each { it.getDownloaders().add(request.downloader.getHumanReadableName()) } SharedFile sharedFile = sharedFiles.iterator().next(); mesh = meshManager.getOrCreate(request.infoHash, sharedFile.NPieces, false) file = sharedFile.file diff --git a/core/src/main/java/com/muwire/core/SharedFile.java b/core/src/main/java/com/muwire/core/SharedFile.java index 1860b91e..ad17ae40 100644 --- a/core/src/main/java/com/muwire/core/SharedFile.java +++ b/core/src/main/java/com/muwire/core/SharedFile.java @@ -3,7 +3,10 @@ package com.muwire.core; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import com.muwire.core.util.DataUtil; @@ -23,6 +26,8 @@ public class SharedFile { private final List b64EncodedHashList; private volatile String comment; + private volatile int hits; + private final Set downloaders = Collections.synchronizedSet(new HashSet<>()); public SharedFile(File file, InfoHash infoHash, int pieceSize) throws IOException { this.file = file; @@ -90,6 +95,22 @@ public class SharedFile { public String getComment() { return comment; } + + public int getHits() { + return hits; + } + + public void hit() { + hits++; + } + + public Set getDownloaders() { + return downloaders; + } + + public void addDownloader(String name) { + downloaders.add(name); + } @Override public int hashCode() { diff --git a/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy b/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy index 445dd2aa..71831cf4 100644 --- a/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy +++ b/gui/griffon-app/models/com/muwire/gui/MainFrameModel.groovy @@ -35,6 +35,7 @@ import com.muwire.core.files.FileLoadedEvent import com.muwire.core.files.FileSharedEvent import com.muwire.core.files.FileUnsharedEvent import com.muwire.core.search.QueryEvent +import com.muwire.core.search.SearchEvent import com.muwire.core.search.UIResultBatchEvent import com.muwire.core.search.UIResultEvent import com.muwire.core.trust.TrustEvent @@ -199,6 +200,7 @@ class MainFrameModel { core.eventBus.register(AllFilesLoadedEvent.class, this) core.eventBus.register(UpdateDownloadedEvent.class, this) core.eventBus.register(TrustSubscriptionUpdatedEvent.class, this) + core.eventBus.register(SearchEvent.class, this) core.muOptions.watchedKeywords.each { core.eventBus.publish(new ContentControlEvent(term : it, regex: false, add: true)) @@ -379,6 +381,7 @@ class MainFrameModel { uploads << e.uploader JTable table = builder.getVariable("uploads-table") table.model.fireTableDataChanged() + view.refreshSharedFiles() } } @@ -416,6 +419,12 @@ class MainFrameModel { updateTablePreservingSelection("subscription-table") } } + + void onSearchEvent(SearchEvent e) { + runInsideUIAsync { + view.refreshSharedFiles() + } + } void onQueryEvent(QueryEvent e) { if (e.replyTo == core.me.destination) diff --git a/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy b/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy index 7b446421..5e65d344 100644 --- a/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy +++ b/gui/griffon-app/views/com/muwire/gui/MainFrameView.groovy @@ -226,8 +226,10 @@ class MainFrameView { table(id : "shared-files-table", autoCreateRowSorter: true) { tableModel(list : model.shared) { closureColumn(header : "Name", preferredWidth : 500, type : String, read : {row -> row.getCachedPath()}) - closureColumn(header : "Size", preferredWidth : 100, type : Long, read : {row -> row.getCachedLength() }) - closureColumn(header : "Comments", preferredWidth : 100, type : Boolean, read : {it.getComment() != null}) + closureColumn(header : "Size", preferredWidth : 50, type : Long, read : {row -> row.getCachedLength() }) + closureColumn(header : "Comments", preferredWidth : 50, type : Boolean, read : {it.getComment() != null}) + closureColumn(header : "Search Hits", preferredWidth: 50, type : Integer, read : {it.getHits()}) + closureColumn(header : "Downloaders", preferredWidth: 50, type : Integer, read : {it.getDownloaders().size()}) } } }