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) {
|
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();
|
TreeMap ordered = new TreeMap();
|
||||||
for (int i = 0; i < _blogs.size(); i++) {
|
for (int i = 0; i < _blogs.size(); i++) {
|
||||||
BlogSummary summary = (BlogSummary)_blogs.get(i);
|
BlogSummary summary = (BlogSummary)_blogs.get(i);
|
||||||
@ -288,7 +291,7 @@ public class ArchiveIndex {
|
|||||||
if (!blog.equals(summary.blog))
|
if (!blog.equals(summary.blog))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (tag != null) {
|
if ( (tag != null) && (tag.trim().length() > 0) ) {
|
||||||
if (!tag.equals(summary.tag)) {
|
if (!tag.equals(summary.tag)) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Tag [" + summary.tag + "] does not match the requested [" + tag + "] in " + summary.blog.toBase64());
|
_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++) {
|
for (int j = 0; j < summary.entries.size(); j++) {
|
||||||
EntrySummary entry = (EntrySummary)summary.entries.get(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();
|
String k = (Long.MAX_VALUE-entry.entry.getEntryId()) + "-" + entry.entry.getKeyHash().toBase64();
|
||||||
ordered.put(k, entry.entry);
|
ordered.put(k, entry.entry);
|
||||||
//System.err.println("Including match: " + k);
|
//System.err.println("Including match: " + k);
|
||||||
@ -319,6 +324,8 @@ public class ArchiveIndex {
|
|||||||
}
|
}
|
||||||
for (Iterator iter = ordered.values().iterator(); iter.hasNext(); ) {
|
for (Iterator iter = ordered.values().iterator(); iter.hasNext(); ) {
|
||||||
BlogURI entry = (BlogURI)iter.next();
|
BlogURI entry = (BlogURI)iter.next();
|
||||||
|
if (entry.getEntryId() < lowestEntryId)
|
||||||
|
continue;
|
||||||
if (!out.contains(entry))
|
if (!out.contains(entry))
|
||||||
out.add(entry);
|
out.add(entry);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ public class BlogURI {
|
|||||||
private Hash _blogHash;
|
private Hash _blogHash;
|
||||||
private long _entryId;
|
private long _entryId;
|
||||||
|
|
||||||
|
public static final Comparator COMPARATOR = new NewestFirstComparator();
|
||||||
|
|
||||||
public BlogURI() {
|
public BlogURI() {
|
||||||
this(null, -1);
|
this(null, -1);
|
||||||
}
|
}
|
||||||
@ -95,4 +97,20 @@ public class BlogURI {
|
|||||||
if (!u.toString().equals(uri))
|
if (!u.toString().equals(uri))
|
||||||
System.err.println("Not a match: [" + uri + "] != [" + u.toString() + "]");
|
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_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";
|
||||||
|
/** search back through the blog for entries this many days */
|
||||||
|
public static final String PARAM_DAYS_BACK = "daysBack";
|
||||||
// parameters for editing one's profile
|
// parameters for editing one's profile
|
||||||
public static final String PARAM_PROFILE_NAME = "profileName";
|
public static final String PARAM_PROFILE_NAME = "profileName";
|
||||||
public static final String PARAM_PROFILE_DESC = "profileDesc";
|
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);
|
String inReplyTo = (String)_headers.get(HEADER_IN_REPLY_TO);
|
||||||
if ( (inReplyTo != null) && (inReplyTo.trim().length() > 0) ) {
|
if ( (inReplyTo != null) && (inReplyTo.trim().length() > 0) ) {
|
||||||
BlogURI replyURI = new BlogURI(inReplyTo);
|
BlogURI replyURI = new BlogURI(inReplyTo);
|
||||||
if (replyURI.getEntryId() > 0)
|
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");
|
_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");
|
_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) {
|
public String getPageURL(Hash blog, String tag, long entryId, String group, int numPerPage, int pageNum, boolean expandEntries, boolean showImages) {
|
||||||
StringBuffer buf = new StringBuffer(128);
|
StringBuffer buf = new StringBuffer(128);
|
||||||
buf.append(_baseURI).append('?');
|
buf.append(_baseURI).append('?');
|
||||||
|
String entry = null;
|
||||||
if ( (blog != null) && (entryId > 0) ) {
|
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('&');
|
buf.append(PARAM_VISIBLE).append('=').append(Base64.encode(blog.getData())).append('/').append(entryId).append('&');
|
||||||
} else if (blog != null) {
|
} else if (blog != null) {
|
||||||
buf.append(PARAM_AUTHOR).append('=').append(blog.toBase64()).append('&');
|
buf.append(PARAM_AUTHOR).append('=').append(blog.toBase64()).append('&');
|
||||||
}
|
}
|
||||||
if (tag != null)
|
if (tag != null)
|
||||||
buf.append(PARAM_TAGS).append('=').append(sanitizeTagParam(tag)).append('&');
|
buf.append(PARAM_TAGS).append('=').append(sanitizeTagParam(tag)).append('&');
|
||||||
|
if ( (blog != null) && (entryId > 0) )
|
||||||
|
buf.append("#blog://").append(entry);
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,8 @@ public abstract class BaseServlet extends HttpServlet {
|
|||||||
req.setCharacterEncoding("UTF-8");
|
req.setCharacterEncoding("UTF-8");
|
||||||
resp.setCharacterEncoding("UTF-8");
|
resp.setCharacterEncoding("UTF-8");
|
||||||
resp.setContentType("text/html;charset=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");
|
User user = (User)req.getSession().getAttribute("user");
|
||||||
String login = req.getParameter("login");
|
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 {
|
protected void renderBegin(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws IOException {
|
||||||
out.write("<html>\n<head><title>" + getTitle() + "</title>\n");
|
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>");
|
||||||
out.write(STYLE_HTML);
|
out.write(STYLE_HTML);
|
||||||
Reader css = null;
|
Reader css = null;
|
||||||
@ -553,10 +557,11 @@ public abstract class BaseServlet extends HttpServlet {
|
|||||||
SKIP_TAGS.add("filter");
|
SKIP_TAGS.add("filter");
|
||||||
// post and visible are skipped since we aren't good at filtering by tag when the offset will
|
// 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 around randomly. at least, not yet.
|
||||||
SKIP_TAGS.add("visible");
|
SKIP_TAGS.add(ThreadedHTMLRenderer.PARAM_VISIBLE);
|
||||||
//SKIP_TAGS.add("post");
|
//SKIP_TAGS.add("post");
|
||||||
//SKIP_TAGS.add("thread");
|
//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("addLocation");
|
||||||
SKIP_TAGS.add("addGroup");
|
SKIP_TAGS.add("addGroup");
|
||||||
SKIP_TAGS.add("login");
|
SKIP_TAGS.add("login");
|
||||||
@ -597,6 +602,12 @@ public abstract class BaseServlet extends HttpServlet {
|
|||||||
PetNameDB db = user.getPetNameDB();
|
PetNameDB db = user.getPetNameDB();
|
||||||
TreeSet names = new TreeSet(db.getNames());
|
TreeSet names = new TreeSet(db.getNames());
|
||||||
out.write("<option value=\"\">Any authors</option>\n");
|
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 (user.getBlog() != null) {
|
||||||
if ( (author != null) && (author.equals(user.getBlog().toBase64())) )
|
if ( (author != null) && (author.equals(user.getBlog().toBase64())) )
|
||||||
out.write("<option value=\"" + user.getBlog().toBase64() + "\" selected=\"true\">Threads you posted in</option>\n");
|
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
|
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");
|
+ "\" 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("<input type=\"submit\" name=\"action\" value=\"Go\" />\n");
|
||||||
out.write("</td><td class=\"controlBarRight\" width=\"1%\">");
|
out.write("</td><td class=\"controlBarRight\" width=\"1%\">");
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import net.i2p.syndie.sml.*;
|
|||||||
public class ViewThreadedServlet extends BaseServlet {
|
public class ViewThreadedServlet extends BaseServlet {
|
||||||
protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index,
|
protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index,
|
||||||
int threadOffset, BlogURI visibleEntry, Archive archive) throws IOException {
|
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);
|
renderBody(user, req, out, index, archive, posts);
|
||||||
|
|
||||||
renderThreadNav(user, req, out, threadOffset, index);
|
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);
|
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);
|
String post = req.getParameter(ThreadedHTMLRenderer.PARAM_VIEW_POST);
|
||||||
BlogURI uri = getAsBlogURI(post);
|
BlogURI uri = getAsBlogURI(post);
|
||||||
if ( (uri != null) && (uri.getEntryId() > 0) ) {
|
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
|
2005-12-03 jrandom
|
||||||
* Adjusted Syndie to use the threaded view that cervantes suggested, which
|
* Adjusted Syndie to use the threaded view that cervantes suggested, which
|
||||||
|
Reference in New Issue
Block a user