From c4135389a4f26b18f680d950cde17512dc44a743 Mon Sep 17 00:00:00 2001 From: Zlatin Balevsky Date: Fri, 6 Dec 2019 13:16:32 +0000 Subject: [PATCH] wip on shared files display page --- webui/src/main/css/muwire.css | 88 ++++++++++++++----- .../com/muwire/webui/DownloadServlet.java | 2 +- .../java/com/muwire/webui/FileManager.java | 40 +++++++++ .../java/com/muwire/webui/FilesServlet.java | 75 ++++++++++++++++ .../java/com/muwire/webui/SearchServlet.java | 16 ++-- webui/src/main/js/files.js | 9 ++ webui/src/main/webapp/Files.jsp | 28 ++++++ 7 files changed, 226 insertions(+), 32 deletions(-) create mode 100644 webui/src/main/java/com/muwire/webui/FileManager.java create mode 100644 webui/src/main/java/com/muwire/webui/FilesServlet.java create mode 100644 webui/src/main/js/files.js create mode 100644 webui/src/main/webapp/Files.jsp diff --git a/webui/src/main/css/muwire.css b/webui/src/main/css/muwire.css index c1f2f952..d470f900 100644 --- a/webui/src/main/css/muwire.css +++ b/webui/src/main/css/muwire.css @@ -1,24 +1,66 @@ - #table-wrapper { - position:relative; - } - #table-scroll { - height:150px; - overflow:auto; - margin-top:20px; - } - #table-wrapper table { - width:100%; +#table-wrapper { + position:relative; +} +#table-scroll { + height:150px; + overflow:auto; + margin-top:20px; +} +#table-wrapper table { + width:100%; - } - #table-wrapper table * { - background:yellow; - color:black; - } - #table-wrapper table thead th .text { - position:absolute; - top:-20px; - z-index:2; - height:20px; - width:35%; - border:1px solid red; - } +} +#table-wrapper table * { + background:yellow; + color:black; +} +#table-wrapper table thead th .text { + position:absolute; + top:-20px; + z-index:2; + height:20px; + width:35%; + border:1px solid red; +} + +/* File tree CSS */ + + /* Remove default bullets */ +ul, #sharedTree { + list-style-type: none; +} + +/* Remove margins and padding from the parent ul */ +#sharedTree { + margin: 0; + padding: 0; +} + +/* Style the caret/arrow */ +.caret { + cursor: pointer; + user-select: none; /* Prevent text selection */ +} + +/* Create the caret/arrow with a unicode, and style it */ +.caret::before { + content: "\25B6"; + color: black; + display: inline-block; + margin-right: 6px; +} + +/* Rotate the caret/arrow icon when clicked on (using JavaScript) */ +.caret-down::before { + transform: rotate(90deg); +} + +/* Hide the nested list */ +.nested { + display: none; +} + +/* Show the nested list when the user clicks on the caret/arrow (with JavaScript) */ +.active { + display: block; +} diff --git a/webui/src/main/java/com/muwire/webui/DownloadServlet.java b/webui/src/main/java/com/muwire/webui/DownloadServlet.java index 11a174d8..b1e8518f 100644 --- a/webui/src/main/java/com/muwire/webui/DownloadServlet.java +++ b/webui/src/main/java/com/muwire/webui/DownloadServlet.java @@ -48,7 +48,7 @@ public class DownloadServlet extends HttpServlet { downloadManager.getDownloaders().forEach(d -> { sb.append(""); sb.append("").append(Base64.encode(d.getInfoHash().getRoot())).append(""); - sb.append("").append(DataHelper.escapeHTML(d.getFile().getName())).append(""); + sb.append("").append(Util.escapeHTMLinXML(d.getFile().getName())).append(""); sb.append("").append(d.getCurrentState().toString()).append(""); int speed = d.speed(); sb.append("").append(DataHelper.formatSize2Decimal(speed)).append("B/sec").append(""); diff --git a/webui/src/main/java/com/muwire/webui/FileManager.java b/webui/src/main/java/com/muwire/webui/FileManager.java new file mode 100644 index 00000000..30ec10f4 --- /dev/null +++ b/webui/src/main/java/com/muwire/webui/FileManager.java @@ -0,0 +1,40 @@ +package com.muwire.webui; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +import com.muwire.core.Core; +import com.muwire.core.SharedFile; +import com.muwire.core.files.FileDownloadedEvent; +import com.muwire.core.files.FileHashedEvent; +import com.muwire.core.files.FileListCallback; +import com.muwire.core.files.FileLoadedEvent; +import com.muwire.core.files.FileTree; + +public class FileManager { + + private final Core core; + private final FileTree fileTree = new FileTree<>(); + + public FileManager(Core core) { + this.core = core; + } + + public void onFileLoadedEvent(FileLoadedEvent e) { + fileTree.add(e.getLoadedFile().getFile(), e.getLoadedFile()); + } + + public void onFileHashedEvent(FileHashedEvent e) { + fileTree.add(e.getSharedFile().getFile(), e.getSharedFile()); + } + + public void onFileDownloadedEvent(FileDownloadedEvent e) { + if (core.getMuOptions().getShareDownloadedFiles()) + fileTree.add(e.getDownloadedFile().getFile(), e.getDownloadedFile()); + } + + void list(File parent, FileListCallback callback) { + fileTree.list(parent, callback); + } +} diff --git a/webui/src/main/java/com/muwire/webui/FilesServlet.java b/webui/src/main/java/com/muwire/webui/FilesServlet.java new file mode 100644 index 00000000..2be735d8 --- /dev/null +++ b/webui/src/main/java/com/muwire/webui/FilesServlet.java @@ -0,0 +1,75 @@ +package com.muwire.webui; + +import java.io.File; +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.muwire.core.SharedFile; +import com.muwire.core.files.FileListCallback; + +import net.i2p.data.Base64; +import net.i2p.data.DataHelper; + +public class FilesServlet extends HttpServlet { + + private FileManager fileManager; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + StringBuilder sb = new StringBuilder(); + sb.append(""); + sb.append(""); + ListCallback cb = new ListCallback(sb); + String encodedPath = req.getParameter("path"); + File current = null; + if (encodedPath != null) { + String[] split = encodedPath.split(","); + for (String element : split) { + element = Base64.decodeToString(element); + if (current == null) { + current = new File(element); + continue; + } + current = new File(current, element); + } + } + fileManager.list(current, cb); + sb.append(""); + resp.setContentType("text/xml"); + resp.setCharacterEncoding("UTF-8"); + resp.setDateHeader("Expires", 0); + resp.setHeader("Pragma", "no-cache"); + resp.setHeader("Cache-Control", "no-store, max-age=0, no-cache, must-revalidate"); + resp.getWriter().write(sb.toString()); + resp.flushBuffer(); + } + + @Override + public void init(ServletConfig cfg) throws ServletException { + fileManager = (FileManager) cfg.getServletContext().getAttribute("fileManager"); + } + + private static class ListCallback implements FileListCallback { + private final StringBuilder sb; + ListCallback(StringBuilder sb) { + this.sb = sb; + } + @Override + public void onFile(File f, SharedFile value) { + sb.append(""); + sb.append("").append(Util.escapeHTMLinXML(f.getName())).append(""); + sb.append("").append(DataHelper.formatSize2Decimal(value.getCachedLength())).append("B").append(""); + // TODO: other stuff + sb.append(""); + } + @Override + public void onDirectory(File f) { + sb.append("").append(Util.escapeHTMLinXML(f.getName())).append(""); + } + } +} diff --git a/webui/src/main/java/com/muwire/webui/SearchServlet.java b/webui/src/main/java/com/muwire/webui/SearchServlet.java index 451acf98..e9ef9264 100644 --- a/webui/src/main/java/com/muwire/webui/SearchServlet.java +++ b/webui/src/main/java/com/muwire/webui/SearchServlet.java @@ -54,18 +54,18 @@ public class SearchServlet extends HttpServlet { for (SearchResults results : searchManager.getResults().values()) { sb.append(""); sb.append("").append(results.getUUID()).append(""); - sb.append("").append(DataHelper.escapeHTML(results.getSearch())).append(""); + sb.append("").append(Util.escapeHTMLinXML(results.getSearch())).append(""); Map> bySender = results.getBySender(); sb.append(""); bySender.forEach((sender, resultsFromSender) -> { sb.append(""); sb.append(""); - sb.append(DataHelper.escapeHTML(sender.getHumanReadableName())); + sb.append(Util.escapeHTMLinXML(sender.getHumanReadableName())); sb.append(""); resultsFromSender.forEach(result -> { sb.append(""); sb.append(""); - sb.append(DataHelper.escapeHTML(result.getName())); + sb.append(Util.escapeHTMLinXML(result.getName())); sb.append(""); sb.append(""); sb.append(DataHelper.formatSize2Decimal(result.getSize(), false)).append("B"); @@ -76,7 +76,7 @@ public class SearchServlet extends HttpServlet { sb.append(""); sb.append("").append(downloadManager.isDownloading(result.getInfohash())).append(""); if (result.getComment() != null) - sb.append("").append(DataHelper.escapeHTML(result.getComment())).append(""); + sb.append("").append(Util.escapeHTMLinXML(result.getComment())).append(""); sb.append(""); }); sb.append(""); @@ -94,7 +94,7 @@ public class SearchServlet extends HttpServlet { for (SearchResults results : searchManager.getResults().values()) { sb.append(""); sb.append("").append(results.getUUID()).append(""); - sb.append("").append(DataHelper.escapeHTML(results.getSearch())).append(""); + sb.append("").append(Util.escapeHTMLinXML(results.getSearch())).append(""); Map> byInfohash = results.getByInfoHash(); sb.append(""); byInfohash.forEach((infoHash, resultSet) -> { @@ -102,13 +102,13 @@ public class SearchServlet extends HttpServlet { UIResultEvent first = resultSet.iterator().next(); sb.append("").append(Base64.encode(infoHash.getRoot())).append(""); sb.append("").append(downloadManager.isDownloading(infoHash)).append(""); - sb.append("").append(DataHelper.escapeHTML(first.getName())).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(DataHelper.escapeHTML(result.getSender().getHumanReadableName())).append(""); + sb.append("").append(Util.escapeHTMLinXML(result.getSender().getHumanReadableName())).append(""); if (result.getComment() != null) - sb.append("").append(DataHelper.escapeHTML(result.getComment())).append(""); + sb.append("").append(Util.escapeHTMLinXML(result.getComment())).append(""); sb.append(""); }); sb.append(""); diff --git a/webui/src/main/js/files.js b/webui/src/main/js/files.js new file mode 100644 index 00000000..bbf9f201 --- /dev/null +++ b/webui/src/main/js/files.js @@ -0,0 +1,9 @@ +var toggler = document.getElementsByClassName("caret"); +var i; + +for (i = 0; i < toggler.length; i++) { + toggler[i].addEventListener("click", function() { + this.parentElement.querySelector(".nested").classList.toggle("active"); + this.classList.toggle("caret-down"); + }); +} diff --git a/webui/src/main/webapp/Files.jsp b/webui/src/main/webapp/Files.jsp new file mode 100644 index 00000000..330515f8 --- /dev/null +++ b/webui/src/main/webapp/Files.jsp @@ -0,0 +1,28 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@include file="initcode.jsi"%> + +<% String pagetitle="Files"; %> + + + +<%@ include file="css.jsi"%> + + + +<%@ include file="header.jsi"%> +

Shared Files

+
+
+
+ + + +
+
+ + + +
+ + \ No newline at end of file