2005-12-03 jrandom
* Added support for a 'most recent posts' view that CofE requested, which includes the ability to filter by age (e.g. posts by your favorite authors in the last 5 days).
This commit is contained in:
@ -281,6 +281,9 @@ public class ArchiveIndex {
|
||||
*
|
||||
*/
|
||||
public void selectMatchesOrderByEntryId(List out, Hash blog, String tag) {
|
||||
selectMatchesOrderByEntryId(out, blog, tag, 0);
|
||||
}
|
||||
public void selectMatchesOrderByEntryId(List out, Hash blog, String tag, long lowestEntryId) {
|
||||
TreeMap ordered = new TreeMap();
|
||||
for (int i = 0; i < _blogs.size(); i++) {
|
||||
BlogSummary summary = (BlogSummary)_blogs.get(i);
|
||||
@ -288,7 +291,7 @@ public class ArchiveIndex {
|
||||
if (!blog.equals(summary.blog))
|
||||
continue;
|
||||
}
|
||||
if (tag != null) {
|
||||
if ( (tag != null) && (tag.trim().length() > 0) ) {
|
||||
if (!tag.equals(summary.tag)) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Tag [" + summary.tag + "] does not match the requested [" + tag + "] in " + summary.blog.toBase64());
|
||||
@ -312,6 +315,8 @@ public class ArchiveIndex {
|
||||
|
||||
for (int j = 0; j < summary.entries.size(); j++) {
|
||||
EntrySummary entry = (EntrySummary)summary.entries.get(j);
|
||||
if (entry.entry.getEntryId() < lowestEntryId)
|
||||
continue;
|
||||
String k = (Long.MAX_VALUE-entry.entry.getEntryId()) + "-" + entry.entry.getKeyHash().toBase64();
|
||||
ordered.put(k, entry.entry);
|
||||
//System.err.println("Including match: " + k);
|
||||
@ -319,6 +324,8 @@ public class ArchiveIndex {
|
||||
}
|
||||
for (Iterator iter = ordered.values().iterator(); iter.hasNext(); ) {
|
||||
BlogURI entry = (BlogURI)iter.next();
|
||||
if (entry.getEntryId() < lowestEntryId)
|
||||
continue;
|
||||
if (!out.contains(entry))
|
||||
out.add(entry);
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ public class BlogURI {
|
||||
private Hash _blogHash;
|
||||
private long _entryId;
|
||||
|
||||
public static final Comparator COMPARATOR = new NewestFirstComparator();
|
||||
|
||||
public BlogURI() {
|
||||
this(null, -1);
|
||||
}
|
||||
@ -95,4 +97,20 @@ public class BlogURI {
|
||||
if (!u.toString().equals(uri))
|
||||
System.err.println("Not a match: [" + uri + "] != [" + u.toString() + "]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Order the BlogURIs by entryId, with the highest entryId first
|
||||
*/
|
||||
private static class NewestFirstComparator implements Comparator {
|
||||
public int compare(Object lhs, Object rhs) {
|
||||
BlogURI l = (BlogURI)lhs;
|
||||
BlogURI r = (BlogURI)rhs;
|
||||
if (l.getEntryId() > r.getEntryId())
|
||||
return -1;
|
||||
else if (l.getEntryId() < r.getEntryId())
|
||||
return 1;
|
||||
else // same date, compare by blog hash (aka randomly)
|
||||
return DataHelper.compareTo(l.getKeyHash().getData(), r.getKeyHash().getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
public static final String PARAM_OFFSET = "offset";
|
||||
public static final String PARAM_TAGS = "tags";
|
||||
public static final String PARAM_AUTHOR = "author";
|
||||
/** search back through the blog for entries this many days */
|
||||
public static final String PARAM_DAYS_BACK = "daysBack";
|
||||
// parameters for editing one's profile
|
||||
public static final String PARAM_PROFILE_NAME = "profileName";
|
||||
public static final String PARAM_PROFILE_DESC = "profileDesc";
|
||||
@ -446,8 +448,12 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
String inReplyTo = (String)_headers.get(HEADER_IN_REPLY_TO);
|
||||
if ( (inReplyTo != null) && (inReplyTo.trim().length() > 0) ) {
|
||||
BlogURI replyURI = new BlogURI(inReplyTo);
|
||||
if (replyURI.getEntryId() > 0)
|
||||
_postBodyBuffer.append(" <a ").append(getClass("summDetailParent")).append(" href=\"").append(getPageURL(replyURI.getKeyHash(), null, replyURI.getEntryId(), 0, 0, true, true)).append("\">(view parent)</a><br />\n");
|
||||
if (replyURI.getEntryId() > 0) {
|
||||
_postBodyBuffer.append(" <a ").append(getClass("summDetailParent"));
|
||||
_postBodyBuffer.append(" href=\"");
|
||||
_postBodyBuffer.append(getPageURL(replyURI.getKeyHash(), null, replyURI.getEntryId(), 0, 0, true, true));
|
||||
_postBodyBuffer.append("\">(view parent)</a><br />\n");
|
||||
}
|
||||
}
|
||||
|
||||
_postBodyBuffer.append(" </td>\n");
|
||||
@ -487,14 +493,18 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
|
||||
public String getPageURL(Hash blog, String tag, long entryId, String group, int numPerPage, int pageNum, boolean expandEntries, boolean showImages) {
|
||||
StringBuffer buf = new StringBuffer(128);
|
||||
buf.append(_baseURI).append('?');
|
||||
String entry = null;
|
||||
if ( (blog != null) && (entryId > 0) ) {
|
||||
buf.append(PARAM_VIEW_POST).append('=').append(Base64.encode(blog.getData())).append('/').append(entryId).append('&');
|
||||
entry = blog.toBase64() + '/' + entryId;
|
||||
buf.append(PARAM_VIEW_THREAD).append('=').append(entry).append('&');
|
||||
buf.append(PARAM_VISIBLE).append('=').append(Base64.encode(blog.getData())).append('/').append(entryId).append('&');
|
||||
} else if (blog != null) {
|
||||
buf.append(PARAM_AUTHOR).append('=').append(blog.toBase64()).append('&');
|
||||
}
|
||||
if (tag != null)
|
||||
buf.append(PARAM_TAGS).append('=').append(sanitizeTagParam(tag)).append('&');
|
||||
if ( (blog != null) && (entryId > 0) )
|
||||
buf.append("#blog://").append(entry);
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,8 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
req.setCharacterEncoding("UTF-8");
|
||||
resp.setCharacterEncoding("UTF-8");
|
||||
resp.setContentType("text/html;charset=UTF-8");
|
||||
resp.setHeader("cache-control", "no-cache");
|
||||
resp.setHeader("pragma", "no-cache");
|
||||
|
||||
User user = (User)req.getSession().getAttribute("user");
|
||||
String login = req.getParameter("login");
|
||||
@ -490,6 +492,8 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
|
||||
protected void renderBegin(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
||||
out.write("<html>\n<head><title>" + getTitle() + "</title>\n");
|
||||
out.write("<meta http-equiv=\"cache-control\" content=\"no-cache\" />");
|
||||
out.write("<meta http-equiv=\"pragma\" content=\"no-cache\" />");
|
||||
out.write("<style>");
|
||||
out.write(STYLE_HTML);
|
||||
Reader css = null;
|
||||
@ -553,10 +557,11 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
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(ThreadedHTMLRenderer.PARAM_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(ThreadedHTMLRenderer.PARAM_OFFSET); // if we are adjusting the filter, ignore the previous offset
|
||||
SKIP_TAGS.add(ThreadedHTMLRenderer.PARAM_DAYS_BACK);
|
||||
SKIP_TAGS.add("addLocation");
|
||||
SKIP_TAGS.add("addGroup");
|
||||
SKIP_TAGS.add("login");
|
||||
@ -597,6 +602,12 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
PetNameDB db = user.getPetNameDB();
|
||||
TreeSet names = new TreeSet(db.getNames());
|
||||
out.write("<option value=\"\">Any authors</option>\n");
|
||||
if (user.getAuthenticated()) {
|
||||
if ("favorites".equals(author))
|
||||
out.write("<option selected=\"true\" value=\"favorites\">All recent posts by favorite authors</option>\n");
|
||||
else
|
||||
out.write("<option value=\"favorites\">All recent posts by favorite 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");
|
||||
@ -619,6 +630,12 @@ public abstract class BaseServlet extends HttpServlet {
|
||||
out.write("Tags: <input type=\"text\" name=\"" + ThreadedHTMLRenderer.PARAM_TAGS + "\" size=\"10\" value=\"" + tags
|
||||
+ "\" title=\"Threads are filtered to include only ones with posts containing these tags\" />\n");
|
||||
|
||||
String days = req.getParameter(ThreadedHTMLRenderer.PARAM_DAYS_BACK);
|
||||
if (days == null)
|
||||
days = "";
|
||||
out.write("Age: <input type=\"text\" name=\"" + ThreadedHTMLRenderer.PARAM_DAYS_BACK + "\" size=\"2\" value=\"" + days
|
||||
+ "\" title=\"Posts are filtered to include only ones which were made within this many days ago\" /> days\n");
|
||||
|
||||
out.write("<input type=\"submit\" name=\"action\" value=\"Go\" />\n");
|
||||
out.write("</td><td class=\"controlBarRight\" width=\"1%\">");
|
||||
|
||||
|
@ -21,7 +21,7 @@ import net.i2p.syndie.sml.*;
|
||||
public class ViewThreadedServlet extends BaseServlet {
|
||||
protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index,
|
||||
int threadOffset, BlogURI visibleEntry, Archive archive) throws IOException {
|
||||
List posts = getPosts(archive, req, index);
|
||||
List posts = getPosts(user, archive, req, index);
|
||||
renderBody(user, req, out, index, archive, posts);
|
||||
|
||||
renderThreadNav(user, req, out, threadOffset, index);
|
||||
@ -46,8 +46,47 @@ public class ViewThreadedServlet extends BaseServlet {
|
||||
}
|
||||
}
|
||||
|
||||
private List getPosts(Archive archive, HttpServletRequest req, ThreadIndex index) {
|
||||
private List getPosts(User user, Archive archive, HttpServletRequest req, ThreadIndex index) {
|
||||
List rv = new ArrayList(1);
|
||||
String author = req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR);
|
||||
String tags = req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS);
|
||||
if (author != null) {
|
||||
long dayBegin = BlogManager.instance().getDayBegin();
|
||||
String daysStr = req.getParameter(ThreadedHTMLRenderer.PARAM_DAYS_BACK);
|
||||
int days = 1;
|
||||
try {
|
||||
if (daysStr != null)
|
||||
days = Integer.parseInt(daysStr);
|
||||
} catch (NumberFormatException nfe) {
|
||||
days = 1;
|
||||
}
|
||||
dayBegin -= (days-1) * 24*60*60*1000;
|
||||
|
||||
ArchiveIndex aindex = archive.getIndex();
|
||||
PetNameDB db = user.getPetNameDB();
|
||||
if ("favorites".equals(author)) {
|
||||
for (Iterator nameIter = db.getNames().iterator(); nameIter.hasNext(); ) {
|
||||
PetName pn = db.getByName((String)nameIter.next());
|
||||
if (pn.isMember(FilteredThreadIndex.GROUP_FAVORITE) && AddressesServlet.PROTO_BLOG.equals(pn.getProtocol()) ) {
|
||||
Hash loc = new Hash();
|
||||
byte key[] = Base64.decode(pn.getLocation());
|
||||
if ( (key != null) && (key.length == Hash.HASH_LENGTH) ) {
|
||||
loc.setData(key);
|
||||
aindex.selectMatchesOrderByEntryId(rv, loc, tags, dayBegin);
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(rv, BlogURI.COMPARATOR);
|
||||
} else {
|
||||
Hash loc = new Hash();
|
||||
byte key[] = Base64.decode(author);
|
||||
if ( (key != null) && (key.length == Hash.HASH_LENGTH) ) {
|
||||
loc.setData(key);
|
||||
aindex.selectMatchesOrderByEntryId(rv, loc, tags, dayBegin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String post = req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_POST);
|
||||
BlogURI uri = getAsBlogURI(post);
|
||||
if ( (uri != null) && (uri.getEntryId() > 0) ) {
|
||||
|
@ -1,4 +1,9 @@
|
||||
$Id: history.txt,v 1.342 2005/12/03 00:41:25 jrandom Exp $
|
||||
$Id: history.txt,v 1.343 2005/12/03 12:33:35 jrandom Exp $
|
||||
|
||||
2005-12-03 jrandom
|
||||
* Added support for a 'most recent posts' view that CofE requested, which
|
||||
includes the ability to filter by age (e.g. posts by your favorite
|
||||
authors in the last 5 days).
|
||||
|
||||
2005-12-03 jrandom
|
||||
* Adjusted Syndie to use the threaded view that cervantes suggested, which
|
||||
|
Reference in New Issue
Block a user