diff --git a/webui/src/main/java/com/muwire/webui/SearchServlet.java b/webui/src/main/java/com/muwire/webui/SearchServlet.java index 72d2c72f..60207387 100644 --- a/webui/src/main/java/com/muwire/webui/SearchServlet.java +++ b/webui/src/main/java/com/muwire/webui/SearchServlet.java @@ -1,5 +1,6 @@ package com.muwire.webui; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -97,17 +98,22 @@ public class SearchServlet extends HttpServlet { if (results == null) return; - sb.append(""); + List senders = new ArrayList<>(); results.getBySender().forEach( (persona, resultsFromSender) -> { Sender sender = new Sender(persona, core.getTrustService().getLevel(persona.getDestination()), resultsFromSender.iterator().next().getBrowse(), browseManager.isBrowsing(persona), resultsFromSender.size()); - sender.toXML(sb); + senders.add(sender); }); + + sort(senders, req, SENDER_COMPARATORS); + + sb.append(""); + senders.forEach(sender -> sender.toXML(sb)); sb.append(""); - } else if (section.equals("groupBySender")) { + } else if (section.equals("resultsFromSender")) { if (searchManager == null || downloadManager == null) { resp.sendError(403, "Not initialized"); return; @@ -121,46 +127,30 @@ public class SearchServlet extends HttpServlet { UUID uuid = UUID.fromString(uuidString); - SearchResults results = searchManager.getResults().get(uuid); - if (results == null) + String senderB64 = req.getParameter("sender"); + Persona sender; + try { + sender = new Persona(new ByteArrayInputStream(Base64.decode(senderB64))); + } catch (Exception bad) { + resp.sendError(403, "Bad param"); return; + } - Map> bySender = results.getBySender(); - sb.append(""); - bySender.forEach((sender, resultsFromSender) -> { - sb.append(""); - sb.append(""); - sb.append(Util.escapeHTMLinXML(sender.getHumanReadableName())); - sb.append(""); - sb.append("").append(sender.toBase64()).append(""); - sb.append("").append(resultsFromSender.iterator().next().getBrowse()).append(""); - sb.append("").append(browseManager.isBrowsing(sender)).append(""); - sb.append("").append(core.getTrustService().getLevel(sender.getDestination())).append(""); - resultsFromSender.forEach(result -> { - sb.append(""); - sb.append(""); - sb.append(Util.escapeHTMLinXML(result.getName())); - sb.append(""); - sb.append(""); - sb.append(DataHelper.formatSize2Decimal(result.getSize(), false)).append("B"); - sb.append(""); - String infohash = Base64.encode(result.getInfohash().getRoot()); - sb.append(""); - sb.append(infohash); - sb.append(""); - sb.append("").append(downloadManager.isDownloading(result.getInfohash())).append(""); - if (result.getComment() != null) { - sb.append("") - .append(Util.escapeHTMLinXML(result.getComment())) - .append(""); - } - sb.append("").append(result.getCertificates()).append(""); - sb.append(""); - }); - sb.append(""); + SearchResults searchResults = searchManager.getResults().get(uuid); + Set results = searchResults.getBySender().get(sender); + List resultsFromSender = new ArrayList<>(); + results.forEach(result -> { + ResultFromSender resultFromSender = new ResultFromSender(result, + downloadManager.isDownloading(result.getInfohash())); + resultsFromSender.add(resultFromSender); }); - sb.append(""); - } else if (section.equals("groupByFile")) { + + sort(resultsFromSender, req, RESULT_FROM_SENDER_COMPARATORS); + + sb.append(""); + resultsFromSender.forEach(result -> result.toXML(sb)); + sb.append(""); + } else if (section.equals("results")) { if (searchManager == null || downloadManager == null) { resp.sendError(403, "Not initialized"); return; @@ -173,38 +163,73 @@ public class SearchServlet extends HttpServlet { } UUID uuid = UUID.fromString(uuidString); - - SearchResults results = searchManager.getResults().get(uuid); - if (results == null) + SearchResults searchResults = searchManager.getResults().get(uuid); + if (searchResults == null) return; - - Map> byInfohash = results.getByInfoHash(); - sb.append(""); - byInfohash.forEach((infoHash, resultSet) -> { - sb.append(""); - UIResultEvent first = resultSet.iterator().next(); - sb.append("").append(Base64.encode(infoHash.getRoot())).append(""); - sb.append("").append(downloadManager.isDownloading(infoHash)).append(""); - sb.append("").append(Util.escapeHTMLinXML(first.getName())).append(""); - sb.append("").append(DataHelper.formatSize2Decimal(first.getSize(), false)).append("B").append(""); - resultSet.forEach(result -> { - sb.append(""); - sb.append("").append(Util.escapeHTMLinXML(result.getSender().getHumanReadableName())).append(""); - sb.append("").append(result.getSender().toBase64()).append(""); - sb.append("").append(result.getBrowse()).append(""); - sb.append("").append(browseManager.isBrowsing(result.getSender())).append(""); - sb.append("").append(core.getTrustService().getLevel(result.getSender().getDestination())).append(""); - if (result.getComment() != null) { - sb.append("") - .append(Util.escapeHTMLinXML(result.getComment())) - .append(""); - } - sb.append("").append(result.getCertificates()).append(""); - sb.append(""); - }); - sb.append(""); + Map> byInfohash = searchResults.getByInfoHash(); + + List results = new ArrayList<>(); + byInfohash.forEach( (infoHash, resultSet) -> { + UIResultEvent event = resultSet.iterator().next(); + Result result = new Result(event.getName(), + event.getSize(), + downloadManager.isDownloading(infoHash), + infoHash); + results.add(result); }); - sb.append(""); + + sort(results, req, RESULT_COMPARATORS); + + sb.append(""); + results.forEach(result -> result.toXML(sb)); + sb.append(""); + } else if (section.equals("sendersForResult")) { + if (searchManager == null || downloadManager == null) { + resp.sendError(403, "Not initialized"); + return; + } + + String uuidString = req.getParameter("uuid"); + if (uuidString == null) { + resp.sendError(403, "Bad param"); + return; + } + + UUID uuid = UUID.fromString(uuidString); + SearchResults searchResults = searchManager.getResults().get(uuid); + if (searchResults == null) + return; + + String infoHashB64 = req.getParameter("infoHash"); + InfoHash infoHash; + try { + infoHash = new InfoHash(Base64.decode(infoHashB64)); + } catch (Exception bad) { + resp.sendError(403, "Bad param"); + return; + } + + Set resultSet = searchResults.getByInfoHash(infoHash); + if (resultSet == null) + return; + + List sendersForResult = new ArrayList<>(); + resultSet.forEach(event -> { + SenderForResult senderForResult = new SenderForResult(event.getSender(), + event.getBrowse(), + browseManager.isBrowsing(event.getSender()), + event.getComment(), + event.getCertificates(), + core.getTrustService().getLevel(event.getSender().getDestination())); + sendersForResult.add(senderForResult); + }); + + sort(sendersForResult, req, SENDER_FOR_RESULT_COMPARATORS); + + sb.append(""); + sendersForResult.forEach(sender -> sender.toXML(sb)); + sb.append(""); + } else if (section.equals("connectionsCount")) { if (connectionCounter == null) { resp.sendError(403, "Not initialized"); @@ -217,6 +242,7 @@ public class SearchServlet extends HttpServlet { resp.sendError(403, "Bad section param"); return; } + resp.setContentType("text/xml"); resp.setCharacterEncoding("UTF-8"); resp.setDateHeader("Expires", 0); @@ -238,7 +264,7 @@ public class SearchServlet extends HttpServlet { core = (Core) config.getServletContext().getAttribute("core"); } - private class Sender { + private static class Sender { private final Persona persona; private final TrustLevel trustLevel; private final boolean browse; @@ -265,6 +291,100 @@ public class SearchServlet extends HttpServlet { } } + private static class ResultFromSender { + private final String name; + private final long size; + private final InfoHash infoHash; + private final boolean downloading; + private final String comment; + private final int certificates; + + ResultFromSender(UIResultEvent e, boolean downloading) { + this.name = e.getName(); + this.size = e.getSize(); + this.infoHash = e.getInfohash(); + this.downloading = downloading; + this.comment = e.getComment(); + this.certificates = e.getCertificates(); + } + + void toXML(StringBuilder sb) { + sb.append(""); + sb.append("").append(Util.escapeHTMLinXML(name)).append(""); + sb.append("").append(DataHelper.formatSize2Decimal(size, false)).append("B").append(""); + sb.append("").append(Base64.encode(infoHash.getRoot())).append(""); + sb.append("").append(downloading).append(""); + if (comment != null) + sb.append("").append(Util.escapeHTMLinXML(comment)).append(""); + sb.append("").append(certificates).append(""); + sb.append(""); + } + } + + private static class Result { + private final String name; + private final long size; + private final boolean downloading; + private final InfoHash infoHash; + + Result(String name, long size, boolean downloading, InfoHash infoHash) { + this.name = name; + this.size = size; + this.downloading = downloading; + this.infoHash = infoHash; + } + + void toXML(StringBuilder sb) { + sb.append(""); + sb.append("").append(Util.escapeHTMLinXML(name)).append(""); + sb.append("").append(DataHelper.formatSize2Decimal(size, false)).append("B").append(""); + sb.append("").append(Base64.encode(infoHash.getRoot())).append(""); + sb.append("").append(downloading).append(""); + sb.append(""); + } + } + + + private static class SenderForResult { + private final Persona sender; + private final boolean browse; + private final boolean browsing; + private final String comment; + private final int certificates; + private final TrustLevel trustLevel; + + SenderForResult(Persona sender, boolean browse, boolean browsing, String comment, int certificates, TrustLevel trustLevel) { + this.sender = sender; + this.browse = browse; + this.trustLevel = trustLevel; + this.browsing = browsing; + this.comment = comment; + this.certificates = certificates; + } + + void toXML(StringBuilder sb) { + sb.append(""); + sb.append("").append(Util.escapeHTMLinXML(sender.getHumanReadableName())).append(""); + sb.append("").append(sender.toBase64()).append(""); + sb.append("").append(browse).append(""); + sb.append("").append(trustLevel.toString()).append(""); + sb.append("").append(browsing).append(""); + if (comment != null) + sb.append("").append(Util.escapeHTMLinXML(comment)).append(""); + sb.append("").append(certificates).append(""); + sb.append(""); + } + + } + + private static void sort(List items, HttpServletRequest req, ColumnComparators comparators) { + String key = req.getParameter("key"); + String order = req.getParameter("order"); + Comparator comparator = comparators.get(key, order); + if (comparator != null) + Collections.sort(items, comparator); + } + private static final Comparator SEARCH_BY_NAME = (k, v) -> { return k.getSearch().compareTo(v.getSearch()); }; @@ -302,5 +422,61 @@ public class SearchServlet extends HttpServlet { SENDER_COMPARATORS.add("Trust", SENDER_BY_TRUST); SENDER_COMPARATORS.add("Results", SENDER_BY_RESULTS); } + + private static final Comparator RESULT_FROM_SENDER_BY_NAME = (k, v) -> { + return k.name.compareTo(v.name); + }; + + private static final Comparator RESULT_FROM_SENDER_BY_SIZE = (k, v) -> { + return Long.compare(k.size, v.size); + }; + + private static final Comparator RESULT_FROM_SENDER_BY_DOWNLOAD = (k, v) -> { + return Boolean.compare(k.downloading, v.downloading); + }; + + private static final ColumnComparators RESULT_FROM_SENDER_COMPARATORS = new ColumnComparators<>(); + static { + RESULT_FROM_SENDER_COMPARATORS.add("Name", RESULT_FROM_SENDER_BY_NAME); + RESULT_FROM_SENDER_COMPARATORS.add("Size", RESULT_FROM_SENDER_BY_SIZE); + RESULT_FROM_SENDER_COMPARATORS.add("Download", RESULT_FROM_SENDER_BY_DOWNLOAD); + } + + private static final Comparator RESULT_BY_NAME = (k, v) -> { + return k.name.compareTo(v.name); + }; + + private static final Comparator RESULT_BY_SIZE = (k, v) -> { + return Long.compare(k.size, v.size); + }; + + private static final Comparator RESULT_BY_DOWNLOAD = (k, v) -> { + return Boolean.compare(k.downloading, v.downloading); + }; + + private static final ColumnComparators RESULT_COMPARATORS = new ColumnComparators<>(); + static { + RESULT_COMPARATORS.add("Name", RESULT_BY_NAME); + RESULT_COMPARATORS.add("Size", RESULT_BY_SIZE); + RESULT_COMPARATORS.add("Download", RESULT_BY_DOWNLOAD); + } + private static final Comparator SENDER_FOR_RESULT_BY_SENDER = (k, v) -> { + return k.sender.getHumanReadableName().compareTo(v.sender.getHumanReadableName()); + }; + + private static final Comparator SENDER_FOR_RESULT_BY_BROWSING = (k, v) -> { + return Boolean.compare(k.browsing, v.browsing); + }; + + private static final Comparator SENDER_FOR_RESULT_BY_TRUST = (k, v) -> { + return k.trustLevel.toString().compareTo(v.trustLevel.toString()); + }; + + private static final ColumnComparators SENDER_FOR_RESULT_COMPARATORS = new ColumnComparators<>(); + static { + SENDER_FOR_RESULT_COMPARATORS.add("Sender", SENDER_FOR_RESULT_BY_SENDER); + SENDER_FOR_RESULT_COMPARATORS.add("Browse", SENDER_FOR_RESULT_BY_BROWSING); + SENDER_FOR_RESULT_COMPARATORS.add("Trust", SENDER_FOR_RESULT_BY_TRUST); + } } diff --git a/webui/src/main/js/search.js b/webui/src/main/js/search.js index 62e4f0ff..54904a93 100644 --- a/webui/src/main/js/search.js +++ b/webui/src/main/js/search.js @@ -8,48 +8,32 @@ class SearchStatus { } } -class SearchBySender { - constructor(xmlNode) { - this.resultBatches = new Map(); - - var resultsBySender = xmlNode.getElementsByTagName("ResultsBySender")[0]; - var resultsFromSenders = resultsBySender.getElementsByTagName("ResultsFromSender"); - var i; - for (i = 0; i < resultsFromSenders.length; i++) { - var results = new ResultsBySender(resultsFromSenders[i]); - this.resultBatches.set(results.sender, results); - } - } -} -class SearchByFile { +class Sender { constructor(xmlNode) { - 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); - } + this.name = xmlNode.getElementsByTagName("Name")[0].childNodes[0].nodeValue + this.b64 = xmlNode.getElementsByTagName("B64")[0].childNodes[0].nodeValue + this.trust = xmlNode.getElementsByTagName("Trust")[0].childNodes[0].nodeValue + this.browse = xmlNode.getElementsByTagName("Browse")[0].childNodes[0].nodeValue + this.browsing = xmlNode.getElementsByTagName("Browsing")[0].childNodes[0].nodeValue + this.results = xmlNode.getElementsByTagName("Results")[0].childNodes[0].nodeValue } -} - -class ResultsBySender { - constructor(xmlNode) { - this.sender = xmlNode.getElementsByTagName("Sender")[0].childNodes[0].nodeValue; - this.senderB64 = xmlNode.getElementsByTagName("SenderB64")[0].childNodes[0].nodeValue; - this.browse = xmlNode.getElementsByTagName("Browse")[0].childNodes[0].nodeValue; - this.browsing = xmlNode.getElementsByTagName("Browsing")[0].childNodes[0].nodeValue; - this.trust = xmlNode.getElementsByTagName("Trust")[0].childNodes[0].nodeValue; - this.results = new Map(); - var resultNodes = xmlNode.getElementsByTagName("Result"); - var i; - for (i = 0 ; i < resultNodes.length; i ++) { - var result = new ResultBySender(resultNodes[i]); - this.results.set(result.infoHash,result); - } + + getMapping() { + var mapping = new Map() + mapping.set("Sender", this.getSenderLink()) + mapping.set("Results", this.results) + + var trustHtml = this.trust + this.getTrustLinks() + mapping.set("Trust", trustHtml) + + mapping.set("Browse", this.getBrowseBlock()) + + return mapping + } + + getSenderLink() { + return "" + this.name + "" } getTrustLinks() { @@ -62,87 +46,231 @@ class ResultsBySender { } getTrustLink() { - return "" + + return "" + "" + _t("Mark Trusted") + "" + this.b64 + "\"); return false;'>" + _t("Mark Trusted") + "" } getNeutralLink() { - return "" + _t("Mark Neutral") + "" + return "" + _t("Mark Neutral") + "" } getDistrustLink() { - return "" + + return "" + "" + _t("Mark Distrusted") + "" + this.b64 + "\"); return false;'>" + _t("Mark Distrusted") + "" + } + + getBrowseBlock() { + if (this.browse == "false") + return "" + if (this.browsing == "true") + return _t("Browsing") + var link = "" + _t("Browse") + "" + var block = "" + link + "" + return block } } -class ResultsByFile { +class Senders { 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.downloading = xmlNode.getElementsByTagName("Downloading")[0].childNodes[0].nodeValue; - this.results = new Map(); - var resultNodes = xmlNode.getElementsByTagName("Result"); - var i; + this.senders = [] + var senderNodes = xmlNode.getElementsByTagName("Sender") + var i + for (i = 0; i < senderNodes.length; i++) { + this.senders.push(new Sender(senderNodes[i])) + } + } + + render(preserveSortOrder) { + if (!preserveSortOrder) { + if (sendersSortOrder == "descending") + sendersSortOrder = "ascending" + else + sendersSortOrder = "descending" + } + var table = new Table(["Sender", "Browse", "Results", "Trust"], "sortSendersTable", sendersSortKey, sendersSortOrder) + var i + for (i = 0; i < this.senders.length; i++) { + table.addRow(this.senders[i].getMapping()) + } + return table.render() + } +} + +class ResultFromSender { + 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 + this.downloading = xmlNode.getElementsByTagName("Downloading")[0].childNodes[0].nodeValue + this.comment = null + try { + this.comment = xmlNode.getElementsByTagName("Comment")[0].childNodes[0].nodeValue + } catch (ignored) {} + this.certificates = xmlNode.getElementsByTagName("Certificates")[0].childNodes[0].nodeValue + } + + getMapping() { + var mapping = new Map() + + var nameHtml = this.name + nameHtml += this.getCommentBlock() + nameHtml += this.getCertificatesBlock() + mapping.set("Name", nameHtml) + mapping.set("Size", this.size) + mapping.set("Download", this.getDownloadBlock()) + + return mapping + } + + getCommentBlock() { + if (this.comment == null) + return "" + var html = "" + html += "
" + return html + } + + getCertificatesBlock() { + if (this.certificates == "0") + return "" + return _t("View {0} Certificates", this.certificates) + } + + getDownloadBlock() { + if (this.downloading == "true") + return _t("Downloading") + var link = "" + _t("Download") + "" + var block = "" + link + "" + return block + } +} + +class ResultsFromSender { + constructor(xmlNode) { + this.resultsFromSender = [] + var resultNodes = xmlNode.getElementsByTagName("Result") + var i for (i = 0; i < resultNodes.length; i++) { - var result = new ResultByFile(resultNodes[i]); - this.results.set(result.sender, result); + this.resultsFromSender.push(new ResultFromSender(resultNodes[i])) } } -} - -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; - this.downloading = xmlNode.getElementsByTagName("Downloading")[0].childNodes[0].nodeValue; - this.comment = null; - var comment = xmlNode.getElementsByTagName("Comment") - if (comment.length == 1) - this.comment = comment[0].childNodes[0].nodeValue; - this.certificates = xmlNode.getElementsByTagName("Certificates")[0].childNodes[0].nodeValue - } - getCertificatesBlock() { - if (this.certificates == "0") - return "" - var linkText = _t("View {0} Certificates", this.certificates) - var link = "" + - linkText + "" - var id = senderB64 + "_" + this.infoHash - var html = "
" - return html + render(preserveSortOrder) { + if (!preserveSortOrder) { + if (resultsFromSenderSortOrder == "descending") + resultsFromSenderSortOrder = "ascending" + else + resultsFromSenderSortOrder = "descending" + } + var table = new Table(["Name","Size","Download"], "sortResultsFromSenderTable", resultsFromSenderSortKey, resultsFromSenderSortOrder) + var i + for (i = 0 ; i < this.resultsFromSender.length; i++) { + table.addRow(this.resultsFromSender[i].getMapping()) + } + return table.render() } } -class ResultByFile { +class Result { constructor(xmlNode) { - this.sender = xmlNode.getElementsByTagName("Sender")[0].childNodes[0].nodeValue; - this.senderB64 = xmlNode.getElementsByTagName("SenderB64")[0].childNodes[0].nodeValue; - this.browse = xmlNode.getElementsByTagName("Browse")[0].childNodes[0].nodeValue; - this.browsing = xmlNode.getElementsByTagName("Browsing")[0].childNodes[0].nodeValue; - this.trust = xmlNode.getElementsByTagName("Trust")[0].childNodes[0].nodeValue; - this.comment = null; - var comment = xmlNode.getElementsByTagName("Comment") - if (comment.length == 1) - this.comment = comment[0].childNodes[0].nodeValue; + 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 + this.downloading = xmlNode.getElementsByTagName("Downloading")[0].childNodes[0].nodeValue + } + + getMapping() { + var mapping = new Map() + mapping.set("Name", this.getNameBlock()) + mapping.set("Size", this.size) + mapping.set("Download", this.getDownloadBlock()) + return mapping + } + + getNameBlock() { + return "" + this.name + "" + } + getDownloadBlock() { + if (this.downloading == "true") + return _t("Downloading") + var link = "" + _t("Download") + "" + var block = "" + link + "" + return block + } +} + +class Results { + constructor(xmlNode) { + this.results = [] + var resultNodes = xmlNode.getElementsByTagName("Result") + var i + for (i = 0; i < resultNodes.length; i++) { + this.results.push(new Result(resultNodes[i])) + } + } + + render(preserveSortOrder) { + if (!preserveSortOrder) { + if(resultsSortOrder == "descending") + resultsSortOrder = "ascending" + else + resultsSortOrder = "descending" + } + var table = new Table(["Name","Size","Download"], "sortResultsTable", resultsSortKey, resultsSortOrder) + var i + for (i = 0; i < this.results.length; i++) { + table.addRow(this.results[i].getMapping()) + } + return table.render() + } +} + +class SenderForResult { + constructor(xmlNode) { + this.name = xmlNode.getElementsByTagName("Name")[0].childNodes[0].nodeValue + this.b64 = xmlNode.getElementsByTagName("B64")[0].childNodes[0].nodeValue + this.browse = xmlNode.getElementsByTagName("Browse")[0].childNodes[0].nodeValue + this.browsing = xmlNode.getElementsByTagName("Browsing")[0].childNodes[0].nodeValue + this.trust = xmlNode.getElementsByTagName("Trust")[0].childNodes[0].nodeValue + this.comment = null + try { + this.comment = xmlNode.getElementsByTagName("Comment")[0].childNodes[0].nodeValue + } catch (ignored) {} this.certificates = xmlNode.getElementsByTagName("Certificates")[0].childNodes[0].nodeValue } - getCertificatesBlock() { - if (this.certificates == "0") + getMapping() { + var mapping = new Map() + mapping.set("Sender", this.getNameBlock()) + mapping.set("Browse", this.getBrowseBlock()) + mapping.set("Trust", this.getTrustBlock()) + return mapping + } + + getNameBlock() { + return this.name + } + + getBrowseBlock() { + if (this.browse != "true") return "" - var linkText = _t("View {0} Certificates", this.certificates) - var link = "" + linkText + "" - var id = this.senderB64 + "_" + infoHash - var html = "
" - return html + if (this.browsing == "true") + return _t("Browsing") + var link = "" + _t("Browse") + "" + var block = "" + link + "" + return block + } + + getTrustBlock() { + return this.trust + this.getTrustLinks() } getTrustLinks() { @@ -155,41 +283,84 @@ class ResultByFile { } getTrustLink() { - return "" + + return "" + "" + _t("Mark Trusted") + "" + this.b64 + "\"); return false;'>" + _t("Mark Trusted") + "" } getNeutralLink() { - return "" + _t("Mark Neutral") + "" + return "" + _t("Mark Neutral") + "" } getDistrustLink() { - return "" + + return "" + "" + _t("Mark Distrusted") + "" + this.b64 + "\"); return false;'>" + _t("Mark Distrusted") + "" + } +} + +class SendersForResult { + constructor(xmlNode) { + this.sendersForResult = [] + var senderNodes = xmlNode.getElementsByTagName("Sender") + var i + for (i = 0; i < senderNodes.length; i++) { + this.sendersForResult.push(new SenderForResult(senderNodes[i])) + } + } + + render(preserveSortOrder) { + if (!preserveSortOrder) { + if (sendersForResultSortOrder == "descending") + sendersForResultSortOrder = "ascending" + else + sendersForResultsSortOrder = "descending" + } + var table = new Table(["Sender", "Browse", "Trust"], "sortSendersForResultTable", sendersForResultSortKey, sendersForResultSortOrder) + var i + for (i = 0; i < this.sendersForResult.length; i++) { + table.addRow(this.sendersForResult[i].getMapping()) + } + return table.render() } } -var statusByUUID = new Map() -var currentSearchBySender = null -var currentSearchByFile = null -var currentSender = null -var currentFile = null -var expandedComments = new Map(); +// sort fields +var sendersSortKey +var sendersSortOrder +var resultsFromSenderSortKey +var resultsFromSenderSortOrder -var uuid = null; -var sender = null; -var senderB64 = null -var lastXML = null; -var infoHash = null; +var resultsSortKey +var resultsSortOrder +var sendersForResultSortKey +var sendersForResultSortOrder var statusKey = null var statusOrder = null +// global fields +var senders +var currentSender +var resultsFromSender +var results +var currentResult +var sendersForResult + +// status fields +var uuid = null; +var statusByUUID = new Map() + +// expanded comments +var expandedComments = new Map(); + +// pointers based on current view type +var refreshFunction = null +var refreshType = null + function showCommentBySender(divId, spanId) { var split = divId.split("_"); var commentDiv = document.getElementById(divId); @@ -301,9 +472,9 @@ function publishTrust(host, reason, trust) { xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { if (refreshType == "Sender") - refreshGroupBySender(uuid) + refreshSender(uuid) else if (refreshType == "File") - refreshGroupByFile(uuid) + refreshFile(uuid) } } xmlhttp.open("POST","/MuWire/Trust", true) @@ -311,199 +482,6 @@ function publishTrust(host, reason, trust) { xmlhttp.send("action=" + trust + "&reason=" + reason + "&persona=" + host) } -function updateSender(senderName) { - sender = senderName; - - var resultsFromSpan = document.getElementById("resultsFrom"); - resultsFromSpan.innerHTML = _t("Results from {0}", sender); - - var resultsDiv = document.getElementById("bottomTable"); - var table = "" - var x = currentSearchBySender - var senderBatch = x.resultBatches.get(sender) - senderB64 = senderBatch.senderB64 - x = senderBatch.results; - for (var [resultInfoHash, result] of x) { - table += ""; - table += ""; - table += ""; - table += ""; - table += ""; - } - table += "
" + _t("Name") + "" + _t("Size") + "" + _t("Download") + "
"; - table += result.name; - if (result.comment != null) { - var divId = "comment_" + uuid + "_" + senderName + "_" + resultInfoHash; - var spanId = "comment-link-"+resultInfoHash + senderName + uuid; - var comment = expandedComments.get(divId); - if (comment != null) { - var link = "" + _t("Hide Comment") + ""; - table += "
" + link + "
"; - table += "
"+comment+"
"; - } else { - var link = "" + _t("Show Comment") + ""; - table += "
"+link+""; - table += "
"; - } - } - table += result.getCertificatesBlock() - table += "
"; - table += result.size; - table += ""; - if (result.downloading == "false") { - table += "" + _t("Download") + ""; - } else { - table += _t("Downloading"); - } - table += "
"; - if (x.size > 0) - resultsDiv.innerHTML = table; -} - -function updateFile(fileInfoHash) { - infoHash = fileInfoHash; - - var searchResults = currentSearchByFile.resultBatches.get(infoHash); - - var resultsFromSpan = document.getElementById("resultsFrom"); - resultsFromSpan.innerHTML = _t("Results for {0}", searchResults.name); - - var resultsDiv = document.getElementById("bottomTable"); - var table = ""; - var i; - for (var [senderName, result] of searchResults.results) { - table += ""; - table += ""; - if (result.browse == "true") { - if (result.browsing == "true") - table += "" - else { - table += "" - } - } - table += "" - table += ""; - } - table += "
" + _t("Sender") + "" + _t("Browse") + "
"; - table += senderName - if (result.comment != null) { - var divId = "comment_" + uuid + "_" + fileInfoHash + "_" + senderName; - var spanId = "comment-link-" + fileInfoHash + senderName + uuid; - var comment = expandedComments.get(divId); - if (comment != null) { - var link = "" + _t("Hide Comment") + ""; - table += "
" + link + "
"; - table += "
"+comment+"
"; - } else { - var link = "" + _t("Show Comment") + ""; - table += "
"+link+""; - table += "
"; - } - } - table += result.getCertificatesBlock() - table += "
" + _t("Browsing") + "" + getBrowseLink(result.senderB64) + "" + result.trust + " " + result.getTrustLinks() + "
"; - if (searchResults.results.size > 0) - resultsDiv.innerHTML = table; -} - -function updateUUIDBySender(resultUUID) { - uuid = resultUUID; - - var currentStatus = statusByUUID.get(uuid) - - var currentSearchSpan = document.getElementById("currentSearch"); - currentSearchSpan.innerHTML = currentStatus.query + " Results"; - - var sendersDiv = document.getElementById("topTable"); - var table = ""; - var x = currentSearchBySender.resultBatches; - for (var [senderName, senderBatch] of x) { - table += ""; - if (senderBatch.browse == "true") { - if (senderBatch.browsing == "true") - table += "" - else - table += "" - } - table += "" - table += ""; - } - table += "
" + _t("Sender") + "" + _t("Browse") + "" + _t("Trust") + "
" - table += senderName; - table += "" + _t("Browsing") + "" + getBrowseLink(senderBatch.senderB64) + "" + senderBatch.trust + " "+senderBatch.getTrustLinks() + "
"; - if (x.size > 0) - sendersDiv.innerHTML = table; - if (sender != null) - updateSender(sender); -} - -function updateUUIDByFile(resultUUID) { - uuid = resultUUID; - - var currentStatus = statusByUUID.get(uuid) - - var currentSearchSpan = document.getElementById("currentSearch"); - currentSearchSpan.innerHTML = _t("Results for {0}", currentStatus.query) - - var topTableDiv = document.getElementById("topTable"); - var table = ""; - var x = currentSearchByFile.resultBatches; - for (var [fileInfoHash, file] of x) { - table += ""; - table += ""; - table += ""; - } - table += "
" + _t("Name") + "" + _t("Size") + "" + _t("Download") + "
"; - table += file.name; - table += ""; - table += file.size; - table += ""; - if (file.downloading == "false") - table += "" + _t("Download") + ""; - else - table += _t("Downloading"); - table += "
"; - if (x.size > 0) - topTableDiv.innerHTML = table; - if (infoHash != null) - updateFile(infoHash); -} - -function refreshGroupBySender(searchUUID) { - var xmlhttp = new XMLHttpRequest(); - xmlhttp.onreadystatechange = function () { - if (this.readyState == 4 && this.status == 200) { - var xmlDoc = this.responseXML; - currentSearchBySender = new SearchBySender(xmlDoc) - updateUUIDBySender(searchUUID); - } - } - xmlhttp.open("GET", "/MuWire/Search?section=groupBySender&uuid="+searchUUID, true); - xmlhttp.send(); -} - -function refreshGroupByFile(searchUUID) { - var xmlhttp = new XMLHttpRequest(); - xmlhttp.onreadystatechange = function () { - if (this.readyState == 4 && this.status == 200) { - var xmlDoc = this.responseXML; - - currentSearchByFile = new SearchByFile(xmlDoc) - updateUUIDByFile(searchUUID) - } - } - xmlhttp.open("GET", "/MuWire/Search?section=groupByFile&uuid="+searchUUID, true); - xmlhttp.send(); -} - -function getBrowseLink(host) { - return "" + _t("Browse") + "" -} - function browse(host) { var xmlhttp = new XMLHttpRequest() xmlhttp.onreadystatechange = function() { @@ -588,6 +566,81 @@ function hideCertificatesBySender(fileInfoHash, count) { linkSpan.innerHTML = showLink } +function refreshResultsFromSender(sender) { + currentSender = sender + + var xmlhttp = new XMLHttpRequest() + xmlhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + resultsFromSender = new ResultsFromSender(this.responseXML) + var tableHtml = resultsFromSender.render(true) + + var bottomTableDiv = document.getElementById("bottomTable") + bottomTableDiv.innerHTML = tableHtml + } + } + xmlhttp.open("GET", "/MuWire/Search?section=resultsFromSender&uuid=" + uuid + "&sender=" + sender) + xmlhttp.send() +} + +function refreshSendersForResult(result) { + currentResult = result + + var xmlhttp = new XMLHttpRequest() + xmlhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + sendersForResult = new SendersForResult(this.responseXML) + var tableHtml = sendersForResult.render(true) + + var bottomTableDiv = document.getElementById("bottomTable") + bottomTableDiv.innerHTML = tableHtml + } + } + xmlhttp.open("GET", "/MuWire/Search?section=sendersForResult&uuid=" + uuid + "&infoHash=" + currentResult) + xmlhttp.send() +} + +function refreshSender(searchUUID) { + uuid = searchUUID + + var xmlhttp = new XMLHttpRequest() + xmlhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + senders = new Senders(this.responseXML) + var tableHtml = senders.render(true) + + var topTableDiv = document.getElementById("topTable") + topTableDiv.innerHTML = tableHtml + + if (currentSender != null) + refreshResultsFromSender(currentSender) + } + } + xmlhttp.open("GET", "/MuWire/Search?section=senders&uuid=" + uuid, true) + xmlhttp.send() + +} + +function refreshFile(searchUUID) { + uuid = searchUUID + + var xmlhttp = new XMLHttpRequest() + xmlhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + results = new Results(this.responseXML) + var tableHtml = results.render(true) + + var topTableDiv = document.getElementById("topTable") + topTableDiv.innerHTML = tableHtml + + if (currentResult != null) + refreshSendersForResult(currentResult) + } + } + xmlhttp.open("GET", "/MuWire/Search?section=results&uuid=" + uuid, true) + xmlhttp.send() +} + function refreshStatus() { var xmlhttp = new XMLHttpRequest() xmlhttp.onreadystatechange = function() { @@ -617,7 +670,7 @@ function refreshStatus() { var status = statuses[i] var mappings = new Map() - var queryLink = "" + status.query + "" + var queryLink = "" + status.query + "" mappings.set("Query", queryLink) mappings.set("Senders", status.senders) mappings.set("Results", status.results) @@ -645,18 +698,15 @@ function sortStatuses(key, order) { refreshStatus() } -var refreshFunction = null -var refreshType = null - function initGroupBySender() { - refreshFunction = refreshGroupBySender + refreshFunction = refreshSender refreshType = "Sender" setInterval(refreshStatus, 3000); setTimeout(refreshStatus, 1); } function initGroupByFile() { - refreshFunction = refreshGroupByFile + refreshFunction = refreshFile refreshType = "File" setInterval ( refreshStatus, 3000); setTimeout ( refreshStatus, 1);