migrate the profile page to the new format, and refactor the new format's servlets
This commit is contained in:
@ -55,6 +55,7 @@ public class BlogInfo {
|
|||||||
public static final String SIGNATURE = "Signature";
|
public static final String SIGNATURE = "Signature";
|
||||||
public static final String NAME = "Name";
|
public static final String NAME = "Name";
|
||||||
public static final String DESCRIPTION = "Description";
|
public static final String DESCRIPTION = "Description";
|
||||||
|
public static final String CONTACT_URL = "ContactURL";
|
||||||
public static final String EDITION = "Edition";
|
public static final String EDITION = "Edition";
|
||||||
|
|
||||||
public void load(InputStream in) throws IOException {
|
public void load(InputStream in) throws IOException {
|
||||||
|
@ -400,8 +400,12 @@ public class HTMLRenderer extends EventReceiverImpl {
|
|||||||
if (location != null) {
|
if (location != null) {
|
||||||
_bodyBuffer.append(" at ");
|
_bodyBuffer.append(" at ");
|
||||||
SafeURL surl = new SafeURL(locationSchema + "://" + location);
|
SafeURL surl = new SafeURL(locationSchema + "://" + location);
|
||||||
_bodyBuffer.append("<a ").append(getClass("archiveSummaryLink")).append(" href=\"").append(getArchiveURL(null, surl));
|
if (BlogManager.instance().authorizeRemote(_user)) {
|
||||||
_bodyBuffer.append("\">").append(sanitizeString(surl.toString())).append("</a>");
|
_bodyBuffer.append("<a ").append(getClass("archiveSummaryLink")).append(" href=\"").append(getArchiveURL(null, surl));
|
||||||
|
_bodyBuffer.append("\">").append(sanitizeString(surl.toString())).append("</a>");
|
||||||
|
} else {
|
||||||
|
_bodyBuffer.append(sanitizeString(surl.getLocation()));
|
||||||
|
}
|
||||||
if (_user.getAuthenticated()) {
|
if (_user.getAuthenticated()) {
|
||||||
_bodyBuffer.append(" <a ").append(getClass("archiveBookmarkLink")).append(" href=\"");
|
_bodyBuffer.append(" <a ").append(getClass("archiveBookmarkLink")).append(" href=\"");
|
||||||
_bodyBuffer.append(getBookmarkURL(sanitizeString(name), surl.getLocation(), surl.getSchema(), "syndiearchive"));
|
_bodyBuffer.append(getBookmarkURL(sanitizeString(name), surl.getLocation(), surl.getSchema(), "syndiearchive"));
|
||||||
@ -1001,7 +1005,7 @@ public class HTMLRenderer extends EventReceiverImpl {
|
|||||||
if (_entry == null) return "unknown";
|
if (_entry == null) return "unknown";
|
||||||
return getMetadataURL(_entry.getURI().getKeyHash());
|
return getMetadataURL(_entry.getURI().getKeyHash());
|
||||||
}
|
}
|
||||||
public static String getMetadataURL(Hash blog) {
|
public String getMetadataURL(Hash blog) {
|
||||||
return "viewmetadata.jsp?" + ArchiveViewerBean.PARAM_BLOG + "=" +
|
return "viewmetadata.jsp?" + ArchiveViewerBean.PARAM_BLOG + "=" +
|
||||||
Base64.encode(blog.getData());
|
Base64.encode(blog.getData());
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,19 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
|||||||
public static final String PARAM_VISIBLE = "visible";
|
public static final String PARAM_VISIBLE = "visible";
|
||||||
public static final String PARAM_ADD_TO_GROUP_LOCATION = "addLocation";
|
public static final String PARAM_ADD_TO_GROUP_LOCATION = "addLocation";
|
||||||
public static final String PARAM_ADD_TO_GROUP_NAME = "addGroup";
|
public static final String PARAM_ADD_TO_GROUP_NAME = "addGroup";
|
||||||
|
/** name of the bookmarked entry to remove */
|
||||||
|
public static final String PARAM_REMOVE_FROM_GROUP_NAME = "removeName";
|
||||||
|
/** group to remove from the bookmarked entry, or if blank, remove the entry itself */
|
||||||
|
public static final String PARAM_REMOVE_FROM_GROUP = "removeGroup";
|
||||||
/** index into the nav tree to start displaying */
|
/** index into the nav tree to start displaying */
|
||||||
public static final String PARAM_OFFSET = "offset";
|
public static final String PARAM_OFFSET = "offset";
|
||||||
public static final String PARAM_TAGS = "tags";
|
public static final String PARAM_TAGS = "tags";
|
||||||
public static final String PARAM_AUTHOR = "author";
|
public static final String PARAM_AUTHOR = "author";
|
||||||
|
// parameters for editing one's profile
|
||||||
|
public static final String PARAM_PROFILE_NAME = "profileName";
|
||||||
|
public static final String PARAM_PROFILE_DESC = "profileDesc";
|
||||||
|
public static final String PARAM_PROFILE_URL = "profileURL";
|
||||||
|
public static final String PARAM_PROFILE_OTHER = "profileOther";
|
||||||
|
|
||||||
public static String getFilterByTagLink(String uri, ThreadNode node, User user, String tag, String author) {
|
public static String getFilterByTagLink(String uri, ThreadNode node, User user, String tag, String author) {
|
||||||
StringBuffer buf = new StringBuffer(64);
|
StringBuffer buf = new StringBuffer(64);
|
||||||
@ -399,6 +408,13 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
|||||||
//renderPreBodyCell();
|
//renderPreBodyCell();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMetadataURL(Hash blog) {
|
||||||
|
return buildProfileURL(blog);
|
||||||
|
}
|
||||||
|
public static String buildProfileURL(Hash blog) {
|
||||||
|
return "profile.jsp?" + ThreadedHTMLRenderer.PARAM_AUTHOR + "=" +
|
||||||
|
Base64.encode(blog.getData());
|
||||||
|
}
|
||||||
protected String getEntryURL() { return getEntryURL(_user != null ? _user.getShowImages() : false); }
|
protected String getEntryURL() { return getEntryURL(_user != null ? _user.getShowImages() : false); }
|
||||||
protected String getEntryURL(boolean showImages) {
|
protected String getEntryURL(boolean showImages) {
|
||||||
if (_entry == null)
|
if (_entry == null)
|
||||||
|
716
apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java
Normal file
716
apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java
Normal file
@ -0,0 +1,716 @@
|
|||||||
|
package net.i2p.syndie.web;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.client.naming.*;
|
||||||
|
import net.i2p.data.*;
|
||||||
|
import net.i2p.syndie.*;
|
||||||
|
import net.i2p.syndie.data.*;
|
||||||
|
import net.i2p.syndie.sml.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base servlet for handling request and rendering the templates
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class BaseServlet extends HttpServlet {
|
||||||
|
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
req.setCharacterEncoding("UTF-8");
|
||||||
|
resp.setCharacterEncoding("UTF-8");
|
||||||
|
resp.setContentType("text/html");
|
||||||
|
|
||||||
|
User user = (User)req.getSession().getAttribute("user");
|
||||||
|
String login = req.getParameter("login");
|
||||||
|
String pass = req.getParameter("password");
|
||||||
|
String action = req.getParameter("action");
|
||||||
|
boolean forceNewIndex = false;
|
||||||
|
|
||||||
|
if (req.getParameter("regenerateIndex") != null)
|
||||||
|
forceNewIndex = true;
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
if ("Login".equals(action)) {
|
||||||
|
user = BlogManager.instance().login(login, pass); // ignore failures - user will just be unauthorized
|
||||||
|
if (!user.getAuthenticated())
|
||||||
|
user = BlogManager.instance().getDefaultUser();
|
||||||
|
} else {
|
||||||
|
user = BlogManager.instance().getDefaultUser();
|
||||||
|
}
|
||||||
|
forceNewIndex = true;
|
||||||
|
} else if ("Login".equals(action)) {
|
||||||
|
user = BlogManager.instance().login(login, pass); // ignore failures - user will just be unauthorized
|
||||||
|
if (!user.getAuthenticated())
|
||||||
|
user = BlogManager.instance().getDefaultUser();
|
||||||
|
forceNewIndex = true;
|
||||||
|
} else if ("Logout".equals(action)) {
|
||||||
|
user = BlogManager.instance().getDefaultUser();
|
||||||
|
forceNewIndex = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
req.getSession().setAttribute("user", user);
|
||||||
|
|
||||||
|
forceNewIndex = handleBookmarking(user, req) || forceNewIndex;
|
||||||
|
handleUpdateProfile(user, req);
|
||||||
|
|
||||||
|
FilteredThreadIndex index = (FilteredThreadIndex)req.getSession().getAttribute("threadIndex");
|
||||||
|
|
||||||
|
Collection tags = getFilteredTags(req);
|
||||||
|
Collection filteredAuthors = getFilteredAuthors(req);
|
||||||
|
if (forceNewIndex || (index == null) || (!index.getFilteredTags().equals(tags)) || (!index.getFilteredAuthors().equals(filteredAuthors))) {
|
||||||
|
index = new FilteredThreadIndex(user, BlogManager.instance().getArchive(), getFilteredTags(req), filteredAuthors);
|
||||||
|
req.getSession().setAttribute("threadIndex", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
render(user, req, resp.getWriter(), index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleBookmarking(User user, HttpServletRequest req) {
|
||||||
|
if (!user.getAuthenticated())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
boolean rv = false;
|
||||||
|
|
||||||
|
String loc = req.getParameter(ThreadedHTMLRenderer.PARAM_ADD_TO_GROUP_LOCATION);
|
||||||
|
String group = req.getParameter(ThreadedHTMLRenderer.PARAM_ADD_TO_GROUP_NAME);
|
||||||
|
if ( (loc != null) && (group != null) && (group.trim().length() > 0) ) {
|
||||||
|
try {
|
||||||
|
Hash key = new Hash();
|
||||||
|
key.fromBase64(loc);
|
||||||
|
PetNameDB db = user.getPetNameDB();
|
||||||
|
PetName pn = db.getByLocation(loc);
|
||||||
|
boolean isNew = false;
|
||||||
|
if (pn == null) {
|
||||||
|
isNew = true;
|
||||||
|
BlogInfo info = BlogManager.instance().getArchive().getBlogInfo(key);
|
||||||
|
String name = null;
|
||||||
|
if (info != null)
|
||||||
|
name = info.getProperty(BlogInfo.NAME);
|
||||||
|
else
|
||||||
|
name = loc.substring(0,6);
|
||||||
|
|
||||||
|
if (db.containsName(name)) {
|
||||||
|
int i = 0;
|
||||||
|
while (db.containsName(name + i))
|
||||||
|
i++;
|
||||||
|
name = name + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
pn = new PetName(name, "syndie", "syndieblog", loc);
|
||||||
|
}
|
||||||
|
pn.addGroup(group);
|
||||||
|
if (isNew)
|
||||||
|
db.add(pn);
|
||||||
|
BlogManager.instance().saveUser(user);
|
||||||
|
// if we are ignoring someone, we need to recalculate the filters
|
||||||
|
if (FilteredThreadIndex.GROUP_IGNORE.equals(group))
|
||||||
|
rv = true;
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
// bad loc, ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = req.getParameter(ThreadedHTMLRenderer.PARAM_REMOVE_FROM_GROUP_NAME);
|
||||||
|
group = req.getParameter(ThreadedHTMLRenderer.PARAM_REMOVE_FROM_GROUP);
|
||||||
|
if ( (name != null) && (name.trim().length() > 0) ) {
|
||||||
|
PetNameDB db = user.getPetNameDB();
|
||||||
|
PetName pn = db.getByName(name);
|
||||||
|
boolean changed = false;
|
||||||
|
if (pn != null) {
|
||||||
|
if ( (group != null) && (group.trim().length() > 0) ) {
|
||||||
|
// just remove them from the group
|
||||||
|
changed = pn.isMember(group);
|
||||||
|
pn.removeGroup(group);
|
||||||
|
if ( (changed) && (FilteredThreadIndex.GROUP_IGNORE.equals(group)) )
|
||||||
|
rv = true;
|
||||||
|
} else {
|
||||||
|
// remove it completely
|
||||||
|
if (pn.isMember(FilteredThreadIndex.GROUP_IGNORE))
|
||||||
|
rv = true;
|
||||||
|
db.remove(pn);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed)
|
||||||
|
BlogManager.instance().saveUser(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void handleUpdateProfile(User user, HttpServletRequest req) {
|
||||||
|
if ( (user == null) || (!user.getAuthenticated()) || (user.getBlog() == null) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
String action = req.getParameter("action");
|
||||||
|
if ( (action == null) || !("Update profile".equals(action)) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
String name = req.getParameter(ThreadedHTMLRenderer.PARAM_PROFILE_NAME);
|
||||||
|
String desc = req.getParameter(ThreadedHTMLRenderer.PARAM_PROFILE_DESC);
|
||||||
|
String url = req.getParameter(ThreadedHTMLRenderer.PARAM_PROFILE_URL);
|
||||||
|
String other = req.getParameter(ThreadedHTMLRenderer.PARAM_PROFILE_OTHER);
|
||||||
|
|
||||||
|
Properties opts = new Properties();
|
||||||
|
if (!empty(name))
|
||||||
|
opts.setProperty(BlogInfo.NAME, name.trim());
|
||||||
|
if (!empty(desc))
|
||||||
|
opts.setProperty(BlogInfo.DESCRIPTION, desc.trim());
|
||||||
|
if (!empty(url))
|
||||||
|
opts.setProperty(BlogInfo.CONTACT_URL, url.trim());
|
||||||
|
if (!empty(other)) {
|
||||||
|
StringBuffer key = new StringBuffer();
|
||||||
|
StringBuffer val = null;
|
||||||
|
for (int i = 0; i < other.length(); i++) {
|
||||||
|
char c = other.charAt(i);
|
||||||
|
if ( (c == ':') || (c == '=') ) {
|
||||||
|
if (val != null) {
|
||||||
|
val.append(c);
|
||||||
|
} else {
|
||||||
|
val = new StringBuffer();
|
||||||
|
}
|
||||||
|
} else if ( (c == '\n') || (c == '\r') ) {
|
||||||
|
String k = key.toString().trim();
|
||||||
|
String v = (val != null ? val.toString().trim() : "");
|
||||||
|
if ( (k.length() > 0) && (v.length() > 0) ) {
|
||||||
|
opts.setProperty(k, v);
|
||||||
|
}
|
||||||
|
key.setLength(0);
|
||||||
|
val = null;
|
||||||
|
} else if (val != null) {
|
||||||
|
val.append(c);
|
||||||
|
} else {
|
||||||
|
key.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// now finish the last of it
|
||||||
|
String k = key.toString().trim();
|
||||||
|
String v = (val != null ? val.toString().trim() : "");
|
||||||
|
if ( (k.length() > 0) && (v.length() > 0) ) {
|
||||||
|
opts.setProperty(k, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean updated = BlogManager.instance().updateMetadata(user, user.getBlog(), opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void render(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws ServletException, IOException {
|
||||||
|
Archive archive = BlogManager.instance().getArchive();
|
||||||
|
int numThreads = 10;
|
||||||
|
int threadOffset = getOffset(req);
|
||||||
|
if (threadOffset == -1) {
|
||||||
|
threadOffset = index.getRootCount() - numThreads;
|
||||||
|
}
|
||||||
|
if (threadOffset < 0) {
|
||||||
|
threadOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlogURI visibleEntry = getVisible(req);
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
if ( empty(req, ThreadedHTMLRenderer.PARAM_OFFSET) && (visibleEntry != null) ) {
|
||||||
|
// we're on a permalink, so jump the tree to the given thread
|
||||||
|
threadOffset = index.getRoot(visibleEntry);
|
||||||
|
if (threadOffset < 0)
|
||||||
|
threadOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderBegin(user, req, out, index);
|
||||||
|
renderNavBar(user, req, out, index);
|
||||||
|
renderControlBar(user, req, out, index);
|
||||||
|
renderServletDetails(user, req, out, index, threadOffset, visibleEntry, archive);
|
||||||
|
renderEnd(user, req, out, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderBegin(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
||||||
|
out.write(BEGIN_HTML);
|
||||||
|
}
|
||||||
|
protected void renderNavBar(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
||||||
|
//out.write("<tr class=\"topNav\"><td class=\"topNav_user\" colspan=\"2\" nowrap=\"true\">\n");
|
||||||
|
out.write("<tr class=\"topNav\"><td colspan=\"3\" nowrap=\"true\"><span class=\"topNav_user\">\n");
|
||||||
|
out.write("<!-- nav bar begin -->\n");
|
||||||
|
if (user.getAuthenticated() && (user.getBlog() != null) ) {
|
||||||
|
out.write("Logged in as <a href=\"" + getProfileLink(req, user.getBlog()) + "\" title=\"Edit your profile\">");
|
||||||
|
out.write(user.getUsername());
|
||||||
|
out.write("</a>\n");
|
||||||
|
out.write("(<a href=\"switchuser.jsp\" title=\"Log in as another user\">switch</a>)\n");
|
||||||
|
out.write("<a href=\"post.jsp\" title=\"Post a new thread\">Post a new thread</a>\n");
|
||||||
|
} else {
|
||||||
|
out.write("<form action=\"" + req.getRequestURI() + "\" method=\"GET\">\n");
|
||||||
|
out.write("Login: <input type=\"text\" name=\"login\" />\n");
|
||||||
|
out.write("Password: <input type=\"password\" name=\"password\" />\n");
|
||||||
|
out.write("<input type=\"submit\" name=\"action\" value=\"Login\" /></form>\n");
|
||||||
|
}
|
||||||
|
//out.write("</td><td class=\"topNav_admin\">\n");
|
||||||
|
out.write("</span><span class=\"topNav_admin\">\n");
|
||||||
|
if (user.getAuthenticated() && user.getAllowAccessRemote()) {
|
||||||
|
out.write("<a href=\"syndicate.jsp\" title=\"Syndicate data between other Syndie nodes\">Syndicate</a>\n");
|
||||||
|
out.write("<a href=\"importfeed.jsp\" title=\"Import RSS/Atom data\">Import RSS/Atom</a>\n");
|
||||||
|
out.write("<a href=\"admin.jsp\" title=\"Configure this Syndie node\">Admin</a>\n");
|
||||||
|
}
|
||||||
|
out.write("</span><!-- nav bar end -->\n</td></tr>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final ArrayList SKIP_TAGS = new ArrayList();
|
||||||
|
static {
|
||||||
|
SKIP_TAGS.add("action");
|
||||||
|
SKIP_TAGS.add("filter");
|
||||||
|
// post and visible are skipped since we aren't good at filtering by tag when the offset will
|
||||||
|
// skip around randomly. at least, not yet.
|
||||||
|
SKIP_TAGS.add("visible");
|
||||||
|
//SKIP_TAGS.add("post");
|
||||||
|
//SKIP_TAGS.add("thread");
|
||||||
|
SKIP_TAGS.add("offset"); // if we are adjusting the filter, ignore the previous offset
|
||||||
|
SKIP_TAGS.add("login");
|
||||||
|
SKIP_TAGS.add("password");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String CONTROL_TARGET = "threads.jsp";
|
||||||
|
protected String getControlTarget() { return CONTROL_TARGET; }
|
||||||
|
|
||||||
|
protected void renderControlBar(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
||||||
|
out.write("<form action=\"");
|
||||||
|
//out.write(req.getRequestURI());
|
||||||
|
out.write(getControlTarget());
|
||||||
|
out.write("\" method=\"GET\">\n");
|
||||||
|
String tags = "";
|
||||||
|
String author = "";
|
||||||
|
Enumeration params = req.getParameterNames();
|
||||||
|
while (params.hasMoreElements()) {
|
||||||
|
String param = (String)params.nextElement();
|
||||||
|
String val = req.getParameter(param);
|
||||||
|
if (ThreadedHTMLRenderer.PARAM_TAGS.equals(param)) {
|
||||||
|
tags = val;
|
||||||
|
} else if (ThreadedHTMLRenderer.PARAM_AUTHOR.equals(param)) {
|
||||||
|
author = val;
|
||||||
|
} else if (SKIP_TAGS.contains(param)) {
|
||||||
|
// skip
|
||||||
|
} else if (param.length() <= 0) {
|
||||||
|
// skip
|
||||||
|
} else {
|
||||||
|
out.write("<input type=\"hidden\" name=\"" + param + "\" value=\"" + val + "\" />\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write("<tr class=\"controlBar\"><td colspan=\"2\">\n");
|
||||||
|
out.write("<!-- control bar begin -->\n");
|
||||||
|
out.write("Filter: <select name=\"" + ThreadedHTMLRenderer.PARAM_AUTHOR + "\">\n");
|
||||||
|
|
||||||
|
PetNameDB db = user.getPetNameDB();
|
||||||
|
TreeSet names = new TreeSet(db.getNames());
|
||||||
|
out.write("<option value=\"\">Any authors</option>\n");
|
||||||
|
if (user.getBlog() != null) {
|
||||||
|
if ( (author != null) && (author.equals(user.getBlog().toBase64())) )
|
||||||
|
out.write("<option value=\"" + user.getBlog().toBase64() + "\" selected=\"true\">Threads you posted in</option>\n");
|
||||||
|
else
|
||||||
|
out.write("<option value=\"" + user.getBlog().toBase64() + "\">Threads you posted in</option>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Iterator iter = names.iterator(); iter.hasNext(); ) {
|
||||||
|
String name = (String) iter.next();
|
||||||
|
PetName pn = db.getByName(name);
|
||||||
|
if ("syndieblog".equals(pn.getProtocol())) {
|
||||||
|
if ( (author != null) && (author.equals(pn.getLocation())) )
|
||||||
|
out.write("<option value=\"" + pn.getLocation() + "\" selected=\"true\">Threads " + name + " posted in</option>\n");
|
||||||
|
else
|
||||||
|
out.write("<option value=\"" + pn.getLocation() + "\">Threads " + name + " posted in</option>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write("</select>\n");
|
||||||
|
|
||||||
|
out.write("Tags: <input type=\"text\" name=\"" + ThreadedHTMLRenderer.PARAM_TAGS + "\" size=\"10\" value=\"" + tags + "\" />\n");
|
||||||
|
|
||||||
|
out.write("<input type=\"submit\" name=\"action\" value=\"Go\" />\n");
|
||||||
|
out.write("</td><td class=\"controlBarRight\"><a href=\"#threads\" title=\"Jump to the thread navigation\">Threads</a></td>\n");
|
||||||
|
out.write("<!-- control bar end -->\n");
|
||||||
|
out.write("</tr>\n");
|
||||||
|
out.write("</form>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void renderServletDetails(User user, HttpServletRequest req, PrintWriter out,
|
||||||
|
ThreadIndex index, int threadOffset, BlogURI visibleEntry,
|
||||||
|
Archive archive) throws IOException;
|
||||||
|
|
||||||
|
protected static final int getOffset(HttpServletRequest req) {
|
||||||
|
String off = req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET);
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(off);
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protected static final BlogURI getVisible(HttpServletRequest req) {
|
||||||
|
return getAsBlogURI(req.getParameter(ThreadedHTMLRenderer.PARAM_VISIBLE));
|
||||||
|
}
|
||||||
|
protected static final BlogURI getAsBlogURI(String uri) {
|
||||||
|
if (uri != null) {
|
||||||
|
int split = uri.indexOf('/');
|
||||||
|
if ( (split <= 0) || (split + 1 >= uri.length()) )
|
||||||
|
return null;
|
||||||
|
String blog = uri.substring(0, split);
|
||||||
|
String id = uri.substring(split+1);
|
||||||
|
try {
|
||||||
|
Hash hash = new Hash();
|
||||||
|
hash.fromBase64(blog);
|
||||||
|
long msgId = Long.parseLong(id);
|
||||||
|
if (msgId > 0)
|
||||||
|
return new BlogURI(hash, msgId);
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
return null;
|
||||||
|
} catch (NumberFormatException nfe) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected String trim(String orig, int maxLen) {
|
||||||
|
if ( (orig == null) || (orig.length() <= maxLen) )
|
||||||
|
return orig;
|
||||||
|
return orig.substring(0, maxLen) + "...";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final boolean empty(HttpServletRequest req, String param) {
|
||||||
|
String val = req.getParameter(param);
|
||||||
|
return (val == null) || (val.trim().length() <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final boolean empty(String val) {
|
||||||
|
return (val == null) || (val.trim().length() <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getExpandLink(HttpServletRequest req, ThreadNode node) {
|
||||||
|
return getExpandLink(node, req.getRequestURI(), req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_POST),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_THREAD),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
||||||
|
}
|
||||||
|
protected static String getExpandLink(ThreadNode node, String uri, String viewPost, String viewThread,
|
||||||
|
String offset, String tags, String author) {
|
||||||
|
StringBuffer buf = new StringBuffer(64);
|
||||||
|
buf.append(uri);
|
||||||
|
buf.append('?');
|
||||||
|
// expand node == let one of node's children be visible
|
||||||
|
if (node.getChildCount() > 0) {
|
||||||
|
ThreadNode child = node.getChild(0);
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=');
|
||||||
|
buf.append(child.getEntry().getKeyHash().toBase64()).append('/');
|
||||||
|
buf.append(child.getEntry().getEntryId()).append('&');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty(viewPost))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_POST).append('=').append(viewPost).append('&');
|
||||||
|
else if (!empty(viewThread))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_THREAD).append('=').append(viewThread).append('&');
|
||||||
|
|
||||||
|
if (!empty(offset))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_OFFSET).append('=').append(offset).append('&');
|
||||||
|
|
||||||
|
if (!empty(tags))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_TAGS).append('=').append(tags).append('&');
|
||||||
|
|
||||||
|
if (!empty(author))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(author).append('&');
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
protected String getCollapseLink(HttpServletRequest req, ThreadNode node) {
|
||||||
|
return getCollapseLink(node, req.getRequestURI(),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_POST),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_THREAD),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getCollapseLink(ThreadNode node, String uri, String viewPost, String viewThread,
|
||||||
|
String offset, String tags, String author) {
|
||||||
|
StringBuffer buf = new StringBuffer(64);
|
||||||
|
buf.append(uri);
|
||||||
|
// collapse node == let the node be visible
|
||||||
|
buf.append('?').append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=');
|
||||||
|
buf.append(node.getEntry().getKeyHash().toBase64()).append('/');
|
||||||
|
buf.append(node.getEntry().getEntryId()).append('&');
|
||||||
|
|
||||||
|
if (!empty(viewPost))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_POST).append('=').append(viewPost).append('&');
|
||||||
|
else if (!empty(viewThread))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_THREAD).append('=').append(viewThread).append('&');
|
||||||
|
|
||||||
|
if (!empty(offset))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_OFFSET).append('=').append(offset).append('&');
|
||||||
|
|
||||||
|
if (!empty(tags))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_TAGS).append('=').append(tags).append('&');
|
||||||
|
|
||||||
|
if (!empty(author))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(author).append('&');
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
protected String getProfileLink(HttpServletRequest req, Hash author) {
|
||||||
|
return getProfileLink(author);
|
||||||
|
}
|
||||||
|
protected String getProfileLink(Hash author) { return ThreadedHTMLRenderer.buildProfileURL(author); }
|
||||||
|
|
||||||
|
protected String getAddToGroupLink(HttpServletRequest req, Hash author, User user, String group) {
|
||||||
|
return getAddToGroupLink(user, author, group, req.getRequestURI(),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_VISIBLE),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_POST),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_THREAD),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
||||||
|
}
|
||||||
|
protected String getAddToGroupLink(User user, Hash author, String group, String uri, String visible,
|
||||||
|
String viewPost, String viewThread, String offset, String tags, String filteredAuthor) {
|
||||||
|
StringBuffer buf = new StringBuffer(64);
|
||||||
|
buf.append(uri);
|
||||||
|
buf.append('?');
|
||||||
|
if (!empty(visible))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=').append(visible).append('&');
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_ADD_TO_GROUP_LOCATION).append('=').append(author.toBase64()).append('&');
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_ADD_TO_GROUP_NAME).append('=').append(group).append('&');
|
||||||
|
|
||||||
|
if (!empty(viewPost))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_POST).append('=').append(viewPost).append('&');
|
||||||
|
else if (!empty(viewThread))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_THREAD).append('=').append(viewThread).append('&');
|
||||||
|
|
||||||
|
if (!empty(offset))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_OFFSET).append('=').append(offset).append('&');
|
||||||
|
|
||||||
|
if (!empty(tags))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_TAGS).append('=').append(tags).append('&');
|
||||||
|
|
||||||
|
if (!empty(filteredAuthor))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(filteredAuthor).append('&');
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
protected String getRemoveFromGroupLink(User user, String name, String group, String uri, String visible,
|
||||||
|
String viewPost, String viewThread, String offset, String tags, String filteredAuthor) {
|
||||||
|
StringBuffer buf = new StringBuffer(64);
|
||||||
|
buf.append(uri);
|
||||||
|
buf.append('?');
|
||||||
|
if (!empty(visible))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=').append(visible).append('&');
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_REMOVE_FROM_GROUP_NAME).append('=').append(name).append('&');
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_REMOVE_FROM_GROUP).append('=').append(group).append('&');
|
||||||
|
|
||||||
|
if (!empty(viewPost))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_POST).append('=').append(viewPost).append('&');
|
||||||
|
else if (!empty(viewThread))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_THREAD).append('=').append(viewThread).append('&');
|
||||||
|
|
||||||
|
if (!empty(offset))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_OFFSET).append('=').append(offset).append('&');
|
||||||
|
|
||||||
|
if (!empty(tags))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_TAGS).append('=').append(tags).append('&');
|
||||||
|
|
||||||
|
if (!empty(filteredAuthor))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(filteredAuthor).append('&');
|
||||||
|
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
protected String getViewPostLink(HttpServletRequest req, ThreadNode node, User user, boolean isPermalink) {
|
||||||
|
return ThreadedHTMLRenderer.getViewPostLink(req.getRequestURI(), node, user, isPermalink,
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
||||||
|
}
|
||||||
|
protected String getViewThreadLink(HttpServletRequest req, ThreadNode node, User user) {
|
||||||
|
return getViewThreadLink(req.getRequestURI(), node, user,
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
||||||
|
}
|
||||||
|
protected static String getViewThreadLink(String uri, ThreadNode node, User user, String offset,
|
||||||
|
String tags, String author) {
|
||||||
|
StringBuffer buf = new StringBuffer(64);
|
||||||
|
buf.append(uri);
|
||||||
|
if (node.getChildCount() > 0) {
|
||||||
|
buf.append('?').append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=');
|
||||||
|
ThreadNode child = node.getChild(0);
|
||||||
|
buf.append(child.getEntry().getKeyHash().toBase64()).append('/');
|
||||||
|
buf.append(child.getEntry().getEntryId()).append('&');
|
||||||
|
} else {
|
||||||
|
buf.append('?').append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=');
|
||||||
|
buf.append(node.getEntry().getKeyHash().toBase64()).append('/');
|
||||||
|
buf.append(node.getEntry().getEntryId()).append('&');
|
||||||
|
}
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_THREAD).append('=');
|
||||||
|
buf.append(node.getEntry().getKeyHash().toBase64()).append('/');
|
||||||
|
buf.append(node.getEntry().getEntryId()).append('&');
|
||||||
|
|
||||||
|
if (!empty(offset))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_OFFSET).append('=').append(offset).append('&');
|
||||||
|
|
||||||
|
if (!empty(tags))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_TAGS).append('=').append(tags).append('&');
|
||||||
|
|
||||||
|
if (!empty(author))
|
||||||
|
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(author).append('&');
|
||||||
|
|
||||||
|
buf.append("#").append(node.getEntry().toString());
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
protected String getFilterByTagLink(HttpServletRequest req, ThreadNode node, User user, String tag, String author) {
|
||||||
|
return ThreadedHTMLRenderer.getFilterByTagLink(req.getRequestURI(), node, user, tag, author);
|
||||||
|
}
|
||||||
|
protected String getNavLink(HttpServletRequest req, int offset) {
|
||||||
|
return ThreadedHTMLRenderer.getNavLink(req.getRequestURI(),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_POST),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_THREAD),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
||||||
|
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR),
|
||||||
|
offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderEnd(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
||||||
|
out.write(END_HTML);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Collection getFilteredTags(HttpServletRequest req) {
|
||||||
|
String tags = req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS);
|
||||||
|
if (tags != null) {
|
||||||
|
StringTokenizer tok = new StringTokenizer(tags, "\n\t ");
|
||||||
|
ArrayList rv = new ArrayList();
|
||||||
|
while (tok.hasMoreTokens()) {
|
||||||
|
String tag = tok.nextToken().trim();
|
||||||
|
if (tag.length() > 0)
|
||||||
|
rv.add(tag);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
} else {
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Collection getFilteredAuthors(HttpServletRequest req) {
|
||||||
|
String authors = req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR);
|
||||||
|
if (authors != null) {
|
||||||
|
StringTokenizer tok = new StringTokenizer(authors, "\n\t ");
|
||||||
|
ArrayList rv = new ArrayList();
|
||||||
|
while (tok.hasMoreTokens()) {
|
||||||
|
try {
|
||||||
|
Hash h = new Hash();
|
||||||
|
h.fromBase64(tok.nextToken().trim());
|
||||||
|
rv.add(h);
|
||||||
|
} catch (DataFormatException dfe) {}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
} else {
|
||||||
|
return Collections.EMPTY_LIST;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String BEGIN_HTML = "<html>\n" +
|
||||||
|
"<head>\n" +
|
||||||
|
"<title>Syndie</title>\n" +
|
||||||
|
"<style>\n" +
|
||||||
|
".overallTable {\n" +
|
||||||
|
" border-spacing: 0px;\n" +
|
||||||
|
" border-width: 0px;\n" +
|
||||||
|
" border: 0px;\n" +
|
||||||
|
" margin: 0px;\n" +
|
||||||
|
" padding: 0px;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".topNav {\n" +
|
||||||
|
" background-color: #BBBBBB;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".topNav_user {\n" +
|
||||||
|
" text-align: left;\n" +
|
||||||
|
" float: left;\n" +
|
||||||
|
" align: left;\n" +
|
||||||
|
" display: inline;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".topNav_admin {\n" +
|
||||||
|
" text-align: right;\n" +
|
||||||
|
" float: right;\n" +
|
||||||
|
" align: right;\n" +
|
||||||
|
" display: inline;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".controlBar {\n" +
|
||||||
|
" background-color: #BBBBBB;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".controlBarRight {\n" +
|
||||||
|
" text-align: right;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".threadEven {\n" +
|
||||||
|
" background-color: #FFFFFF;\n" +
|
||||||
|
" white-space: nowrap;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".threadOdd {\n" +
|
||||||
|
" background-color: #EEEEEE;\n" +
|
||||||
|
" white-space: nowrap;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".threadLeft {\n" +
|
||||||
|
" text-align: left;\n" +
|
||||||
|
" align: left;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".threadRight {\n" +
|
||||||
|
" text-align: right;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".threadNav {\n" +
|
||||||
|
" background-color: #BBBBBB;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".threadNavRight {\n" +
|
||||||
|
" text-align: right;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".postMeta {\n" +
|
||||||
|
" background-color: #BBBBFF;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".postMetaSubject {\n" +
|
||||||
|
" text-align: left;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".postMetaLink {\n" +
|
||||||
|
" text-align: right;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".postDetails {\n" +
|
||||||
|
" background-color: #DDDDFF;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".postReply {\n" +
|
||||||
|
" background-color: #BBBBFF;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".postReplyText {\n" +
|
||||||
|
" background-color: #BBBBFF;\n" +
|
||||||
|
"}\n" +
|
||||||
|
".postReplyOptions {\n" +
|
||||||
|
" background-color: #BBBBFF;\n" +
|
||||||
|
"}\n" +
|
||||||
|
"</style>\n" +
|
||||||
|
"<link href=\"style.jsp\" rel=\"stylesheet\" type=\"text/css\" >\n" +
|
||||||
|
"<link href=\"rss.jsp\" rel=\"alternate\" type=\"application/rss+xml\" >\n" +
|
||||||
|
"</head>\n" +
|
||||||
|
"<body>\n" +
|
||||||
|
"<span style=\"display: none\"><a href=\"#bodySubject\">Jump to the beginning of the first post rendered, if any</a>\n" +
|
||||||
|
"<a href=\"#threads\">Jump to the thread navigation</a>\n</span>\n" +
|
||||||
|
"<table border=\"0\" width=\"100%\" class=\"overallTable\">\n";
|
||||||
|
|
||||||
|
private static final String END_HTML = "</table>\n" +
|
||||||
|
"</body>\n";
|
||||||
|
|
||||||
|
protected static class TreeRenderState {
|
||||||
|
private int _rowsWritten;
|
||||||
|
private int _rowsSkipped;
|
||||||
|
private List _ignored;
|
||||||
|
public TreeRenderState(List ignored) {
|
||||||
|
_rowsWritten = 0;
|
||||||
|
_rowsSkipped = 0;
|
||||||
|
_ignored = ignored;
|
||||||
|
}
|
||||||
|
public int getRowsWritten() { return _rowsWritten; }
|
||||||
|
public void incrementRowsWritten() { _rowsWritten++; }
|
||||||
|
public int getRowsSkipped() { return _rowsSkipped; }
|
||||||
|
public void incrementRowsSkipped() { _rowsSkipped++; }
|
||||||
|
public List getIgnoredAuthors() { return _ignored; }
|
||||||
|
}
|
||||||
|
}
|
209
apps/syndie/java/src/net/i2p/syndie/web/ProfileServlet.java
Normal file
209
apps/syndie/java/src/net/i2p/syndie/web/ProfileServlet.java
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
package net.i2p.syndie.web;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.client.naming.*;
|
||||||
|
import net.i2p.data.*;
|
||||||
|
import net.i2p.syndie.*;
|
||||||
|
import net.i2p.syndie.data.*;
|
||||||
|
import net.i2p.syndie.sml.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the requested profile
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ProfileServlet extends BaseServlet {
|
||||||
|
protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index,
|
||||||
|
int threadOffset, BlogURI visibleEntry, Archive archive) throws IOException {
|
||||||
|
Hash author = null;
|
||||||
|
String str = req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR);
|
||||||
|
if (str != null) {
|
||||||
|
try {
|
||||||
|
author = new Hash();
|
||||||
|
author.fromBase64(str);
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
author = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
author = user.getBlog();
|
||||||
|
}
|
||||||
|
|
||||||
|
String uri = req.getRequestURI();
|
||||||
|
|
||||||
|
if (author == null) {
|
||||||
|
renderInvalidProfile(out);
|
||||||
|
} else if ( (user.getBlog() != null) && (user.getBlog().equals(author)) ) {
|
||||||
|
renderMyProfile(user, uri, out, archive);
|
||||||
|
} else {
|
||||||
|
renderProfile(user, uri, out, author, archive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderInvalidProfile(PrintWriter out) throws IOException {
|
||||||
|
out.write(INVALID_PROFILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderMyProfile(User user, String baseURI, PrintWriter out, Archive archive) throws IOException {
|
||||||
|
BlogInfo info = archive.getBlogInfo(user.getBlog());
|
||||||
|
if (info == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
out.write("<!-- " + info.toString() + "-->\n");
|
||||||
|
out.write("<form action=\"" + baseURI + "\" method=\"POST\">\n");
|
||||||
|
// now add the form to update
|
||||||
|
out.write("<tr><td colspan=\"3\">Your profile</td></tr>\n");
|
||||||
|
out.write("<tr><td colspan=\"3\">Name: <input type=\"text\" name=\""
|
||||||
|
+ ThreadedHTMLRenderer.PARAM_PROFILE_NAME + "\" value=\""
|
||||||
|
+ HTMLRenderer.sanitizeTagParam(info.getProperty(BlogInfo.NAME)) + "\"></td></tr>\n");
|
||||||
|
out.write("<tr><td colspan=\"3\">Account description: <input type=\"text\" name=\""
|
||||||
|
+ ThreadedHTMLRenderer.PARAM_PROFILE_DESC + "\" value=\""
|
||||||
|
+ HTMLRenderer.sanitizeTagParam(info.getProperty(BlogInfo.DESCRIPTION)) + "\"></td></tr>\n");
|
||||||
|
out.write("<tr><td colspan=\"3\">Contact information: <input type=\"text\" name=\""
|
||||||
|
+ ThreadedHTMLRenderer.PARAM_PROFILE_URL + "\" value=\""
|
||||||
|
+ HTMLRenderer.sanitizeTagParam(info.getProperty(BlogInfo.CONTACT_URL)) + "\"></td></tr>\n");
|
||||||
|
out.write("<tr><td colspan=\"3\">Other attributes:<br /><textarea rows=\"3\" name=\""
|
||||||
|
+ ThreadedHTMLRenderer.PARAM_PROFILE_OTHER + "\" cols=\"60\">");
|
||||||
|
String props[] = info.getProperties();
|
||||||
|
if (props != null) {
|
||||||
|
for (int i = 0; i < props.length; i++) {
|
||||||
|
if (!BlogInfo.NAME.equals(props[i]) &&
|
||||||
|
!BlogInfo.DESCRIPTION.equals(props[i]) &&
|
||||||
|
!BlogInfo.EDITION.equals(props[i]) &&
|
||||||
|
!BlogInfo.OWNER_KEY.equals(props[i]) &&
|
||||||
|
!BlogInfo.POSTERS.equals(props[i]) &&
|
||||||
|
!BlogInfo.SIGNATURE.equals(props[i]) &&
|
||||||
|
!BlogInfo.CONTACT_URL.equals(props[i])) {
|
||||||
|
out.write(HTMLRenderer.sanitizeString(props[i], false) + ": "
|
||||||
|
+ HTMLRenderer.sanitizeString(info.getProperty(props[i]), false) + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write("</textarea></td></tr>\n");
|
||||||
|
|
||||||
|
out.write("<tr><td colspan=\"3\"><input type=\"submit\" name=\"action\" value=\"Update profile\" /></td></tr>\n");
|
||||||
|
out.write("</form>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderProfile(User user, String baseURI, PrintWriter out, Hash author, Archive archive) throws IOException {
|
||||||
|
out.write("<tr><td colspan=\"3\">Profile for <a href=\"" + getControlTarget() + "?"
|
||||||
|
+ ThreadedHTMLRenderer.PARAM_AUTHOR + '=' + author.toBase64()
|
||||||
|
+ "\" title=\"View threads by the profiled author\">");
|
||||||
|
PetName pn = user.getPetNameDB().getByLocation(author.toBase64());
|
||||||
|
BlogInfo info = archive.getBlogInfo(author);
|
||||||
|
if (pn != null) {
|
||||||
|
out.write(pn.getName());
|
||||||
|
String name = null;
|
||||||
|
if (info != null)
|
||||||
|
name = info.getProperty(BlogInfo.NAME);
|
||||||
|
|
||||||
|
if ( (name == null) || (name.trim().length() <= 0) )
|
||||||
|
name = author.toBase64().substring(0, 6);
|
||||||
|
|
||||||
|
out.write(" (" + name + ")");
|
||||||
|
} else {
|
||||||
|
String name = null;
|
||||||
|
if (info != null)
|
||||||
|
name = info.getProperty(BlogInfo.NAME);
|
||||||
|
|
||||||
|
if ( (name == null) || (name.trim().length() <= 0) )
|
||||||
|
name = author.toBase64().substring(0, 6);
|
||||||
|
out.write(name);
|
||||||
|
}
|
||||||
|
out.write("</a>");
|
||||||
|
if (info != null)
|
||||||
|
out.write(" [edition " + info.getEdition() + "]");
|
||||||
|
out.write("</td></tr>\n");
|
||||||
|
|
||||||
|
out.write("<tr><td colspan=\"3\"><hr /></td></tr>\n");
|
||||||
|
if (pn == null) {
|
||||||
|
out.write("<tr><td colspan=\"3\">Not currently bookmarked. Add them to your ");
|
||||||
|
String addFav = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_FAVORITE,
|
||||||
|
baseURI, "", "", "", "", "", author.toBase64());
|
||||||
|
String addIgnore = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_IGNORE,
|
||||||
|
baseURI, "", "", "", "", "", author.toBase64());
|
||||||
|
out.write("<a href=\"" + addFav + "\" title=\"Threads by favorite authors are shown specially\">favorites</a> or ");
|
||||||
|
out.write("<a href=\"" + addIgnore + "\" title=\"Threads by ignored authors are hidden from view\">ignored</a> ");
|
||||||
|
out.write("</td></tr>\n");
|
||||||
|
} else if (pn.isMember(FilteredThreadIndex.GROUP_IGNORE)) {
|
||||||
|
out.write("<tr><td colspan=\"3\">Currently ignored - threads they create are hidden.</td></tr>\n");
|
||||||
|
String remIgnore = getRemoveFromGroupLink(user, pn.getName(), FilteredThreadIndex.GROUP_IGNORE,
|
||||||
|
baseURI, "", "", "", "", "", author.toBase64());
|
||||||
|
out.write("<tr><td></td><td colspan=\"2\"><a href=\"" + remIgnore + "\">Unignore " + pn.getName() + "</a></td></tr>\n");
|
||||||
|
String remCompletely = getRemoveFromGroupLink(user, pn.getName(), "",
|
||||||
|
baseURI, "", "", "", "", "", author.toBase64());
|
||||||
|
out.write("<tr><td></td><td colspan=\"2\"><a href=\"" + remCompletely + "\">Forget about " + pn.getName() + " entirely</a></td></tr>\n");
|
||||||
|
} else if (pn.isMember(FilteredThreadIndex.GROUP_FAVORITE)) {
|
||||||
|
out.write("<tr><td colspan=\"3\">Currently marked as a favorite author - threads they participate in " +
|
||||||
|
"are highlighted.</td></tr>\n");
|
||||||
|
String remIgnore = getRemoveFromGroupLink(user, pn.getName(), FilteredThreadIndex.GROUP_FAVORITE,
|
||||||
|
baseURI, "", "", "", "", "", author.toBase64());
|
||||||
|
out.write("<tr><td></td><td colspan=\"2\"><a href=\"" + remIgnore + "\">Remove " + pn.getName() + " from the list of favorite authors</a></td></tr>\n");
|
||||||
|
String addIgnore = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_IGNORE,
|
||||||
|
baseURI, "", "", "", "", "", author.toBase64());
|
||||||
|
out.write("<tr><td></td><td colspan=\"2\"><a href=\"" + addIgnore + "\" title=\"Threads by ignored authors are hidden from view\">Ignore the author</a></td></tr>");
|
||||||
|
String remCompletely = getRemoveFromGroupLink(user, pn.getName(), "",
|
||||||
|
baseURI, "", "", "", "", "", author.toBase64());
|
||||||
|
out.write("<tr><td></td><td colspan=\"2\"><a href=\"" + remCompletely + "\">Forget about " + pn.getName() + " entirely</a></td></tr>\n");
|
||||||
|
} else {
|
||||||
|
out.write("<tr><td colspan=\"3\">Currently bookmarked. Add them to your ");
|
||||||
|
String addFav = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_FAVORITE,
|
||||||
|
baseURI, "", "", "", "", "", author.toBase64());
|
||||||
|
String addIgnore = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_IGNORE,
|
||||||
|
baseURI, "", "", "", "", "", author.toBase64());
|
||||||
|
out.write("<a href=\"" + addFav + "\" title=\"Threads by favorite authors are shown specially\">favorites</a> or ");
|
||||||
|
out.write("<a href=\"" + addIgnore + "\" title=\"Threads by ignored authors are hidden from view\">ignored</a> list</td></tr>");
|
||||||
|
String remCompletely = getRemoveFromGroupLink(user, pn.getName(), "",
|
||||||
|
baseURI, "", "", "", "", "", author.toBase64());
|
||||||
|
out.write("<tr><td></td><td colspan=\"2\"><a href=\"" + remCompletely + "\">Forget about " + pn.getName() + " entirely</a></td></tr>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info != null) {
|
||||||
|
String descr = info.getProperty(BlogInfo.DESCRIPTION);
|
||||||
|
if ( (descr != null) && (descr.trim().length() > 0) )
|
||||||
|
out.write("<tr><td colspan=\"3\">Account description: " + HTMLRenderer.sanitizeString(descr) + "</td></tr>\n");
|
||||||
|
|
||||||
|
String contactURL = info.getProperty(BlogInfo.CONTACT_URL);
|
||||||
|
if ( (contactURL != null) && (contactURL.trim().length() > 0) )
|
||||||
|
out.write("<tr><td colspan=\"3\">Contact information: "
|
||||||
|
+ HTMLRenderer.sanitizeString(contactURL) + "</td></tr>\n");
|
||||||
|
|
||||||
|
String props[] = info.getProperties();
|
||||||
|
int altCount = 0;
|
||||||
|
if (props != null)
|
||||||
|
for (int i = 0; i < props.length; i++)
|
||||||
|
if (!BlogInfo.NAME.equals(props[i]) &&
|
||||||
|
!BlogInfo.DESCRIPTION.equals(props[i]) &&
|
||||||
|
!BlogInfo.EDITION.equals(props[i]) &&
|
||||||
|
!BlogInfo.OWNER_KEY.equals(props[i]) &&
|
||||||
|
!BlogInfo.POSTERS.equals(props[i]) &&
|
||||||
|
!BlogInfo.SIGNATURE.equals(props[i]) &&
|
||||||
|
!BlogInfo.CONTACT_URL.equals(props[i]))
|
||||||
|
altCount++;
|
||||||
|
if (altCount > 0) {
|
||||||
|
for (int i = 0; i < props.length; i++) {
|
||||||
|
if (!BlogInfo.NAME.equals(props[i]) &&
|
||||||
|
!BlogInfo.DESCRIPTION.equals(props[i]) &&
|
||||||
|
!BlogInfo.EDITION.equals(props[i]) &&
|
||||||
|
!BlogInfo.OWNER_KEY.equals(props[i]) &&
|
||||||
|
!BlogInfo.POSTERS.equals(props[i]) &&
|
||||||
|
!BlogInfo.SIGNATURE.equals(props[i]) &&
|
||||||
|
!BlogInfo.CONTACT_URL.equals(props[i])) {
|
||||||
|
out.write("<tr><td colspan=\"3\">");
|
||||||
|
out.write(HTMLRenderer.sanitizeString(props[i]) + ": "
|
||||||
|
+ HTMLRenderer.sanitizeString(info.getProperty(props[i])));
|
||||||
|
out.write("</td></tr>\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String INVALID_PROFILE = "<tr><td colspan=\"3\">The profile requested is invalid</td></tr>\n";
|
||||||
|
}
|
@ -6,7 +6,6 @@ import java.util.*;
|
|||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.ServletException;
|
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.client.naming.*;
|
import net.i2p.client.naming.*;
|
||||||
@ -16,225 +15,20 @@ import net.i2p.syndie.data.*;
|
|||||||
import net.i2p.syndie.sml.*;
|
import net.i2p.syndie.sml.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Render the appropriate posts and the thread tree
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ViewThreadedServlet extends HttpServlet {
|
public class ViewThreadedServlet extends BaseServlet {
|
||||||
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index,
|
||||||
req.setCharacterEncoding("UTF-8");
|
int threadOffset, BlogURI visibleEntry, Archive archive) throws IOException {
|
||||||
resp.setCharacterEncoding("UTF-8");
|
|
||||||
resp.setContentType("text/html");
|
|
||||||
|
|
||||||
User user = (User)req.getSession().getAttribute("user");
|
|
||||||
String login = req.getParameter("login");
|
|
||||||
String pass = req.getParameter("password");
|
|
||||||
String action = req.getParameter("action");
|
|
||||||
boolean forceNewIndex = false;
|
|
||||||
|
|
||||||
if (req.getParameter("regenerateIndex") != null)
|
|
||||||
forceNewIndex = true;
|
|
||||||
|
|
||||||
if (user == null) {
|
|
||||||
if ("Login".equals(action)) {
|
|
||||||
user = BlogManager.instance().login(login, pass); // ignore failures - user will just be unauthorized
|
|
||||||
if (!user.getAuthenticated())
|
|
||||||
user.invalidate();
|
|
||||||
} else {
|
|
||||||
user = new User();
|
|
||||||
}
|
|
||||||
forceNewIndex = true;
|
|
||||||
} else if ("Login".equals(action)) {
|
|
||||||
user = BlogManager.instance().login(login, pass); // ignore failures - user will just be unauthorized
|
|
||||||
forceNewIndex = true;
|
|
||||||
} else if ("Logout".equals(action)) {
|
|
||||||
user = new User();
|
|
||||||
forceNewIndex = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
req.getSession().setAttribute("user", user);
|
|
||||||
|
|
||||||
if (user.getAuthenticated()) {
|
|
||||||
String loc = req.getParameter(ThreadedHTMLRenderer.PARAM_ADD_TO_GROUP_LOCATION);
|
|
||||||
String group = req.getParameter(ThreadedHTMLRenderer.PARAM_ADD_TO_GROUP_NAME);
|
|
||||||
if ( (loc != null) && (group != null) && (group.trim().length() > 0) ) {
|
|
||||||
try {
|
|
||||||
Hash key = new Hash();
|
|
||||||
key.fromBase64(loc);
|
|
||||||
PetNameDB db = user.getPetNameDB();
|
|
||||||
PetName pn = db.getByLocation(loc);
|
|
||||||
boolean isNew = false;
|
|
||||||
if (pn == null) {
|
|
||||||
isNew = true;
|
|
||||||
BlogInfo info = BlogManager.instance().getArchive().getBlogInfo(key);
|
|
||||||
String name = null;
|
|
||||||
if (info != null)
|
|
||||||
name = info.getProperty(BlogInfo.NAME);
|
|
||||||
else
|
|
||||||
name = loc.substring(0,6);
|
|
||||||
|
|
||||||
if (db.containsName(name)) {
|
|
||||||
int i = 0;
|
|
||||||
while (db.containsName(name + i))
|
|
||||||
i++;
|
|
||||||
name = name + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
pn = new PetName(name, "syndie", "syndieblog", loc);
|
|
||||||
}
|
|
||||||
pn.addGroup(group);
|
|
||||||
if (isNew)
|
|
||||||
db.add(pn);
|
|
||||||
BlogManager.instance().saveUser(user);
|
|
||||||
// if we are ignoring someone, we need to recalculate the filters
|
|
||||||
if (FilteredThreadIndex.GROUP_IGNORE.equals(group))
|
|
||||||
forceNewIndex = true;
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
// bad loc, ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FilteredThreadIndex index = (FilteredThreadIndex)req.getSession().getAttribute("threadIndex");
|
|
||||||
|
|
||||||
Collection tags = getFilteredTags(req);
|
|
||||||
Collection filteredAuthors = getFilteredAuthors(req);
|
|
||||||
if (forceNewIndex || (index == null) || (!index.getFilteredTags().equals(tags)) || (!index.getFilteredAuthors().equals(filteredAuthors))) {
|
|
||||||
index = new FilteredThreadIndex(user, BlogManager.instance().getArchive(), getFilteredTags(req), filteredAuthors);
|
|
||||||
req.getSession().setAttribute("threadIndex", index);
|
|
||||||
}
|
|
||||||
|
|
||||||
render(user, req, resp.getWriter(), index);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void render(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws ServletException, IOException {
|
|
||||||
Archive archive = BlogManager.instance().getArchive();
|
|
||||||
int numThreads = 10;
|
|
||||||
int threadOffset = getOffset(req);
|
|
||||||
if (threadOffset == -1) {
|
|
||||||
threadOffset = index.getRootCount() - numThreads;
|
|
||||||
}
|
|
||||||
if (threadOffset < 0) {
|
|
||||||
threadOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlogURI visibleEntry = getVisible(req);
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
if ( empty(req, ThreadedHTMLRenderer.PARAM_OFFSET) && (visibleEntry != null) ) {
|
|
||||||
// we're on a permalink, so jump the tree to the given thread
|
|
||||||
threadOffset = index.getRoot(visibleEntry);
|
|
||||||
if (threadOffset < 0)
|
|
||||||
threadOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderBegin(user, req, out, index);
|
|
||||||
renderNavBar(user, req, out, index);
|
|
||||||
renderControlBar(user, req, out, index);
|
|
||||||
renderBody(user, req, out, index);
|
renderBody(user, req, out, index);
|
||||||
|
|
||||||
renderThreadNav(user, req, out, threadOffset, index);
|
renderThreadNav(user, req, out, threadOffset, index);
|
||||||
renderThreadTree(user, req, out, threadOffset, visibleEntry, archive, index);
|
renderThreadTree(user, req, out, threadOffset, visibleEntry, archive, index);
|
||||||
renderThreadNav(user, req, out, threadOffset, index);
|
renderThreadNav(user, req, out, threadOffset, index);
|
||||||
renderEnd(user, req, out, index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderBegin(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
private void renderBody(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
||||||
out.write(BEGIN_HTML);
|
|
||||||
}
|
|
||||||
private void renderNavBar(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
|
||||||
//out.write("<tr class=\"topNav\"><td class=\"topNav_user\" colspan=\"2\" nowrap=\"true\">\n");
|
|
||||||
out.write("<tr class=\"topNav\"><td colspan=\"3\" nowrap=\"true\"><span class=\"topNav_user\">\n");
|
|
||||||
out.write("<!-- nav bar begin -->\n");
|
|
||||||
if (user.getAuthenticated()) {
|
|
||||||
out.write("Logged in as <a href=\"" + getProfileLink(req, user.getBlog()) + "\" title=\"Edit your profile\">");
|
|
||||||
out.write(user.getUsername());
|
|
||||||
out.write("</a>\n");
|
|
||||||
out.write("(<a href=\"switchuser.jsp\" title=\"Log in as another user\">switch</a>)\n");
|
|
||||||
out.write("<a href=\"post.jsp\" title=\"Post a new thread\">Post a new thread</a>\n");
|
|
||||||
} else {
|
|
||||||
out.write("<form action=\"" + req.getRequestURI() + "\" method=\"GET\">\n");
|
|
||||||
out.write("Login: <input type=\"text\" name=\"login\" />\n");
|
|
||||||
out.write("Password: <input type=\"password\" name=\"password\" />\n");
|
|
||||||
out.write("<input type=\"submit\" name=\"action\" value=\"Login\" /></form>\n");
|
|
||||||
}
|
|
||||||
//out.write("</td><td class=\"topNav_admin\">\n");
|
|
||||||
out.write("</span><span class=\"topNav_admin\">\n");
|
|
||||||
if (user.getAuthenticated() && user.getAllowAccessRemote()) {
|
|
||||||
out.write("<a href=\"syndicate.jsp\" title=\"Syndicate data between other Syndie nodes\">Syndicate</a>\n");
|
|
||||||
out.write("<a href=\"importfeed.jsp\" title=\"Import RSS/Atom data\">Import RSS/Atom</a>\n");
|
|
||||||
out.write("<a href=\"admin.jsp\" title=\"Configure this Syndie node\">Admin</a>\n");
|
|
||||||
}
|
|
||||||
out.write("</span><!-- nav bar end -->\n</td></tr>\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final ArrayList SKIP_TAGS = new ArrayList();
|
|
||||||
static {
|
|
||||||
SKIP_TAGS.add("action");
|
|
||||||
SKIP_TAGS.add("filter");
|
|
||||||
// post and visible are skipped since we aren't good at filtering by tag when the offset will
|
|
||||||
// skip around randomly. at least, not yet.
|
|
||||||
SKIP_TAGS.add("visible");
|
|
||||||
//SKIP_TAGS.add("post");
|
|
||||||
//SKIP_TAGS.add("thread");
|
|
||||||
SKIP_TAGS.add("offset"); // if we are adjusting the filter, ignore the previous offset
|
|
||||||
SKIP_TAGS.add("login");
|
|
||||||
SKIP_TAGS.add("password");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderControlBar(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
|
||||||
out.write("<form action=\"");
|
|
||||||
out.write(req.getRequestURI());
|
|
||||||
out.write("\" method=\"GET\">\n");
|
|
||||||
String tags = "";
|
|
||||||
String author = "";
|
|
||||||
Enumeration params = req.getParameterNames();
|
|
||||||
while (params.hasMoreElements()) {
|
|
||||||
String param = (String)params.nextElement();
|
|
||||||
String val = req.getParameter(param);
|
|
||||||
if (ThreadedHTMLRenderer.PARAM_TAGS.equals(param)) {
|
|
||||||
tags = val;
|
|
||||||
} else if (ThreadedHTMLRenderer.PARAM_AUTHOR.equals(param)) {
|
|
||||||
author = val;
|
|
||||||
} else if (SKIP_TAGS.contains(param)) {
|
|
||||||
// skip
|
|
||||||
} else if (param.length() <= 0) {
|
|
||||||
// skip
|
|
||||||
} else {
|
|
||||||
out.write("<input type=\"hidden\" name=\"" + param + "\" value=\"" + val + "\" />\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out.write("<tr class=\"controlBar\"><td colspan=\"2\">\n");
|
|
||||||
out.write("<!-- control bar begin -->\n");
|
|
||||||
out.write("Filter: <select name=\"" + ThreadedHTMLRenderer.PARAM_AUTHOR + "\">\n");
|
|
||||||
|
|
||||||
PetNameDB db = user.getPetNameDB();
|
|
||||||
TreeSet names = new TreeSet(db.getNames());
|
|
||||||
out.write("<option value=\"\">Any authors</option>\n");
|
|
||||||
if (author.equals(user.getBlog().toBase64()))
|
|
||||||
out.write("<option value=\"" + user.getBlog().toBase64() + "\" selected=\"true\">Threads you posted in</option>\n");
|
|
||||||
else
|
|
||||||
out.write("<option value=\"" + user.getBlog().toBase64() + "\">Threads you posted in</option>\n");
|
|
||||||
|
|
||||||
for (Iterator iter = names.iterator(); iter.hasNext(); ) {
|
|
||||||
String name = (String) iter.next();
|
|
||||||
PetName pn = db.getByName(name);
|
|
||||||
if ("syndieblog".equals(pn.getProtocol())) {
|
|
||||||
if (author.equals(pn.getLocation()))
|
|
||||||
out.write("<option value=\"" + pn.getLocation() + "\" selected=\"true\">Threads " + name + " posted in</option>\n");
|
|
||||||
else
|
|
||||||
out.write("<option value=\"" + pn.getLocation() + "\">Threads " + name + " posted in</option>\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out.write("</select>\n");
|
|
||||||
|
|
||||||
out.write("Tags: <input type=\"text\" name=\"" + ThreadedHTMLRenderer.PARAM_TAGS + "\" size=\"10\" value=\"" + tags + "\" />\n");
|
|
||||||
|
|
||||||
out.write("<input type=\"submit\" name=\"action\" value=\"Go\" />\n");
|
|
||||||
out.write("</td><td class=\"controlBarRight\"><a href=\"#threads\" title=\"Jump to the thread navigation\">Threads</a></td>\n");
|
|
||||||
out.write("<!-- control bar end -->\n");
|
|
||||||
out.write("</tr>\n");
|
|
||||||
out.write("</form>\n");
|
|
||||||
}
|
|
||||||
private void renderBody(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException, ServletException {
|
|
||||||
ThreadedHTMLRenderer renderer = new ThreadedHTMLRenderer(I2PAppContext.getGlobalContext());
|
ThreadedHTMLRenderer renderer = new ThreadedHTMLRenderer(I2PAppContext.getGlobalContext());
|
||||||
Archive archive = BlogManager.instance().getArchive();
|
Archive archive = BlogManager.instance().getArchive();
|
||||||
List posts = getPosts(archive, req, index);
|
List posts = getPosts(archive, req, index);
|
||||||
@ -324,73 +118,6 @@ public class ViewThreadedServlet extends HttpServlet {
|
|||||||
renderThreadTree(user, out, index, archive, req, threadOffset, numThreads, visibleEntry);
|
renderThreadTree(user, out, index, archive, req, threadOffset, numThreads, visibleEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int getOffset(HttpServletRequest req) {
|
|
||||||
String off = req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET);
|
|
||||||
try {
|
|
||||||
return Integer.parseInt(off);
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static final BlogURI getVisible(HttpServletRequest req) {
|
|
||||||
return getAsBlogURI(req.getParameter(ThreadedHTMLRenderer.PARAM_VISIBLE));
|
|
||||||
}
|
|
||||||
private static final BlogURI getAsBlogURI(String uri) {
|
|
||||||
if (uri != null) {
|
|
||||||
int split = uri.indexOf('/');
|
|
||||||
if ( (split <= 0) || (split + 1 >= uri.length()) )
|
|
||||||
return null;
|
|
||||||
String blog = uri.substring(0, split);
|
|
||||||
String id = uri.substring(split+1);
|
|
||||||
try {
|
|
||||||
Hash hash = new Hash();
|
|
||||||
hash.fromBase64(blog);
|
|
||||||
long msgId = Long.parseLong(id);
|
|
||||||
if (msgId > 0)
|
|
||||||
return new BlogURI(hash, msgId);
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
return null;
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Collection getFilteredTags(HttpServletRequest req) {
|
|
||||||
String tags = req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS);
|
|
||||||
if (tags != null) {
|
|
||||||
StringTokenizer tok = new StringTokenizer(tags, "\n\t ");
|
|
||||||
ArrayList rv = new ArrayList();
|
|
||||||
while (tok.hasMoreTokens()) {
|
|
||||||
String tag = tok.nextToken().trim();
|
|
||||||
if (tag.length() > 0)
|
|
||||||
rv.add(tag);
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
} else {
|
|
||||||
return Collections.EMPTY_LIST;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Collection getFilteredAuthors(HttpServletRequest req) {
|
|
||||||
String authors = req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR);
|
|
||||||
if (authors != null) {
|
|
||||||
StringTokenizer tok = new StringTokenizer(authors, "\n\t ");
|
|
||||||
ArrayList rv = new ArrayList();
|
|
||||||
while (tok.hasMoreTokens()) {
|
|
||||||
try {
|
|
||||||
Hash h = new Hash();
|
|
||||||
h.fromBase64(tok.nextToken().trim());
|
|
||||||
rv.add(h);
|
|
||||||
} catch (DataFormatException dfe) {}
|
|
||||||
}
|
|
||||||
return rv;
|
|
||||||
} else {
|
|
||||||
return Collections.EMPTY_LIST;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderThreadTree(User user, PrintWriter out, ThreadIndex index, Archive archive, HttpServletRequest req,
|
private void renderThreadTree(User user, PrintWriter out, ThreadIndex index, Archive archive, HttpServletRequest req,
|
||||||
int threadOffset, int numThreads, BlogURI visibleEntry) {
|
int threadOffset, int numThreads, BlogURI visibleEntry) {
|
||||||
|
|
||||||
@ -421,12 +148,10 @@ public class ViewThreadedServlet extends HttpServlet {
|
|||||||
out.write("<!-- threads end -->\n");
|
out.write("<!-- threads end -->\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if some post in the thread has been written
|
|
||||||
*/
|
|
||||||
private boolean renderThread(User user, PrintWriter out, ThreadIndex index, Archive archive, HttpServletRequest req,
|
private boolean renderThread(User user, PrintWriter out, ThreadIndex index, Archive archive, HttpServletRequest req,
|
||||||
ThreadNode node, int depth, BlogURI visibleEntry, TreeRenderState state) {
|
ThreadNode node, int depth, BlogURI visibleEntry, TreeRenderState state) {
|
||||||
boolean isFavorite = false;
|
boolean isFavorite = false;
|
||||||
|
boolean ignored = false;
|
||||||
|
|
||||||
HTMLRenderer rend = new HTMLRenderer(I2PAppContext.getGlobalContext());
|
HTMLRenderer rend = new HTMLRenderer(I2PAppContext.getGlobalContext());
|
||||||
SMLParser parser = new SMLParser(I2PAppContext.getGlobalContext());
|
SMLParser parser = new SMLParser(I2PAppContext.getGlobalContext());
|
||||||
@ -436,6 +161,8 @@ public class ViewThreadedServlet extends HttpServlet {
|
|||||||
if (pn.isMember(FilteredThreadIndex.GROUP_FAVORITE)) {
|
if (pn.isMember(FilteredThreadIndex.GROUP_FAVORITE)) {
|
||||||
isFavorite = true;
|
isFavorite = true;
|
||||||
}
|
}
|
||||||
|
if (pn.isMember(FilteredThreadIndex.GROUP_IGNORE))
|
||||||
|
ignored = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.incrementRowsWritten();
|
state.incrementRowsWritten();
|
||||||
@ -498,10 +225,12 @@ public class ViewThreadedServlet extends HttpServlet {
|
|||||||
}
|
}
|
||||||
out.write("</a>\n");
|
out.write("</a>\n");
|
||||||
|
|
||||||
if (node.getEntry().getKeyHash().equals(user.getBlog())) {
|
if ( (user.getBlog() != null) && (node.getEntry().getKeyHash().equals(user.getBlog())) ) {
|
||||||
out.write("<img src=\"images/self.png\" alt=\"You wrote this\" border=\"0\" />\n");
|
out.write("<img src=\"images/self.png\" alt=\"You wrote this\" border=\"0\" />\n");
|
||||||
} else if (isFavorite) {
|
} else if (isFavorite) {
|
||||||
out.write("<img src=\"images/favorites.png\" alt=\"favorites\" border=\"0\" />\n");
|
out.write("<img src=\"images/favorites.png\" alt=\"favorites\" border=\"0\" />\n");
|
||||||
|
} else if (ignored) {
|
||||||
|
out.write("<img src=\"images/addToIgnored.png\" alt=\"ignored\" border=\"0\" />\n");
|
||||||
} else {
|
} else {
|
||||||
if (user.getAuthenticated()) {
|
if (user.getAuthenticated()) {
|
||||||
// give them a link to bookmark or ignore the peer
|
// give them a link to bookmark or ignore the peer
|
||||||
@ -547,14 +276,8 @@ public class ViewThreadedServlet extends HttpServlet {
|
|||||||
return rendered;
|
return rendered;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String trim(String orig, int maxLen) {
|
|
||||||
if ( (orig == null) || (orig.length() <= maxLen) )
|
|
||||||
return orig;
|
|
||||||
return orig.substring(0, maxLen) + "...";
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getFlagHTML(User user, ThreadNode node) {
|
private String getFlagHTML(User user, ThreadNode node) {
|
||||||
if (node.containsAuthor(user.getBlog()))
|
if ( (user.getBlog() != null) && (node.containsAuthor(user.getBlog())) )
|
||||||
return "<img src=\"images/self.png\" border=\"0\" alt=\"You have posted in the thread\" />";
|
return "<img src=\"images/self.png\" border=\"0\" alt=\"You have posted in the thread\" />";
|
||||||
|
|
||||||
// grab all of the peers in the user's favorites group and check to see if
|
// grab all of the peers in the user's favorites group and check to see if
|
||||||
@ -579,282 +302,4 @@ public class ViewThreadedServlet extends HttpServlet {
|
|||||||
return " ";
|
return " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final boolean empty(HttpServletRequest req, String param) {
|
|
||||||
String val = req.getParameter(param);
|
|
||||||
return (val == null) || (val.trim().length() <= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final boolean empty(String val) {
|
|
||||||
return (val == null) || (val.trim().length() <= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getExpandLink(HttpServletRequest req, ThreadNode node) {
|
|
||||||
return getExpandLink(node, req.getRequestURI(), req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_POST),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_THREAD),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
|
||||||
}
|
|
||||||
private static String getExpandLink(ThreadNode node, String uri, String viewPost, String viewThread,
|
|
||||||
String offset, String tags, String author) {
|
|
||||||
StringBuffer buf = new StringBuffer(64);
|
|
||||||
buf.append(uri);
|
|
||||||
buf.append('?');
|
|
||||||
// expand node == let one of node's children be visible
|
|
||||||
if (node.getChildCount() > 0) {
|
|
||||||
ThreadNode child = node.getChild(0);
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=');
|
|
||||||
buf.append(child.getEntry().getKeyHash().toBase64()).append('/');
|
|
||||||
buf.append(child.getEntry().getEntryId()).append('&');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty(viewPost))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_POST).append('=').append(viewPost).append('&');
|
|
||||||
else if (!empty(viewThread))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_THREAD).append('=').append(viewThread).append('&');
|
|
||||||
|
|
||||||
if (!empty(offset))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_OFFSET).append('=').append(offset).append('&');
|
|
||||||
|
|
||||||
if (!empty(tags))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_TAGS).append('=').append(tags).append('&');
|
|
||||||
|
|
||||||
if (!empty(author))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(author).append('&');
|
|
||||||
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
private String getCollapseLink(HttpServletRequest req, ThreadNode node) {
|
|
||||||
return getCollapseLink(node, req.getRequestURI(),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_POST),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_THREAD),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getCollapseLink(ThreadNode node, String uri, String viewPost, String viewThread,
|
|
||||||
String offset, String tags, String author) {
|
|
||||||
StringBuffer buf = new StringBuffer(64);
|
|
||||||
buf.append(uri);
|
|
||||||
// collapse node == let the node be visible
|
|
||||||
buf.append('?').append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=');
|
|
||||||
buf.append(node.getEntry().getKeyHash().toBase64()).append('/');
|
|
||||||
buf.append(node.getEntry().getEntryId()).append('&');
|
|
||||||
|
|
||||||
if (!empty(viewPost))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_POST).append('=').append(viewPost).append('&');
|
|
||||||
else if (!empty(viewThread))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_THREAD).append('=').append(viewThread).append('&');
|
|
||||||
|
|
||||||
if (!empty(offset))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_OFFSET).append('=').append(offset).append('&');
|
|
||||||
|
|
||||||
if (!empty(tags))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_TAGS).append('=').append(tags).append('&');
|
|
||||||
|
|
||||||
if (!empty(author))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(author).append('&');
|
|
||||||
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
private String getProfileLink(HttpServletRequest req, Hash author) {
|
|
||||||
return getProfileLink(author);
|
|
||||||
}
|
|
||||||
private static String getProfileLink(Hash author) { return HTMLRenderer.getMetadataURL(author); }
|
|
||||||
|
|
||||||
private String getAddToGroupLink(HttpServletRequest req, Hash author, User user, String group) {
|
|
||||||
return getAddToGroupLink(user, author, group, req.getRequestURI(),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_VISIBLE),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_POST),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_THREAD),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
|
||||||
}
|
|
||||||
private String getAddToGroupLink(User user, Hash author, String group, String uri, String visible,
|
|
||||||
String viewPost, String viewThread, String offset, String tags, String filteredAuthor) {
|
|
||||||
StringBuffer buf = new StringBuffer(64);
|
|
||||||
buf.append(uri);
|
|
||||||
buf.append('?');
|
|
||||||
if (!empty(visible))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=').append(visible).append('&');
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_ADD_TO_GROUP_LOCATION).append('=').append(author.toBase64()).append('&');
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_ADD_TO_GROUP_NAME).append('=').append(group).append('&');
|
|
||||||
|
|
||||||
if (!empty(viewPost))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_POST).append('=').append(viewPost).append('&');
|
|
||||||
else if (!empty(viewThread))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_THREAD).append('=').append(viewThread).append('&');
|
|
||||||
|
|
||||||
if (!empty(offset))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_OFFSET).append('=').append(offset).append('&');
|
|
||||||
|
|
||||||
if (!empty(tags))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_TAGS).append('=').append(tags).append('&');
|
|
||||||
|
|
||||||
if (!empty(filteredAuthor))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(filteredAuthor).append('&');
|
|
||||||
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
private String getViewPostLink(HttpServletRequest req, ThreadNode node, User user, boolean isPermalink) {
|
|
||||||
return ThreadedHTMLRenderer.getViewPostLink(req.getRequestURI(), node, user, isPermalink,
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
|
||||||
}
|
|
||||||
private String getViewThreadLink(HttpServletRequest req, ThreadNode node, User user) {
|
|
||||||
return getViewThreadLink(req.getRequestURI(), node, user,
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
|
||||||
}
|
|
||||||
private static String getViewThreadLink(String uri, ThreadNode node, User user, String offset,
|
|
||||||
String tags, String author) {
|
|
||||||
StringBuffer buf = new StringBuffer(64);
|
|
||||||
buf.append(uri);
|
|
||||||
if (node.getChildCount() > 0) {
|
|
||||||
buf.append('?').append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=');
|
|
||||||
ThreadNode child = node.getChild(0);
|
|
||||||
buf.append(child.getEntry().getKeyHash().toBase64()).append('/');
|
|
||||||
buf.append(child.getEntry().getEntryId()).append('&');
|
|
||||||
} else {
|
|
||||||
buf.append('?').append(ThreadedHTMLRenderer.PARAM_VISIBLE).append('=');
|
|
||||||
buf.append(node.getEntry().getKeyHash().toBase64()).append('/');
|
|
||||||
buf.append(node.getEntry().getEntryId()).append('&');
|
|
||||||
}
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_VIEW_THREAD).append('=');
|
|
||||||
buf.append(node.getEntry().getKeyHash().toBase64()).append('/');
|
|
||||||
buf.append(node.getEntry().getEntryId()).append('&');
|
|
||||||
|
|
||||||
if (!empty(offset))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_OFFSET).append('=').append(offset).append('&');
|
|
||||||
|
|
||||||
if (!empty(tags))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_TAGS).append('=').append(tags).append('&');
|
|
||||||
|
|
||||||
if (!empty(author))
|
|
||||||
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(author).append('&');
|
|
||||||
|
|
||||||
buf.append("#").append(node.getEntry().toString());
|
|
||||||
return buf.toString();
|
|
||||||
}
|
|
||||||
private String getFilterByTagLink(HttpServletRequest req, ThreadNode node, User user, String tag, String author) {
|
|
||||||
return ThreadedHTMLRenderer.getFilterByTagLink(req.getRequestURI(), node, user, tag, author);
|
|
||||||
}
|
|
||||||
private String getNavLink(HttpServletRequest req, int offset) {
|
|
||||||
return ThreadedHTMLRenderer.getNavLink(req.getRequestURI(),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_POST),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_THREAD),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
|
||||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR),
|
|
||||||
offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void renderEnd(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
|
||||||
out.write(END_HTML);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String BEGIN_HTML = "<html>\n" +
|
|
||||||
"<head>\n" +
|
|
||||||
"<title>Syndie</title>\n" +
|
|
||||||
"<style>\n" +
|
|
||||||
".overallTable {\n" +
|
|
||||||
" border-spacing: 0px;\n" +
|
|
||||||
" border-width: 0px;\n" +
|
|
||||||
" border: 0px;\n" +
|
|
||||||
" margin: 0px;\n" +
|
|
||||||
" padding: 0px;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".topNav {\n" +
|
|
||||||
" background-color: #BBBBBB;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".topNav_user {\n" +
|
|
||||||
" text-align: left;\n" +
|
|
||||||
" float: left;\n" +
|
|
||||||
" align: left;\n" +
|
|
||||||
" display: inline;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".topNav_admin {\n" +
|
|
||||||
" text-align: right;\n" +
|
|
||||||
" float: right;\n" +
|
|
||||||
" align: right;\n" +
|
|
||||||
" display: inline;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".controlBar {\n" +
|
|
||||||
" background-color: #BBBBBB;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".controlBarRight {\n" +
|
|
||||||
" text-align: right;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".threadEven {\n" +
|
|
||||||
" background-color: #FFFFFF;\n" +
|
|
||||||
" white-space: nowrap;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".threadOdd {\n" +
|
|
||||||
" background-color: #EEEEEE;\n" +
|
|
||||||
" white-space: nowrap;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".threadLeft {\n" +
|
|
||||||
" text-align: left;\n" +
|
|
||||||
" align: left;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".threadRight {\n" +
|
|
||||||
" text-align: right;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".threadNav {\n" +
|
|
||||||
" background-color: #BBBBBB;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".threadNavRight {\n" +
|
|
||||||
" text-align: right;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".postMeta {\n" +
|
|
||||||
" background-color: #BBBBFF;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".postMetaSubject {\n" +
|
|
||||||
" text-align: left;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".postMetaLink {\n" +
|
|
||||||
" text-align: right;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".postDetails {\n" +
|
|
||||||
" background-color: #DDDDFF;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".postReply {\n" +
|
|
||||||
" background-color: #BBBBFF;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".postReplyText {\n" +
|
|
||||||
" background-color: #BBBBFF;\n" +
|
|
||||||
"}\n" +
|
|
||||||
".postReplyOptions {\n" +
|
|
||||||
" background-color: #BBBBFF;\n" +
|
|
||||||
"}\n" +
|
|
||||||
"</style>\n" +
|
|
||||||
"<link href=\"style.jsp\" rel=\"stylesheet\" type=\"text/css\" >\n" +
|
|
||||||
"<link href=\"rss.jsp\" rel=\"alternate\" type=\"application/rss+xml\" >\n" +
|
|
||||||
"</head>\n" +
|
|
||||||
"<body>\n" +
|
|
||||||
"<span style=\"display: none\"><a href=\"#bodySubject\">Jump to the beginning of the first post rendered, if any</a>\n" +
|
|
||||||
"<a href=\"#threads\">Jump to the thread navigation</a>\n</span>\n" +
|
|
||||||
"<table border=\"0\" width=\"100%\" class=\"overallTable\">\n";
|
|
||||||
|
|
||||||
private static final String END_HTML = "</table>\n" +
|
|
||||||
"</body>\n";
|
|
||||||
|
|
||||||
private static class TreeRenderState {
|
|
||||||
private int _rowsWritten;
|
|
||||||
private int _rowsSkipped;
|
|
||||||
private List _ignored;
|
|
||||||
public TreeRenderState(List ignored) {
|
|
||||||
_rowsWritten = 0;
|
|
||||||
_rowsSkipped = 0;
|
|
||||||
_ignored = ignored;
|
|
||||||
}
|
|
||||||
public int getRowsWritten() { return _rowsWritten; }
|
|
||||||
public void incrementRowsWritten() { _rowsWritten++; }
|
|
||||||
public int getRowsSkipped() { return _rowsSkipped; }
|
|
||||||
public void incrementRowsSkipped() { _rowsSkipped++; }
|
|
||||||
public List getIgnoredAuthors() { return _ignored; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
<servlet-class>net.i2p.syndie.web.ViewThreadedServlet</servlet-class>
|
<servlet-class>net.i2p.syndie.web.ViewThreadedServlet</servlet-class>
|
||||||
</servlet>
|
</servlet>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>net.i2p.syndie.web.ProfileServlet</servlet-name>
|
||||||
|
<servlet-class>net.i2p.syndie.web.ProfileServlet</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>net.i2p.syndie.UpdaterServlet</servlet-name>
|
<servlet-name>net.i2p.syndie.UpdaterServlet</servlet-name>
|
||||||
<servlet-class>net.i2p.syndie.UpdaterServlet</servlet-class>
|
<servlet-class>net.i2p.syndie.UpdaterServlet</servlet-class>
|
||||||
@ -45,6 +50,10 @@
|
|||||||
<servlet-name>net.i2p.syndie.web.ViewThreadedServlet</servlet-name>
|
<servlet-name>net.i2p.syndie.web.ViewThreadedServlet</servlet-name>
|
||||||
<url-pattern>/threads.jsp</url-pattern>
|
<url-pattern>/threads.jsp</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>net.i2p.syndie.web.ProfileServlet</servlet-name>
|
||||||
|
<url-pattern>/profile.jsp</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
<session-config>
|
<session-config>
|
||||||
<session-timeout>
|
<session-timeout>
|
||||||
|
Reference in New Issue
Block a user