2005-01-09 jrandom

* Bugfix for a rare SSU error (thanks cervantes!)
    * More progress on the blog interface, allowing customizable blog-wide
      links.
This commit is contained in:
jrandom
2006-01-09 06:33:29 +00:00
committed by zzz
parent 66e6dbec33
commit 1ca27ffd39
11 changed files with 462 additions and 182 deletions

View File

@ -102,6 +102,7 @@ public class BlogInfoData {
prevGroup = pn.getGroup(0);
}
}
line.setLength(0);
if (!ok)
break;
}

View File

@ -61,6 +61,8 @@ public class FilteredThreadIndex extends ThreadIndex {
}
private boolean isIgnored(ThreadNode node, List ignoredAuthors, Collection requestedTags, Collection filteredAuthors, boolean filterAuthorsByRoot) {
if (node.getTags().contains(BlogInfoData.TAG))
return true; // its a fake post, containing some updated metadata for the blog
if (filteredAuthors.size() <= 0) {
boolean allAuthorsIgnored = true;
for (Iterator iter = node.getRecursiveAuthorIterator(); iter.hasNext(); ) {

View File

@ -1102,7 +1102,7 @@ public class HTMLRenderer extends EventReceiverImpl {
+ "&" + SyndicateServlet.PARAM_SCHEMA + "=" + sanitizeTagParam(archiveLocation.getSchema())
+ "&" + SyndicateServlet.PARAM_LOCATION + "=" + sanitizeTagParam(archiveLocation.getLocation());
}
public String getBookmarkURL(String name, String location, String schema, String protocol) {
public static String getBookmarkURL(String name, String location, String schema, String protocol) {
return "addresses.jsp?" + AddressesServlet.PARAM_NAME + '=' + sanitizeTagParam(name)
+ "&" + AddressesServlet.PARAM_NET + '=' + sanitizeTagParam(schema)
+ "&" + AddressesServlet.PARAM_PROTO + '=' + sanitizeTagParam(protocol)

View File

@ -23,7 +23,7 @@ import net.i2p.util.Log;
*/
public abstract class BaseServlet extends HttpServlet {
protected static final String PARAM_AUTH_ACTION = "syndie.auth";
private static long _authNonce;
protected static long _authNonce;
protected I2PAppContext _context;
protected Log _log;
@ -141,6 +141,7 @@ public abstract class BaseServlet extends HttpServlet {
forceNewIndex = handleBookmarking(user, req) || forceNewIndex;
forceNewIndex = handleManageTags(user, req) || forceNewIndex;
handleUpdateProfile(user, req);
req.setAttribute(BaseServlet.class.getName() + ".auth", "true");
}
// the 'dataImported' flag is set by successful fetches in the SyndicateServlet/RemoteArchiveBean
@ -176,6 +177,10 @@ public abstract class BaseServlet extends HttpServlet {
protected void render(User user, HttpServletRequest req, HttpServletResponse resp, ThreadIndex index) throws IOException, ServletException {
render(user, req, resp.getWriter(), index);
}
protected boolean isAuthed(HttpServletRequest req) {
String auth = (String)req.getAttribute(BaseServlet.class.getName() + ".auth");
return (auth != null) && (Boolean.valueOf(auth).booleanValue());
}
private boolean handleBookmarking(User user, HttpServletRequest req) {
if (!user.getAuthenticated())

View File

@ -33,6 +33,8 @@ public class BlogConfigBean {
_styleOverrides = new Properties();
}
public boolean isUpdated() { return _updated; }
public User getUser() { return _user; }
public void setUser(User user) {
_user = user;
@ -74,6 +76,8 @@ public class BlogConfigBean {
PetName pn = (PetName)grp.get(0);
if ( (pn.getGroupCount() == 0) && ( (name == null) || (name.length() <= 0) ) )
return grp;
if (pn.getGroupCount() == 0)
continue;
String curGroup = pn.getGroup(0);
if (curGroup.equals(name))
return grp;
@ -94,6 +98,7 @@ public class BlogConfigBean {
} else {
group.add(pn);
}
_updated = true;
}
public void remove(PetName pn) {
String groupName = null;
@ -105,6 +110,7 @@ public class BlogConfigBean {
if (group.size() <= 0)
_groups.remove(group);
}
_updated = true;
}
public void remove(String name) {
for (int i = 0; i < getGroupCount(); i++) {
@ -115,6 +121,7 @@ public class BlogConfigBean {
group.remove(j);
if (group.size() <= 0)
_groups.remove(group);
_updated = true;
return;
}
}
@ -140,7 +147,7 @@ public class BlogConfigBean {
_logo = logo;
_updated = true;
}
public boolean hasPendingChanges() { return _updated; }
public boolean hasPendingChanges() { return _loaded && _updated; }
private void load() {
Archive archive = BlogManager.instance().getArchive();
@ -175,7 +182,9 @@ public class BlogConfigBean {
add(pn);
}
}
_styleOverrides.putAll(data.getStyleOverrides());
Properties overrides = data.getStyleOverrides();
if (overrides != null)
_styleOverrides.putAll(overrides);
} catch (IOException ioe) {
_log.warn("Unable to load the blog info data from " + uri, ioe);
}
@ -183,9 +192,10 @@ public class BlogConfigBean {
}
}
_loaded = true;
_updated = false;
}
public boolean publishChanges() throws IOException {
public boolean publishChanges() {
FileInputStream logo = null;
try {
if (_logo != null)
@ -229,6 +239,7 @@ public class BlogConfigBean {
if (updated) {
// ok great, published locally, though should we push it to others?
_log.info("Blog summary updated for " + _user + " in " + uri.toString());
setUser(_user);
return true;
}
} else {
@ -239,6 +250,8 @@ public class BlogConfigBean {
_log.error("Error creating the summary entry");
return false;
}
} catch (IOException ioe) {
_log.error("Error publishing", ioe);
} finally {
if (logo != null) try { logo.close(); } catch (IOException ioe) {}
// the other streams are in-memory, drop with the scope

View File

@ -22,8 +22,8 @@ import net.i2p.syndie.sml.*;
public class BlogConfigServlet extends BaseServlet {
private static final String ATTR_CONFIG_BEAN = "__blogConfigBean";
public static final String PARAM_CONFIG_SCREEN = "screen";
public static final String SCREEN_GENERAL = "general";
public static final String SCREEN_REFERENCES = "references";
public static final String SCREEN_IMAGES = "images";
protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index,
int threadOffset, BlogURI visibleEntry, Archive archive) throws IOException {
if ( (user == null) || (!user.getAuthenticated() && !BlogManager.instance().isSingleUser())) {
@ -34,6 +34,7 @@ public class BlogConfigServlet extends BaseServlet {
if (bean == null) {
bean = new BlogConfigBean();
bean.setUser(user);
req.getSession().setAttribute(ATTR_CONFIG_BEAN, bean);
}
// handle actions here...
@ -41,191 +42,329 @@ public class BlogConfigServlet extends BaseServlet {
String screen = req.getParameter(PARAM_CONFIG_SCREEN);
if (screen == null)
screen = SCREEN_GENERAL;
out.write("todo: Display screen " + screen);
/*
if (SCREEN_REFERENCES.equals(screen)) {
displayReferencesScreen(req, out, bean);
screen = SCREEN_REFERENCES;
out.write("<tr><td colspan=\"3\">\n");
showConfigNav(req, out);
if (isAuthed(req)) {
StringBuffer buf = handleOtherAuthedActions(user, req, bean);
if (buf != null) out.write(buf.toString());
} else {
displayGeneralScreen(req, out, bean);
}
*/
}
/*
private void renderMyProfile(User user, String baseURI, PrintWriter out, Archive archive) throws IOException {
BlogInfo info = archive.getBlogInfo(user.getBlog());
if (info == null)
return;
if (bean.isUpdated())
showCommitForm(req, out);
out.write("<!-- " + info.toString() + "-->\n");
out.write("<form action=\"" + baseURI + "\" method=\"POST\">\n");
if (SCREEN_REFERENCES.equals(screen)) {
displayReferencesScreen(req, out, user, bean);
} else {
displayUnknownScreen(out, screen);
}
out.write("</td></tr>\n");
}
private void showCommitForm(HttpServletRequest req, PrintWriter out) throws IOException {
out.write("<form action=\"" + req.getRequestURI() + "\" method=\"GET\">\n");
writeAuthActionFields(out);
// now add the form to update
out.write("<tr><td colspan=\"3\">Your profile</td></tr>\n");
out.write("<tr><td colspan=\"3\">Name: <input type=\"text\" name=\""
+ ThreadedHTMLRenderer.PARAM_PROFILE_NAME + "\" value=\""
+ HTMLRenderer.sanitizeTagParam(info.getProperty(BlogInfo.NAME)) + "\"></td></tr>\n");
out.write("<tr><td colspan=\"3\">Account description: <input type=\"text\" name=\""
+ ThreadedHTMLRenderer.PARAM_PROFILE_DESC + "\" value=\""
+ HTMLRenderer.sanitizeTagParam(info.getProperty(BlogInfo.DESCRIPTION)) + "\"></td></tr>\n");
out.write("<tr><td colspan=\"3\">Contact information: <input type=\"text\" name=\""
+ ThreadedHTMLRenderer.PARAM_PROFILE_URL + "\" value=\""
+ HTMLRenderer.sanitizeTagParam(info.getProperty(BlogInfo.CONTACT_URL)) + "\"></td></tr>\n");
out.write("<tr><td colspan=\"3\">Other attributes:<br /><textarea rows=\"3\" name=\""
+ ThreadedHTMLRenderer.PARAM_PROFILE_OTHER + "\" cols=\"60\">");
String props[] = info.getProperties();
if (props != null) {
for (int i = 0; i < props.length; i++) {
if (!BlogInfo.NAME.equals(props[i]) &&
!BlogInfo.DESCRIPTION.equals(props[i]) &&
!BlogInfo.EDITION.equals(props[i]) &&
!BlogInfo.OWNER_KEY.equals(props[i]) &&
!BlogInfo.POSTERS.equals(props[i]) &&
!BlogInfo.SIGNATURE.equals(props[i]) &&
!BlogInfo.CONTACT_URL.equals(props[i])) {
out.write(HTMLRenderer.sanitizeString(props[i], false) + ": "
+ HTMLRenderer.sanitizeString(info.getProperty(props[i]), false) + "\n");
}
}
}
out.write("</textarea></td></tr>\n");
if (user.getAuthenticated()) {
if ( (user.getUsername() == null) || (user.getUsername().equals(BlogManager.instance().getDefaultLogin())) ) {
// this is the default user, don't let them change the password
out.write("<i>Note: Uncommitted changes outstanding</a> <input type=\"submit\" name=\"action\" " +
"value=\"Publish blog configuration\" />\n</form>\n");
}
private void showConfigNav(HttpServletRequest req, PrintWriter out) throws IOException {
out.write("<span class=\"syndieBlogConfigNav\"><a href=\"" + getScreenURL(req, SCREEN_REFERENCES, false)
+ "\" title=\"Configure the blog's references\">References</a> "
+ "<a href=\"" + getScreenURL(req, SCREEN_IMAGES, false)
+ "\" title=\"Configure the images used on the blog\">Images</a></span><hr />\n");
}
private String getScreenURL(HttpServletRequest req, String screen, boolean wantAuth) {
StringBuffer buf = new StringBuffer(128);
buf.append(req.getRequestURI()).append("?").append(PARAM_CONFIG_SCREEN).append("=");
buf.append(screen).append("&amp;");
if (wantAuth)
buf.append(PARAM_AUTH_ACTION).append('=').append(_authNonce).append("&amp;");
return buf.toString();
}
private void displayUnknownScreen(PrintWriter out, String screen) throws IOException {
out.write("<br /><hr />The screen " + HTMLRenderer.sanitizeString(screen) + " has not yet been implemented");
}
private void displayReferencesScreen(HttpServletRequest req, PrintWriter out, User user, BlogConfigBean bean) throws IOException {
out.write("<form action=\"" + getScreenURL(req, SCREEN_REFERENCES, false) + "\" method=\"POST\">\n");
writeAuthActionFields(out);
out.write("<ol class=\"syndieReferenceGroupList\">\n");
boolean defaultFound = false;
for (int i = 0; i < bean.getGroupCount(); i++) {
List group = bean.getGroup(i);
String groupName = null;
PetName pn = (PetName)group.get(0);
if (pn.getGroupCount() <= 0) {
groupName = ViewBlogServlet.DEFAULT_GROUP_NAME;
defaultFound = true;
} else {
out.write("<tr><td colspan=\"3\">Old Password: <input type=\"password\" name=\"oldPassword\" /></td></tr>\n");
out.write("<tr><td colspan=\"3\">Password: <input type=\"password\" name=\"password\" /></td></tr>\n");
out.write("<tr><td colspan=\"3\">Password again: <input type=\"password\" name=\"passwordConfirm\" /></td></tr>\n");
groupName = pn.getGroup(0);
}
if (!BlogManager.instance().authorizeRemote(user)) {
out.write("<tr><td colspan=\"3\">To access the remote functionality, please specify the administrative password: <br />\n" +
"<input type=\"password\" name=\"adminPass\" /></td></tr>\n");
out.write("<li><b>Group:</b> " + HTMLRenderer.sanitizeString(groupName) + "\n");
if (i > 0)
out.write(" <a href=\"" + getScreenURL(req, SCREEN_REFERENCES, true) + "moveFrom=" + i +
"&amp;moveTo=" + (i-1) + "\" title=\"Move higher\">^</a>");
if (i + 1 < bean.getGroupCount())
out.write(" <a href=\"" + getScreenURL(req, SCREEN_REFERENCES, true) + "moveFrom=" + i +
"&amp;moveTo=" + (i+1) + "\" title=\"Move lower\">v</a>");
out.write(" <a href=\"" + getScreenURL(req, SCREEN_REFERENCES, true) + "delete=" + i + "\" title=\"Delete\">X</a>");
out.write("<ol class=\"syndieReferenceGroupElementList\">\n");
for (int j = 0; j < group.size(); j++) {
out.write("<li>" + ViewBlogServlet.renderLink(user.getBlog(), (PetName)group.get(j)));
if (j > 0)
out.write(" <a href=\"" + getScreenURL(req, SCREEN_REFERENCES, true) + "moveRefFrom=" + i + "." + j +
"&amp;moveRefTo=" + i + "." + (j-1) + "\" title=\"Move higher\">^</a>");
if (j + 1 < group.size())
out.write(" <a href=\"" + getScreenURL(req, SCREEN_REFERENCES, true) + "moveRefFrom=" + i + "." + j +
"&amp;moveRefTo=" + i + "." + (j+1) + "\" title=\"Move lower\">v</a>");
out.write(" <a href=\"" + getScreenURL(req, SCREEN_REFERENCES, true) + "delete=" + i + "." + j
+ "\" title=\"Delete\">X</a>");
out.write("</li>\n");
}
out.write("</ol><!-- end of the syndieReferenceGroupElementList -->\n");
out.write("</li>\n");
}
out.write("</ol><!-- end of the syndieReferenceGroupList -->\n");
out.write("<tr><td colspan=\"3\"><input type=\"submit\" name=\"action\" value=\"Update profile\" /></td></tr>\n");
out.write("Add a new element: <br />Group: <select name=\"new.group\"><option value=\"\">Select a group...</option>");
for (int i = 0; i < bean.getGroupCount(); i++) {
List group = bean.getGroup(i);
String groupName = null;
PetName pn = (PetName)group.get(0);
if (pn.getGroupCount() <= 0)
groupName = ViewBlogServlet.DEFAULT_GROUP_NAME;
else
groupName = pn.getGroup(0);
if (groupName != null)
out.write("<option value=\"" + HTMLRenderer.sanitizeTagParam(groupName) + "\">" +
HTMLRenderer.sanitizeString(groupName) + "</option>\n");
}
if (!defaultFound)
out.write("<option value=\"" + ViewBlogServlet.DEFAULT_GROUP_NAME + "\">"
+ ViewBlogServlet.DEFAULT_GROUP_NAME + "</option>\n");
out.write("</select> or <input type=\"text\" size=\"12\" name=\"new.groupOther\" /><br />" +
"Type: <select name=\"new.type\"><option value=\"blog\">Syndie blog</option>\n" +
"<option value=\"blogpost\">Post within a syndie blog</option>\n" +
"<option value=\"blogpostattachment\">Attachment within a syndie blog</option>\n" +
"<option value=\"eepsite\">Eepsite</option>\n" +
"<option value=\"website\">Website</option>\n</select><br />\n" +
"Name: <input type=\"text\" size=\"20\" name=\"new.name\" /><br /> " +
"Location: <input type=\"text\" name=\"new.location\" size=\"40\" />\n" +
"<ul><li>Blogs should be specified as <code>$base64Key</code></li>\n" +
"<li>Blog posts should be specified as <code>$base64Key/$postEntryId</code></li>\n" +
"<li>Blog post attachments should be specified as <code>$base64Key/$postEntryId/$attachmentNum</code></li>\n" +
"</ul><hr />\n");
out.write("<input type=\"submit\" name=\"action\" value=\"Save changes\">\n");
out.write("</form>\n");
}
private void renderProfile(User user, String baseURI, PrintWriter out, Hash author, Archive archive) throws IOException {
out.write("<tr><td colspan=\"3\">Profile for ");
PetName pn = user.getPetNameDB().getByLocation(author.toBase64());
String name = null;
BlogInfo info = archive.getBlogInfo(author);
private void writePetnameDropdown(PrintWriter out, PetNameDB db) throws IOException {
Set names = db.getNames();
TreeSet ordered = new TreeSet(names);
for (Iterator iter = ordered.iterator(); iter.hasNext(); ) {
String name = (String)iter.next();
PetName pn = db.getByName(name);
String proto = pn.getProtocol();
if ("syndietag".equals(proto))
continue;
out.write("<option value=\"" + HTMLRenderer.sanitizeTagParam(pn.getName()) + "\">");
if ("syndieblog".equals(proto))
out.write("Blog: ");
else if ("syndiearchive".equals(proto))
out.write("Archive: ");
else if ("eep".equals(proto))
out.write("Eepsite: ");
else
out.write(HTMLRenderer.sanitizeString(proto) + ": ");
out.write(HTMLRenderer.sanitizeString(pn.getName()) + "</option>\n");
}
}
protected StringBuffer handleOtherAuthedActions(User user, HttpServletRequest req, BlogConfigBean bean) {
StringBuffer buf = new StringBuffer();
req.setAttribute(getClass().getName() + ".output", buf);
String action = req.getParameter("action");
if ("Publish blog configuration".equals(action)) {
if (bean.publishChanges()) {
buf.append("Changes published<br />\n");
} else {
buf.append("Changes could not be published (please check the log)<br />\n");
}
} else {
if ("Save changes".equals(action)) {
String newGroup = req.getParameter("new.group");
if ( (newGroup == null) || (newGroup.trim().length() <= 0) )
newGroup = req.getParameter("new.groupOther");
if ( (newGroup != null) && (newGroup.trim().length() > 0) ) {
addElement(req, user, newGroup, buf, bean);
} else {
}
} else {
}
handleDelete(req, user, bean, buf);
handleReorderGroup(req, user, bean, buf);
handleReorderRef(req, user, bean, buf);
}
return buf;
}
private void addElement(HttpServletRequest req, User user, String newGroup, StringBuffer actionOutputHTML, BlogConfigBean bean) {
String type = req.getParameter("new.type");
String loc = req.getParameter("new.location");
String name = req.getParameter("new.name");
if (empty(type) || empty(loc) || empty(name)) return;
PetName pn = null;
if ("blog".equals(type))
pn = new PetName(name, "syndie", "syndieblog", loc);
else if ("blogpost".equals(type))
pn = new PetName(name, "syndie", "syndieblogpost", loc);
else if ("blogpostattachment".equals(type))
pn = new PetName(name, "syndie", "syndieblogattachment", loc);
else if ("eepsite".equals(type))
pn = new PetName(name, "i2p", "http", loc);
else if ("website".equals(type))
pn = new PetName(name, "web", "http", loc);
else {
// unknown type
}
if (pn != null) {
out.write(pn.getName());
name = null;
if (info != null)
name = info.getProperty(BlogInfo.NAME);
if ( (name == null) || (name.trim().length() <= 0) )
name = author.toBase64().substring(0, 6);
out.write(" (" + name + ")");
} else {
if (info != null)
name = info.getProperty(BlogInfo.NAME);
if ( (name == null) || (name.trim().length() <= 0) )
name = author.toBase64().substring(0, 6);
out.write(name);
if (!ViewBlogServlet.DEFAULT_GROUP_NAME.equals(newGroup))
pn.addGroup(newGroup);
bean.add(pn);
actionOutputHTML.append("Reference '").append(HTMLRenderer.sanitizeString(name));
actionOutputHTML.append("' for ").append(HTMLRenderer.sanitizeString(loc)).append(" added to ");
actionOutputHTML.append(HTMLRenderer.sanitizeString(newGroup)).append("<br />\n");
}
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");
if (pn == null) {
out.write("<tr><td colspan=\"3\">Not currently bookmarked. Add them to your ");
String addFav = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_FAVORITE,
baseURI, "", "", "", "", "", author.toBase64());
String addIgnore = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_IGNORE,
baseURI, "", "", "", "", "", author.toBase64());
out.write("<a href=\"" + addFav + "\" title=\"Threads by favorite authors are shown specially\">favorites</a> or ");
out.write("<a href=\"" + addIgnore + "\" title=\"Threads by ignored authors are hidden from view\">ignored</a> ");
out.write("</td></tr>\n");
} else if (pn.isMember(FilteredThreadIndex.GROUP_IGNORE)) {
out.write("<tr><td colspan=\"3\">Currently ignored - threads they create are hidden.</td></tr>\n");
String remIgnore = getRemoveFromGroupLink(user, pn.getName(), FilteredThreadIndex.GROUP_IGNORE,
baseURI, "", "", "", "", "", author.toBase64());
out.write("<tr><td colspan=\"3\"><a href=\"" + remIgnore + "\">Unignore " + pn.getName() + "</a></td></tr>\n");
String remCompletely = getRemoveFromGroupLink(user, pn.getName(), "",
baseURI, "", "", "", "", "", author.toBase64());
out.write("<tr><td colspan=\"3\"><a href=\"" + remCompletely + "\">Forget about " + pn.getName() + " entirely</a></td></tr>\n");
} else if (pn.isMember(FilteredThreadIndex.GROUP_FAVORITE)) {
out.write("<tr><td colspan=\"3\">Currently marked as a favorite author - threads they participate in " +
"are highlighted.</td></tr>\n");
String remIgnore = getRemoveFromGroupLink(user, pn.getName(), FilteredThreadIndex.GROUP_FAVORITE,
baseURI, "", "", "", "", "", author.toBase64());
out.write("<tr><td colspan=\"3\"><a href=\"" + remIgnore + "\">Remove " + pn.getName() + " from the list of favorite authors</a></td></tr>\n");
String addIgnore = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_IGNORE,
baseURI, "", "", "", "", "", author.toBase64());
out.write("<tr><td colspan=\"3\"><a href=\"" + addIgnore + "\" title=\"Threads by ignored authors are hidden from view\">Ignore the author</a></td></tr>");
String remCompletely = getRemoveFromGroupLink(user, pn.getName(), "",
baseURI, "", "", "", "", "", author.toBase64());
out.write("<tr><td colspan=\"3\"><a href=\"" + remCompletely + "\">Forget about " + pn.getName() + " entirely</a></td></tr>\n");
}
private void handleDelete(HttpServletRequest req, User user, BlogConfigBean bean, StringBuffer actionOutputHTML) {
// control parameters:
// delete=$i removes group # $i
// delete=$i.$j removes element $j in group $i
String del = req.getParameter("delete");
if (empty(del)) return;
int split = del.indexOf('.');
int group = -1;
int elem = -1;
if (split <= 0) {
try { group = Integer.parseInt(del); } catch (NumberFormatException nfe) {}
} else {
out.write("<tr><td colspan=\"3\">Currently bookmarked. Add them to your ");
String addFav = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_FAVORITE,
baseURI, "", "", "", "", "", author.toBase64());
String addIgnore = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_IGNORE,
baseURI, "", "", "", "", "", author.toBase64());
out.write("<a href=\"" + addFav + "\" title=\"Threads by favorite authors are shown specially\">favorites</a> or ");
out.write("<a href=\"" + addIgnore + "\" title=\"Threads by ignored authors are hidden from view\">ignored</a> list</td></tr>");
String remCompletely = getRemoveFromGroupLink(user, pn.getName(), "",
baseURI, "", "", "", "", "", author.toBase64());
out.write("<tr><td colspan=\"3\"><a href=\"" + remCompletely + "\">Forget about " + pn.getName() + " entirely</a></td></tr>\n");
try {
group = Integer.parseInt(del.substring(0, split));
elem = Integer.parseInt(del.substring(split+1));
} catch (NumberFormatException nfe) {
group = -1;
elem = -1;
}
}
if (info != null) {
String descr = info.getProperty(BlogInfo.DESCRIPTION);
if ( (descr != null) && (descr.trim().length() > 0) )
out.write("<tr><td colspan=\"3\">Account description: " + HTMLRenderer.sanitizeString(descr) + "</td></tr>\n");
if ( (elem >= 0) && (group >= 0) ) {
List l = bean.getGroup(group);
if (elem < l.size()) {
PetName pn = (PetName)l.get(elem);
bean.remove(pn);
actionOutputHTML.append("Reference '").append(HTMLRenderer.sanitizeString(pn.getName()));
actionOutputHTML.append("' for ").append(HTMLRenderer.sanitizeString(pn.getLocation()));
actionOutputHTML.append(" removed<br />\n");
}
} else if ( (elem == -1) && (group >= 0) ) {
List l = bean.getGroup(group);
for (int i = 0; i < l.size(); i++) {
PetName pn = (PetName)l.get(i);
bean.remove(pn);
}
actionOutputHTML.append("All references in the selected group were removed<br />\n");
} else {
// noop
}
}
private void handleReorderGroup(HttpServletRequest req, User user, BlogConfigBean bean, StringBuffer actionOutputHTML) {
// control parameters:
// moveFrom=$i & moveTo=$j moves group $i to position $j
int from = -1;
int to = -1;
try {
String str = req.getParameter("moveFrom");
if (str != null)
from = Integer.parseInt(str);
str = req.getParameter("moveTo");
if (str != null)
to = Integer.parseInt(str);
String contactURL = info.getProperty(BlogInfo.CONTACT_URL);
if ( (contactURL != null) && (contactURL.trim().length() > 0) )
out.write("<tr><td colspan=\"3\">Contact information: "
+ HTMLRenderer.sanitizeString(contactURL) + "</td></tr>\n");
String props[] = info.getProperties();
int altCount = 0;
if (props != null)
for (int i = 0; i < props.length; i++)
if (!BlogInfo.NAME.equals(props[i]) &&
!BlogInfo.DESCRIPTION.equals(props[i]) &&
!BlogInfo.EDITION.equals(props[i]) &&
!BlogInfo.OWNER_KEY.equals(props[i]) &&
!BlogInfo.POSTERS.equals(props[i]) &&
!BlogInfo.SIGNATURE.equals(props[i]) &&
!BlogInfo.CONTACT_URL.equals(props[i]))
altCount++;
if (altCount > 0) {
for (int i = 0; i < props.length; i++) {
if (!BlogInfo.NAME.equals(props[i]) &&
!BlogInfo.DESCRIPTION.equals(props[i]) &&
!BlogInfo.EDITION.equals(props[i]) &&
!BlogInfo.OWNER_KEY.equals(props[i]) &&
!BlogInfo.POSTERS.equals(props[i]) &&
!BlogInfo.SIGNATURE.equals(props[i]) &&
!BlogInfo.CONTACT_URL.equals(props[i])) {
out.write("<tr><td colspan=\"3\">");
out.write(HTMLRenderer.sanitizeString(props[i]) + ": "
+ HTMLRenderer.sanitizeString(info.getProperty(props[i])));
out.write("</td></tr>\n");
if ( (from >= 0) && (to >= 0) ) {
List src = bean.getGroup(from);
List dest = bean.getGroup(to);
List orig = new ArrayList(dest);
dest.clear();
dest.addAll(src);
src.clear();
src.addAll(orig);
bean.groupsUpdated();
actionOutputHTML.append("Reference group moved<br />\n");
}
} catch (NumberFormatException nfe) {
// ignore
}
}
private void handleReorderRef(HttpServletRequest req, User user, BlogConfigBean bean, StringBuffer actionOutputHTML) {
// control parameters:
// moveRefFrom=$i.$j & moveRefTo=$k.$l moves element $j in group $i to position $l in group l
// (i == k)
int from = -1;
int fromElem = -1;
int to = -1; // ignored
int toElem = -1;
try {
String str = req.getParameter("moveRefFrom");
if (str != null) {
int split = str.indexOf('.');
if (split > 0) {
try {
from = Integer.parseInt(str.substring(0, split));
fromElem = Integer.parseInt(str.substring(split+1));
} catch (NumberFormatException nfe) {
from = -1;
fromElem = -1;
}
}
}
str = req.getParameter("moveRefTo");
if (str != null) {
int split = str.indexOf('.');
if (split > 0) {
try {
to = Integer.parseInt(str.substring(0, split));
toElem = Integer.parseInt(str.substring(split+1));
} catch (NumberFormatException nfe) {
to = -1;
toElem = -1;
}
}
}
if ( (from >= 0) && (fromElem >= 0) && (toElem >= 0) ) {
List src = bean.getGroup(from);
PetName pn = (PetName)src.remove(fromElem);
src.add(toElem, pn);
bean.groupsUpdated();
actionOutputHTML.append("Reference element moved<br />\n");
}
} catch (NumberFormatException nfe) {
// ignore
}
}
*/
protected String getTitle() { return "Syndie :: Configure blog"; }
}

View File

@ -104,6 +104,7 @@ public class ProfileServlet extends BaseServlet {
out.write("<tr><td colspan=\"3\"><input type=\"submit\" name=\"action\" value=\"Update profile\" /></td></tr>\n");
out.write("</form>\n");
out.write("<tr><td colspan=\"3\"><a href=\"configblog.jsp\">Configure your blog</a></td></tr>\n");
}
private void renderProfile(User user, String baseURI, PrintWriter out, Hash author, Archive archive) throws IOException {

View File

@ -79,6 +79,20 @@ public class ViewBlogServlet extends BaseServlet {
private List getPosts(User user, Archive archive, BlogInfo info, HttpServletRequest req, ThreadIndex index) {
List rv = new ArrayList(1);
if (info == null) return rv;
String entrySelected = req.getParameter(PARAM_ENTRY);
if (entrySelected != null) {
// $blogKey/$entryId
BlogURI uri = null;
if (entrySelected.startsWith("blog://"))
uri = new BlogURI(entrySelected);
else
uri = new BlogURI("blog://" + entrySelected.trim());
if (uri.getEntryId() >= 0) {
rv.add(uri);
return rv;
}
}
ArchiveIndex aindex = archive.getIndex();
@ -188,7 +202,7 @@ public class ViewBlogServlet extends BaseServlet {
out.write("</div>\n");
}
private static final String DEFAULT_GROUP_NAME = "References";
public static final String DEFAULT_GROUP_NAME = "References";
private void renderReferences(PrintWriter out, BlogInfo info, BlogInfoData data) throws IOException {
out.write("<div class=\"syndieBlogLinks\">\n");
if (data != null) {
@ -207,23 +221,118 @@ public class ViewBlogServlet extends BaseServlet {
out.write("<ul>\n");
for (int j = 0; j < group.size(); j++) {
pn = (PetName)group.get(j);
out.write("<li>" + renderLink(pn) + "</li>\n");
out.write("<li>" + renderLink(info.getKey().calculateHash(), pn) + "</li>\n");
}
out.write("</ul>\n</div>\n<!-- end " + name + " -->\n");
}
}
out.write("<div class=\"syndieBlogLinkGroup\">\n");
out.write("<span class=\"syndieBlogLinkGroupName\">Custom links</span>\n");
out.write("<ul><li><a href=\"\">are not yet implemented</a></li><li><a href=\"\">but are coming soon</a></li></ul>\n");
out.write("</div><!-- end fake group -->");
//out.write("<div class=\"syndieBlogLinkGroup\">\n");
//out.write("<span class=\"syndieBlogLinkGroupName\">Custom links</span>\n");
//out.write("<ul><li><a href=\"\">are not yet implemented</a></li><li><a href=\"\">but are coming soon</a></li></ul>\n");
//out.write("</div><!-- end fake group -->");
out.write("<div class=\"syndieBlogMeta\">");
out.write("Secured by <a href=\"http://syndie.i2p.net/\">Syndie</a>");
out.write("</div>\n");
out.write("</div><!-- end syndieBlogLinks -->\n\n");
}
private String renderLink(PetName pn) {
return "<a href=\"\" title=\"go somewhere\">" + HTMLRenderer.sanitizeString(pn.getName()) + "</a>";
/** generate a link for the given petname within the scope of the given blog */
public static String renderLink(Hash blogFrom, PetName pn) {
StringBuffer buf = new StringBuffer(64);
String type = pn.getProtocol();
if ("syndieblog".equals(type)) {
String loc = pn.getLocation();
if (loc != null) {
buf.append("<a href=\"blog.jsp?").append(PARAM_BLOG).append("=");
buf.append(HTMLRenderer.sanitizeTagParam(pn.getLocation()));
buf.append("\" title=\"View ").append(HTMLRenderer.sanitizeTagParam(pn.getName())).append("\">");
}
buf.append(HTMLRenderer.sanitizeString(pn.getName()));
if (loc != null) {
buf.append("</a>");
//buf.append(" <a href=\"").append(HTMLRenderer.getBookmarkURL(pn.getName(), pn.getLocation(), "syndie", "syndieblog"));
//buf.append("\" title=\"Bookmark ").append(HTMLRenderer.sanitizeTagParam(pn.getName())).append("\"><image src=\"images/addToFavorites.png\" alt=\"\" /></a>\n");
}
} else if ("syndieblogpost".equals(type)) {
String loc = pn.getLocation();
if (loc != null) {
buf.append("<a href=\"blog.jsp?").append(PARAM_BLOG).append("=");
buf.append(blogFrom.toBase64()).append("&amp;");
buf.append(PARAM_ENTRY).append("=").append(HTMLRenderer.sanitizeTagParam(pn.getLocation()));
buf.append("\" title=\"View the specified post\">");
}
buf.append(HTMLRenderer.sanitizeString(pn.getName()));
if (loc != null) {
buf.append("</a>");
}
} else if ("syndieblogattachment".equals(type)) {
String loc = pn.getLocation();
if (loc != null) {
int split = loc.lastIndexOf('/');
try {
int attachmentId = -1;
if (split > 0)
attachmentId = Integer.parseInt(loc.substring(split+1));
if (attachmentId < 0) {
loc = null;
} else {
BlogURI post = null;
if (loc.startsWith("blog://"))
post = new BlogURI(loc.substring(0, split));
else
post = new BlogURI("blog://" + loc.substring(0, split));
EntryContainer entry = BlogManager.instance().getArchive().getEntry(post);
if (entry != null) {
Attachment attachments[] = entry.getAttachments();
if (attachmentId < attachments.length) {
buf.append("<a href=\"blog.jsp?").append(PARAM_BLOG).append("=");
buf.append(blogFrom.toBase64()).append("&amp;");
buf.append(PARAM_ATTACHMENT).append("=").append(HTMLRenderer.sanitizeTagParam(loc));
buf.append("\" title=\"");
buf.append("'");
buf.append(HTMLRenderer.sanitizeTagParam(attachments[attachmentId].getName()));
buf.append("', ");
buf.append(attachments[attachmentId].getDataLength()/1024).append("KB, ");
buf.append("of type ").append(HTMLRenderer.sanitizeTagParam(attachments[attachmentId].getMimeType()));
buf.append("\">");
buf.append(HTMLRenderer.sanitizeString(pn.getName()));
buf.append("</a>");
} else {
loc = null;
}
} else {
loc = null;
}
}
} catch (Exception e) {
e.printStackTrace();
loc = null;
}
}
if (loc == null)
buf.append(HTMLRenderer.sanitizeString(pn.getName()));
} else if ( ("eepsite".equals(type)) || ("i2p".equals(type)) ||
("website".equals(type)) || ("http".equals(type)) || ("web".equals(type)) ) {
String loc = pn.getLocation();
if (loc != null) {
buf.append("<a href=\"externallink.jsp?");
if (pn.getNetwork() != null)
buf.append("schema=").append(Base64.encode(pn.getNetwork())).append("&amp;");
if (pn.getLocation() != null)
buf.append("location=").append(Base64.encode(pn.getLocation())).append("&amp;");
buf.append("\" title=\"View ").append(HTMLRenderer.sanitizeTagParam(pn.getLocation())).append("\">");
}
buf.append(HTMLRenderer.sanitizeString(pn.getName()));
if (loc != null) {
buf.append("</a>");
}
} else {
buf.append("<a href=\"\" title=\"go somewhere? ").append(HTMLRenderer.sanitizeString(pn.toString())).append("\">");
buf.append(HTMLRenderer.sanitizeString(pn.getName())).append("</a>");
}
return buf.toString();
}
private static final int POSTS_PER_PAGE = 5;
@ -410,7 +519,7 @@ public class ViewBlogServlet extends BaseServlet {
"}\n" +
".syndieBlogLinkGroup li a {\n" +
" display: block;\n" +
" width: 100%;\n" +
//" width: 100%;\n" +
"}\n" +
".syndieBlogLinkGroupName {\n" +
" font-size: 80%;\n" +

View File

@ -1,4 +1,9 @@
$Id: history.txt,v 1.378 2006/01/04 21:48:17 jrandom Exp $
$Id: history.txt,v 1.379 2006/01/08 15:54:39 jrandom Exp $
2005-01-09 jrandom
* Bugfix for a rare SSU error (thanks cervantes!)
* More progress on the blog interface, allowing customizable blog-wide
links.
2006-01-08 jrandom
* First pass of the new blog interface, though without much of the useful

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.324 $ $Date: 2006/01/01 12:23:29 $";
public final static String ID = "$Revision: 1.325 $ $Date: 2006/01/04 21:48:17 $";
public final static String VERSION = "0.6.1.8";
public final static long BUILD = 8;
public final static long BUILD = 9;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -473,6 +473,7 @@ public class OutboundMessageFragments {
// ok, simplest possible thing is to always tack on the bitfields if
List msgIds = peer.getCurrentFullACKs();
if (msgIds == null) msgIds = new ArrayList();
List partialACKBitfields = new ArrayList();
peer.fetchPartialACKs(partialACKBitfields);
int piggybackedPartialACK = partialACKBitfields.size();
@ -482,6 +483,10 @@ public class OutboundMessageFragments {
for (int i = 0; i < fragments; i++) {
if (state.needsSending(i)) {
rv[i] = _builder.buildPacket(state, i, peer, remaining, partialACKBitfields);
if (rv[i] == null) {
sparseCount++;
continue;
}
rv[i].setFragmentCount(fragments);
OutNetMessage msg = state.getMessage();
if (msg != null)