From a4cc18df7615ff9339df52c56a749be088f945ab Mon Sep 17 00:00:00 2001 From: jrandom Date: Sun, 4 Dec 2005 03:18:08 +0000 Subject: [PATCH] 2005-12-03 jrandom * Use newgroup-like tags by default in Syndie's interface --- apps/syndie/java/src/net/i2p/syndie/User.java | 37 ++++++- .../i2p/syndie/sml/ThreadedHTMLRenderer.java | 42 +++++++- .../net/i2p/syndie/web/AddressesServlet.java | 57 +++++++++++ .../src/net/i2p/syndie/web/BaseServlet.java | 97 +++++++++++++++++-- .../src/net/i2p/syndie/web/PostServlet.java | 15 ++- history.txt | 5 +- 6 files changed, 241 insertions(+), 12 deletions(-) diff --git a/apps/syndie/java/src/net/i2p/syndie/User.java b/apps/syndie/java/src/net/i2p/syndie/User.java index 2924bcb73..3892cccc0 100644 --- a/apps/syndie/java/src/net/i2p/syndie/User.java +++ b/apps/syndie/java/src/net/i2p/syndie/User.java @@ -5,7 +5,9 @@ import java.io.IOException; import java.util.*; import net.i2p.I2PAppContext; import net.i2p.client.naming.PetNameDB; +import net.i2p.client.naming.PetName; import net.i2p.data.*; +import net.i2p.syndie.web.AddressesServlet; /** * User session state and preferences. @@ -44,6 +46,14 @@ public class User { private boolean _dataImported; static final String PROP_USERHASH = "__userHash"; + + private static final String DEFAULT_FAVORITE_TAGS[] = { + "syndie", "syndie.tech", "syndie.intro", "syndie.bugs", "syndie.featurerequest", "syndie.announce", + "i2p", "i2p.tech", "i2p.bugs", "i2p.i2phex", "i2p.susimail", "i2p.irc", + "security.misc", + "chat", + "test" + }; /** * Ugly hack to fetch the default User instance - this is the default @@ -99,6 +109,24 @@ public class User { public long getMostRecentEntry() { return _mostRecentEntry; } public Map getBlogGroups() { return _blogGroups; } public List getShitlistedBlogs() { return _shitlistedBlogs; } + public List getFavoriteTags() { + List rv = new ArrayList(); + for (Iterator iter = _petnames.getNames().iterator(); iter.hasNext(); ) { + String name = (String)iter.next(); + PetName pn = _petnames.getByName(name); + if (AddressesServlet.PROTO_TAG.equals(pn.getProtocol())) + rv.add(pn.getLocation()); + } + if (rv.size() <= 0) { + for (int i = 0; i < DEFAULT_FAVORITE_TAGS.length; i++) { + if (!_petnames.containsName(DEFAULT_FAVORITE_TAGS[i])) { + _petnames.add(new PetName(DEFAULT_FAVORITE_TAGS[i], AddressesServlet.NET_SYNDIE, + AddressesServlet.PROTO_TAG, DEFAULT_FAVORITE_TAGS[i])); + } + } + } + return rv; + } public String getAddressbookLocation() { return _addressbookLocation; } public boolean getShowImages() { return _showImagesByDefault; } public boolean getShowExpanded() { return _showExpandedByDefault; } @@ -282,7 +310,7 @@ public class User { // shitlist=hash,hash,hash List shitlistedBlogs = getShitlistedBlogs(); if (shitlistedBlogs.size() > 0) { - buf.setLength(0); + //buf.setLength(0); buf.append("shitlistedblogs="); for (int i = 0; i < shitlistedBlogs.size(); i++) { Hash blog = (Hash)shitlistedBlogs.get(i); @@ -292,6 +320,13 @@ public class User { } buf.append('\n'); } + List favoriteTags = getFavoriteTags(); + if (favoriteTags.size() > 0) { + buf.append("favoritetags="); + for (int i = 0; i < favoriteTags.size(); i++) + buf.append(((String)favoriteTags.get(i)).trim()).append(" "); + buf.append('\n'); + } return buf.toString(); } 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 37b4ac244..baec9ccd2 100644 --- a/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java +++ b/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java @@ -36,6 +36,8 @@ public class ThreadedHTMLRenderer extends HTMLRenderer { 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"; + /** add the specified tag to the favorites list */ + public static final String PARAM_ADD_TAG = "addTag"; /** index into the nav tree to start displaying */ public static final String PARAM_OFFSET = "offset"; public static final String PARAM_TAGS = "tags"; @@ -66,6 +68,32 @@ public class ThreadedHTMLRenderer extends HTMLRenderer { return buf.toString(); } + public static String getAddTagToFavoritesLink(String uri, String tag, String author, String visible, String viewPost, + String viewThread, String offset) { + //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(PARAM_VISIBLE).append('=').append(visible).append('&'); + buf.append(PARAM_ADD_TAG).append('=').append(sanitizeTagParam(tag)).append('&'); + + if (!empty(viewPost)) + buf.append(PARAM_VIEW_POST).append('=').append(viewPost).append('&'); + else if (!empty(viewThread)) + buf.append(PARAM_VIEW_THREAD).append('=').append(viewThread).append('&'); + + if (!empty(offset)) + buf.append(PARAM_OFFSET).append('=').append(offset).append('&'); + + if (!empty(author)) + buf.append(PARAM_AUTHOR).append('=').append(author).append('&'); + + BaseServlet.addAuthActionParams(buf); + return buf.toString(); + } + public static String getNavLink(String uri, String viewPost, String viewThread, String tags, String author, int offset) { StringBuffer buf = new StringBuffer(64); buf.append(uri); @@ -213,6 +241,16 @@ public class ThreadedHTMLRenderer extends HTMLRenderer { out.write("'\">"); out.write(" " + tag); out.write("\n"); + if (user.getAuthenticated() && (!user.getFavoriteTags().contains(tag)) && (!"[none]".equals(tag)) ) { + out.write(""); + out.write("\":)\""); + out.write("\n"); + } } } @@ -297,7 +335,9 @@ public class ThreadedHTMLRenderer extends HTMLRenderer { out.write("\n"); out.write(" \n"); out.write(" \n"); - out.write(" Tags: \n"); + out.write(" Tags: "); + BaseServlet.writeTagField(_user, "", out, "Optional tags to categorize your response", "No tags", false); + // \n"); out.write(" in a new thread? \n"); out.write(" refuse replies? \n"); out.write(" attachment: \n"); diff --git a/apps/syndie/java/src/net/i2p/syndie/web/AddressesServlet.java b/apps/syndie/java/src/net/i2p/syndie/web/AddressesServlet.java index e4792982b..d11843d14 100644 --- a/apps/syndie/java/src/net/i2p/syndie/web/AddressesServlet.java +++ b/apps/syndie/java/src/net/i2p/syndie/web/AddressesServlet.java @@ -28,12 +28,14 @@ public class AddressesServlet extends BaseServlet { public static final String PARAM_NET = "addrNet"; public static final String PARAM_PROTO = "addrProto"; public static final String PARAM_SYNDICATE = "addrSyndicate"; + public static final String PARAM_TAG = "addrTag"; public static final String PARAM_ACTION = "action"; public static final String PROTO_BLOG = "syndieblog"; public static final String PROTO_ARCHIVE = "syndiearchive"; public static final String PROTO_I2PHEX = "i2phex"; public static final String PROTO_EEPSITE = "eep"; + public static final String PROTO_TAG = "syndietag"; public static final String NET_SYNDIE = "syndie"; public static final String NET_I2P = "i2p"; @@ -57,6 +59,10 @@ public class AddressesServlet extends BaseServlet { public static final String ACTION_UPDATE_EEPSITE = "Update eepsite"; public static final String ACTION_ADD_EEPSITE = "Add eepsite"; + public static final String ACTION_DELETE_TAG = "Delete tag"; + public static final String ACTION_UPDATE_TAG = "Update tag"; + public static final String ACTION_ADD_TAG = "Add tag"; + public static final String ACTION_DELETE_OTHER = "Delete address"; public static final String ACTION_UPDATE_OTHER = "Update address"; public static final String ACTION_ADD_OTHER = "Add other address"; @@ -75,6 +81,9 @@ public class AddressesServlet extends BaseServlet { pn = buildNewName(req, PROTO_ARCHIVE); _log.debug("pn for protoArchive [" + req.getParameter(PARAM_PROTO) + "]: " + pn); renderArchives(user, db, uri, pn, out); + pn = buildNewName(req, PROTO_TAG); + _log.debug("pn for protoTag [" + req.getParameter(PARAM_TAG) + "]: " + pn); + renderTags(user, db, uri, pn, out); pn = buildNewName(req, PROTO_I2PHEX); _log.debug("pn for protoPhex [" + req.getParameter(PARAM_PROTO) + "]: " + pn); renderI2Phex(user, db, uri, pn, out); @@ -329,6 +338,53 @@ public class AddressesServlet extends BaseServlet { out.write("
\n"); } + + private void renderTags(User user, PetNameDB db, String baseURI, PetName newName, PrintWriter out) throws IOException { + TreeSet names = new TreeSet(); + for (Iterator iter = db.getNames().iterator(); iter.hasNext(); ) { + String name = (String)iter.next(); + PetName pn = db.getByName(name); + if (PROTO_TAG.equals(pn.getProtocol())) + names.add(name); + } + out.write("Favorite tags\n"); + + for (Iterator iter = names.iterator(); iter.hasNext(); ) { + PetName pn = db.getByName((String)iter.next()); + out.write("
"); + writeAuthActionFields(out); + out.write(""); + out.write(""); + out.write(""); + out.write("\n"); + out.write("Name: " + pn.getName() + " "); + out.write(" "); + + out.write(" "); + out.write("\n"); + out.write("
\n"); + } + + out.write("
"); + writeAuthActionFields(out); + out.write(""); + out.write(""); + out.write(""); + out.write("\n"); + out.write("Name: "); + + out.write(" "); + out.write("\n"); + out.write("
\n"); + + out.write("
\n"); + } + private void renderOther(User user, PetNameDB db, String baseURI, PetName newName, PrintWriter out) throws IOException { TreeSet names = new TreeSet(); for (Iterator iter = db.getNames().iterator(); iter.hasNext(); ) { @@ -429,6 +485,7 @@ public class AddressesServlet extends BaseServlet { if (PROTO_ARCHIVE.equals(reqProto) || PROTO_BLOG.equals(reqProto) || PROTO_EEPSITE.equals(reqProto) || + PROTO_TAG.equals(reqProto) || PROTO_I2PHEX.equals(reqProto)) return false; else // its something other than the four default types 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 8c32847c5..608d09456 100644 --- a/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java +++ b/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java @@ -64,12 +64,12 @@ public abstract class BaseServlet extends HttpServlet { * key=value& of params that need to be tacked onto an http request that updates data, to * prevent spoofing */ - protected String getAuthActionParams() { return PARAM_AUTH_ACTION + '=' + _authNonce + '&'; } + protected static String getAuthActionParams() { return PARAM_AUTH_ACTION + '=' + _authNonce + '&'; } /** * key=value& of params that need to be tacked onto an http request that updates data, to * prevent spoofing */ - protected void addAuthActionParams(StringBuffer buf) { + public static void addAuthActionParams(StringBuffer buf) { buf.append(PARAM_AUTH_ACTION).append('=').append(_authNonce).append('&'); } @@ -139,6 +139,7 @@ public abstract class BaseServlet extends HttpServlet { forceNewIndex = handleAddressbook(user, req) || forceNewIndex; forceNewIndex = handleBookmarking(user, req) || forceNewIndex; + forceNewIndex = handleManageTags(user, req) || forceNewIndex; handleUpdateProfile(user, req); } @@ -240,6 +241,35 @@ public abstract class BaseServlet extends HttpServlet { return rv; } + private boolean handleManageTags(User user, HttpServletRequest req) { + if (!user.getAuthenticated()) + return false; + + boolean rv = false; + + String tag = req.getParameter(ThreadedHTMLRenderer.PARAM_ADD_TAG); + if ( (tag != null) && (tag.trim().length() > 0) ) { + tag = HTMLRenderer.sanitizeString(tag, false); + String name = tag; + PetNameDB db = user.getPetNameDB(); + PetName pn = db.getByLocation(tag); + if (pn == null) { + if (db.containsName(name)) { + int i = 0; + while (db.containsName(name + i)) + i++; + name = tag + i; + } + + pn = new PetName(name, AddressesServlet.NET_SYNDIE, AddressesServlet.PROTO_TAG, tag); + db.add(pn); + BlogManager.instance().saveUser(user); + } + } + + return false; + } + private boolean handleAddressbook(User user, HttpServletRequest req) { if ( (!user.getAuthenticated()) || (empty(AddressesServlet.PARAM_ACTION)) ) { return false; @@ -247,7 +277,15 @@ public abstract class BaseServlet extends HttpServlet { String action = req.getParameter(AddressesServlet.PARAM_ACTION); - if ( (AddressesServlet.ACTION_ADD_ARCHIVE.equals(action)) || + if (AddressesServlet.ACTION_ADD_TAG.equals(action)) { + String name = req.getParameter(AddressesServlet.PARAM_NAME); + if (!user.getPetNameDB().containsName(name)) { + PetName pn = new PetName(name, AddressesServlet.NET_SYNDIE, AddressesServlet.PROTO_TAG, name); + user.getPetNameDB().add(pn); + BlogManager.instance().saveUser(user); + } + return false; + } else if ( (AddressesServlet.ACTION_ADD_ARCHIVE.equals(action)) || (AddressesServlet.ACTION_ADD_BLOG.equals(action)) || (AddressesServlet.ACTION_ADD_EEPSITE.equals(action)) || (AddressesServlet.ACTION_ADD_OTHER.equals(action)) || @@ -279,6 +317,7 @@ public abstract class BaseServlet extends HttpServlet { (AddressesServlet.ACTION_DELETE_BLOG.equals(action)) || (AddressesServlet.ACTION_DELETE_EEPSITE.equals(action)) || (AddressesServlet.ACTION_DELETE_OTHER.equals(action)) || + (AddressesServlet.ACTION_DELETE_TAG.equals(action)) || (AddressesServlet.ACTION_DELETE_PEER.equals(action)) ) { PetName pn = user.getPetNameDB().getByName(req.getParameter(AddressesServlet.PARAM_NAME)); if (pn != null) { @@ -525,7 +564,7 @@ public abstract class BaseServlet extends HttpServlet { out.write(user.getUsername()); out.write("\n"); out.write("(switch)\n"); - out.write("Post a new thread\n"); + out.write("Post\n"); out.write("Addressbook\n"); } else { out.write("
\n"); @@ -627,8 +666,8 @@ public abstract class BaseServlet extends HttpServlet { } out.write("\n"); - out.write("Tags: \n"); + out.write("Tags: "); + writeTagField(user, tags, out); String days = req.getParameter(ThreadedHTMLRenderer.PARAM_DAYS_BACK); if (days == null) @@ -647,6 +686,52 @@ public abstract class BaseServlet extends HttpServlet { out.write("\n"); out.write("
\n"); } + + protected void writeTagField(User user, String selectedTags, PrintWriter out) throws IOException { + writeTagField(user, selectedTags, out, "Threads are filtered to include only ones with posts containing these tags", "Any tags - no filtering", true); + } + public static void writeTagField(User user, String selectedTags, Writer out, String title, String blankTitle, boolean includeFavoritesTag) throws IOException { + Set favoriteTags = new TreeSet(user.getFavoriteTags()); + if (favoriteTags.size() <= 0) { + out.write("\n"); + } else { + out.write("\n"); + } + } protected abstract void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index, int threadOffset, BlogURI visibleEntry, diff --git a/apps/syndie/java/src/net/i2p/syndie/web/PostServlet.java b/apps/syndie/java/src/net/i2p/syndie/web/PostServlet.java index b063b4d90..2e36dfb19 100644 --- a/apps/syndie/java/src/net/i2p/syndie/web/PostServlet.java +++ b/apps/syndie/java/src/net/i2p/syndie/web/PostServlet.java @@ -27,7 +27,7 @@ public class PostServlet extends BaseServlet { public static final String ACTION_CONFIRM = "confirm"; public static final String PARAM_SUBJECT = "entrysubject"; - public static final String PARAM_TAGS = "entrytags"; + public static final String PARAM_TAGS = ThreadedHTMLRenderer.PARAM_TAGS; public static final String PARAM_INCLUDENAMES = "includenames"; public static final String PARAM_TEXT = "entrytext"; public static final String PARAM_HEADERS = "entryheaders"; @@ -104,6 +104,8 @@ public class PostServlet extends BaseServlet { } } + if (entryTags == null) entryTags = ""; + if ( (entryHeaders == null) || (entryHeaders.trim().length() <= 0) ) entryHeaders = ThreadedHTMLRenderer.HEADER_FORCE_NEW_THREAD + ": " + inNewThread + '\n' + ThreadedHTMLRenderer.HEADER_REFUSE_REPLIES + ": " + refuseReplies; @@ -223,7 +225,10 @@ public class PostServlet extends BaseServlet { if ( (parentURI != null) && (parentURI.trim().length() > 0) ) out.write("\n"); - out.write(" Tags:
\n"); + out.write(" Tags: "); + BaseServlet.writeTagField(user, getParam(req, PARAM_TAGS), out, "Optional tags to categorize your post", "No tags", false); + //
\n"); + out.write("
\n"); boolean inNewThread = getInNewThread(req); boolean refuseReplies = getRefuseReplies(req); @@ -276,7 +281,11 @@ public class PostServlet extends BaseServlet { if ( (parentURI != null) && (parentURI.trim().length() > 0) ) out.write("\n"); - out.write(" Tags:
\n"); + out.write(" Tags: "); + //
\n"); + out.write(" Tags: "); + BaseServlet.writeTagField(user, getParam(req, PARAM_TAGS), out, "Optional tags to categorize your post", "No tags", false); + out.write("
\n"); boolean inNewThread = getInNewThread(req); boolean refuseReplies = getRefuseReplies(req); diff --git a/history.txt b/history.txt index 6dbcd4af3..0baa03722 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,7 @@ -$Id: history.txt,v 1.343 2005/12/03 12:33:35 jrandom Exp $ +$Id: history.txt,v 1.344 2005/12/03 14:03:46 jrandom Exp $ + +2005-12-03 jrandom + * Use newgroup-like tags by default in Syndie's interface 2005-12-03 jrandom * Added support for a 'most recent posts' view that CofE requested, which