implement grouping by file

This commit is contained in:
Zlatin Balevsky
2019-12-04 07:45:51 +00:00
parent ea32af9b91
commit a2becfa6e2
3 changed files with 204 additions and 30 deletions

View File

@@ -69,6 +69,10 @@ public class SearchResults {
return bySender;
}
public Map<InfoHash, Set<UIResultEvent>> getByInfoHash() {
return byInfohash;
}
public Set<UIResultEvent> getByInfoHash(InfoHash infoHash) {
return byInfohash.get(infoHash);
}

View File

@@ -10,6 +10,7 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.muwire.core.InfoHash;
import com.muwire.core.Persona;
import com.muwire.core.search.UIResultEvent;
@@ -35,19 +36,13 @@ public class SearchServlet extends HttpServlet {
String section = req.getParameter("section");
StringBuilder sb = new StringBuilder();
sb.append("<?xml version='1.0' encoding='UTF-8'?>");
if (section.equals("activeSearches")) {
if (section.equals("groupBySender")) {
sb.append("<Searches>");
for (SearchResults results : searchManager.getResults().values()) {
sb.append("<Search>");
sb.append("<uuid>").append(results.getUUID()).append("</uuid>");
sb.append("<Query>").append(results.getSearch()).append("</Query>");
Map<Persona, Set<UIResultEvent>> bySender = results.getBySender();
sb.append("<Senders>").append(bySender.size()).append("</Senders>");
int total = 0;
for (Set<UIResultEvent> s : bySender.values()) {
total += s.size();
}
sb.append("<Results>").append(total).append("</Results>");
sb.append("<ResultsBySender>");
bySender.forEach((sender, resultsFromSender) -> {
sb.append("<ResultsFromSender>");
@@ -73,7 +68,32 @@ public class SearchServlet extends HttpServlet {
sb.append("</ResultsBySender>");
sb.append("</Search>");
}
sb.append("</Searches>");
sb.append("</Searches>");
} else if (section.equals("groupByFile")) {
sb.append("<Searches>");
for (SearchResults results : searchManager.getResults().values()) {
sb.append("<Search>");
sb.append("<uuid>").append(results.getUUID()).append("</uuid>");
sb.append("<Query>").append(results.getSearch()).append("</Query>");
Map<InfoHash, Set<UIResultEvent>> byInfohash = results.getByInfoHash();
sb.append("<ResultsByFile>");
byInfohash.forEach((infoHash, resultSet) -> {
sb.append("<ResultsForFile>");
UIResultEvent first = resultSet.iterator().next();
sb.append("<InfoHash>").append(Base64.encode(infoHash.getRoot())).append("</InfoHash>");
sb.append("<Name>").append(first.getName()).append("</Name>");
sb.append("<Size>").append(DataHelper.formatSize2Decimal(first.getSize(), false)).append("B").append("</Size>");
resultSet.forEach(result -> {
sb.append("<Result>");
sb.append("<Sender>").append(result.getSender().getHumanReadableName()).append("</Sender>");
sb.append("</Result>");
});
sb.append("</ResultsForFile>");
});
sb.append("</ResultsByFile>");
sb.append("</Search>");
}
sb.append("</Searches>");
} else if (section.equals("connectionsCount")) {
sb.append("<Connections>");
sb.append(connectionCounter.getConnections());

View File

@@ -12,6 +12,10 @@
String version = client.getCore().getVersion();
session.setAttribute("persona", persona);
session.setAttribute("version", version);
String groupBy = request.getParameter("groupBy");
if (groupBy == null)
groupBy = "sender";
%>
<html>
<head>
@@ -69,6 +73,11 @@
border:1px solid red;
}
</style>
<% if (groupBy.equals("sender")) { %>
<center><a href="/MuWire/Home.jsp?groupBy=file">Group By File</a></center>
<% } else { %>
<center><a href="/MuWire/Home.jsp?groupBy=sender">Group By Sender</a></center>
<% } %>
<table width="100%">
<tr>
<td width="20%">
@@ -109,7 +118,7 @@
<td>
<div id="table-wrapper">
<div id="table-scroll">
<div id="senders"></div>
<div id="topTable"></div>
</div>
</div>
</td>
@@ -129,7 +138,7 @@
<td>
<div id="table-wrapper">
<div id="table-scroll">
<div id="results">
<div id="bottomTable">
</div>
</div>
</td>
@@ -145,7 +154,7 @@
<script>
class Search {
class SearchBySender {
constructor(xmlNode) {
this.uuid = xmlNode.getElementsByTagName("uuid")[0].childNodes[0].nodeValue;
this.query = xmlNode.getElementsByTagName("Query")[0].childNodes[0].nodeValue;
@@ -155,38 +164,76 @@
var resultsFromSenders = resultsBySender.getElementsByTagName("ResultsFromSender");
var i;
for (i = 0; i < resultsFromSenders.length; i++) {
var results = new Results(resultsFromSenders[i]);
var results = new ResultsBySender(resultsFromSenders[i]);
this.resultBatches.set(results.sender, results);
}
}
}
class Results {
class SearchByFile {
constructor(xmlNode) {
this.uuid = xmlNode.getElementsByTagName("uuid")[0].childNodes[0].nodeValue;
this.query = xmlNode.getElementsByTagName("Query")[0].childNodes[0].nodeValue;
this.resultBatches = new Map();
var resultsByFile = xmlNode.getElementsByTagName("ResultsByFile")[0];
var resultsForFile = resultsByFile.getElementsByTagName("ResultsForFile");
var i;
for (i = 0; i < resultsForFile.length; i++) {
var results = new ResultsByFile(resultsForFile[i]);
this.resultBatches.set(results.infoHash, results);
}
}
}
class ResultsBySender {
constructor(xmlNode) {
this.sender = xmlNode.getElementsByTagName("Sender")[0].childNodes[0].nodeValue;
this.results = [];
var resultNodes = xmlNode.getElementsByTagName("Result");
var i;
for (i = 0 ; i < resultNodes.length; i ++) {
var result = new Result(resultNodes[i]);
var result = new ResultBySender(resultNodes[i]);
this.results.push(result);
}
}
}
class Result {
class ResultsByFile {
constructor(xmlNode) {
this.name = xmlNode.getElementsByTagName("Name")[0].childNodes[0].nodeValue;
this.infoHash = xmlNode.getElementsByTagName("InfoHash")[0].childNodes[0].nodeValue;
this.size = xmlNode.getElementsByTagName("Size")[0].childNodes[0].nodeValue;
this.results = [];
var resultNodes = xmlNode.getElementsByTagName("Result");
var i;
for (i = 0; i < resultNodes.length; i++) {
var result = new ResultByFile(resultNodes[i]);
this.results.push(result);
}
}
}
class ResultBySender {
constructor(xmlNode) {
this.name = xmlNode.getElementsByTagName("Name")[0].childNodes[0].nodeValue;
this.size = xmlNode.getElementsByTagName("Size")[0].childNodes[0].nodeValue;
this.infoHash = xmlNode.getElementsByTagName("InfoHash")[0].childNodes[0].nodeValue;
}
}
class ResultByFile {
constructor(xmlNode) {
this.sender = xmlNode.getElementsByTagName("Sender")[0].childNodes[0].nodeValue;
}
}
var searches = new Map();
var uuid = null;
var sender = null;
var lastXML = null;
var infoHash = null;
function refreshConnectionsCount() {
var xmlhttp = new XMLHttpRequest();
@@ -209,7 +256,7 @@
var resultsFromSpan = document.getElementById("resultsFrom");
resultsFromSpan.innerHTML = "Results From "+sender;
var resultsDiv = document.getElementById("results");
var resultsDiv = document.getElementById("bottomTable");
var table = "<table><thead><tr><th>Name</th><th>Size</th></tr></thead><tbody>"
var x = searches.get(uuid)
x = x.resultBatches.get(sender).results;
@@ -226,17 +273,40 @@
}
table += "</tbody></table>";
if (x.length > 0)
resultsDiv.innerHTML = table
resultsDiv.innerHTML = table;
}
function updateUUID(resultUUID) {
function updateFile(fileInfoHash) {
infoHash = fileInfoHash;
var searchResults = searches.get(uuid).resultBatches.get(infoHash);
var resultsFromSpan = document.getElementById("resultsFrom");
resultsFromSpan.innerHTML = "Results For "+searchResults.name;
var resultsDiv = document.getElementById("bottomTable");
var table = "<table><thead><tr><th>Sender</th></tr></thead><tbody>";
var i;
for (i = 0; i < searchResults.results.length; i++) {
table += "<tr>";
table += "<td>";
table += searchResults.results[i].sender;
table += "</td>";
table += "</tr>";
}
table += "</tbody></table>";
if (searchResults.results.length > 0)
resultsDiv.innerHTML = table;
}
function updateUUIDBySender(resultUUID) {
uuid = resultUUID;
var currentSearchSpan = document.getElementById("currentSearch");
currentSearchSpan.innerHTML = searches.get(uuid).query + " Results";
var sendersDiv = document.getElementById("senders");
var table = "<table><thead><tr><th>Sender</th></thead></tr><tbody>";
var sendersDiv = document.getElementById("topTable");
var table = "<table><thead><tr><th>Sender</th></tr></thead><tbody>";
var x = searches.get(uuid).resultBatches;
for (var [senderName, ignored] of x) {
table += "<tr><td><a href='#' onclick='updateSender(\""+senderName+"\");return false;'>"
@@ -250,7 +320,31 @@
updateSender(sender);
}
function refreshActiveSearches() {
function updateUUIDByFile(resultUUID) {
uuid = resultUUID;
var currentSearchSpan = document.getElementById("currentSearch");
currentSearchSpan.innerHTML = searches.get(uuid).query + " Results";
var topTableDiv = document.getElementById("topTable");
var table = "<table><thead><tr><th>Name</th><th>Size</th></tr></thead><tbody>";
var x = searches.get(uuid).resultBatches;
for (var [fileInfoHash, file] of x) {
table += "<tr><td><a href='#' onclick='updateFile(\""+fileInfoHash+"\");return false;'>";
table += file.name;
table += "</a></td>";
table += "<td>";
table += file.size;
table += "</td></tr>";
}
table += "</tbody></table>";
if (x.size > 0)
topTableDiv.innerHTML = table;
if (infoHash != null)
updateFile(infoHash);
}
function refreshGroupBySender() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
@@ -260,23 +354,26 @@
var i;
var x = xmlDoc.getElementsByTagName("Search");
for (i = 0; i < x.length; i++) {
var search = new Search(x[i]);
var search = new SearchBySender(x[i]);
searches.set(search.uuid, search);
}
var table = "<table><thead><tr><th>Search</th><th>Senders</th><th>Results</th></tr></thead><tbody>";
var activeSearchesDiv = document.getElementById("activeSearches");
for (var [resultsUUID, search] of searches) {
table += "<tr><td><a href='#' onclick='updateUUID(\"" + resultsUUID+ "\");return false;'>"
table += "<tr><td><a href='#' onclick='updateUUIDBySender(\"" + resultsUUID+ "\");return false;'>"
table += search.query;
table += "</a></td>";
table += "<td>"
table += search.resultBatches.size;
table += "</td>";
var totalResults = 0;
search.resultBatches.forEach(resultBatch => totalResults+=resultBatch.results.length);
var map = new Map();
for ( var [sender, results] of search.resultBatches ) {
results.results.forEach(result => map.set(result.infoHash, 1));
}
table += "<td>";
table += totalResults;
table += map.size;
table += "</td>"
table += "</tr>"
}
@@ -284,16 +381,69 @@
if (x.length > 0)
activeSearchesDiv.innerHTML = table;
if (uuid != null)
updateUUID(uuid);
updateUUIDBySender(uuid);
}
}
xmlhttp.open("GET", "/MuWire/Search?section=activeSearches", true);
xmlhttp.open("GET", "/MuWire/Search?section=groupBySender", true);
xmlhttp.send();
}
setInterval(refreshActiveSearches, 3000);
setTimeout(refreshActiveSearches, 1);
function refreshGroupByFile() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var xmlDoc = this.responseXML;
lastXML = xmlDoc;
searches.clear();
var i;
var x = xmlDoc.getElementsByTagName("Search");
for (i = 0; i < x.length; i++) {
var search = new SearchByFile(x[i]);
searches.set(search.uuid, search);
}
var table = "<table><thead><tr><th>Search</th><th>Senders</th><th>Results</th></tr></thead><tbody>";
var activeSearchesDiv = document.getElementById("activeSearches");
for (var [resultsUUID, search] of searches) {
table += "<tr><td><a href='#' onclick='updateUUIDByFile(\"" + resultsUUID+ "\");return false;'>"
table += search.query;
table += "</a></td>";
var map = new Map()
for (var [fileInfoHash, result] of search.resultBatches) {
result.results.forEach(sender => map.set(sender.sender, 1));
}
table += "<td>"
table += map.size;
table += "</td>";
table += "<td>";
table += search.resultBatches.size;
table += "</td>"
table += "</tr>"
}
table += "</tbody></table>"
if (x.length > 0)
activeSearchesDiv.innerHTML = table;
if (uuid != null)
updateUUIDByFile(uuid);
}
}
xmlhttp.open("GET", "/MuWire/Search?section=groupByFile", true);
xmlhttp.send();
}
<% if (groupBy.equals("sender")) { %>
setInterval(refreshGroupBySender, 3000);
setTimeout(refreshGroupBySender, 1);
<% } else { %>
setInterval(refreshGroupByFile, 3000);
setTimeout(refreshGroupByFile, 1);
<% } %>
setInterval(refreshConnectionsCount, 3000);
setTimeout(refreshConnectionsCount, 1);
</script>