diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java index cadcd544a640612c56749e73f70dc9d38b003947..702c24bf50e36c5408b6a95726809f066c88aaa3 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java @@ -479,9 +479,12 @@ public class IndexBean { public void setStartOnLoad(String moo) { _startOnLoad = true; } - public void setSharedClient(String moo) { + public void setShared(String moo) { _sharedClient=true; } + public void setShared(boolean val) { + _sharedClient=val; + } public void setConnectDelay(String moo) { _connectDelay = true; } diff --git a/apps/i2ptunnel/jsp/editClient.jsp b/apps/i2ptunnel/jsp/editClient.jsp index 31516add16a005bccb2cc7e9cf1c5c8fad769715..dd6de657b98fdea565ace35ccc44675c85fae709 100644 --- a/apps/i2ptunnel/jsp/editClient.jsp +++ b/apps/i2ptunnel/jsp/editClient.jsp @@ -166,9 +166,9 @@ if (curTunnel >= 0) { </td> <td> <% if (editBean.isSharedClient(curTunnel)) { %> -<input type="checkbox" value="true" name="sharedClient" checked="true" /> +<input type="checkbox" value="true" name="shared" checked="true" /> <% } else { %> -<input type="checkbox" value="true" name="sharedClient" /> +<input type="checkbox" value="true" name="shared" /> <% } %> <i>(Share tunnels with other clients and httpclients? Change requires restart of client proxy)</i> </td> diff --git a/apps/syndie/java/src/net/i2p/syndie/ArchiveIndexer.java b/apps/syndie/java/src/net/i2p/syndie/ArchiveIndexer.java index bec41742735c56050dbb2e7c5da68cd17cd08eee..09e65683124298aea0730ff0069bc2b7f20e4490 100644 --- a/apps/syndie/java/src/net/i2p/syndie/ArchiveIndexer.java +++ b/apps/syndie/java/src/net/i2p/syndie/ArchiveIndexer.java @@ -158,7 +158,7 @@ class ArchiveIndexer { _headers.setProperty(header, value); } - public void receiveAddress(String name, String schema, String location, String anchorText) {} + public void receiveAddress(String name, String schema, String protocol, String location, String anchorText) {} public void receiveArchive(String name, String description, String locationSchema, String location, String postingKey, String anchorText) {} public void receiveAttachment(int id, String anchorText) {} public void receiveBegin() {} diff --git a/apps/syndie/java/src/net/i2p/syndie/BlogManager.java b/apps/syndie/java/src/net/i2p/syndie/BlogManager.java index e6f04a19827a969149eb5645b35bdc242f0b5c29..c0c2d13b45a738372c245e397c3dc08d975e5054 100644 --- a/apps/syndie/java/src/net/i2p/syndie/BlogManager.java +++ b/apps/syndie/java/src/net/i2p/syndie/BlogManager.java @@ -225,6 +225,7 @@ public class BlogManager { try { out = new FileOutputStream(userFile); out.write(DataHelper.getUTF8(user.export())); + user.getPetNameDB().store(user.getAddressbookLocation()); } catch (IOException ioe) { ioe.printStackTrace(); } finally { @@ -399,7 +400,7 @@ public class BlogManager { } - public String addAddress(User user, String name, String location, String schema) { + public String addAddress(User user, String name, String protocol, String location, String schema) { if (!user.getAuthenticated()) return "Not logged in"; boolean ok = validateAddressName(name); if (!ok) return "Invalid name: " + HTMLRenderer.sanitizeString(name); @@ -408,19 +409,17 @@ public class BlogManager { if (!validateAddressSchema(schema)) return "Unsupported schema: " + HTMLRenderer.sanitizeString(schema); // no need to quote user/location further, as they've been sanitized - FileOutputStream out = null; - try { - File userHostsFile = new File(user.getAddressbookLocation()); - Properties knownHosts = getKnownHosts(user, true); - if (knownHosts.containsKey(name)) return "Name is already in use"; + PetNameDB names = user.getPetNameDB(); + if (names.exists(name)) + return "Name is already in use"; + PetName pn = new PetName(name, schema, protocol, location); + names.set(name, pn); - out = new FileOutputStream(userHostsFile, true); - out.write(DataHelper.getUTF8(name + "=" + location + '\n')); - return "Address " + name + " written to your hosts file (" + userHostsFile.getName() + ")"; + try { + names.store(user.getAddressbookLocation()); + return "Address " + name + " written to your addressbook"; } catch (IOException ioe) { - return "Error writing out host entry: " + ioe.getMessage(); - } finally { - if (out != null) try { out.close(); } catch (IOException ioe) {} + return "Error writing out the name: " + ioe.getMessage(); } } @@ -455,12 +454,17 @@ public class BlogManager { private boolean validateAddressLocation(String location) { if ( (location == null) || (location.trim().length() <= 0) ) return false; - try { - Destination d = new Destination(location); - return (d.getPublicKey() != null); - } catch (DataFormatException dfe) { - dfe.printStackTrace(); - return false; + if (false) { + try { + Destination d = new Destination(location); + return (d.getPublicKey() != null); + } catch (DataFormatException dfe) { + dfe.printStackTrace(); + return false; + } + } else { + // not everything is an i2p destination... + return true; } } diff --git a/apps/syndie/java/src/net/i2p/syndie/PetName.java b/apps/syndie/java/src/net/i2p/syndie/PetName.java new file mode 100644 index 0000000000000000000000000000000000000000..a6c42e9da5000be7b5e65b7fb996ba3ec9a53b1c --- /dev/null +++ b/apps/syndie/java/src/net/i2p/syndie/PetName.java @@ -0,0 +1,175 @@ +package net.i2p.syndie; + +import java.util.*; +import net.i2p.data.DataHelper; + +/** + * + */ +public class PetName { + private String _name; + private String _network; + private String _protocol; + private List _groups; + private boolean _isPublic; + private String _location; + + public PetName() { + this(null, null, null, null); + } + public PetName(String name, String network, String protocol, String location) { + _name = name; + _network = network; + _protocol = protocol; + _location = location; + _groups = new ArrayList(); + _isPublic = false; + } + /** + * @param dbLine name:network:protocol:isPublic:group1,group2,group3:location + */ + public PetName(String dbLine) { + _groups = new ArrayList(); + StringTokenizer tok = new StringTokenizer(dbLine, ":\n", true); + int tokens = tok.countTokens(); + System.out.println("Tokens: " + tokens); + if (tokens < 7) { + return; + } + String s = tok.nextToken(); + if (":".equals(s)) { + _name = null; + } else { + _name = s; + s = tok.nextToken(); // skip past the : + } + s = tok.nextToken(); + if (":".equals(s)) { + _network = null; + } else { + _network = s; + s = tok.nextToken(); // skip past the : + } + s = tok.nextToken(); + if (":".equals(s)) { + _protocol = null; + } else { + _protocol = s; + s = tok.nextToken(); // skip past the : + } + s = tok.nextToken(); + if (":".equals(s)) { + _isPublic = false; + } else { + if ("true".equals(s)) + _isPublic = true; + else + _isPublic = false; + s = tok.nextToken(); // skip past the : + } + s = tok.nextToken(); + if (":".equals(s)) { + // noop + } else { + StringTokenizer gtok = new StringTokenizer(s, ","); + while (gtok.hasMoreTokens()) + _groups.add(gtok.nextToken().trim()); + s = tok.nextToken(); // skip past the : + } + if (tok.hasMoreTokens()) { + s = tok.nextToken(); + if (":".equals(s)) { + _location = null; + } else { + _location = s; + } + } else { + _location = null; + } + } + + public String getName() { return _name; } + public String getNetwork() { return _network; } + public String getProtocol() { return _protocol; } + public String getLocation() { return _location; } + public boolean getIsPublic() { return _isPublic; } + public int getGroupCount() { return _groups.size(); } + public String getGroup(int i) { return (String)_groups.get(i); } + + public void setName(String name) { _name = name; } + public void setNetwork(String network) { _network = network; } + public void setProtocol(String protocol) { _protocol = protocol; } + public void setLocation(String location) { _location = location; } + public void setIsPublic(boolean pub) { _isPublic = pub; } + public void addGroup(String name) { + if ( (name != null) && (name.length() > 0) && (!_groups.contains(name)) ) + _groups.add(name); + } + public void removeGroup(String name) { _groups.remove(name); } + public void setGroups(String groups) { + if (groups != null) { + _groups.clear(); + StringTokenizer tok = new StringTokenizer(groups, ", \t"); + while (tok.hasMoreTokens()) + addGroup(tok.nextToken().trim()); + } else { + _groups.clear(); + } + } + public boolean isMember(String group) { + for (int i = 0; i < getGroupCount(); i++) + if (getGroup(i).equals(group)) + return true; + return false; + } + + public String toString() { + StringBuffer buf = new StringBuffer(256); + if (_name != null) buf.append(_name.trim()); + buf.append(':'); + if (_network != null) buf.append(_network.trim()); + buf.append(':'); + if (_protocol != null) buf.append(_protocol.trim()); + buf.append(':').append(_isPublic).append(':'); + if (_groups != null) { + for (int i = 0; i < _groups.size(); i++) { + buf.append(((String)_groups.get(i)).trim()); + if (i + 1 < _groups.size()) + buf.append(','); + } + } + buf.append(':'); + if (_location != null) buf.append(_location.trim()); + return buf.toString(); + } + + public boolean equals(Object obj) { + if ( (obj == null) || !(obj instanceof PetName) ) return false; + PetName pn = (PetName)obj; + return DataHelper.eq(_name, pn._name) && + DataHelper.eq(_location, pn._location) && + DataHelper.eq(_network, pn._network) && + DataHelper.eq(_protocol, pn._protocol); + } + public int hashCode() { + int rv = 0; + rv += DataHelper.hashCode(_name); + rv += DataHelper.hashCode(_location); + rv += DataHelper.hashCode(_network); + rv += DataHelper.hashCode(_protocol); + return rv; + } + + public static void main(String args[]) { + test("a:b:c:d:e:f"); + test("a:::::d"); + test("a:::::"); + test("a:b::::"); + test(":::::"); + } + private static void test(String line) { + PetName pn = new PetName(line); + String val = pn.toString(); + System.out.println("OK? " + val.equals(line) + ": " + line); + } +} diff --git a/apps/syndie/java/src/net/i2p/syndie/PetNameDB.java b/apps/syndie/java/src/net/i2p/syndie/PetNameDB.java new file mode 100644 index 0000000000000000000000000000000000000000..700464924c2e950e8ffbb098940ec8532599a935 --- /dev/null +++ b/apps/syndie/java/src/net/i2p/syndie/PetNameDB.java @@ -0,0 +1,74 @@ +package net.i2p.syndie; + +import java.io.*; +import java.util.*; + +/** + * + */ +public class PetNameDB { + /** name (String) to PetName mapping */ + private Map _names; + + public PetNameDB() { + _names = Collections.synchronizedMap(new HashMap()); + } + + public PetName get(String name) { return (PetName)_names.get(name); } + public boolean exists(String name) { return _names.containsKey(name); } + public void set(String name, PetName pn) { _names.put(name, pn); } + public void remove(String name) { _names.remove(name); } + public Set getNames() { return new HashSet(_names.keySet()); } + public List getGroups() { + List rv = new ArrayList(); + for (Iterator iter = new HashSet(_names.values()).iterator(); iter.hasNext(); ) { + PetName name = (PetName)iter.next(); + for (int i = 0; i < name.getGroupCount(); i++) + if (!rv.contains(name.getGroup(i))) + rv.add(name.getGroup(i)); + } + return rv; + } + + public String getNameByLocation(String location) { + if (location == null) return null; + synchronized (_names) { + for (Iterator iter = _names.values().iterator(); iter.hasNext(); ) { + PetName name = (PetName)iter.next(); + if ( (name.getLocation() != null) && (name.getLocation().trim().equals(location.trim())) ) + return name.getName(); + } + } + return null; + } + + public void load(String location) throws IOException { + File f = new File(location); + if (!f.exists()) return; + BufferedReader in = null; + try { + in = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8")); + String line = null; + while ( (line = in.readLine()) != null) { + PetName name = new PetName(line); + if (name.getName() != null) + _names.put(name.getName(), name); + } + } finally { + in.close(); + } + } + public void store(String location) throws IOException { + Writer out = null; + try { + out = new OutputStreamWriter(new FileOutputStream(location), "UTF-8"); + for (Iterator names = getNames().iterator(); names.hasNext(); ) { + PetName name = get((String)names.next()); + if (name != null) + out.write(name.toString() + "\n"); + } + } finally { + out.close(); + } + } +} diff --git a/apps/syndie/java/src/net/i2p/syndie/User.java b/apps/syndie/java/src/net/i2p/syndie/User.java index c75e951e556eba42dc545ce0973fe1324a4ae2f8..b4f435c50c7b31b85767332e179ece8d81be16e5 100644 --- a/apps/syndie/java/src/net/i2p/syndie/User.java +++ b/apps/syndie/java/src/net/i2p/syndie/User.java @@ -1,6 +1,7 @@ package net.i2p.syndie; import java.io.UnsupportedEncodingException; +import java.io.IOException; import java.util.*; import net.i2p.I2PAppContext; import net.i2p.data.*; @@ -36,6 +37,7 @@ public class User { private int _webProxyPort; private String _torProxyHost; private int _torProxyPort; + private PetNameDB _petnames; public User() { _context = I2PAppContext.getGlobalContext(); @@ -62,6 +64,7 @@ public class User { _torProxyPort = -1; _lastLogin = -1; _lastMetaEntry = 0; + _petnames = new PetNameDB(); } public boolean getAuthenticated() { return _authenticated; } @@ -92,6 +95,8 @@ public class User { public String getTorProxyHost() { return _torProxyHost; } public int getTorProxyPort() { return _torProxyPort; } + public PetNameDB getPetNameDB() { return _petnames; } + public void invalidate() { BlogManager.instance().saveUser(this); init(); @@ -156,8 +161,14 @@ public class User { } String addr = props.getProperty("addressbook", "userhosts.txt"); - if (addr != null) + if (addr != null) { _addressbookLocation = addr; + try { + _petnames.load(addr); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } String show = props.getProperty("showimages", "false"); _showImagesByDefault = (show != null) && (show.equals("true")); diff --git a/apps/syndie/java/src/net/i2p/syndie/sml/EventReceiverImpl.java b/apps/syndie/java/src/net/i2p/syndie/sml/EventReceiverImpl.java index e00fb3ccef9ce837507e2cbbc64e67a93b5bb28c..3b8bfb5b6a775bf7dfba9d304c8e4b26195e2585 100644 --- a/apps/syndie/java/src/net/i2p/syndie/sml/EventReceiverImpl.java +++ b/apps/syndie/java/src/net/i2p/syndie/sml/EventReceiverImpl.java @@ -25,7 +25,7 @@ public class EventReceiverImpl implements SMLParser.EventReceiver { public void receiveImage(String alternateText, int attachmentId) { System.out.println("Receive image [" + alternateText + "]/[" + attachmentId + "]"); } - public void receiveAddress(String name, String schema, String location, String anchorText) { + public void receiveAddress(String name, String schema, String protocol, String location, String anchorText) { System.out.println("Receive address [" + name + "]/[" + schema + "]/[" + location + "]/[" + anchorText+ "]"); } public void receiveBold(String text) { System.out.println("Receive bold [" + text+ "]"); } diff --git a/apps/syndie/java/src/net/i2p/syndie/sml/HTMLPreviewRenderer.java b/apps/syndie/java/src/net/i2p/syndie/sml/HTMLPreviewRenderer.java index 8a9ad82fddd8318167f919bffbbf7745a17a3244..21274d79cde871abf812ac8fc673c50abb74dbdf 100644 --- a/apps/syndie/java/src/net/i2p/syndie/sml/HTMLPreviewRenderer.java +++ b/apps/syndie/java/src/net/i2p/syndie/sml/HTMLPreviewRenderer.java @@ -94,11 +94,20 @@ public class HTMLPreviewRenderer extends HTMLRenderer { _postBodyBuffer.append("<b>Addresses:</b> "); for (int i = 0; i < _addresses.size(); i++) { Address a = (Address)_addresses.get(i); - _postBodyBuffer.append("<a href=\"addaddress.jsp?schema="); - _postBodyBuffer.append(sanitizeURL(a.schema)).append("&location="); - _postBodyBuffer.append(sanitizeURL(a.location)).append("&name="); - _postBodyBuffer.append(sanitizeURL(a.name)); - _postBodyBuffer.append("\">").append(sanitizeString(a.name)); + + String knownName = null; + if (_user != null) + knownName = _user.getPetNameDB().getNameByLocation(a.location); + if (knownName != null) { + _postBodyBuffer.append(' ').append(sanitizeString(knownName)); + } else { + _postBodyBuffer.append(" <a href=\"addaddress.jsp?schema="); + _postBodyBuffer.append(sanitizeURL(a.schema)).append("&location="); + _postBodyBuffer.append(sanitizeURL(a.location)).append("&name="); + _postBodyBuffer.append(sanitizeURL(a.protocol)).append("&protocol="); + _postBodyBuffer.append(sanitizeURL(a.name)); + _postBodyBuffer.append("\">").append(sanitizeString(a.name)); + } } _postBodyBuffer.append("<br />\n"); } diff --git a/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java b/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java index b9a957441e732960103691d23624844809b87c88..57032b5c46992e1dadbd7d8cd6b3f59908529802 100644 --- a/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java +++ b/apps/syndie/java/src/net/i2p/syndie/sml/HTMLRenderer.java @@ -387,25 +387,37 @@ public class HTMLRenderer extends EventReceiverImpl { public String name; public String schema; public String location; + public String protocol; public int hashCode() { return -1; } public boolean equals(Object o) { Address a = (Address)o; - return DataHelper.eq(schema, a.schema) && DataHelper.eq(location, a.location) && DataHelper.eq(name, a.name); + return DataHelper.eq(schema, a.schema) && DataHelper.eq(location, a.location) && DataHelper.eq(protocol, a.protocol) && DataHelper.eq(name, a.name); } } - public void receiveAddress(String name, String schema, String location, String anchorText) { + public void receiveAddress(String name, String schema, String protocol, String location, String anchorText) { Address a = new Address(); a.name = name; a.schema = schema; a.location = location; + a.protocol = protocol; if (!_addresses.contains(a)) _addresses.add(a); if (!continueBody()) { return; } if ( (schema == null) || (location == null) ) return; - _bodyBuffer.append("<a href=\"addaddress.jsp?schema="); - _bodyBuffer.append(sanitizeURL(schema)).append("&name="); - _bodyBuffer.append(sanitizeURL(name)).append("&location="); - _bodyBuffer.append(sanitizeURL(location)).append("\">").append(sanitizeString(anchorText)).append("</a>"); + String knownName = null; + if (_user != null) + knownName = _user.getPetNameDB().getNameByLocation(location); + if (knownName != null) { + _bodyBuffer.append(sanitizeString(anchorText)); + _bodyBuffer.append(" <i>(").append(sanitizeString(knownName)).append(")</i>"); + } else { + System.err.println("Receiving address [" + location + "]"); + _bodyBuffer.append("<a href=\"addaddress.jsp?schema="); + _bodyBuffer.append(sanitizeURL(schema)).append("&name="); + _bodyBuffer.append(sanitizeURL(name)).append("&protocol="); + _bodyBuffer.append(sanitizeURL(protocol)).append("&location="); + _bodyBuffer.append(sanitizeURL(location)).append("\">").append(sanitizeString(anchorText)).append("</a>"); + } } public void receiveAttachment(int id, String anchorText) { @@ -540,11 +552,20 @@ public class HTMLRenderer extends EventReceiverImpl { _postBodyBuffer.append("<b>Addresses:</b>"); for (int i = 0; i < _addresses.size(); i++) { Address a = (Address)_addresses.get(i); - _postBodyBuffer.append(" <a href=\"addaddress.jsp?schema="); - _postBodyBuffer.append(sanitizeURL(a.schema)).append("&location="); - _postBodyBuffer.append(sanitizeURL(a.location)).append("&name="); - _postBodyBuffer.append(sanitizeURL(a.name)); - _postBodyBuffer.append("\">").append(sanitizeString(a.name)); + + String knownName = null; + if (_user != null) + knownName = _user.getPetNameDB().getNameByLocation(a.location); + if (knownName != null) { + _postBodyBuffer.append(' ').append(sanitizeString(knownName)); + } else { + _postBodyBuffer.append(" <a href=\"addaddress.jsp?schema="); + _postBodyBuffer.append(sanitizeURL(a.schema)).append("&location="); + _postBodyBuffer.append(sanitizeURL(a.location)).append("&name="); + _postBodyBuffer.append(sanitizeURL(a.name)).append("&protocol="); + _postBodyBuffer.append(sanitizeURL(a.protocol)); + _postBodyBuffer.append("\">").append(sanitizeString(a.name)); + } } _postBodyBuffer.append("<br />\n"); } @@ -632,20 +653,47 @@ public class HTMLRenderer extends EventReceiverImpl { if ( (tags != null) && (tags.length > 0) ) _preBodyBuffer.append("<form action=\"index.jsp\">"); _preBodyBuffer.append("<td nowrap=\"true\" align=\"right\" valign=\"top\" class=\"syndieEntryMetaCell\">\n"); + + String knownName = null; + if ( (_entry != null) && (_user != null) ) + knownName = _user.getPetNameDB().getNameByLocation(_entry.getURI().getKeyHash().toBase64()); + //if (knownName != null) + // _preBodyBuffer.append("Pet name: ").append(sanitizeString(knownName)).append(" "); + BlogInfo info = null; if (_entry != null) info = _archive.getBlogInfo(_entry.getURI()); if (info != null) { _preBodyBuffer.append("<a href=\"").append(getMetadataURL()).append("\">"); - String nameStr = info.getProperty("Name"); - if (nameStr == null) - _preBodyBuffer.append("[no name]"); - else - _preBodyBuffer.append(sanitizeString(nameStr)); + if (knownName != null) { + _preBodyBuffer.append(sanitizeString(knownName)); + } else { + String nameStr = info.getProperty("Name"); + if (nameStr == null) + _preBodyBuffer.append("[no name]"); + else + _preBodyBuffer.append(sanitizeString(nameStr)); + } _preBodyBuffer.append("</a>"); } else { _preBodyBuffer.append("[unknown blog]"); } + + + if ( (_user != null) && (_user.getAuthenticated()) && (_entry != null) ) { + PetName pn = _user.getPetNameDB().get(knownName); + if ( (pn == null) || (!pn.isMember("Favorites")) ) + _preBodyBuffer.append(" <input type=\"submit\" name=\"action\" value=\"Bookmark blog\" />"); + if ( (pn == null) || (!pn.isMember("Ignore")) ) + _preBodyBuffer.append(" <input type=\"submit\" name=\"action\" value=\"Ignore blog\" />"); + else + _preBodyBuffer.append(" <input type=\"submit\" name=\"action\" value=\"Unignore blog\" />"); + _preBodyBuffer.append(" <input type=\"hidden\" name=\"blog\" value=\"").append(_entry.getURI().getKeyHash().toBase64()).append("\" />"); + if (info != null) + _preBodyBuffer.append(" <input type=\"hidden\" name=\"name\" value=\"").append(sanitizeTagParam(info.getProperty("Name"))).append("\" />"); + } + + if ( (tags != null) && (tags.length > 0) ) { _preBodyBuffer.append(" Tags: "); _preBodyBuffer.append("<select name=\"selector\">"); @@ -680,8 +728,9 @@ public class HTMLRenderer extends EventReceiverImpl { _preBodyBuffer.append(getEntryDate(_entry.getURI().getEntryId())); else _preBodyBuffer.append(getEntryDate(new Date().getTime())); - if ( (_user != null) && (_user.getAuthenticated()) ) + if ( (_user != null) && (_user.getAuthenticated()) ) { _preBodyBuffer.append(" <a href=\"").append(getPostURL(_user.getBlog(), true)).append("\">Reply</a>\n"); + } _preBodyBuffer.append("\n</td>"); if ( (tags != null) && (tags.length > 0) ) _preBodyBuffer.append("</form>"); @@ -694,7 +743,7 @@ public class HTMLRenderer extends EventReceiverImpl { try { String str = _dateFormat.format(new Date(when)); long dayBegin = _dateFormat.parse(str).getTime(); - return str + "." + (when - dayBegin); + return str + " [" + (when - dayBegin) + "]"; } catch (ParseException pe) { pe.printStackTrace(); // wtf diff --git a/apps/syndie/java/src/net/i2p/syndie/sml/SMLParser.java b/apps/syndie/java/src/net/i2p/syndie/sml/SMLParser.java index 1560fb276bdf5d82be82ad9b1535cdefbb4bc20b..d9d3be9ad6c7dcc010d3ccc2230788c7150bd48b 100644 --- a/apps/syndie/java/src/net/i2p/syndie/sml/SMLParser.java +++ b/apps/syndie/java/src/net/i2p/syndie/sml/SMLParser.java @@ -211,6 +211,7 @@ public class SMLParser { private static final String P_ADDRESS_NAME = "name"; private static final String P_ADDRESS_LOCATION = "location"; private static final String P_ADDRESS_SCHEMA = "schema"; + private static final String P_ADDRESS_PROTOCOL = "proto"; private static final String P_ATTACHMENT_ID = "id"; private static final String P_ARCHIVE_NAME = "name"; private static final String P_ARCHIVE_DESCRIPTION = "description"; @@ -254,7 +255,7 @@ public class SMLParser { } else if (T_LINK.equals(tagName)) { receiver.receiveLink(getString(P_LINK_SCHEMA, attr), getString(P_LINK_LOCATION, attr), body); } else if (T_ADDRESS.equals(tagName)) { - receiver.receiveAddress(getString(P_ADDRESS_NAME, attr), getString(P_ADDRESS_SCHEMA, attr), getString(P_ADDRESS_LOCATION, attr), body); + receiver.receiveAddress(getString(P_ADDRESS_NAME, attr), getString(P_ADDRESS_SCHEMA, attr), getString(P_ADDRESS_PROTOCOL, attr), getString(P_ADDRESS_LOCATION, attr), body); } else if (T_H1.equals(tagName)) { receiver.receiveH1(body); } else if (T_H2.equals(tagName)) { @@ -381,7 +382,7 @@ public class SMLParser { public void receiveArchive(String name, String description, String locationSchema, String location, String postingKey, String anchorText); public void receiveImage(String alternateText, int attachmentId); - public void receiveAddress(String name, String schema, String location, String anchorText); + public void receiveAddress(String name, String schema, String protocol, String location, String anchorText); public void receiveAttachment(int id, String anchorText); public void receiveBold(String text); public void receiveItalic(String text); diff --git a/apps/syndie/java/src/net/i2p/syndie/web/ArchiveViewerBean.java b/apps/syndie/java/src/net/i2p/syndie/web/ArchiveViewerBean.java index 3cdfc609a4c723c302fd938a534cfd38f511a2ea..7d56d035e37f01a7cbc061def5c27f087bfc9f32 100644 --- a/apps/syndie/java/src/net/i2p/syndie/web/ArchiveViewerBean.java +++ b/apps/syndie/java/src/net/i2p/syndie/web/ArchiveViewerBean.java @@ -102,12 +102,12 @@ public class ArchiveViewerBean { out.write(SEL_ALL); out.write("\">All posts from all blogs</option>\n"); - Map groups = null; + List groups = null; if (user != null) - groups = user.getBlogGroups(); + groups = user.getPetNameDB().getGroups(); if (groups != null) { - for (Iterator iter = groups.keySet().iterator(); iter.hasNext(); ) { - String name = (String)iter.next(); + for (int i = 0; i < groups.size(); i++) { + String name = (String)groups.get(i); out.write("<option value=\"group://" + Base64.encode(DataHelper.getUTF8(name)) + "\">" + "Group: " + HTMLRenderer.sanitizeString(name) + "</option>\n"); } @@ -226,6 +226,7 @@ public class ArchiveViewerBean { if (blogStr != null) blog = new Hash(Base64.decode(blogStr)); String tag = getString(parameters, PARAM_TAG); if (tag != null) tag = DataHelper.getUTF8(Base64.decode(tag)); + long entryId = -1; if (blogStr != null) { String entryIdStr = getString(parameters, PARAM_ENTRY); @@ -237,6 +238,14 @@ public class ArchiveViewerBean { if (group != null) group = DataHelper.getUTF8(Base64.decode(group)); String sel = getString(parameters, PARAM_SELECTOR); + + if (getString(parameters, "action") != null) { + tag = null; + blog = null; + sel = null; + group = null; + } + if ( (sel == null) && (blog == null) && (group == null) && (tag == null) ) sel = getDefaultSelector(user, parameters); if (sel != null) { @@ -453,13 +462,43 @@ public class ArchiveViewerBean { else index.selectMatchesOrderByEntryId(rv, s.blog, s.tag); } - return rv; } + PetNameDB db = user.getPetNameDB(); + for (Iterator iter = db.getNames().iterator(); iter.hasNext(); ) { + String name = (String)iter.next(); + PetName pn = db.get(name); + if ("syndie".equals(pn.getNetwork()) && "syndieblog".equals(pn.getProtocol()) && pn.isMember(group)) { + byte pnLoc[] = Base64.decode(pn.getLocation()); + if (pnLoc != null) { + Hash pnHash = new Hash(pnLoc); + index.selectMatchesOrderByEntryId(rv, pnHash, null); + } + } + } + if (rv.size() > 0) + return rv; } index.selectMatchesOrderByEntryId(rv, blog, tag); + filterIgnored(user, rv); return rv; } + private static void filterIgnored(User user, List uris) { + for (int i = 0; i < uris.size(); i++) { + BlogURI uri = (BlogURI)uris.get(i); + Hash k = uri.getKeyHash(); + if (k == null) continue; + String pname = user.getPetNameDB().getNameByLocation(k.toBase64()); + if (pname != null) { + PetName pn = user.getPetNameDB().get(pname); + if ( (pn != null) && (pn.isMember("Ignore")) ) { + uris.remove(i); + i--; + } + } + } + } + public static final String getString(Map parameters, String param) { if ( (parameters == null) || (parameters.get(param) == null) ) return null; diff --git a/apps/syndie/jsp/_bodyindex.jsp b/apps/syndie/jsp/_bodyindex.jsp index adafede9d12f74f361fbab593dfc6e52213b9087..e31810486bfa0f2e03a6c8d867acff876b1f8dcd 100644 --- a/apps/syndie/jsp/_bodyindex.jsp +++ b/apps/syndie/jsp/_bodyindex.jsp @@ -1,6 +1,37 @@ <%@page contentType="text/html; charset=UTF-8" import="net.i2p.syndie.web.ArchiveViewerBean, net.i2p.syndie.*" %> <% request.setCharacterEncoding("UTF-8"); %> -<jsp:useBean scope="session" class="net.i2p.syndie.User" id="user" /><table border="0" width="100%"> +<jsp:useBean scope="session" class="net.i2p.syndie.User" id="user" /><% +if (user.getAuthenticated() && (null != request.getParameter("action")) ) { + %><!-- <%=request.getParameterMap()%> --><% + String blog = request.getParameter("blog"); + String group = null; + if (request.getParameter("action").equals("Bookmark blog")) + group = "Favorites"; + else if (request.getParameter("action").equals("Ignore blog")) + group = "Ignore"; + boolean unignore = ("Unignore blog".equals(request.getParameter("action"))); + + String name = user.getPetNameDB().getNameByLocation(blog); + if (name == null) + name = request.getParameter("name"); + if (name == null) + name = blog; + if ( (name != null) && (blog != null) && ( (group != null) || (unignore) ) ) { + PetName pn = user.getPetNameDB().get(name); + if (pn != null) { + if (unignore) + pn.removeGroup("Ignore"); + else + pn.addGroup(group); + } else { + pn = new PetName(name, "syndie", "syndieblog", blog); + pn.addGroup(group); + user.getPetNameDB().set(name, pn); + } + BlogManager.instance().saveUser(user); + } +} +%><table border="0" width="100%"> <tr><form action="index.jsp"><td nowrap="true"> <b>Blogs:</b> <%ArchiveViewerBean.renderBlogSelector(user, request.getParameterMap(), out);%> <input type="submit" value="Refresh" /> diff --git a/apps/syndie/jsp/_topnav.jsp b/apps/syndie/jsp/_topnav.jsp index 43a2055d2d2497455581e064ed3b94e6a5b8735e..66c1ac764638243a21facf1df3d3a91b433e8fff 100644 --- a/apps/syndie/jsp/_topnav.jsp +++ b/apps/syndie/jsp/_topnav.jsp @@ -24,6 +24,7 @@ Logged in as: <b><jsp:getProperty property="username" name="user" />:</b> <a href="<%=HTMLRenderer.getPageURL(user.getBlog(), null, -1, -1, -1, user.getShowExpanded(), user.getShowImages())%>"><%=HTMLRenderer.sanitizeString(ArchiveViewerBean.getBlogName(user.getBlogStr()))%></a> <a href="<%=HTMLRenderer.getPostURL(user.getBlog())%>">Post</a> <a href="<%=HTMLRenderer.getMetadataURL(user.getBlog())%>">Metadata</a> +<a href="addresses.jsp">Addressbook</a> <a href="index.jsp?logout=true">Logout</a><br /> <%} else {%> Login: <input type="text" name="login" size="8" /> diff --git a/apps/syndie/jsp/addaddress.jsp b/apps/syndie/jsp/addaddress.jsp index 681e186dc48df11b37219af13f14a34c28d57ac1..9a63e9774d9664b51ad0346ea9f80c461b5d199f 100644 --- a/apps/syndie/jsp/addaddress.jsp +++ b/apps/syndie/jsp/addaddress.jsp @@ -14,13 +14,17 @@ <td valign="top" align="left" rowspan="2"><jsp:include page="_rightnav.jsp" /></td></tr> <tr><td valign="top" align="left" colspan="3"><% String nameStr = request.getParameter("name"); +String protoStr = request.getParameter("proto"); String locStr = request.getParameter("location"); String schemaStr = request.getParameter("schema"); String name = null; +String proto = null; String location = null; String schema = null; try { name = DataHelper.getUTF8(Base64.decode(nameStr)); + if ( (protoStr != null) && (protoStr.trim().length() > 0) ) + proto = DataHelper.getUTF8(Base64.decode(protoStr)); location = DataHelper.getUTF8(Base64.decode(locStr)); schema = DataHelper.getUTF8(Base64.decode(schemaStr)); } catch (NullPointerException npe) { @@ -30,7 +34,7 @@ try { if ( (name == null) || (location == null) || (schema == null) ) { out.write("<b>No location specified</b>"); } else if (user.getAuthenticated() && ("Add".equals(request.getParameter("action"))) ) { - out.write("<b>" + BlogManager.instance().addAddress(user, name, location, schema) + "</b>"); + out.write("<b>" + BlogManager.instance().addAddress(user, name, proto, location, schema) + "</b>"); } else { %>Are you sure you really want to add the addressbook mapping of <%=HTMLRenderer.sanitizeString(name)%> to <input type="text" size="20" value="<%=HTMLRenderer.sanitizeString(location)%>" />, applicable within the diff --git a/apps/syndie/jsp/addresses.jsp b/apps/syndie/jsp/addresses.jsp new file mode 100644 index 0000000000000000000000000000000000000000..e591dcad1cc11409ca3e1291d3514520bcbdff73 --- /dev/null +++ b/apps/syndie/jsp/addresses.jsp @@ -0,0 +1,158 @@ +<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="net.i2p.data.Base64, net.i2p.syndie.web.*, net.i2p.syndie.sml.*, net.i2p.syndie.data.*, net.i2p.syndie.*, org.mortbay.servlet.MultiPartRequest, java.util.*, java.io.*" %> +<% request.setCharacterEncoding("UTF-8"); %> +<jsp:useBean scope="session" class="net.i2p.syndie.User" id="user" /> +<html> +<head> +<title>SyndieMedia addressbook</title> +<link href="style.jsp" rel="stylesheet" type="text/css" /> +</head> +<body> +<table border="1" cellpadding="0" cellspacing="0" width="100%"> +<tr><td colspan="5" valign="top" align="left"><jsp:include page="_toplogo.jsp" /></td></tr> +<tr><td valign="top" align="left" rowspan="2"><jsp:include page="_leftnav.jsp" /></td> + <jsp:include page="_topnav.jsp" /> + <td valign="top" align="left" rowspan="2"><jsp:include page="_rightnav.jsp" /></td></tr> +<tr><td valign="top" align="left" colspan="3"><% +if (!user.getAuthenticated()) { + %>You must log in to view your addressbook<% +} else { + PetNameDB names = user.getPetNameDB(); + String action = request.getParameter("action"); + if ( (action != null) && ("Change".equals(action)) ) { + String oldPetname = request.getParameter("petname"); + PetName cur = names.get(oldPetname); + if (cur != null) { + cur.setName(request.getParameter("name")); + cur.setNetwork(request.getParameter("network")); + cur.setProtocol(request.getParameter("protocol")); + cur.setIsPublic(null != request.getParameter("isPublic")); + cur.setLocation(request.getParameter("location")); + cur.setGroups(request.getParameter("groups")); + names.store(user.getAddressbookLocation()); + %><b>Address updated</b><% + } + } else if ( (action != null) && ("Add".equals(action)) ) { + PetName cur = names.get(request.getParameter("name")); + if (cur != null) { %><b>Address already exists</b><% } else { + cur = new PetName(); + cur.setName(request.getParameter("name")); + cur.setNetwork(request.getParameter("network")); + cur.setProtocol(request.getParameter("protocol")); + cur.setIsPublic(null != request.getParameter("isPublic")); + cur.setLocation(request.getParameter("location")); + cur.setGroups(request.getParameter("groups")); + names.set(cur.getName(), cur); + names.store(user.getAddressbookLocation()); + %><b>Address added</b><% + } + } else if ( (action != null) && ("Delete".equals(action)) ) { + PetName cur = names.get(request.getParameter("name")); + if (cur != null) { + names.remove(cur.getName()); + names.store(user.getAddressbookLocation()); + %><b>Address removed</b><% + } + } + TreeSet sorted = new TreeSet(names.getNames()); + %><table border="0" width="100%"> +<tr><td><b>Name</b></td><td><b>Network</b></td><td><b>Protocol</b></td><td><b>Location</b></td><td><b>Public?</b></td><td><b>Groups</b><td> </td></tr> +<% + StringBuffer buf = new StringBuffer(128); + for (Iterator iter = sorted.iterator(); iter.hasNext(); ) { + PetName name = names.get((String)iter.next()); + buf.append("<tr><form action=\"addresses.jsp\" method=\"POST\">"); + buf.append("<input type=\"hidden\" name=\"petname\" value=\"").append(name.getName()).append("\" />"); + buf.append("<td><input type=\"text\" size=\"20\" name=\"name\" value=\"").append(name.getName()).append("\" /></td><td>"); + buf.append("<select name=\"network\">"); + String net = name.getNetwork(); + if (net == null) net = ""; + buf.append("<option value=\"i2p\" "); + if ("i2p".equals(net)) + buf.append("selected=\"true\" "); + buf.append("/>I2P</option>"); + + buf.append("<option value=\"syndie\" "); + if ( ("syndie".equals(net)) || ("".equals(net)) ) + buf.append("selected=\"true\" "); + buf.append("/>Syndie</option>"); + + buf.append("<option value=\"tor\" "); + if ("tor".equals(net)) + buf.append("selected=\"true\" "); + buf.append("/>TOR</option>"); + + buf.append("<option value=\"freenet\" "); + if ("freenet".equals(net)) + buf.append("selected=\"true\" "); + buf.append("/>Freenet</option>"); + + buf.append("<option value=\"internet\" "); + if ("internet".equals(net)) + buf.append("selected=\"true\" "); + buf.append("/>Internet</option>"); + + buf.append("</select></td><td><select name=\"protocol\">"); + String proto = name.getProtocol(); + if (proto == null) proto = ""; + + buf.append("<option value=\"http\" "); + if ("http".equals(proto)) + buf.append("selected=\"true\" "); + buf.append("/>HTTP</option>"); + + buf.append("<option value=\"irc\" "); + if ("irc".equals(proto)) + buf.append("selected=\"true\" "); + buf.append("/>IRC</option>"); + + buf.append("<option value=\"i2phex\" "); + if ("i2phex".equals(proto)) + buf.append("selected=\"true\" "); + buf.append("/>I2Phex</option>"); + + buf.append("<option value=\"syndiearchive\" "); + if ("syndiearchive".equals(proto)) + buf.append("selected=\"true\" "); + buf.append("/>Syndie archive</option>"); + + buf.append("<option value=\"syndieblog\" "); + if ("syndieblog".equals(proto)) + buf.append("selected=\"true\" "); + buf.append("/>Syndie blog</option>"); + + buf.append("</select></td><td>"); + if (name.getLocation() != null) + buf.append("<input name=\"location\" size=\"50\" value=\"").append(name.getLocation()).append("\" />"); + else + buf.append("<input name=\"location\" size=\"50\" value=\"\" />"); + + buf.append("</td><td><input type=\"checkbox\" name=\"isPublic\" "); + if (name.getIsPublic()) + buf.append("checked=\"true\" "); + buf.append(" /></td><td><input type=\"text\" name=\"groups\" size=\"10\" value=\""); + for (int j = 0; j < name.getGroupCount(); j++) { + buf.append(HTMLRenderer.sanitizeTagParam(name.getGroup(j))); + if (j + 1 < name.getGroupCount()) + buf.append(','); + } + buf.append("\" /></td><td nowrap=\"true\">"); + buf.append("<input type=\"submit\" name=\"action\" value=\"Change\" /> <input type=\"submit\" name=\"action\" value=\"Delete\" />"); + buf.append("</td></form></tr>"); + out.write(buf.toString()); + buf.setLength(0); + } + %> + <tr><form action="addresses.jsp" method="POST"><td><input type="text" name="name" size="20" /></td> + <td><select name="network"><option value="i2p">I2P</option><option value="syndie">Syndie</option><option value="tor">Tor</option><option value="freenet">Freenet</option><option value="internet">Internet</option></select></td> + <td><select name="protocol"><option value="http">HTTP</option><option value="irc">IRC</option><option value="i2phex">I2Phex</option><option value="syndiearchive">Syndie archive</option><option value="syndieblog">Syndie blog</option></select></td> + <td><input type="text" size="50" name="location" /></td> + <td><input type="checkbox" name="isPublic" /></td> + <td><input type="text" name="groups" size="10" /></td> + <td><input type="submit" name="action" value="Add" /></td> + </form></tr> + </table><% +} +%> +</td></tr> +</table> +</body> diff --git a/history.txt b/history.txt index ef2770b47b96b01f14934d5df18f1faf20778ed6..393a46bf24e5a020b53c14a6cf6c47ec16d56e74 100644 --- a/history.txt +++ b/history.txt @@ -1,4 +1,12 @@ -$Id: history.txt,v 1.236 2005/09/02 13:34:14 jrandom Exp $ +$Id: history.txt,v 1.237 2005/09/02 14:10:05 jrandom Exp $ + +2005-09-04 jrandom + * Don't persist peer profiles until we are shutting down, as the + persistence process gobbles RAM and wall time. + * Bugfix to allow you to check/uncheck the sharedClient setting on the + I2PTunnel web interface. + * Be more careful when expiring a failed tunnel message fragment so we + don't drop the data while attempting to read it. * 2005-09-02 0.6.0.5 released diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 02d92e0b7be14aca33bae3c2fcef781bf33ba9cb..7ac878557595a23a4a75a769ab928d9c6731054a 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -15,9 +15,9 @@ import net.i2p.CoreVersion; * */ public class RouterVersion { - public final static String ID = "$Revision: 1.225 $ $Date: 2005/09/02 13:34:15 $"; + public final static String ID = "$Revision: 1.226 $ $Date: 2005/09/02 14:10:06 $"; public final static String VERSION = "0.6.0.5"; - public final static long BUILD = 0; + public final static long BUILD = 1; public static void main(String args[]) { System.out.println("I2P Router version: " + VERSION); System.out.println("Router ID: " + RouterVersion.ID); diff --git a/router/java/src/net/i2p/router/peermanager/PeerManager.java b/router/java/src/net/i2p/router/peermanager/PeerManager.java index 68aa11e9b7ec241a4d3de7e8188c9dae92963abd..9eae7279156c4b3e403fdd530b1352659d30024c 100644 --- a/router/java/src/net/i2p/router/peermanager/PeerManager.java +++ b/router/java/src/net/i2p/router/peermanager/PeerManager.java @@ -39,7 +39,7 @@ class PeerManager { _organizer.setUs(context.routerHash()); loadProfiles(); _context.jobQueue().addJob(new EvaluateProfilesJob(_context)); - _context.jobQueue().addJob(new PersistProfilesJob(_context, this)); + //_context.jobQueue().addJob(new PersistProfilesJob(_context, this)); } void storeProfiles() { diff --git a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java index 4b80c32e12e66d8b450ff1d07f2092077f7c1aea..b3ea7dac9788cf3e0584032bb1fab9321eb3d34b 100644 --- a/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java +++ b/router/java/src/net/i2p/router/transport/udp/PeerTestManager.java @@ -408,7 +408,7 @@ class PeerTestManager { charlieInfo = _context.netDb().lookupRouterInfoLocally(charlie.getRemotePeer()); } - if (charlie == null) { + if ( (charlie == null) || (charlieInfo == null) ) { if (_log.shouldLog(Log.WARN)) _log.warn("Unable to pick a charlie"); return; diff --git a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java index 9aefba1f39553062311aaefe4545971357be2be9..e8f81d50b494fb488055bd320120c9e0e206def7 100644 --- a/router/java/src/net/i2p/router/tunnel/FragmentHandler.java +++ b/router/java/src/net/i2p/router/tunnel/FragmentHandler.java @@ -353,6 +353,8 @@ public class FragmentHandler { _completed++; try { byte data[] = msg.toByteArray(); + if (msg == null) + return; if (_log.shouldLog(Log.DEBUG)) _log.debug("RECV(" + data.length + "): " + Base64.encode(data) + " " + _context.sha().calculateHash(data).toBase64()); diff --git a/router/java/src/net/i2p/router/tunnel/FragmentedMessage.java b/router/java/src/net/i2p/router/tunnel/FragmentedMessage.java index d39a5e56b2b950c86f1c0f516db6620b27083366..186843d815512fa7f5518553b267d091cfcb3d80 100644 --- a/router/java/src/net/i2p/router/tunnel/FragmentedMessage.java +++ b/router/java/src/net/i2p/router/tunnel/FragmentedMessage.java @@ -214,15 +214,20 @@ public class FragmentedMessage { _completed = true; } public byte[] toByteArray() { - byte rv[] = new byte[getCompleteSize()]; - writeComplete(rv, 0); - releaseFragments(); - return rv; + synchronized (this) { + if (_releasedAfter > 0) return null; + byte rv[] = new byte[getCompleteSize()]; + writeComplete(rv, 0); + releaseFragments(); + return rv; + } } public long getReleasedAfter() { return _releasedAfter; } public void failed() { - releaseFragments(); + synchronized (this) { + releaseFragments(); + } } /**