forked from I2P_Developers/i2p.i2p
snark sorters for details page
no links yet
This commit is contained in:
@ -221,7 +221,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
resp.sendError(404);
|
||||
} else {
|
||||
String base = addPaths(req.getRequestURI(), "/");
|
||||
String listing = getListHTML(resource, base, true, method.equals("POST") ? req.getParameterMap() : null);
|
||||
String listing = getListHTML(resource, base, true, method.equals("POST") ? req.getParameterMap() : null,
|
||||
req.getParameter("sort"));
|
||||
if (method.equals("POST")) {
|
||||
// P-R-G
|
||||
sendRedirect(req, resp, "");
|
||||
@ -2493,23 +2494,6 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
|
||||
private static final String FOOTER = "</div></center></body></html>";
|
||||
|
||||
/**
|
||||
* Sort alphabetically in current locale, ignore case,
|
||||
* directories first
|
||||
* @since 0.9.6
|
||||
*/
|
||||
private static class ListingComparator implements Comparator<File>, Serializable {
|
||||
|
||||
public int compare(File l, File r) {
|
||||
boolean ld = l.isDirectory();
|
||||
boolean rd = r.isDirectory();
|
||||
if (ld && !rd)
|
||||
return -1;
|
||||
if (rd && !ld)
|
||||
return 1;
|
||||
return Collator.getInstance().compare(l.getName(), r.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modded heavily from the Jetty version in Resource.java,
|
||||
@ -2538,10 +2522,11 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
* @param base The encoded base URL
|
||||
* @param parent True if the parent directory should be included
|
||||
* @param postParams map of POST parameters or null if not a POST
|
||||
* @param sortParam may be null
|
||||
* @return String of HTML or null if postParams != null
|
||||
* @since 0.7.14
|
||||
*/
|
||||
private String getListHTML(File xxxr, String base, boolean parent, Map<String, String[]> postParams)
|
||||
private String getListHTML(File xxxr, String base, boolean parent, Map<String, String[]> postParams, String sortParam)
|
||||
throws IOException
|
||||
{
|
||||
String decodedBase = decodePath(base);
|
||||
@ -2845,7 +2830,6 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
File[] ls = null;
|
||||
if (r.isDirectory()) {
|
||||
ls = r.listFiles();
|
||||
Arrays.sort(ls, new ListingComparator());
|
||||
} // if r is not a directory, we are only showing torrent info section
|
||||
|
||||
if (ls == null) {
|
||||
@ -2854,6 +2838,21 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
Storage storage = snark != null ? snark.getStorage() : null;
|
||||
List<Sorters.FileAndIndex> fileList = new ArrayList<Sorters.FileAndIndex>(ls.length);
|
||||
for (int i = 0; i < ls.length; i++) {
|
||||
fileList.add(new Sorters.FileAndIndex(ls[i], storage));
|
||||
}
|
||||
if (fileList.size() > 1) {
|
||||
int sort = 0;
|
||||
if (sortParam != null) {
|
||||
try {
|
||||
sort = Integer.parseInt(sortParam);
|
||||
} catch (NumberFormatException nfe) {}
|
||||
}
|
||||
Collections.sort(fileList, Sorters.getFileComparator(sort, this));
|
||||
}
|
||||
|
||||
// second table - dir info
|
||||
buf.append("<table class=\"snarkDirInfo\"><thead>\n");
|
||||
buf.append("<tr>\n")
|
||||
@ -2884,25 +2883,27 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
//DateFormat dfmt=DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
|
||||
// DateFormat.MEDIUM);
|
||||
boolean showSaveButton = false;
|
||||
for (int i=0 ; i< ls.length ; i++)
|
||||
boolean rowEven = true;
|
||||
for (Sorters.FileAndIndex fai : fileList)
|
||||
{
|
||||
//String encoded = encodePath(ls[i].getName());
|
||||
// bugfix for I2P - Backport from Jetty 6 (zero file lengths and last-modified times)
|
||||
// http://jira.codehaus.org/browse/JETTY-361?page=com.atlassian.jira.plugin.system.issuetabpanels%3Achangehistory-tabpanel#issue-tabs
|
||||
// See resource.diff attachment
|
||||
//Resource item = addPath(encoded);
|
||||
File item = ls[i];
|
||||
File item = fai.file;
|
||||
|
||||
String rowClass = (i % 2 == 0 ? "snarkTorrentEven" : "snarkTorrentOdd");
|
||||
String rowClass = (rowEven ? "snarkTorrentEven" : "snarkTorrentOdd");
|
||||
rowEven = !rowEven;
|
||||
buf.append("<TR class=\"").append(rowClass).append("\">");
|
||||
|
||||
// Get completeness and status string
|
||||
boolean complete = false;
|
||||
String status = "";
|
||||
long length = item.length();
|
||||
int fileIndex = -1;
|
||||
int fileIndex = fai.index;
|
||||
int priority = 0;
|
||||
if (item.isDirectory()) {
|
||||
if (fai.isDirectory) {
|
||||
complete = true;
|
||||
//status = toImg("tick") + ' ' + _("Directory");
|
||||
} else {
|
||||
@ -2911,10 +2912,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
complete = true;
|
||||
status = toImg("cancel") + ' ' + _("Torrent not found?");
|
||||
} else {
|
||||
Storage storage = snark.getStorage();
|
||||
fileIndex = storage.indexOf(item);
|
||||
|
||||
long remaining = storage.remaining(fileIndex);
|
||||
long remaining = fai.remaining;
|
||||
if (remaining < 0) {
|
||||
complete = true;
|
||||
status = toImg("cancel") + ' ' + _("File not found in torrent?");
|
||||
@ -2922,7 +2921,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
complete = true;
|
||||
status = toImg("tick") + ' ' + _("Complete");
|
||||
} else {
|
||||
priority = storage.getPriority(fileIndex);
|
||||
priority = fai.priority;
|
||||
if (priority < 0)
|
||||
status = toImg("cancel");
|
||||
else if (priority == 0)
|
||||
@ -2937,7 +2936,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
}
|
||||
}
|
||||
|
||||
String path = addPaths(decodedBase, ls[i].getName());
|
||||
String path = addPaths(decodedBase, item.getName());
|
||||
if (item.isDirectory() && !path.endsWith("/"))
|
||||
path=addPaths(path,"/");
|
||||
path = encodePath(path);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.klomp.snark.web;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serializable;
|
||||
import java.text.Collator;
|
||||
import java.util.Collections;
|
||||
@ -8,6 +9,7 @@ import java.util.Locale;
|
||||
|
||||
import org.klomp.snark.MetaInfo;
|
||||
import org.klomp.snark.Snark;
|
||||
import org.klomp.snark.Storage;
|
||||
|
||||
/**
|
||||
* Comparators for various columns
|
||||
@ -338,4 +340,192 @@ class Sorters {
|
||||
return servlet.toIcon(meta.getName());
|
||||
}
|
||||
}
|
||||
|
||||
////////////// Comparators for details page below
|
||||
|
||||
/**
|
||||
* Class to precompute and efficiently sort data
|
||||
* on a torrent file entry.
|
||||
*/
|
||||
public static class FileAndIndex {
|
||||
public final File file;
|
||||
public final boolean isDirectory;
|
||||
public final long length;
|
||||
public final long remaining;
|
||||
public final int priority;
|
||||
public final int index;
|
||||
|
||||
/**
|
||||
* @param storage may be null
|
||||
*/
|
||||
public FileAndIndex(File file, Storage storage) {
|
||||
this.file = file;
|
||||
index = storage != null ? storage.indexOf(file) : -1;
|
||||
if (index >= 0) {
|
||||
isDirectory = false;
|
||||
remaining = storage.remaining(index);
|
||||
priority = storage.getPriority(index);
|
||||
} else {
|
||||
isDirectory = file.isDirectory();
|
||||
remaining = -1;
|
||||
priority = 0;
|
||||
}
|
||||
length = isDirectory ? 0 : file.length();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Negative is reverse
|
||||
*
|
||||
*<ul>
|
||||
*<li>0, 1: Name
|
||||
*<li>5: Size
|
||||
*<li>10: Remaining (needed)
|
||||
*<li>12: File type
|
||||
*<li>13: Priority
|
||||
*</ul>
|
||||
*
|
||||
* @param servlet for file type callback only
|
||||
*/
|
||||
public static Comparator<FileAndIndex> getFileComparator(int type, I2PSnarkServlet servlet) {
|
||||
boolean rev = type < 0;
|
||||
Comparator<FileAndIndex> rv;
|
||||
|
||||
switch (type) {
|
||||
|
||||
case -1:
|
||||
case 0:
|
||||
case 1:
|
||||
default:
|
||||
rv = new FileNameComparator();
|
||||
if (rev)
|
||||
rv = Collections.reverseOrder(rv);
|
||||
break;
|
||||
|
||||
case -5:
|
||||
case 5:
|
||||
rv = new FAISizeComparator(rev);
|
||||
break;
|
||||
|
||||
case -10:
|
||||
case 10:
|
||||
rv = new FAIRemainingComparator(rev);
|
||||
break;
|
||||
|
||||
case -12:
|
||||
case 12:
|
||||
rv = new FAITypeComparator(rev, servlet);
|
||||
break;
|
||||
|
||||
case -13:
|
||||
case 13:
|
||||
rv = new FAIPriorityComparator(rev);
|
||||
break;
|
||||
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort alphabetically in current locale, ignore case,
|
||||
* directories first
|
||||
* @since 0.9.6 moved from I2PSnarkServlet in 0.9.16
|
||||
*/
|
||||
private static class FileNameComparator implements Comparator<FileAndIndex>, Serializable {
|
||||
|
||||
public int compare(FileAndIndex l, FileAndIndex r) {
|
||||
return comp(l, r);
|
||||
}
|
||||
|
||||
public static int comp(FileAndIndex l, FileAndIndex r) {
|
||||
boolean ld = l.isDirectory;
|
||||
boolean rd = r.isDirectory;
|
||||
if (ld && !rd)
|
||||
return -1;
|
||||
if (rd && !ld)
|
||||
return 1;
|
||||
return Collator.getInstance().compare(l.file.getName(), r.file.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward or reverse sort, but the fallback is always forward
|
||||
*/
|
||||
private static abstract class FAISort implements Comparator<FileAndIndex>, Serializable {
|
||||
|
||||
private final boolean _rev;
|
||||
|
||||
public FAISort(boolean rev) {
|
||||
_rev = rev;
|
||||
}
|
||||
|
||||
public int compare(FileAndIndex l, FileAndIndex r) {
|
||||
int rv = compareIt(l, r);
|
||||
if (rv != 0)
|
||||
return _rev ? 0 - rv : rv;
|
||||
return FileNameComparator.comp(l, r);
|
||||
}
|
||||
|
||||
protected abstract int compareIt(FileAndIndex l, FileAndIndex r);
|
||||
|
||||
protected static int compLong(long l, long r) {
|
||||
if (l < r)
|
||||
return -1;
|
||||
if (l > r)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FAIRemainingComparator extends FAISort {
|
||||
|
||||
public FAIRemainingComparator(boolean rev) { super(rev); }
|
||||
|
||||
public int compareIt(FileAndIndex l, FileAndIndex r) {
|
||||
return compLong(l.remaining, r.remaining);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FAISizeComparator extends FAISort {
|
||||
|
||||
public FAISizeComparator(boolean rev) { super(rev); }
|
||||
|
||||
public int compareIt(FileAndIndex l, FileAndIndex r) {
|
||||
return compLong(l.length, r.length);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FAITypeComparator extends FAISort {
|
||||
|
||||
private final I2PSnarkServlet servlet;
|
||||
|
||||
public FAITypeComparator(boolean rev, I2PSnarkServlet servlet) {
|
||||
super(rev);
|
||||
this.servlet = servlet;
|
||||
}
|
||||
|
||||
public int compareIt(FileAndIndex l, FileAndIndex r) {
|
||||
String ls = toName(l);
|
||||
String rs = toName(r);
|
||||
return ls.compareTo(rs);
|
||||
}
|
||||
|
||||
private String toName(FileAndIndex fai) {
|
||||
if (fai.isDirectory)
|
||||
return "0";
|
||||
// arbitrary sort based on icon name
|
||||
return servlet.toIcon(fai.file.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private static class FAIPriorityComparator extends FAISort {
|
||||
|
||||
public FAIPriorityComparator(boolean rev) { super(rev); }
|
||||
|
||||
/** highest first */
|
||||
public int compareIt(FileAndIndex l, FileAndIndex r) {
|
||||
return r.priority - l.priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user