use of org.klomp.snark.comments.Comment in project i2p.i2p by i2p.
the class I2PSnarkServlet method saveComments.
/**
* @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");
}
use of org.klomp.snark.comments.Comment in project i2p.i2p by i2p.
the class ExtensionHandler method locked_sendComments.
/**
* Send comments
* Caller must sync on comments
* @param num max to send
* @param comments non-null
* @since 0.9.31
*/
public static void locked_sendComments(Peer peer, int num, CommentSet comments) {
int toSend = Math.min(num, comments.size());
if (toSend <= 0)
return;
Map<String, Object> map = new HashMap<String, Object>();
map.put("msg_type", Integer.valueOf(1));
List<Object> lc = new ArrayList<Object>(toSend);
long now = I2PAppContext.getGlobalContext().clock().now();
int i = 0;
for (Comment c : comments) {
if (i++ >= toSend)
break;
Map<String, Object> mc = new HashMap<String, Object>();
String s = c.getName();
mc.put("owner", s != null ? s : "");
s = c.getText();
mc.put("text", s != null ? s : "");
mc.put("like", Integer.valueOf(c.getRating()));
mc.put("timestamp", Long.valueOf((now - c.getTime()) / 1000L));
lc.add(mc);
}
map.put("comments", lc);
byte[] payload = BEncoder.bencode(map);
try {
int hisMsgCode = peer.getHandshakeMap().get("m").getMap().get(TYPE_COMMENT).getInt();
peer.sendExtension(hisMsgCode, payload);
} catch (Exception e) {
// NPE, no caps
}
}
use of org.klomp.snark.comments.Comment in project i2p.i2p by i2p.
the class I2PSnarkServlet method displayComments.
/**
* @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();
boolean canRate = esc && _manager.util().getCommentsName().length() > 0;
buf.append("<div id=\"snarkCommentSection\"><table class=\"snarkCommentInfo\">\n<tr><th colspan=\"3\">").append(_t("Ratings and Comments"));
if (esc && !canRate) {
buf.append(" <span id=\"nameRequired\">");
buf.append(_t("Author name required to rate or comment"));
buf.append(" <a href=\"").append(_contextPath).append("/configure#configureAuthor\">[");
buf.append(_t("Configure"));
buf.append("]</a></span>");
} else if (esc) {
buf.append(" <span id=\"nameRequired\"><span class=\"commentAuthorName\" title=\"").append(_t("Your author name for published comments and ratings")).append("\">");
buf.append(DataHelper.escapeHTML(_manager.util().getCommentsName()));
buf.append("</span></span>");
}
buf.append("</th></tr>\n<tr id=\"commentsConfig\"><td>");
buf.append(_t("Comments"));
buf.append(":</td><td><label><input type=\"checkbox\" class=\"optbox\" name=\"enableComments\" id=\"enableComments\" ");
if (esc)
buf.append("checked=\"checked\"");
else if (!ec)
buf.append("disabled=\"disabled\"");
buf.append("> ");
buf.append(_t("Enable viewing and posting comments for this torrent"));
buf.append("</label></td><td class=\"commentAction\">");
if (ec) {
buf.append("<input type=\"submit\" name=\"setCommentsEnabled\" value=\"");
buf.append(_t("Save Preference"));
buf.append("\" class=\"accept\">");
}
buf.append("</td></tr>\n");
// new rating / comment form
if (canRate) {
buf.append("<tr id=\"newRating\">\n");
if (er) {
buf.append("<td>\n<select name=\"myRating\">\n");
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) {
for (int j = 0; j < i; j++) {
buf.append("★");
}
buf.append(' ').append(ngettext("1 star", "{0} stars", i));
} else {
buf.append("☆ ").append(_t("No rating"));
}
buf.append("</option>\n");
}
buf.append("</select>\n</td>");
} else {
buf.append("<td></td>");
}
if (esc) {
buf.append("<td id=\"addCommentText\"><textarea name=\"nofilter_newComment\" cols=\"44\" rows=\"4\"></textarea></td>");
} else {
buf.append("<td></td>");
}
buf.append("<td class=\"commentAction\"><input type=\"submit\" name=\"addComment\" value=\"");
if (er && esc)
buf.append(_t("Rate and Comment"));
else if (er)
buf.append(_t("Rate Torrent"));
else
buf.append(_t("Add Comment"));
buf.append("\" class=\"accept\"></td>\n");
buf.append("</tr>\n");
}
if (comments != null) {
synchronized (comments) {
// current rating
if (er) {
buf.append("<tr id=\"myRating\"><td>");
myRating = comments.getMyRating();
if (myRating > 0) {
buf.append(_t("My Rating")).append(":</td><td colspan=\"2\" class=\"commentRating\">");
String img = toThemeImg("rateme", "★", "");
for (int i = 0; i < myRating; i++) {
buf.append(img);
}
}
buf.append("</td></tr>");
}
if (er) {
buf.append("<tr id=\"showRatings\"><td>");
int rcnt = comments.getRatingCount();
if (rcnt > 0) {
double avg = comments.getAverageRating();
// todo format
buf.append(_t("Average Rating")).append(":</td><td>").append(avg);
// buf.append(' ').append(_t("Total Ratings")).append(": ").append(rcnt);
} else {
buf.append(_t("Average Rating")).append(":</td><td colspan=\"2\">");
buf.append(_t("No community ratings currently available"));
}
buf.append("</td></tr>");
}
if (ec) {
int sz = comments.size();
if (sz > 0)
iter = comments.iterator();
}
}
}
buf.append("</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 class=\"commentAuthor\">");
// TODO can't be hidden... hide if comments are hidden?
if (c.getName() != null) {
buf.append("<span class=\"commentAuthorName\">");
buf.append(DataHelper.escapeHTML(c.getName()));
buf.append("</span>");
}
buf.append("</td><td class=\"commentRating\">");
if (er) {
int rt = c.getRating();
if (rt > 0) {
String img = toThemeImg("rateme", "★", "");
for (int i = 0; i < rt; i++) {
buf.append(img);
}
}
}
buf.append("</td><td class=\"commentDate\">").append(fmt.format(new Date(c.getTime())));
buf.append("</td><td class=\"commentText\">");
if (esc) {
if (c.getText() != null) {
buf.append("<div class=\"commentWrapper\">");
buf.append(DataHelper.escapeHTML(c.getText()));
buf.append("</div></td><td class=\"commentDelete\"><input type=\"checkbox\" class=\"optbox\" name=\"cdelete.").append(c.getID()).append("\" title=\"").append(_t("Mark for deletion")).append("\">");
ccount++;
} else {
// insert empty named columns to maintain table layout
buf.append("</td><td class=\"commentDelete\">");
}
} else {
// insert empty named columns to maintain table layout
buf.append("</td><td class=\"commentDelete\">");
}
buf.append("</td></tr>\n");
}
if (esc && ccount > 0) {
// TODO format better
buf.append("<tr id=\"commentDeleteAction\"><td colspan=\"5\" class=\"commentAction\" align=\"right\"><input type=\"submit\" name=\"deleteComments\" value=\"");
buf.append(_t("Delete Selected"));
buf.append("\" class=\"delete\"></td></tr>\n");
}
buf.append("</table>");
} else if (esc) {
// buf.append(_t("No comments for this torrent"));
}
// iter != null
buf.append("</div>");
}
use of org.klomp.snark.comments.Comment in project i2p.i2p by i2p.
the class ExtensionHandler method handleComment.
/**
* Handle comment request and response
*
* Ref: https://blinkenlights.ch/ccms/software/bittorrent.html
* Ref: https://github.com/adrian-bl/bitflu/blob/3cb7fe887dbdea8132e4fa36fbbf5f26cf992db3/plugins/Bitflu/20_DownloadBitTorrent.pm#L3403
* @since 0.9.31
*/
private static void handleComment(Peer peer, PeerListener listener, byte[] bs, Log log) {
if (log.shouldLog(Log.DEBUG))
log.debug("Got comment msg from " + peer);
try {
InputStream is = new ByteArrayInputStream(bs);
BDecoder dec = new BDecoder(is);
BEValue bev = dec.bdecodeMap();
Map<String, BEValue> map = bev.getMap();
int type = map.get("msg_type").getInt();
if (type == 0) {
// request
int num = 20;
BEValue b = map.get("num");
if (b != null)
num = b.getInt();
listener.gotCommentReq(peer, num);
} else if (type == 1) {
// response
List<BEValue> list = map.get("comments").getList();
if (list.isEmpty())
return;
List<Comment> comments = new ArrayList<Comment>(list.size());
long now = I2PAppContext.getGlobalContext().clock().now();
for (BEValue li : list) {
Map<String, BEValue> m = li.getMap();
String owner = m.get("owner").getString();
String text = m.get("text").getString();
// 0-5 range for rating is enforced by Comment constructor
int rating = m.get("like").getInt();
long time = now - (Math.max(0, m.get("timestamp").getInt()) * 1000L);
Comment c = new Comment(text, owner, rating, time, false);
comments.add(c);
}
listener.gotComments(peer, comments);
} else {
if (log.shouldLog(Log.INFO))
log.info("Unknown comment msg type " + type + " from " + peer);
}
} catch (Exception e) {
if (log.shouldLog(Log.INFO))
log.info("Comment msg exception from " + peer, e);
// peer.disconnect(false);
}
}
Aggregations