diff --git a/apps/syndie/java/src/net/i2p/syndie/NewestEntryFirstComparator.java b/apps/syndie/java/src/net/i2p/syndie/NewestEntryFirstComparator.java new file mode 100644 index 000000000..21304ef7a --- /dev/null +++ b/apps/syndie/java/src/net/i2p/syndie/NewestEntryFirstComparator.java @@ -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; + } + } +} diff --git a/apps/syndie/java/src/net/i2p/syndie/NewestNodeFirstComparator.java b/apps/syndie/java/src/net/i2p/syndie/NewestNodeFirstComparator.java new file mode 100644 index 000000000..6046bf0c7 --- /dev/null +++ b/apps/syndie/java/src/net/i2p/syndie/NewestNodeFirstComparator.java @@ -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; + } + } +} diff --git a/apps/syndie/java/src/net/i2p/syndie/ThreadNodeImpl.java b/apps/syndie/java/src/net/i2p/syndie/ThreadNodeImpl.java index 891d1f5b6..406ca10e4 100644 --- a/apps/syndie/java/src/net/i2p/syndie/ThreadNodeImpl.java +++ b/apps/syndie/java/src/net/i2p/syndie/ThreadNodeImpl.java @@ -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); diff --git a/apps/syndie/java/src/net/i2p/syndie/WritableThreadIndex.java b/apps/syndie/java/src/net/i2p/syndie/WritableThreadIndex.java index 224e03710..06ffc8e35 100644 --- a/apps/syndie/java/src/net/i2p/syndie/WritableThreadIndex.java +++ b/apps/syndie/java/src/net/i2p/syndie/WritableThreadIndex.java @@ -136,44 +136,4 @@ class WritableThreadIndex extends ThreadIndex { buf.append("\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; - } - } - } } diff --git a/apps/syndie/java/src/net/i2p/syndie/data/FilteredThreadIndex.java b/apps/syndie/java/src/net/i2p/syndie/data/FilteredThreadIndex.java index fb9dde971..eeaa9ee80 100644 --- a/apps/syndie/java/src/net/i2p/syndie/data/FilteredThreadIndex.java +++ b/apps/syndie/java/src/net/i2p/syndie/data/FilteredThreadIndex.java @@ -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; } } diff --git a/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java b/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java index ad21c196b..f981214ea 100644 --- a/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java +++ b/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java @@ -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("\npermalink\n"); diff --git a/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java b/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java index 8c5c80991..65e7e078e 100644 --- a/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java +++ b/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java @@ -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("