forked from I2P_Developers/i2p.i2p
i2psnark: Add ut_comment UI and per-torrent configuration
Some UI cleanup still to do
This commit is contained in:
@ -81,6 +81,7 @@ class PeerCheckerTask implements Runnable
|
|||||||
" interested: " + coordinator.getInterestedUploaders() +
|
" interested: " + coordinator.getInterestedUploaders() +
|
||||||
" limit: " + uploadLimit + " overBW? " + overBWLimit);
|
" limit: " + uploadLimit + " overBW? " + overBWLimit);
|
||||||
DHT dht = _util.getDHT();
|
DHT dht = _util.getDHT();
|
||||||
|
boolean fetchComments = _util.utCommentsEnabled();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Peer peer : peerList) {
|
for (Peer peer : peerList) {
|
||||||
i++;
|
i++;
|
||||||
@ -232,7 +233,7 @@ class PeerCheckerTask implements Runnable
|
|||||||
if (((_runCount + i) % 17) == 0 && !peer.isCompleted())
|
if (((_runCount + i) % 17) == 0 && !peer.isCompleted())
|
||||||
coordinator.sendPeers(peer);
|
coordinator.sendPeers(peer);
|
||||||
// send Comment Request, about every 30 minutes
|
// send Comment Request, about every 30 minutes
|
||||||
if ( /* comments enabled && */ ((_runCount + i) % 47) == 0)
|
if (fetchComments && ((_runCount + i) % 47) == 0)
|
||||||
coordinator.sendCommentReq(peer);
|
coordinator.sendCommentReq(peer);
|
||||||
// cheap failsafe for seeds connected to seeds, stop pinging and hopefully
|
// cheap failsafe for seeds connected to seeds, stop pinging and hopefully
|
||||||
// the inactive checker (above) will eventually disconnect it
|
// the inactive checker (above) will eventually disconnect it
|
||||||
|
@ -112,6 +112,8 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
//private static final String PROP_META_BITFIELD_SUFFIX = ".bitfield";
|
//private static final String PROP_META_BITFIELD_SUFFIX = ".bitfield";
|
||||||
//private static final String PROP_META_PRIORITY_SUFFIX = ".priority";
|
//private static final String PROP_META_PRIORITY_SUFFIX = ".priority";
|
||||||
private static final String PROP_META_MAGNET_PREFIX = "i2psnark.magnet.";
|
private static final String PROP_META_MAGNET_PREFIX = "i2psnark.magnet.";
|
||||||
|
/** @since 0.9.31 */
|
||||||
|
private static final String PROP_META_COMMENTS = "comments";
|
||||||
|
|
||||||
private static final String CONFIG_FILE_SUFFIX = ".config";
|
private static final String CONFIG_FILE_SUFFIX = ".config";
|
||||||
private static final String CONFIG_FILE = "i2psnark" + CONFIG_FILE_SUFFIX;
|
private static final String CONFIG_FILE = "i2psnark" + CONFIG_FILE_SUFFIX;
|
||||||
@ -1924,6 +1926,31 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get setting for comments enabled from the config file.
|
||||||
|
* Caller must first check global I2PSnarkUtil.commentsEnabled()
|
||||||
|
* Default true.
|
||||||
|
* @since 0.9.31
|
||||||
|
*/
|
||||||
|
public boolean getSavedCommentsEnabled(Snark snark) {
|
||||||
|
boolean rv = true;
|
||||||
|
Properties config = getConfig(snark);
|
||||||
|
if (config != null) {
|
||||||
|
String s = config.getProperty(PROP_META_COMMENTS);
|
||||||
|
if (s != null)
|
||||||
|
rv = Boolean.parseBoolean(s);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set setting for comments enabled in the config file.
|
||||||
|
* @since 0.9.31
|
||||||
|
*/
|
||||||
|
public void setSavedCommentsEnabled(Snark snark, boolean yes) {
|
||||||
|
saveTorrentStatus(snark, Boolean.valueOf(yes));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the completion status of a torrent and other data in the config file
|
* Save the completion status of a torrent and other data in the config file
|
||||||
@ -1932,13 +1959,24 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
* @since 0.9.15
|
* @since 0.9.15
|
||||||
*/
|
*/
|
||||||
public void saveTorrentStatus(Snark snark) {
|
public void saveTorrentStatus(Snark snark) {
|
||||||
|
saveTorrentStatus(snark, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the completion status of a torrent and other data in the config file
|
||||||
|
* for that torrent. Does nothing for magnets.
|
||||||
|
*
|
||||||
|
* @param comments null for no change
|
||||||
|
* @since 0.9.31
|
||||||
|
*/
|
||||||
|
private void saveTorrentStatus(Snark snark, Boolean comments) {
|
||||||
MetaInfo meta = snark.getMetaInfo();
|
MetaInfo meta = snark.getMetaInfo();
|
||||||
Storage storage = snark.getStorage();
|
Storage storage = snark.getStorage();
|
||||||
if (meta == null || storage == null)
|
if (meta == null || storage == null)
|
||||||
return;
|
return;
|
||||||
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(),
|
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(),
|
||||||
storage.getBase(), storage.getPreserveFileNames(),
|
storage.getBase(), storage.getPreserveFileNames(),
|
||||||
snark.getUploaded(), snark.isStopped());
|
snark.getUploaded(), snark.isStopped(), comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1955,13 +1993,24 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
*/
|
*/
|
||||||
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
||||||
File base, boolean preserveNames, long uploaded, boolean stopped) {
|
File base, boolean preserveNames, long uploaded, boolean stopped) {
|
||||||
|
saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded, stopped, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param comments null for no change
|
||||||
|
* @since 0.9.31
|
||||||
|
*/
|
||||||
|
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
||||||
|
File base, boolean preserveNames, long uploaded, boolean stopped,
|
||||||
|
Boolean comments) {
|
||||||
synchronized (_configLock) {
|
synchronized (_configLock) {
|
||||||
locked_saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded, stopped);
|
locked_saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded, stopped, comments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
||||||
File base, boolean preserveNames, long uploaded, boolean stopped) {
|
File base, boolean preserveNames, long uploaded, boolean stopped,
|
||||||
|
Boolean comments) {
|
||||||
byte[] ih = metainfo.getInfoHash();
|
byte[] ih = metainfo.getInfoHash();
|
||||||
Properties config = getConfig(ih);
|
Properties config = getConfig(ih);
|
||||||
String now = Long.toString(System.currentTimeMillis());
|
String now = Long.toString(System.currentTimeMillis());
|
||||||
@ -1985,6 +2034,8 @@ public class SnarkManager implements CompleteListener, ClientApp {
|
|||||||
config.setProperty(PROP_META_RUNNING, Boolean.toString(running));
|
config.setProperty(PROP_META_RUNNING, Boolean.toString(running));
|
||||||
if (base != null)
|
if (base != null)
|
||||||
config.setProperty(PROP_META_BASE, base.getAbsolutePath());
|
config.setProperty(PROP_META_BASE, base.getAbsolutePath());
|
||||||
|
if (comments != null)
|
||||||
|
config.setProperty(PROP_META_COMMENTS, comments.toString());
|
||||||
|
|
||||||
// now the file priorities
|
// now the file priorities
|
||||||
if (priorities != null) {
|
if (priorities != null) {
|
||||||
|
@ -324,6 +324,8 @@ public class CommentSet extends AbstractSet<Comment> {
|
|||||||
* due to additional deduping in the iterator.
|
* due to additional deduping in the iterator.
|
||||||
*/
|
*/
|
||||||
public Iterator<Comment> iterator() {
|
public Iterator<Comment> iterator() {
|
||||||
|
if (size <= 0)
|
||||||
|
return Collections.<Comment>emptyList().iterator();
|
||||||
List<Comment> list = new ArrayList<Comment>(size);
|
List<Comment> list = new ArrayList<Comment>(size);
|
||||||
for (List<Comment> l : map.values()) {
|
for (List<Comment> l : map.values()) {
|
||||||
int hc = l.get(0).hashCode();
|
int hc = l.get(0).hashCode();
|
||||||
|
@ -13,6 +13,7 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -45,6 +46,8 @@ import org.klomp.snark.Storage;
|
|||||||
import org.klomp.snark.Tracker;
|
import org.klomp.snark.Tracker;
|
||||||
import org.klomp.snark.TrackerClient;
|
import org.klomp.snark.TrackerClient;
|
||||||
import org.klomp.snark.dht.DHT;
|
import org.klomp.snark.dht.DHT;
|
||||||
|
import org.klomp.snark.comments.Comment;
|
||||||
|
import org.klomp.snark.comments.CommentSet;
|
||||||
import org.klomp.snark.standalone.ConfigUIHelper;
|
import org.klomp.snark.standalone.ConfigUIHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2219,6 +2222,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
boolean useOpenTrackers = _manager.util().shouldUseOpenTrackers();
|
boolean useOpenTrackers = _manager.util().shouldUseOpenTrackers();
|
||||||
//String openTrackers = _manager.util().getOpenTrackerString();
|
//String openTrackers = _manager.util().getOpenTrackerString();
|
||||||
boolean useDHT = _manager.util().shouldUseDHT();
|
boolean useDHT = _manager.util().shouldUseDHT();
|
||||||
|
boolean useRatings = _manager.util().ratingsEnabled();
|
||||||
|
boolean useComments = _manager.util().commentsEnabled();
|
||||||
//int seedPct = 0;
|
//int seedPct = 0;
|
||||||
|
|
||||||
out.write("<form action=\"" + _contextPath + "/configure\" method=\"POST\">\n" +
|
out.write("<form action=\"" + _contextPath + "/configure\" method=\"POST\">\n" +
|
||||||
@ -2398,7 +2403,27 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
+ (useDHT ? "checked " : "")
|
+ (useDHT ? "checked " : "")
|
||||||
+ "title=\"");
|
+ "title=\"");
|
||||||
out.write(_t("Use DHT to find additional peers"));
|
out.write(_t("Use DHT to find additional peers"));
|
||||||
out.write("\" ></td></tr>\n");
|
out.write("\" ></td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td>");
|
||||||
|
out.write(_t("Enable Ratings"));
|
||||||
|
out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"ratings\" value=\"true\" "
|
||||||
|
+ (useRatings ? "checked " : "")
|
||||||
|
+ "title=\"");
|
||||||
|
out.write(_t("Show ratings on torrent pages"));
|
||||||
|
out.write("\" ></td></tr>\n" +
|
||||||
|
|
||||||
|
"<tr><td>");
|
||||||
|
out.write(_t("Enable Comments"));
|
||||||
|
out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"comments\" value=\"true\" "
|
||||||
|
+ (useComments ? "checked " : "")
|
||||||
|
+ "title=\"");
|
||||||
|
out.write(_t("Show comments on torrent pages"));
|
||||||
|
out.write("\"> ");
|
||||||
|
out.write(_t("Your commenter name"));
|
||||||
|
out.write(": <input type=\"text\" name=\"nofilter_commentsName\" spellcheck=\"false\" value=\""
|
||||||
|
+ DataHelper.escapeHTML(_manager.util().getCommentsName()) + "\" size=\"32\" maxlength=\"32\" > " +
|
||||||
|
"</td></tr>\n");
|
||||||
|
|
||||||
// "<tr><td>");
|
// "<tr><td>");
|
||||||
//out.write(_t("Open tracker announce URLs"));
|
//out.write(_t("Open tracker announce URLs"));
|
||||||
@ -2752,6 +2777,12 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
if (String.valueOf(_nonce).equals(nonce)) {
|
if (String.valueOf(_nonce).equals(nonce)) {
|
||||||
if (postParams.get("savepri") != null) {
|
if (postParams.get("savepri") != null) {
|
||||||
savePriorities(snark, postParams);
|
savePriorities(snark, postParams);
|
||||||
|
} else if (postParams.get("addComment") != null) {
|
||||||
|
saveComments(snark, postParams);
|
||||||
|
} else if (postParams.get("deleteComments") != null) {
|
||||||
|
deleteComments(snark, postParams);
|
||||||
|
} else if (postParams.get("setCommentsEnabled") != null) {
|
||||||
|
saveCommentsSetting(snark, postParams);
|
||||||
} else if (postParams.get("stop") != null) {
|
} else if (postParams.get("stop") != null) {
|
||||||
_manager.stopTorrent(snark, false);
|
_manager.stopTorrent(snark, false);
|
||||||
} else if (postParams.get("start") != null) {
|
} else if (postParams.get("start") != null) {
|
||||||
@ -2794,7 +2825,9 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
buf.append(DOCTYPE).append("<HTML><HEAD><TITLE>");
|
buf.append(DOCTYPE).append("<HTML><HEAD><TITLE>");
|
||||||
if (title.endsWith("/"))
|
if (title.endsWith("/"))
|
||||||
title = title.substring(0, title.length() - 1);
|
title = title.substring(0, title.length() - 1);
|
||||||
String directory = title;
|
final String directory = title;
|
||||||
|
final int dirSlash = directory.indexOf('/');
|
||||||
|
final boolean isTopLevel = dirSlash <= 0;
|
||||||
title = _t("Torrent") + ": " + DataHelper.escapeHTML(title);
|
title = _t("Torrent") + ": " + DataHelper.escapeHTML(title);
|
||||||
buf.append(title);
|
buf.append(title);
|
||||||
buf.append("</TITLE>\n").append(HEADER_A).append(_themePath).append(HEADER_B)
|
buf.append("</TITLE>\n").append(HEADER_A).append(_themePath).append(HEADER_B)
|
||||||
@ -2817,7 +2850,11 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
if (parent) // always true
|
if (parent) // always true
|
||||||
buf.append("<div class=\"page\">\n<div class=\"mainsection\">");
|
buf.append("<div class=\"page\">\n<div class=\"mainsection\">");
|
||||||
// for stop/start/check
|
// for stop/start/check
|
||||||
if (showStopStart || showPriority) {
|
final boolean er = isTopLevel && _manager.util().ratingsEnabled();
|
||||||
|
final boolean ec = isTopLevel && _manager.util().commentsEnabled(); // global setting
|
||||||
|
final boolean esc = ec && _manager.getSavedCommentsEnabled(snark); // per-torrent setting
|
||||||
|
final boolean includeForm = showStopStart || showPriority || er || ec;
|
||||||
|
if (includeForm) {
|
||||||
buf.append("<form action=\"").append(base).append("\" method=\"POST\">\n");
|
buf.append("<form action=\"").append(base).append("\" method=\"POST\">\n");
|
||||||
buf.append("<input type=\"hidden\" name=\"nonce\" value=\"").append(_nonce).append("\" >\n");
|
buf.append("<input type=\"hidden\" name=\"nonce\" value=\"").append(_nonce).append("\" >\n");
|
||||||
if (sortParam != null) {
|
if (sortParam != null) {
|
||||||
@ -3125,6 +3162,10 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
|
|
||||||
if (ls == null) {
|
if (ls == null) {
|
||||||
// We are only showing the torrent info section
|
// We are only showing the torrent info section
|
||||||
|
if (er || ec)
|
||||||
|
displayComments(snark, er, ec, esc, buf);
|
||||||
|
if (includeForm)
|
||||||
|
buf.append("</form>");
|
||||||
buf.append("</div></div></BODY></HTML>");
|
buf.append("</div></div></BODY></HTML>");
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
@ -3176,8 +3217,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
: tx + ": " + directory);
|
: tx + ": " + directory);
|
||||||
if (showSort)
|
if (showSort)
|
||||||
buf.append("</a>");
|
buf.append("</a>");
|
||||||
int dirSlash = directory.indexOf('/');
|
if (!isTopLevel) {
|
||||||
if (dirSlash > 0) {
|
|
||||||
buf.append(" ");
|
buf.append(" ");
|
||||||
buf.append(DataHelper.escapeHTML(directory.substring(dirSlash + 1)));
|
buf.append(DataHelper.escapeHTML(directory.substring(dirSlash + 1)));
|
||||||
}
|
}
|
||||||
@ -3360,14 +3400,160 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
"</th></tr></thead>\n");
|
"</th></tr></thead>\n");
|
||||||
}
|
}
|
||||||
buf.append("</table>\n");
|
buf.append("</table>\n");
|
||||||
|
if (er || ec)
|
||||||
|
displayComments(snark, er, ec, esc, buf);
|
||||||
// for stop/start/check
|
// for stop/start/check
|
||||||
if (showStopStart || showPriority)
|
if (includeForm)
|
||||||
buf.append("</form>");
|
buf.append("</form>");
|
||||||
buf.append("</div></div></BODY></HTML>\n");
|
buf.append("</div></div></BODY></HTML>\n");
|
||||||
|
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param er ratings enabled globally
|
||||||
|
* @param ec comments enabled globally
|
||||||
|
* @param esc comments enabled this torrent
|
||||||
|
* @since 0.9.31
|
||||||
|
*/
|
||||||
|
private void displayComments(Snark snark, boolean er, boolean ec, boolean esc, StringBuilder buf) {
|
||||||
|
Iterator<Comment> iter = null;
|
||||||
|
int myRating = 0;
|
||||||
|
CommentSet comments = snark.getComments();
|
||||||
|
buf.append("<table class=\"snarkCommentInfo\"><tr><th colspan=\"5\">")
|
||||||
|
.append(_t("Ratings and Comments"))
|
||||||
|
.append("</th><tr><td>");
|
||||||
|
if (comments != null) {
|
||||||
|
synchronized(comments) {
|
||||||
|
// current rating
|
||||||
|
if (er) {
|
||||||
|
myRating = comments.getMyRating();
|
||||||
|
if (myRating > 0) {
|
||||||
|
buf.append(_t("My Rating")).append(": ");
|
||||||
|
String img = toImg("itoopie_xxsm");
|
||||||
|
for (int i = 0; i < myRating; i++) {
|
||||||
|
buf.append(img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.append("</td><td>");
|
||||||
|
if (er) {
|
||||||
|
int rcnt = comments.getRatingCount();
|
||||||
|
if (rcnt > 0) {
|
||||||
|
double avg = comments.getAverageRating();
|
||||||
|
buf.append(_t("Average Rating")).append(": ").append(avg); // todo format
|
||||||
|
//buf.append(' ').append(_t("Total Ratings")).append(": ").append(rcnt);
|
||||||
|
} else {
|
||||||
|
buf.append(_t("No ratings for this torrent"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ec) {
|
||||||
|
int sz = comments.size();
|
||||||
|
if (sz > 0)
|
||||||
|
iter = comments.iterator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buf.append("</td><td>");
|
||||||
|
}
|
||||||
|
buf.append("</td><td></td><td>");
|
||||||
|
buf.append(_t("Comments Enabled for this Torrent"));
|
||||||
|
buf.append(": <input type=\"checkbox\" class=\"optbox\" name=\"enableComments\" ");
|
||||||
|
if (esc)
|
||||||
|
buf.append("checked=\"checked\"");
|
||||||
|
else if (!ec)
|
||||||
|
buf.append("disabled=\"disabled\"");
|
||||||
|
buf.append("></td><td>");
|
||||||
|
if (ec) {
|
||||||
|
buf.append(" <input type=\"submit\" name=\"setCommentsEnabled\" value=\"");
|
||||||
|
buf.append(_t("Save Comments Setting"));
|
||||||
|
buf.append("\" class=\"accept\">\n");
|
||||||
|
}
|
||||||
|
if (esc && _manager.util().getCommentsName().length() == 0) {
|
||||||
|
buf.append("<br><a href=\"").append(_contextPath).append("/configure\">");
|
||||||
|
buf.append(_t("Please configure your name for comments on the configuration page"));
|
||||||
|
buf.append("</a>");
|
||||||
|
}
|
||||||
|
buf.append("</td></tr><tr><td>");
|
||||||
|
// new rating / comment form
|
||||||
|
if (er) {
|
||||||
|
buf.append(" <select name=\"myRating\">");
|
||||||
|
for (int i = 5; i >= 0; i--) {
|
||||||
|
buf.append("<option value=\"").append(i).append("\" ");
|
||||||
|
if (i == myRating)
|
||||||
|
buf.append("selected=\"selected\"");
|
||||||
|
buf.append('>');
|
||||||
|
if (i != 0) {
|
||||||
|
buf.append(ngettext("{0} toopie", "{0} toopies", i));
|
||||||
|
} else {
|
||||||
|
buf.append(_t("no rating"));
|
||||||
|
}
|
||||||
|
buf.append("</option>\n");
|
||||||
|
}
|
||||||
|
buf.append("</select></td><td></td><td>\n");
|
||||||
|
}
|
||||||
|
if (esc) {
|
||||||
|
buf.append("<textarea name=\"nofilter_newComment\" cols=\"44\" rows=\"4\"></textarea>");
|
||||||
|
}
|
||||||
|
buf.append("</td><td></td><td><input type=\"submit\" name=\"addComment\" value=\"");
|
||||||
|
if (er && esc)
|
||||||
|
buf.append(_t("Add Rating and Comment"));
|
||||||
|
else if (er)
|
||||||
|
buf.append(_t("Add Rating"));
|
||||||
|
else
|
||||||
|
buf.append(_t("Add Comment"));
|
||||||
|
buf.append("\" class=\"accept\">\n");
|
||||||
|
buf.append("</td></tr></table>");
|
||||||
|
// TODO disable / enable comments for this torrent
|
||||||
|
// existing ratings / comments table
|
||||||
|
int ccount = 0;
|
||||||
|
if (iter != null) {
|
||||||
|
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||||
|
fmt.setTimeZone(SystemVersion.getSystemTimeZone(_context));
|
||||||
|
buf.append("<table class=\"snarkComments\">");
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Comment c = iter.next();
|
||||||
|
buf.append("<tr><td>");
|
||||||
|
// (c.isMine())
|
||||||
|
// buf.append(_t("me"));
|
||||||
|
//else if (c.getName() != null)
|
||||||
|
// TODO can't be hidden... hide if comments are hidden?
|
||||||
|
if (c.getName() != null)
|
||||||
|
buf.append(DataHelper.escapeHTML(c.getName()));
|
||||||
|
buf.append("</td><td>");
|
||||||
|
if (er) {
|
||||||
|
int rt = c.getRating();
|
||||||
|
if (rt > 0) {
|
||||||
|
String img = toImg("itoopie_xxsm");
|
||||||
|
for (int i = 0; i < rt; i++) {
|
||||||
|
buf.append(img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.append("</td><td>").append(fmt.format(new Date(c.getTime())));
|
||||||
|
if (esc) {
|
||||||
|
buf.append("</td><td>");
|
||||||
|
if (c.getText() != null) {
|
||||||
|
buf.append(DataHelper.escapeHTML(c.getText()));
|
||||||
|
buf.append("</td><td><input type=\"checkbox\" class=\"optbox\" name=\"cdelete.")
|
||||||
|
.append(c.getID()).append("\" title=\"").append(_t("Delete")).append("\">");
|
||||||
|
ccount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.append("</td></tr>\n");
|
||||||
|
}
|
||||||
|
if (esc && ccount > 0) {
|
||||||
|
// TODO format better
|
||||||
|
buf.append("<tr><td colspan=\"5\" align=\"right\"><input type=\"submit\" name=\"deleteComments\" value=\"");
|
||||||
|
buf.append(_t("Delete Selected Comments"));
|
||||||
|
buf.append("\" class=\"delete\"></td></tr>\n");
|
||||||
|
}
|
||||||
|
buf.append("</table>");
|
||||||
|
} else if (esc) {
|
||||||
|
//buf.append(_t("No comments for this torrent"));
|
||||||
|
} // iter != null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param so null ok
|
* @param so null ok
|
||||||
* @return query string or ""
|
* @return query string or ""
|
||||||
@ -3539,6 +3725,50 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
_manager.saveTorrentStatus(snark);
|
_manager.saveTorrentStatus(snark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.31 */
|
||||||
|
private void saveComments(Snark snark, Map<String, String[]> postParams) {
|
||||||
|
String[] a = postParams.get("myRating");
|
||||||
|
String r = (a != null) ? a[0] : null;
|
||||||
|
a = postParams.get("nofilter_newComment");
|
||||||
|
String c = (a != null) ? a[0] : null;
|
||||||
|
if ((r == null || r.equals("0")) && (c == null || c.length() == 0))
|
||||||
|
return;
|
||||||
|
int rat = 0;
|
||||||
|
try {
|
||||||
|
rat = Integer.parseInt(r);
|
||||||
|
} catch (NumberFormatException nfe) {}
|
||||||
|
Comment com = new Comment(c, _manager.util().getCommentsName(), rat);
|
||||||
|
boolean changed = snark.addComments(Collections.singletonList(com));
|
||||||
|
if (!changed)
|
||||||
|
_log.warn("Add of comment ID " + com.getID() + " UNSUCCESSFUL");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.31 */
|
||||||
|
private void deleteComments(Snark snark, Map<String, String[]> postParams) {
|
||||||
|
CommentSet cs = snark.getComments();
|
||||||
|
if (cs == null)
|
||||||
|
return;
|
||||||
|
synchronized(cs) {
|
||||||
|
for (Map.Entry<String, String[]> entry : postParams.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
if (key.startsWith("cdelete.")) {
|
||||||
|
try {
|
||||||
|
int id = Integer.parseInt(key.substring(8));
|
||||||
|
boolean changed = cs.remove(id);
|
||||||
|
if (!changed)
|
||||||
|
_log.warn("Delete of comment ID " + id + " UNSUCCESSFUL");
|
||||||
|
} catch (NumberFormatException nfe) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 0.9.31 */
|
||||||
|
private void saveCommentsSetting(Snark snark, Map<String, String[]> postParams) {
|
||||||
|
boolean yes = postParams.get("enableComments") != null;
|
||||||
|
_manager.setSavedCommentsEnabled(snark, yes);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is "a" equal to "b",
|
* Is "a" equal to "b",
|
||||||
* or is "a" a directory and a parent of file or directory "b",
|
* or is "a" a directory and a parent of file or directory "b",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
2017-05-19 zzz
|
2017-05-19 zzz
|
||||||
* Console: Move /peers page rendering from router to console (ticket #1879)
|
* Console: Move /peers page rendering from router to console (ticket #1879)
|
||||||
|
* i2psnark: Add ut_comment UI and per-torrent configuration
|
||||||
|
|
||||||
2017-05-18 str4d
|
2017-05-18 str4d
|
||||||
Prop from i2p.i2p.str4d.ui:
|
Prop from i2p.i2p.str4d.ui:
|
||||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
|||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Monotone";
|
public final static String ID = "Monotone";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 6;
|
public final static long BUILD = 7;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
Reference in New Issue
Block a user