2005-12-07 jrandom
* Added a first pass at a blog view in Syndie
This commit is contained in:
@ -0,0 +1,20 @@
|
||||
package net.i2p.syndie;
|
||||
|
||||
import java.util.*;
|
||||
import net.i2p.data.*;
|
||||
import net.i2p.syndie.data.*;
|
||||
|
||||
/** sort BlogURI instances with the highest entryId first */
|
||||
public class NewestEntryFirstComparator implements Comparator {
|
||||
public int compare(Object lhs, Object rhs) {
|
||||
BlogURI left = (BlogURI)lhs;
|
||||
BlogURI right = (BlogURI)rhs;
|
||||
if (left.getEntryId() > right.getEntryId()) {
|
||||
return -1;
|
||||
} else if (left.getEntryId() == right.getEntryId()) {
|
||||
return DataHelper.compareTo(left.getKeyHash().getData(), right.getKeyHash().getData());
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package net.i2p.syndie;
|
||||
|
||||
import java.util.*;
|
||||
import net.i2p.data.*;
|
||||
|
||||
/** sort ThreadNodeImpl instances with the highest entryId first */
|
||||
public class NewestNodeFirstComparator implements Comparator {
|
||||
public int compare(Object lhs, Object rhs) {
|
||||
ThreadNodeImpl left = (ThreadNodeImpl)lhs;
|
||||
ThreadNodeImpl right = (ThreadNodeImpl)rhs;
|
||||
long l = left.getMostRecentPostDate();
|
||||
long r = right.getMostRecentPostDate();
|
||||
if (l > r) {
|
||||
return -1;
|
||||
} else if (l == r) {
|
||||
// ok, the newest responses match, so lets fall back and compare the roots themselves
|
||||
l = left.getEntry().getEntryId();
|
||||
r = right.getEntry().getEntryId();
|
||||
if (l > r) {
|
||||
return -1;
|
||||
} else if (l == r) {
|
||||
return DataHelper.compareTo(left.getEntry().getKeyHash().getData(), right.getEntry().getKeyHash().getData());
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
@ -80,7 +80,7 @@ class ThreadNodeImpl implements ThreadNode {
|
||||
}
|
||||
|
||||
// now reorder the children
|
||||
TreeSet ordered = new TreeSet(new WritableThreadIndex.NewestNodeFirstComparator());
|
||||
TreeSet ordered = new TreeSet(new NewestNodeFirstComparator());
|
||||
for (int i = 0; i < _children.size(); i++) {
|
||||
ThreadNodeImpl kid = (ThreadNodeImpl)_children.get(i);
|
||||
ordered.add(kid);
|
||||
|
@ -136,44 +136,4 @@ class WritableThreadIndex extends ThreadIndex {
|
||||
buf.append("</threadIndex>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** sort BlogURI instances with the highest entryId first */
|
||||
private class NewestEntryFirstComparator implements Comparator {
|
||||
public int compare(Object lhs, Object rhs) {
|
||||
BlogURI left = (BlogURI)lhs;
|
||||
BlogURI right = (BlogURI)rhs;
|
||||
if (left.getEntryId() > right.getEntryId()) {
|
||||
return -1;
|
||||
} else if (left.getEntryId() == right.getEntryId()) {
|
||||
return DataHelper.compareTo(left.getKeyHash().getData(), right.getKeyHash().getData());
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/** sort ThreadNodeImpl instances with the highest entryId first */
|
||||
public static class NewestNodeFirstComparator implements Comparator {
|
||||
public int compare(Object lhs, Object rhs) {
|
||||
ThreadNodeImpl left = (ThreadNodeImpl)lhs;
|
||||
ThreadNodeImpl right = (ThreadNodeImpl)rhs;
|
||||
long l = left.getMostRecentPostDate();
|
||||
long r = right.getMostRecentPostDate();
|
||||
if (l > r) {
|
||||
return -1;
|
||||
} else if (l == r) {
|
||||
// ok, the newest responses match, so lets fall back and compare the roots themselves
|
||||
l = left.getEntry().getEntryId();
|
||||
r = right.getEntry().getEntryId();
|
||||
if (l > r) {
|
||||
return -1;
|
||||
} else if (l == r) {
|
||||
return DataHelper.compareTo(left.getEntry().getKeyHash().getData(), right.getEntry().getKeyHash().getData());
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,11 +16,12 @@ public class FilteredThreadIndex extends ThreadIndex {
|
||||
private List _roots;
|
||||
private List _ignoredAuthors;
|
||||
private Collection _filteredAuthors;
|
||||
private boolean _filterAuthorsByRoot;
|
||||
|
||||
public static final String GROUP_FAVORITE = "Favorite";
|
||||
public static final String GROUP_IGNORE = "Ignore";
|
||||
|
||||
public FilteredThreadIndex(User user, Archive archive, Collection tags, Collection authors) {
|
||||
public FilteredThreadIndex(User user, Archive archive, Collection tags, Collection authors, boolean filterAuthorsByRoot) {
|
||||
super();
|
||||
_user = user;
|
||||
_archive = archive;
|
||||
@ -31,6 +32,7 @@ public class FilteredThreadIndex extends ThreadIndex {
|
||||
_filteredAuthors = authors;
|
||||
if (_filteredAuthors == null)
|
||||
_filteredAuthors = Collections.EMPTY_SET;
|
||||
_filterAuthorsByRoot = filterAuthorsByRoot;
|
||||
|
||||
_ignoredAuthors = new ArrayList();
|
||||
for (Iterator iter = user.getPetNameDB().iterator(); iter.hasNext(); ) {
|
||||
@ -53,12 +55,12 @@ public class FilteredThreadIndex extends ThreadIndex {
|
||||
_roots = new ArrayList(_baseIndex.getRootCount());
|
||||
for (int i = 0; i < _baseIndex.getRootCount(); i++) {
|
||||
ThreadNode node = _baseIndex.getRoot(i);
|
||||
if (!isIgnored(node, _ignoredAuthors, _filteredTags, _filteredAuthors))
|
||||
if (!isIgnored(node, _ignoredAuthors, _filteredTags, _filteredAuthors, _filterAuthorsByRoot))
|
||||
_roots.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isIgnored(ThreadNode node, List ignoredAuthors, Collection requestedTags, Collection filteredAuthors) {
|
||||
private boolean isIgnored(ThreadNode node, List ignoredAuthors, Collection requestedTags, Collection filteredAuthors, boolean filterAuthorsByRoot) {
|
||||
if (filteredAuthors.size() <= 0) {
|
||||
boolean allAuthorsIgnored = true;
|
||||
for (Iterator iter = node.getRecursiveAuthorIterator(); iter.hasNext(); ) {
|
||||
@ -75,9 +77,16 @@ public class FilteredThreadIndex extends ThreadIndex {
|
||||
boolean filteredAuthorMatches = false;
|
||||
for (Iterator iter = filteredAuthors.iterator(); iter.hasNext(); ) {
|
||||
Hash author = (Hash)iter.next();
|
||||
if (node.containsAuthor(author)) {
|
||||
filteredAuthorMatches = true;
|
||||
break;
|
||||
if (filterAuthorsByRoot) {
|
||||
if (node.getEntry().getKeyHash().equals(author)) {
|
||||
filteredAuthorMatches = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (node.containsAuthor(author)) {
|
||||
filteredAuthorMatches = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!filteredAuthorMatches)
|
||||
@ -107,4 +116,5 @@ public class FilteredThreadIndex extends ThreadIndex {
|
||||
public ThreadNode getNode(BlogURI uri) { return _baseIndex.getNode(uri); }
|
||||
public Collection getFilteredTags() { return _filteredTags; }
|
||||
public Collection getFilteredAuthors() { return _filteredAuthors; }
|
||||
public boolean getFilterAuthorsByRoot() { return _filterAuthorsByRoot; }
|
||||
}
|
||||
|
@ -41,7 +41,10 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
/** index into the nav tree to start displaying */
|
||||
public static final String PARAM_OFFSET = "offset";
|
||||
public static final String PARAM_TAGS = "tags";
|
||||
/** only show threads that the given author participates in */
|
||||
public static final String PARAM_AUTHOR = "author";
|
||||
/** only show threads started by the given author */
|
||||
public static final String PARAM_THREAD_AUTHOR = "threadAuthorOnly";
|
||||
/** search back through the blog for entries this many days */
|
||||
public static final String PARAM_DAYS_BACK = "daysBack";
|
||||
// parameters for editing one's profile
|
||||
@ -94,7 +97,7 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String getNavLink(String uri, String viewPost, String viewThread, String tags, String author, int offset) {
|
||||
public static String getNavLink(String uri, String viewPost, String viewThread, String tags, String author, boolean authorOnly, int offset) {
|
||||
StringBuffer buf = new StringBuffer(64);
|
||||
buf.append(uri);
|
||||
buf.append('?');
|
||||
@ -106,8 +109,11 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
if (!empty(tags))
|
||||
buf.append(PARAM_TAGS).append('=').append(tags).append('&');
|
||||
|
||||
if (!empty(author))
|
||||
if (!empty(author)) {
|
||||
buf.append(PARAM_AUTHOR).append('=').append(author).append('&');
|
||||
if (authorOnly)
|
||||
buf.append(PARAM_THREAD_AUTHOR).append("=true&");
|
||||
}
|
||||
|
||||
buf.append(PARAM_OFFSET).append('=').append(offset).append('&');
|
||||
|
||||
@ -115,7 +121,7 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
}
|
||||
|
||||
public static String getViewPostLink(String uri, ThreadNode node, User user, boolean isPermalink,
|
||||
String offset, String tags, String author) {
|
||||
String offset, String tags, String author, boolean authorOnly) {
|
||||
StringBuffer buf = new StringBuffer(64);
|
||||
buf.append(uri);
|
||||
if (node.getChildCount() > 0) {
|
||||
@ -137,15 +143,19 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
buf.append(PARAM_OFFSET).append('=').append(offset).append('&');
|
||||
if (!empty(tags))
|
||||
buf.append(PARAM_TAGS).append('=').append(tags).append('&');
|
||||
if (!empty(author))
|
||||
buf.append(PARAM_AUTHOR).append('=').append(author).append('&');
|
||||
}
|
||||
|
||||
if (authorOnly && !empty(author)) {
|
||||
buf.append(PARAM_AUTHOR).append('=').append(author).append('&');
|
||||
buf.append(PARAM_THREAD_AUTHOR).append("=true&");
|
||||
} else if (!isPermalink && !empty(author))
|
||||
buf.append(PARAM_AUTHOR).append('=').append(author).append('&');
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String getViewPostLink(String uri, BlogURI post, User user, boolean isPermalink,
|
||||
String offset, String tags, String author) {
|
||||
String offset, String tags, String author, boolean authorOnly) {
|
||||
StringBuffer buf = new StringBuffer(64);
|
||||
buf.append(uri);
|
||||
buf.append('?').append(PARAM_VISIBLE).append('=');
|
||||
@ -160,8 +170,11 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
buf.append(PARAM_OFFSET).append('=').append(offset).append('&');
|
||||
if (!empty(tags))
|
||||
buf.append(PARAM_TAGS).append('=').append(tags).append('&');
|
||||
if (!empty(author))
|
||||
if (!empty(author)) {
|
||||
buf.append(PARAM_AUTHOR).append('=').append(author).append('&');
|
||||
if (authorOnly)
|
||||
buf.append(PARAM_THREAD_AUTHOR).append("=true&");
|
||||
}
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
@ -174,7 +187,7 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
*/
|
||||
public void render(User user, Writer out, Archive archive, BlogURI post,
|
||||
boolean inlineReply, ThreadIndex index, String baseURI, String replyHiddenFields,
|
||||
String offset, String requestTags, String filteredAuthor) throws IOException {
|
||||
String offset, String requestTags, String filteredAuthor, boolean authorOnly) throws IOException {
|
||||
EntryContainer entry = archive.getEntry(post);
|
||||
if (entry == null) return;
|
||||
_entry = entry;
|
||||
@ -255,7 +268,7 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
}
|
||||
|
||||
out.write("\n<a href=\"");
|
||||
out.write(getViewPostLink(baseURI, node, user, true, offset, requestTags, filteredAuthor));
|
||||
out.write(getViewPostLink(baseURI, node, user, true, offset, requestTags, filteredAuthor, authorOnly));
|
||||
out.write("\" title=\"Select a shareable link directly to this post\">permalink</a>\n");
|
||||
|
||||
|
||||
|
@ -152,12 +152,20 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
|
||||
FilteredThreadIndex index = (FilteredThreadIndex)req.getSession().getAttribute("threadIndex");
|
||||
|
||||
boolean authorOnly = Boolean.valueOf(req.getParameter(ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR)).booleanValue();
|
||||
if ( (index != null) && (authorOnly != index.getFilterAuthorsByRoot()) )
|
||||
forceNewIndex = true;
|
||||
|
||||
Collection tags = getFilteredTags(req);
|
||||
Collection filteredAuthors = getFilteredAuthors(req);
|
||||
boolean tagsChanged = ( (index != null) && (!index.getFilteredTags().equals(tags)) );
|
||||
boolean authorsChanged = ( (index != null) && (!index.getFilteredAuthors().equals(filteredAuthors)) );
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("authorOnly=" + authorOnly + " forceNewIndex? " + forceNewIndex + " authors=" + filteredAuthors);
|
||||
|
||||
if (forceNewIndex || (index == null) || (tagsChanged) || (authorsChanged) ) {
|
||||
index = new FilteredThreadIndex(user, BlogManager.instance().getArchive(), getFilteredTags(req), filteredAuthors);
|
||||
index = new FilteredThreadIndex(user, BlogManager.instance().getArchive(), getFilteredTags(req), filteredAuthors, authorOnly);
|
||||
req.getSession().setAttribute("threadIndex", index);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("New filtered index created (forced? " + forceNewIndex + ", tagsChanged? " + tagsChanged + ", authorsChanged? " + authorsChanged + ")");
|
||||
@ -561,7 +569,7 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
//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");
|
||||
out.write("<a href=\"threads.jsp\" title=\"Syndie home\">Home</a> ");
|
||||
out.write("<a href=\"threads.jsp\" title=\"Syndie home\">Home</a> <a href=\"blogs.jsp\" title=\"Blog summary\">Blogs</a> ");
|
||||
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());
|
||||
@ -933,22 +941,25 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
return ThreadedHTMLRenderer.getViewPostLink(req.getRequestURI(), node, user, isPermalink,
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR),
|
||||
Boolean.valueOf(req.getParameter(ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR)).booleanValue());
|
||||
}
|
||||
protected String getViewPostLink(HttpServletRequest req, BlogURI post, User user) {
|
||||
return ThreadedHTMLRenderer.getViewPostLink(req.getRequestURI(), post, user, false,
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR),
|
||||
Boolean.valueOf(req.getParameter(ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR)).booleanValue());
|
||||
}
|
||||
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));
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR),
|
||||
Boolean.valueOf(req.getParameter(ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR)).booleanValue());
|
||||
}
|
||||
protected static String getViewThreadLink(String uri, ThreadNode node, User user, String offset,
|
||||
String tags, String author) {
|
||||
String tags, String author, boolean authorOnly) {
|
||||
StringBuffer buf = new StringBuffer(64);
|
||||
buf.append(uri);
|
||||
BlogURI expandTo = node.getEntry();
|
||||
@ -975,8 +986,11 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
if (!empty(tags))
|
||||
buf.append(ThreadedHTMLRenderer.PARAM_TAGS).append('=').append(tags).append('&');
|
||||
|
||||
if (!empty(author))
|
||||
if (!empty(author)) {
|
||||
buf.append(ThreadedHTMLRenderer.PARAM_AUTHOR).append('=').append(author).append('&');
|
||||
if (authorOnly)
|
||||
buf.append(ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR).append("=true&");
|
||||
}
|
||||
|
||||
buf.append("#").append(node.getEntry().toString());
|
||||
return buf.toString();
|
||||
@ -990,6 +1004,7 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_THREAD),
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS),
|
||||
req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR),
|
||||
Boolean.valueOf(req.getParameter(ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR)).booleanValue(),
|
||||
offset);
|
||||
}
|
||||
|
||||
@ -1014,7 +1029,13 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
}
|
||||
|
||||
protected Collection getFilteredAuthors(HttpServletRequest req) {
|
||||
String authors = req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR);
|
||||
List rv = new ArrayList();
|
||||
rv.addAll(getAuthors(req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR)));
|
||||
//rv.addAll(getAuthors(req.getParameter(ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR)));
|
||||
return rv;
|
||||
}
|
||||
|
||||
private Collection getAuthors(String authors) {
|
||||
if (authors != null) {
|
||||
StringTokenizer tok = new StringTokenizer(authors, "\n\t ");
|
||||
ArrayList rv = new ArrayList();
|
||||
|
@ -103,14 +103,13 @@ public class ProfileServlet extends BaseServlet {
|
||||
}
|
||||
|
||||
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\">");
|
||||
out.write("<tr><td colspan=\"3\">Profile for ");
|
||||
PetName pn = user.getPetNameDB().getByLocation(author.toBase64());
|
||||
String name = null;
|
||||
BlogInfo info = archive.getBlogInfo(author);
|
||||
if (pn != null) {
|
||||
out.write(pn.getName());
|
||||
String name = null;
|
||||
name = null;
|
||||
if (info != null)
|
||||
name = info.getProperty(BlogInfo.NAME);
|
||||
|
||||
@ -119,7 +118,6 @@ public class ProfileServlet extends BaseServlet {
|
||||
|
||||
out.write(" (" + name + ")");
|
||||
} else {
|
||||
String name = null;
|
||||
if (info != null)
|
||||
name = info.getProperty(BlogInfo.NAME);
|
||||
|
||||
@ -130,6 +128,12 @@ public class ProfileServlet extends BaseServlet {
|
||||
out.write("</a>");
|
||||
if (info != null)
|
||||
out.write(" [edition " + info.getEdition() + "]");
|
||||
out.write("<br />\n");
|
||||
out.write("<a href=\"" + getControlTarget() + "?" + ThreadedHTMLRenderer.PARAM_AUTHOR
|
||||
+ '=' + author.toBase64() + "&" + ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR + "=true&\""
|
||||
+ " title=\"View '" + HTMLRenderer.sanitizeTagParam(name) + "'s blog\">View their blog</a> or ");
|
||||
out.write("<a href=\"" + getControlTarget() + "?" + ThreadedHTMLRenderer.PARAM_AUTHOR
|
||||
+ '=' + author.toBase64() + "&\">threads they have participated in</a>\n");
|
||||
out.write("</td></tr>\n");
|
||||
|
||||
out.write("<tr><td colspan=\"3\"><hr /></td></tr>\n");
|
||||
|
@ -60,7 +60,7 @@ public class RSSServlet extends HttpServlet {
|
||||
if (count > 100) count = 100;
|
||||
|
||||
Archive archive = BlogManager.instance().getArchive();
|
||||
FilteredThreadIndex index = new FilteredThreadIndex(user, archive, tagSet, null);
|
||||
FilteredThreadIndex index = new FilteredThreadIndex(user, archive, tagSet, null, false);
|
||||
List entries = new ArrayList();
|
||||
// depth first search of the most recent threads
|
||||
for (int i = 0; i < count && i < index.getRootCount(); i++) {
|
||||
|
@ -0,0 +1,95 @@
|
||||
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 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.*;
|
||||
|
||||
/**
|
||||
* List the blogs known in the archive
|
||||
*
|
||||
*/
|
||||
public class ViewBlogsServlet extends BaseServlet {
|
||||
private static final int MAX_AUTHORS_AT_ONCE = 100;
|
||||
private static final int MAX_TAGS = 50;
|
||||
|
||||
protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index,
|
||||
int threadOffset, BlogURI visibleEntry, Archive archive) throws IOException {
|
||||
TreeSet orderedRoots = new TreeSet(new NewestEntryFirstComparator());
|
||||
// The thread index is ordered by last updated date, as opposed to root posting date,
|
||||
// so lets reorder things
|
||||
int count = index.getRootCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
ThreadNode node = index.getRoot(i);
|
||||
orderedRoots.add(node.getEntry());
|
||||
}
|
||||
|
||||
TreeSet tags = new TreeSet();
|
||||
List writtenAuthors = new ArrayList();
|
||||
out.write("<tr><td colspan=\"3\"><b>Blogs:</b></td></tr>\n");
|
||||
out.write("<tr><td colspan=\"3\">");
|
||||
for (Iterator iter = orderedRoots.iterator(); iter.hasNext() && writtenAuthors.size() < MAX_AUTHORS_AT_ONCE; ) {
|
||||
BlogURI uri= (BlogURI)iter.next();
|
||||
String curTags[] = archive.getEntry(uri).getTags();
|
||||
if (curTags != null)
|
||||
for (int i = 0; i < curTags.length && tags.size() < MAX_TAGS; i++)
|
||||
tags.add(curTags[i]);
|
||||
if (writtenAuthors.contains(uri.getKeyHash())) {
|
||||
// skip
|
||||
} else {
|
||||
BlogInfo info = archive.getBlogInfo(uri);
|
||||
if (info == null)
|
||||
continue;
|
||||
String name = info.getProperty(BlogInfo.NAME);
|
||||
if ( (name == null) || (name.trim().length() <= 0) )
|
||||
name = uri.getKeyHash().toBase64().substring(0,8);
|
||||
String desc = info.getProperty(BlogInfo.DESCRIPTION);
|
||||
if ( (desc == null) || (desc.trim().length() <= 0) )
|
||||
desc = name + "'s blog";
|
||||
String age = null;
|
||||
long dayBegin = BlogManager.instance().getDayBegin();
|
||||
long postId = uri.getEntryId();
|
||||
if (postId >= dayBegin) {
|
||||
age = "today";
|
||||
} else if (postId >= dayBegin - 24*60*60*1000) {
|
||||
age = "yesterday";
|
||||
} else {
|
||||
int daysAgo = (int)((dayBegin - postId + 24*60*60*1000-1)/(24*60*60*1000));
|
||||
age = daysAgo + " days ago";
|
||||
}
|
||||
|
||||
out.write("<a href=\"" + getControlTarget() + "?"
|
||||
+ ThreadedHTMLRenderer.PARAM_AUTHOR + '=' + uri.getKeyHash().toBase64()
|
||||
+ "&" + ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR + "=true&"
|
||||
+ "\" title=\"Posts by " + trim(HTMLRenderer.sanitizeTagParam(name), 32)
|
||||
+ ", last post " + age + "\">");
|
||||
out.write(HTMLRenderer.sanitizeString(desc, 32));
|
||||
out.write("</a> \n");
|
||||
writtenAuthors.add(uri.getKeyHash());
|
||||
}
|
||||
}
|
||||
out.write("</td></tr>\n");
|
||||
|
||||
out.write("<tr><td colspan=\"3\"><b>Topics:</b></td></tr>\n");
|
||||
out.write("<tr><td colspan=\"3\">");
|
||||
for (Iterator iter = tags.iterator(); iter.hasNext(); ) {
|
||||
String tag = (String)iter.next();
|
||||
out.write("<a href=\"" + getFilterByTagLink(req, null, user, tag, null)
|
||||
+ "\" title=\"View threads flagged with the tag '" + HTMLRenderer.sanitizeTagParam(tag) + "'\">");
|
||||
out.write(HTMLRenderer.sanitizeString(tag, 32));
|
||||
out.write("</a> ");
|
||||
}
|
||||
out.write("</td></tr>\n");
|
||||
}
|
||||
|
||||
protected String getTitle() { return "Syndie :: View blogs"; }
|
||||
}
|
@ -36,13 +36,15 @@ public class ViewThreadedServlet extends BaseServlet {
|
||||
String off = req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET);
|
||||
String tags = req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS);
|
||||
String author = req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR);
|
||||
|
||||
boolean authorOnly = Boolean.valueOf(req.getParameter(ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR)).booleanValue();
|
||||
|
||||
for (int i = 0; i < posts.size(); i++) {
|
||||
BlogURI post = (BlogURI)posts.get(i);
|
||||
boolean inlineReply = (posts.size() == 1);
|
||||
//if (true)
|
||||
// inlineReply = true;
|
||||
renderer.render(user, out, archive, post, inlineReply, index, uri, getAuthActionFields(), off, tags, author);
|
||||
renderer.render(user, out, archive, post, inlineReply, index, uri, getAuthActionFields(), off, tags, author, authorOnly);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,11 @@
|
||||
<servlet-class>net.i2p.syndie.web.ThreadNavServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>net.i2p.syndie.web.ViewBlogsServlet</servlet-name>
|
||||
<servlet-class>net.i2p.syndie.web.ViewBlogsServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>net.i2p.syndie.UpdaterServlet</servlet-name>
|
||||
<servlet-class>net.i2p.syndie.UpdaterServlet</servlet-class>
|
||||
@ -126,6 +131,10 @@
|
||||
<servlet-name>net.i2p.syndie.web.ThreadNavServlet</servlet-name>
|
||||
<url-pattern>/threadnav/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>net.i2p.syndie.web.ViewBlogsServlet</servlet-name>
|
||||
<url-pattern>/blogs.jsp</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<session-config>
|
||||
<session-timeout>
|
||||
|
@ -1,4 +1,7 @@
|
||||
$Id: history.txt,v 1.348 2005/12/05 01:14:16 jrandom Exp $
|
||||
$Id: history.txt,v 1.349 2005/12/07 15:19:43 jrandom Exp $
|
||||
|
||||
2005-12-07 jrandom
|
||||
* Added a first pass at a blog view in Syndie
|
||||
|
||||
2005-12-07 jrandom
|
||||
* Expand the thread we're viewing to its leaf
|
||||
|
Reference in New Issue
Block a user