wip on shared files display page

pull/34/head
Zlatin Balevsky 2019-12-06 13:16:32 +00:00
parent a6e0834722
commit c4135389a4
7 changed files with 226 additions and 32 deletions

View File

@ -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;
}

View File

@ -48,7 +48,7 @@ public class DownloadServlet extends HttpServlet {
downloadManager.getDownloaders().forEach(d -> {
sb.append("<Download>");
sb.append("<InfoHash>").append(Base64.encode(d.getInfoHash().getRoot())).append("</InfoHash>");
sb.append("<Name>").append(DataHelper.escapeHTML(d.getFile().getName())).append("</Name>");
sb.append("<Name>").append(Util.escapeHTMLinXML(d.getFile().getName())).append("</Name>");
sb.append("<State>").append(d.getCurrentState().toString()).append("</State>");
int speed = d.speed();
sb.append("<Speed>").append(DataHelper.formatSize2Decimal(speed)).append("B/sec").append("</Speed>");

View File

@ -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<SharedFile> 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<SharedFile> callback) {
fileTree.list(parent, callback);
}
}

View File

@ -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("<?xml version='1.0' encoding='UTF-8'?>");
sb.append("<Files>");
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("</Files>");
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<SharedFile> {
private final StringBuilder sb;
ListCallback(StringBuilder sb) {
this.sb = sb;
}
@Override
public void onFile(File f, SharedFile value) {
sb.append("<File>");
sb.append("<Name>").append(Util.escapeHTMLinXML(f.getName())).append("</Name>");
sb.append("<Size>").append(DataHelper.formatSize2Decimal(value.getCachedLength())).append("B").append("</Size>");
// TODO: other stuff
sb.append("</File>");
}
@Override
public void onDirectory(File f) {
sb.append("<Directory>").append(Util.escapeHTMLinXML(f.getName())).append("</Directory>");
}
}
}

View File

@ -54,18 +54,18 @@ public class SearchServlet extends HttpServlet {
for (SearchResults results : searchManager.getResults().values()) {
sb.append("<Search>");
sb.append("<uuid>").append(results.getUUID()).append("</uuid>");
sb.append("<Query>").append(DataHelper.escapeHTML(results.getSearch())).append("</Query>");
sb.append("<Query>").append(Util.escapeHTMLinXML(results.getSearch())).append("</Query>");
Map<Persona, Set<UIResultEvent>> bySender = results.getBySender();
sb.append("<ResultsBySender>");
bySender.forEach((sender, resultsFromSender) -> {
sb.append("<ResultsFromSender>");
sb.append("<Sender>");
sb.append(DataHelper.escapeHTML(sender.getHumanReadableName()));
sb.append(Util.escapeHTMLinXML(sender.getHumanReadableName()));
sb.append("</Sender>");
resultsFromSender.forEach(result -> {
sb.append("<Result>");
sb.append("<Name>");
sb.append(DataHelper.escapeHTML(result.getName()));
sb.append(Util.escapeHTMLinXML(result.getName()));
sb.append("</Name>");
sb.append("<Size>");
sb.append(DataHelper.formatSize2Decimal(result.getSize(), false)).append("B");
@ -76,7 +76,7 @@ public class SearchServlet extends HttpServlet {
sb.append("</InfoHash>");
sb.append("<Downloading>").append(downloadManager.isDownloading(result.getInfohash())).append("</Downloading>");
if (result.getComment() != null)
sb.append("<Comment>").append(DataHelper.escapeHTML(result.getComment())).append("</Comment>");
sb.append("<Comment>").append(Util.escapeHTMLinXML(result.getComment())).append("</Comment>");
sb.append("</Result>");
});
sb.append("</ResultsFromSender>");
@ -94,7 +94,7 @@ public class SearchServlet extends HttpServlet {
for (SearchResults results : searchManager.getResults().values()) {
sb.append("<Search>");
sb.append("<uuid>").append(results.getUUID()).append("</uuid>");
sb.append("<Query>").append(DataHelper.escapeHTML(results.getSearch())).append("</Query>");
sb.append("<Query>").append(Util.escapeHTMLinXML(results.getSearch())).append("</Query>");
Map<InfoHash, Set<UIResultEvent>> byInfohash = results.getByInfoHash();
sb.append("<ResultsByFile>");
byInfohash.forEach((infoHash, resultSet) -> {
@ -102,13 +102,13 @@ public class SearchServlet extends HttpServlet {
UIResultEvent first = resultSet.iterator().next();
sb.append("<InfoHash>").append(Base64.encode(infoHash.getRoot())).append("</InfoHash>");
sb.append("<Downloading>").append(downloadManager.isDownloading(infoHash)).append("</Downloading>");
sb.append("<Name>").append(DataHelper.escapeHTML(first.getName())).append("</Name>");
sb.append("<Name>").append(Util.escapeHTMLinXML(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(DataHelper.escapeHTML(result.getSender().getHumanReadableName())).append("</Sender>");
sb.append("<Sender>").append(Util.escapeHTMLinXML(result.getSender().getHumanReadableName())).append("</Sender>");
if (result.getComment() != null)
sb.append("<Comment>").append(DataHelper.escapeHTML(result.getComment())).append("</Comment>");
sb.append("<Comment>").append(Util.escapeHTMLinXML(result.getComment())).append("</Comment>");
sb.append("</Result>");
});
sb.append("</ResultsForFile>");

View File

@ -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");
});
}

View File

@ -0,0 +1,28 @@
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@include file="initcode.jsi"%>
<% String pagetitle="Files"; %>
<html>
<head>
<%@ include file="css.jsi"%>
<script src="js/files.js"?<%=version%>" type="text/javascript"></script>
</head>
<body onload="initConnectionsCount(); initFiles();">
<%@ include file="header.jsi"%>
<p>Shared Files</p>
<div id="sharedTree"></div>
<hr/>
<form action="/MuWire/Files" method="post">
<input type="text" name="file">
<input type="hidden" name="action" value="share">
<input type="submit" value="Share">
</form>
<form action="/MuWire/Files" method="post">
<input type="text" name="file">
<input type="hidden" name="action" value="unshare">
<input type="submit" value="Unshare">
</form>
</body>
</html>