Author: fred Date: 2007-04-23 22:41:07 +0000 (Mon, 23 Apr 2007) New Revision: 12908
Added: trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java trunk/freenet/src/freenet/clients/http/bookmark/ trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategories.java trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItems.java trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java trunk/freenet/src/freenet/clients/http/staticfiles/bookmark.css trunk/freenet/src/freenet/clients/http/staticfiles/icon/ trunk/freenet/src/freenet/clients/http/staticfiles/icon/bookmark-new.png trunk/freenet/src/freenet/clients/http/staticfiles/icon/delete.png trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit-delete.png trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit.png trunk/freenet/src/freenet/clients/http/staticfiles/icon/folder-new.png trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-down.png trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-up.png Removed: trunk/freenet/src/freenet/clients/http/Bookmark.java trunk/freenet/src/freenet/clients/http/BookmarkManager.java Modified: trunk/freenet/src/freenet/clients/http/FProxyToadlet.java trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java trunk/freenet/src/freenet/clients/http/staticfiles/themes/boxed/theme.css trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css trunk/freenet/src/freenet/clients/http/staticfiles/themes/grayandblue/theme.css trunk/freenet/src/freenet/clients/http/staticfiles/themes/sky/theme.css trunk/freenet/src/freenet/node/NodeClientCore.java Log: Bookmarks are now organized by categories, new bookmark editor Deleted: trunk/freenet/src/freenet/clients/http/Bookmark.java =================================================================== --- trunk/freenet/src/freenet/clients/http/Bookmark.java 2007-04-23 22:28:38 UTC (rev 12907) +++ trunk/freenet/src/freenet/clients/http/Bookmark.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -1,143 +0,0 @@ -/* This code is part of Freenet. It is distributed under the GNU General - * Public License, version 2 (or at your option any later version). See - * http://www.gnu.org/ for further details of the GPL. */ -package freenet.clients.http; - -import freenet.keys.FreenetURI; -import freenet.keys.USK; -import freenet.node.NodeClientCore; -import freenet.node.useralerts.UserAlert; -import freenet.node.useralerts.UserAlertManager; -import freenet.support.HTMLNode; - -import java.net.MalformedURLException; - -public class Bookmark { - - private FreenetURI key; - private String desc; - private boolean updated; - private final BookmarkUpdatedUserAlert alert; - private UserAlertManager alerts; - - private class BookmarkUpdatedUserAlert implements UserAlert { - - public boolean userCanDismiss() { - return true; - } - - public String getTitle() { - return "Bookmark updated: "+desc; - } - - public String getText() { - return "The bookmarked site "+desc+" has been updated to edition "+key.getSuggestedEdition(); - } - - public HTMLNode getHTMLText() { - HTMLNode n = new HTMLNode("div"); - n.addChild("#", "The bookmarked site "); - n.addChild("a", "href", '/'+key.toString()).addChild("#", desc); - n.addChild("#", " has been updated to edition "+key.getSuggestedEdition()+"."); - return n; - } - - public short getPriorityClass() { - return UserAlert.MINOR; - } - - public boolean isValid() { - synchronized(Bookmark.this) { - return updated; - } - } - - public void isValid(boolean validity) { - if(validity) return; - disableBookmark(); - } - - public String dismissButtonText() { - return "Delete notification"; - } - - public boolean shouldUnregisterOnDismiss() { - return true; - } - - public void onDismiss() { - disableBookmark(); - } - - } - - private synchronized void disableBookmark() { - updated = false; - alerts.unregister(alert); - } - - private synchronized void enableBookmark() { - if(updated) return; - updated = true; - alerts.register(alert); - } - - Bookmark(String k, String d, UserAlertManager uam) throws MalformedURLException { - this.key = new FreenetURI(k); - this.desc = d; - alert = new BookmarkUpdatedUserAlert(); - this.alerts = uam; - } - - Bookmark(String from, UserAlertManager uam) throws MalformedURLException { - int eqpos = from.indexOf("="); - - if (eqpos < 0) { - this.key = new FreenetURI(from); - this.desc = from; - } else { - this.key = new FreenetURI(from.substring(0, eqpos)); - this.desc = from.substring(eqpos + 1); - } - alert = new BookmarkUpdatedUserAlert(); - this.alerts = uam; - } - - public String getKey() { - return key.toString(); - } - - public synchronized FreenetURI getURI() { - return key; - } - - public synchronized void setKey(FreenetURI uri) { - key = uri; - } - - public synchronized String getKeyType() { - return key.getKeyType(); - } - - public String getDesc() { - if (desc.equals("")) { - return "Unnamed Bookmark"; - } else { - return desc; - } - } - - public String toString() { - return this.key.toString() + '=' + this.desc; - } - - public synchronized void setEdition(long ed, NodeClientCore node) { - if(key.getSuggestedEdition() >= ed) return; - key = key.setSuggestedEdition(ed); - enableBookmark(); - } - - public USK getUSK() throws MalformedURLException { - return USK.create(key); - } -} \ No newline at end of file Added: trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java =================================================================== --- trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java (rev 0) +++ trunk/freenet/src/freenet/clients/http/BookmarkEditorToadlet.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -0,0 +1,272 @@ +package freenet.clients.http; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import freenet.node.Node; + +import freenet.clients.http.bookmark.Bookmark; +import freenet.clients.http.bookmark.BookmarkItem; +import freenet.clients.http.bookmark.BookmarkItems; +import freenet.clients.http.bookmark.BookmarkCategory; +import freenet.clients.http.bookmark.BookmarkCategories; +import freenet.clients.http.bookmark.BookmarkManager; + +import freenet.node.useralerts.UserAlertManager; +import freenet.keys.FreenetURI; +import freenet.node.NodeClientCore; +import freenet.client.HighLevelSimpleClient; +import freenet.support.HTMLEncoder; +import freenet.support.HTMLNode; +import freenet.support.api.HTTPRequest; + +public class BookmarkEditorToadlet extends Toadlet { + + private static final int MAX_ACTION_LENGTH = 20; + private static final int MAX_KEY_LENGTH = QueueToadlet.MAX_KEY_LENGTH; + private static final int MAX_NAME_LENGTH = 500; + private static final int MAX_BOOKMARK_PATH_LENGTH = 10 * MAX_NAME_LENGTH; + + private final Node node; + private final NodeClientCore core; + private final BookmarkManager bookmarkManager; + + + BookmarkEditorToadlet(HighLevelSimpleClient client, Node node) + { + super(client); + this.node = node; + this.core = node.clientCore; + this.bookmarkManager = core.bookmarkManager; + } + + private void addCategoryToList(BookmarkCategory cat, String path, HTMLNode list) + { + BookmarkItems items = cat.getItems(); + + for(int i = 0; i < items.size(); i++) { + + String itemPath = path + items.get(i).getName(); + HTMLNode li = new HTMLNode("li", "class","item" , items.get(i).getName()); + + HTMLNode actions = new HTMLNode("span", "class", "actions"); + actions.addChild("a", "href", "?action=edit&bookmark=" + itemPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/edit.png", "edit", "Edit"}); + + actions.addChild("a", "href", "?action=del&bookmark=" + itemPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/delete.png", "delete", "Delete"}); + + if(i != 0) + actions.addChild("a", "href", "?action=up&bookmark=" + itemPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/go-up.png", "up", "Go up"}); + + if(i != items.size()-1) + actions.addChild("a", "href", "?action=down&bookmark=" + itemPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/go-down.png", "down", "Go down"}); + + li.addChild(actions); + list.addChild(li); + } + + BookmarkCategories cats = cat.getSubCategories(); + for(int i = 0; i < cats.size(); i++) { + + String catPath = path + cats.get(i).getName() + "/"; + + HTMLNode subCat = list.addChild("li", "class", "cat", cats.get(i).getName()); + + HTMLNode actions = new HTMLNode("span", "class", "actions"); + + actions.addChild("a", "href", "?action=edit&bookmark=" + catPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/edit.png", "edit", "Edit"}); + + actions.addChild("a", "href", "?action=del&bookmark=" + catPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/delete.png", "delete", "Delete"}); + + actions.addChild("a", "href", "?action=addItem&bookmark=" + catPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/bookmark-new.png", "add bookmark", "Add bookmark"}); + + actions.addChild("a", "href", "?action=addCat&bookmark=" + catPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/folder-new.png", "add category", "Add category"}); + + if(i != 0) + actions.addChild("a", "href", "?action=up&bookmark=" + catPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/go-up.png", "up", "Go up"}); + + if(i != cats.size() -1) + actions.addChild("a", "href", "?action=down&bookmark=" + catPath).addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/go-down.png", "down", "Go down"}); + + subCat.addChild(actions); + addCategoryToList(cats.get(i), catPath, list.addChild("li").addChild("ul")); + } + } + + public HTMLNode getBookmarksList() + { + HTMLNode bookmarks = new HTMLNode("ul", "id", "bookmarks"); + + HTMLNode root = bookmarks.addChild("li", "class", "cat,root", "/"); + HTMLNode actions = new HTMLNode("span", "class", "actions"); + actions.addChild("a", "href", "?action=addItem&bookmark=/").addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/bookmark-new.png", "add bookmark", "Add bookmark"}); + actions.addChild("a", "href", "?action=addCat&bookmark=/").addChild("img", new String[] {"src", "alt", "title"}, new String[] {"/static/icon/folder-new.png", "add category", "Add category"}); + root.addChild(actions); + + addCategoryToList(bookmarkManager.getMainCategory(), "/", root.addChild("li").addChild("ul")); + + return bookmarks; + } + + public void handleGet(URI uri, HTTPRequest req, ToadletContext ctx) + throws ToadletContextClosedException, IOException + { + + HTMLNode pageNode = ctx.getPageMaker().getPageNode("Bookmark Editor", ctx); + HTMLNode content = ctx.getPageMaker().getContentNode(pageNode); + + if (req.getParam("action").length() > 0 && req.getParam("bookmark").length() > 0) { + String action = req.getParam("action"); + String bookmarkPath = req.getParam("bookmark"); + Bookmark bookmark; + + if (bookmarkPath.endsWith("/")) + bookmark = bookmarkManager.getCategoryByPath(bookmarkPath); + else + bookmark = bookmarkManager.getItemByPath(bookmarkPath); + + if(bookmark == null) { + HTMLNode errorBox = content.addChild(ctx.getPageMaker().getInfobox("infobox-error", "Error")); + errorBox.addChild("#", "Bookmark \""+ bookmarkPath + "\" does not exists."); + } else { + + if(action.equals("del")){ + + HTMLNode infoBox = content.addChild(ctx.getPageMaker().getInfobox("infobox-query", "Delete " + (bookmark instanceof BookmarkItem ? "bookmark" : "category"))); + + String query = "Are you sure you wish to delete " + bookmarkPath; + if(bookmark instanceof BookmarkCategory) + query+= " and all its children"; + query+= " ?"; + infoBox.addChild("p").addChild("#", query); + + HTMLNode confirmForm = ctx.addFormChild(infoBox.addChild("p"), "", "confirmDeleteForm"); + confirmForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "hidden", "bookmark", bookmarkPath}); + confirmForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "submit", "cancel", "Cancel" }); + confirmForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "submit", "confirmdelete", "Delete" }); + + + } else if (action.equals("edit") || action.equals("addItem") || action.equals("addCat")) { + + String header; + if(action.equals("edit")) + header = "Edit "+(bookmark instanceof BookmarkItem ? "bookmark" : "category"); + else if(action.equals("addItem")) + header = "Add a new bookmark"; + else + header = "Add a new category"; + + HTMLNode actionBox = content.addChild(ctx.getPageMaker().getInfobox("infobox-query", header)); + + HTMLNode form = ctx.addFormChild(actionBox, "", "editBookmarkForm"); + + form.addChild("label", "for", "name", "Name : "); + form.addChild("input", new String[]{"type", "id", "name", "size", "value"}, new String []{"text", "name", "name", "20", action.equals("edit")?bookmark.getName():""}); + + form.addChild("br"); + if ((action.equals("edit") && bookmark instanceof BookmarkItem) || action.equals("addItem")) { + String key = (action.equals("edit") ? ((BookmarkItem) bookmark).getKey() : ""); + form.addChild("label", "for", "key", "Key : "); + form.addChild("input", new String[]{"type", "id", "name", "size", "value"}, new String []{"text", "key", "key", "50", key}); + } + + form.addChild("input", new String[] {"type", "name", "value"}, new String[] {"hidden", "bookmark",bookmarkPath}); + + form.addChild("input", new String[] {"type", "name", "value"}, new String[] {"hidden", "action",req.getParam("action")}); + + form.addChild("br"); + form.addChild("input", new String[]{"type", "value"}, new String[]{"submit", "Save"}); + } else if (action.equals("up") || action.equals("down")) { + if(action.equals("up")) + bookmarkManager.moveBookmarkUp(bookmarkPath, true); + else + bookmarkManager.moveBookmarkDown(bookmarkPath, true); + } + } + + } + + HTMLNode bookmarksBox = content.addChild(ctx.getPageMaker().getInfobox("infobox-normal", "My Bookmarks")); + bookmarksBox.addChild(getBookmarksList()); + + this.writeReply(ctx, 200, "text/html", "OK", pageNode.generate()); + } + + + public void handlePost(URI uri, HTTPRequest req, ToadletContext ctx) + throws ToadletContextClosedException, IOException + { + HTMLNode pageNode = ctx.getPageMaker().getPageNode("Bookmark Editor", ctx); + HTMLNode content = ctx.getPageMaker().getContentNode(pageNode); + + String passwd = req.getPartAsString("formPassword", 32); + boolean noPassword = (passwd == null) || !passwd.equals(core.formPassword); + if(noPassword) + return; + + + String bookmarkPath = req.getPartAsString("bookmark", MAX_BOOKMARK_PATH_LENGTH); + try { + + Bookmark bookmark; + if(bookmarkPath.endsWith("/")) + bookmark = bookmarkManager.getCategoryByPath(bookmarkPath); + else + bookmark = bookmarkManager.getItemByPath(bookmarkPath); + + String action = req.getPartAsString("action", MAX_ACTION_LENGTH); + + if (req.isPartSet("confirmdelete")) { + bookmarkManager.removeBookmark(bookmarkPath, true); + HTMLNode successBox = content.addChild(ctx.getPageMaker().getInfobox("infobox-success", "Delete succeeded")); + successBox.addChild("p", "The bookmark has been deleted successfully"); + + } else if (action.equals("edit") || action.equals("addItem") || action.equals("addCat")) { + + String name = "unnamed"; + if (req.getPartAsString("name", MAX_NAME_LENGTH).length() > 0) + name = req.getPartAsString("name", MAX_NAME_LENGTH); + + if(action.equals("edit")) { + bookmarkManager.renameBookmark(bookmarkPath, name); + if(bookmark instanceof BookmarkItem) + ((BookmarkItem) bookmark).setKey(new FreenetURI(req.getPartAsString("key", MAX_KEY_LENGTH))); + + HTMLNode successBox = content.addChild(ctx.getPageMaker().getInfobox("infobox-success", "Modifications saved")); + successBox.addChild("p", "The changes has been saved successfully"); + + } else if (action.equals("addItem") || action.equals("addCat")) { + + Bookmark newBookmark; + if(action.equals("addItem")) { + FreenetURI key = new FreenetURI(req.getPartAsString("key", MAX_KEY_LENGTH)); + newBookmark = new BookmarkItem(key, name, core.alerts); + } else + newBookmark = new BookmarkCategory(name); + + bookmarkManager.addBookmark(bookmarkPath, newBookmark, true); + + HTMLNode successBox = content.addChild(ctx.getPageMaker().getInfobox("infobox-success", "New bookmark added")); + successBox.addChild("p", "The new bookmark has been added successfully"); + + } + + } + + } catch (NullPointerException npo) { + HTMLNode errorBox = content.addChild(ctx.getPageMaker().getInfobox("infobox-error", "Error")); + errorBox.addChild("#", "Bookmark \""+ bookmarkPath + "\" does not exists."); + } catch (MalformedURLException mue) { + HTMLNode errorBox = content.addChild(ctx.getPageMaker().getInfobox("infobox-error", "Invalid key")); + errorBox.addChild("#", "Invalid Freenet Key"); + } + HTMLNode bookmarksBox = content.addChild(ctx.getPageMaker().getInfobox("infobox-normal", "My Bookmarks")); + bookmarksBox.addChild(getBookmarksList()); + + this.writeReply(ctx, 200, "text/html", "OK", pageNode.generate()); + } + + public String supportedMethods() + { + return "GET, POST"; + } +} Deleted: trunk/freenet/src/freenet/clients/http/BookmarkManager.java =================================================================== --- trunk/freenet/src/freenet/clients/http/BookmarkManager.java 2007-04-23 22:28:38 UTC (rev 12907) +++ trunk/freenet/src/freenet/clients/http/BookmarkManager.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -1,181 +0,0 @@ -/* This code is part of Freenet. It is distributed under the GNU General - * Public License, version 2 (or at your option any later version). See - * http://www.gnu.org/ for further details of the GPL. */ -package freenet.clients.http; - -import java.net.MalformedURLException; -import java.util.Enumeration; -import java.util.Vector; - -import freenet.client.async.USKCallback; -import freenet.config.InvalidConfigValueException; -import freenet.config.SubConfig; -import freenet.keys.FreenetURI; -import freenet.keys.USK; -import freenet.node.NodeClientCore; -import freenet.support.api.StringArrCallback; - -public class BookmarkManager { - private static final String[] DEFAULT_TESTNET_BOOKMARKS = { - "USK at 60I8H8HinpgZSOuTSD66AVlIFAy-xsppFr0YCzCar7c,NzdivUGCGOdlgngOGRbbKDNfSCnjI0FXjHLzJM4xkJ4,AQABAAE/index/4/=INDEX.7-freesite" - }; - private static final String[] DEFAULT_DARKNET_BOOKMARKS = { - "USK at c55vMxUl-T-lD3nv0iOaXF~G1hnY6pOMRbzZSwACMmY,yd8~uwUmGm164-ipStoiBOJVjkbbYXJMlD~H5ftPxIA,AQABAAE/Indicia/55/=Indicia (Lots of freesites - web sites hosted on freenet)", - "USK at 7H66rhYmxIFgMyw5Dl11JazXGHPhp7dSN7WMa1pbtEo,jQHUQUPTkeRcjmjgrc7t5cDRdDkK3uKkrSzuw5CO9uk,AQACAAE/ENTRY.POINT/19/=Entry Point (Lots of freesites - web sites hosted on freenet)", - "USK at PFeLTa1si2Ml5sDeUy7eDhPso6TPdmw-2gWfQ4Jg02w,3ocfrqgUMVWA2PeorZx40TW0c-FiIOL-TWKQHoDbVdE,AQABAAE/Index/42/=Darknet Index (Older freesite index)" - }; - private Vector bookmarks; - private final NodeClientCore node; - private USKUpdatedCallback uskcb; - private boolean started; - - public class BookmarkCallback implements StringArrCallback { - public String[] get() { - synchronized(BookmarkManager.this) { - String[] values = new String[bookmarks.size()]; - for(int i=0;i<bookmarks.size();i++) - values[i] = bookmarks.get(i).toString(); - return values; - } - } - - public void set(String[] newvals) throws InvalidConfigValueException { - bookmarks.clear(); - for (int i = 0; i < newvals.length; i++) { - try { - bookmarks.add(new Bookmark(newvals[i], node.alerts)); - } catch (MalformedURLException mue) { - throw new InvalidConfigValueException(mue.getMessage()); - } - } - } - } - - private class USKUpdatedCallback implements USKCallback { - public void onFoundEdition(long edition, USK key) { - - for (Enumeration e = bookmarks.elements(); e.hasMoreElements(); ) { - Bookmark b = (Bookmark) e.nextElement(); - - if (!b.getKeyType().equals("USK")) continue; - - try { - FreenetURI furi = new FreenetURI(b.getKey()); - USK usk = USK.create(furi); - - if (usk.equals(key, false)) { - b.setEdition(key.suggestedEdition, node); - break; - } - } catch (MalformedURLException mue) { - } - } - node.storeConfig(); - } - } - - public BookmarkManager(NodeClientCore n, SubConfig sc) { - this.bookmarks = new Vector(); - this.node = n; - this.uskcb = new USKUpdatedCallback(); - sc.register("bookmarks", n.isTestnetEnabled() ? DEFAULT_TESTNET_BOOKMARKS : DEFAULT_DARKNET_BOOKMARKS, 0, true, false, "BookmarkManager.list", "BookmarkManager.listLong", makeCB()); - - String[] initialbookmarks = sc.getStringArr("bookmarks"); - for (int i = 0; i < initialbookmarks.length; i++) { - try { - addBookmark(new Bookmark(initialbookmarks[i], n.alerts), false); - } catch (MalformedURLException mue) { - // just ignore that one - } - } - synchronized(this) { - started = true; - } - } - - public BookmarkCallback makeCB() { - return new BookmarkCallback(); - } - - public Enumeration getBookmarks() { - return this.bookmarks.elements(); - } - - public FreenetURI[] getBookmarkURIs() { - Bookmark[] b = (Bookmark[]) bookmarks.toArray(new Bookmark[bookmarks.size()]); - FreenetURI[] uris = new FreenetURI[b.length]; - for(int i=0;i<uris.length;i++) { - uris[i] = b[i].getURI(); - } - return uris; - } - - public void clear() { - for (Enumeration e = this.bookmarks.elements(); e.hasMoreElements(); ) { - Bookmark i = (Bookmark)e.nextElement(); - - if (!i.getKeyType().equals("USK")) continue; - - try { - USK u = i.getUSK(); - this.node.uskManager.unsubscribe(u, this.uskcb, true); - } catch (MalformedURLException mue) { - - } - } - this.bookmarks.clear(); - } - - public void addBookmark(Bookmark b, boolean store) { - this.bookmarks.add(b); - if (b.getKeyType().equals("USK")) { - try { - USK u = b.getUSK(); - this.node.uskManager.subscribe(u, this.uskcb, true, this); - } catch (MalformedURLException mue) { - - } - } - if(store && started) node.storeConfig(); - } - - public void removeBookmark(Bookmark b, boolean store) { - if (b.getKeyType().equals("USK")) { - try { - USK u = b.getUSK(); - this.node.uskManager.unsubscribe(u, this.uskcb, true); - } catch (MalformedURLException mue) { - - } - } - this.bookmarks.remove(b); - if(store && started) node.storeConfig(); - } - - public void moveBookmarkDown (Bookmark b, boolean store) { - int i = this.bookmarks.indexOf(b); - if (i == -1) return; - - Bookmark bk = (Bookmark)this.bookmarks.get(i); - this.bookmarks.remove(i); - this.bookmarks.add((i+1)%(this.bookmarks.size()+1), bk); - - if(store && started) node.storeConfig(); - } - - public void moveBookmarkUp (Bookmark b, boolean store) { - int i = this.bookmarks.indexOf(b); - if (i == -1) return; - - Bookmark bk = (Bookmark)this.bookmarks.get(i); - this.bookmarks.remove(i); - if (--i < 0) i = this.bookmarks.size(); - this.bookmarks.add(i, bk); - - if(store && started) node.storeConfig(); - } - - public int getSize() { - return this.bookmarks.size(); - } -} Modified: trunk/freenet/src/freenet/clients/http/FProxyToadlet.java =================================================================== --- trunk/freenet/src/freenet/clients/http/FProxyToadlet.java 2007-04-23 22:28:38 UTC (rev 12907) +++ trunk/freenet/src/freenet/clients/http/FProxyToadlet.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -609,6 +609,9 @@ LocalFileInsertToadlet localFileInsertToadlet = new LocalFileInsertToadlet(core, client); server.register(localFileInsertToadlet, "/files/", true, false); + + BookmarkEditorToadlet bookmarkEditorToadlet = new BookmarkEditorToadlet(client, node); + server.register(bookmarkEditorToadlet, "/bookmarkEditor/", true, false); BrowserTestToadlet browsertTestToadlet = new BrowserTestToadlet(client, core); server.register(browsertTestToadlet, "/test/", true, false); Modified: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java =================================================================== --- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java 2007-04-23 22:28:38 UTC (rev 12907) +++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -20,6 +20,11 @@ import freenet.client.InsertBlock; import freenet.client.InserterException; import freenet.clients.http.filter.GenericReadFilterCallback; +import freenet.clients.http.bookmark.BookmarkItem; +import freenet.clients.http.bookmark.BookmarkItems; +import freenet.clients.http.bookmark.BookmarkCategory; +import freenet.clients.http.bookmark.BookmarkCategories; +import freenet.clients.http.bookmark.BookmarkManager; import freenet.keys.FreenetURI; import freenet.node.Node; import freenet.node.NodeClientCore; @@ -32,9 +37,12 @@ import freenet.support.api.Bucket; import freenet.support.api.HTTPRequest; + import freenet.frost.message.*; + + public class WelcomeToadlet extends Toadlet { private final static int MODE_ADD = 1; private final static int MODE_EDIT = 2; @@ -43,13 +51,13 @@ private static final int MAX_NAME_LENGTH = 1024 * 1024; final NodeClientCore core; final Node node; - final BookmarkManager bookmarks; + final BookmarkManager bookmarkManager; WelcomeToadlet(HighLevelSimpleClient client, Node node) { super(client); this.node = node; this.core = node.clientCore; - this.bookmarks = core.bookmarkManager; + this.bookmarkManager = core.bookmarkManager; try { manageBookmarksURI = new URI("/welcome/?managebookmarks"); } catch (URISyntaxException e) { @@ -66,6 +74,22 @@ URI manageBookmarksURI; + + private void addCategoryToList(BookmarkCategory cat, HTMLNode list) + { + BookmarkItems items = cat.getItems(); + for(int i = 0; i < items.size(); i++) { + HTMLNode li = list.addChild("li", "class","item"); + li.addChild("a", "href", "/" + items.get(i).getKey(), items.get(i).getName()); + } + + BookmarkCategories cats = cat.getSubCategories(); + for (int i = 0; i < cats.size(); i++) { + HTMLNode subCat = list.addChild("li", "class", "cat", cats.get(i).getName()); + addCategoryToList(cats.get(i), list.addChild("li").addChild("ul")); + } + } + public void handlePost(URI uri, HTTPRequest request, ToadletContext ctx) throws ToadletContextClosedException, IOException { if(!ctx.isAllowedFullAccess()) { @@ -147,58 +171,6 @@ ctx.getPageMaker().getContentNode(infobox).addChild("#", "Runtime database statistics have been written to the wrapper logfile"); this.writeReply(ctx, 200, "text/html", "OK", pageNode.generate()); - }else if (request.isPartSet("addbookmark")) { - if(noPassword) { - redirectToRoot(ctx); - return; - } - String key = request.getPartAsString("key", MAX_KEY_LENGTH); - String name = request.getPartAsString("name", MAX_NAME_LENGTH); - try { - bookmarks.addBookmark(new Bookmark(key, name, core.alerts), true); - } catch (MalformedURLException mue) { - this.sendBookmarkEditPage(ctx, MODE_ADD, null, key, name, "Given key does not appear to be a valid Freenet key."); - return; - } - - this.handleGet(manageBookmarksURI, new HTTPRequestImpl(manageBookmarksURI), ctx); - } else if (request.isPartSet("managebookmarks")) { - if(noPassword) { - redirectToRoot(ctx); - return; - } - Enumeration e = bookmarks.getBookmarks(); - while (e.hasMoreElements()) { - Bookmark b = (Bookmark)e.nextElement(); - - if (request.isPartSet("delete_"+b.hashCode())) { - bookmarks.removeBookmark(b, true); - break; - } else if (request.isPartSet("movedown_"+b.hashCode())) { - bookmarks.moveBookmarkDown(b, true); - break; - } else if (request.isPartSet("moveup_"+b.hashCode())) { - bookmarks.moveBookmarkUp(b, true); - break; - } else if (request.isPartSet("edit_"+b.hashCode())) { - this.sendBookmarkEditPage(ctx, b); - return; - } else if (request.isPartSet("update_"+b.hashCode())) { - // removing it and adding means that any USK subscriptions are updated properly - String key = request.getPartAsString("key", MAX_KEY_LENGTH); - String name = request.getPartAsString("name", MAX_NAME_LENGTH); - try { - Bookmark newbkmk = new Bookmark(key, name, core.alerts); - bookmarks.removeBookmark(b, false); - bookmarks.addBookmark(newbkmk, true); - } catch (MalformedURLException mue) { - this.sendBookmarkEditPage(ctx, MODE_EDIT, b, key, name, "Given key does not appear to be a valid freenet key."); - return; - } - this.handleGet(manageBookmarksURI, new HTTPRequestImpl(manageBookmarksURI), ctx); - } - } - this.handleGet(manageBookmarksURI, new HTTPRequestImpl(manageBookmarksURI), ctx); }else if(request.isPartSet("disable")){ if(noPassword) { redirectToRoot(ctx); @@ -477,19 +449,7 @@ writeReply(ctx, 200, "text/html; charset=utf-8", "OK", pageNode.generate()); Logger.normal(this, "Node is restarting"); return; - }else if (request.getParam("newbookmark").length() > 0) { - HTMLNode pageNode = ctx.getPageMaker().getPageNode("Add a Bookmark", ctx); - HTMLNode contentNode = ctx.getPageMaker().getContentNode(pageNode); - HTMLNode infobox = contentNode.addChild(ctx.getPageMaker().getInfobox("Confirm Bookmark Addition")); - HTMLNode addForm = ctx.addFormChild(ctx.getPageMaker().getContentNode(infobox), "/", "bookmarkAddForm"); - addForm.addChild("#", "Please confirm that you want to add the key " + request.getParam("newbookmark") + " to your bookmarks and enter the description that you would prefer:"); - addForm.addChild("br"); - addForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "hidden", "key", request.getParam("newbookmark") }); - addForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "text", "name", request.getParam("desc") }); - addForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "submit", "addbookmark", "Add bookmark" }); - this.writeReply(ctx, 200, "text/html", "OK", pageNode.generate()); - return; - } else if (request.getParam(GenericReadFilterCallback.magicHTTPEscapeString).length() > 0) { + }else if (request.getParam(GenericReadFilterCallback.magicHTTPEscapeString).length() > 0) { HTMLNode pageNode = ctx.getPageMaker().getPageNode("Link to external resources", ctx); HTMLNode contentNode = ctx.getPageMaker().getContentNode(pageNode); HTMLNode warnbox = contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-warning", "External link")); @@ -503,38 +463,7 @@ externalLinkForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "submit", "Go", "Go to the specified link" }); this.writeReply(ctx, 200, "text/html", "OK", pageNode.generate()); return; - } else if (request.isParameterSet("managebookmarks")) { - HTMLNode pageNode = ctx.getPageMaker().getPageNode("Bookmark Manager", ctx); - HTMLNode contentNode = ctx.getPageMaker().getContentNode(pageNode); - HTMLNode infobox = contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-normal", "My Bookmarks")); - HTMLNode infoboxContent = ctx.getPageMaker().getContentNode(infobox); - - Enumeration e = bookmarks.getBookmarks(); - boolean moveButtonsEnabled = (bookmarks.getSize() > 1); // activate move{up|down} buttons - - if (!e.hasMoreElements()) { - infoboxContent.addChild("#", "You currently do not have any bookmarks defined."); - } else { - HTMLNode manageForm = ctx.addFormChild(infoboxContent, ".", "manageBookmarksForm"); - HTMLNode bookmarkList = manageForm.addChild("ul", "id", "bookmarks"); - while (e.hasMoreElements()) { - Bookmark b = (Bookmark)e.nextElement(); - - HTMLNode bookmark = bookmarkList.addChild("li", "style", "clear: right;"); /* TODO */ - bookmark.addChild("input", new String[] { "type", "name", "value", "style" }, new String[] { "submit", "delete_" + b.hashCode(), "Delete", "float: right;" }); - bookmark.addChild("input", new String[] { "type", "name", "value", "style" }, new String[] { "submit", "edit_" + b.hashCode(), "Edit", "float: right;" }); - if (moveButtonsEnabled) { - bookmark.addChild("input", new String[] { "type", "name", "value", "style" }, new String[] { "submit", "movedown_" + b.hashCode(), "Down", "float: right;" }); - bookmark.addChild("input", new String[] { "type", "name", "value", "style" }, new String[] { "submit", "moveup_" + b.hashCode(), "Up", "float: right;" }); - } - bookmark.addChild("a", "href", '/' + b.getKey(), b.getDesc()); - } - manageForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "hidden", "managebookmarks", "yes" }); - } - contentNode.addChild(createBookmarkEditForm(ctx, MODE_ADD, null, "", "")); - this.writeReply(ctx, 200, "text/html", "OK", pageNode.generate()); - return; - }else if (request.isParameterSet("exit")) { + } else if (request.isParameterSet("exit")) { HTMLNode pageNode = ctx.getPageMaker().getPageNode("Node Shutdown", ctx); HTMLNode contentNode = ctx.getPageMaker().getContentNode(pageNode); HTMLNode infobox = contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-query", "Node Shutdown")); @@ -598,23 +527,14 @@ bookmarkBoxHeader.addChild("#", "My Bookmarks"); if(ctx.isAllowedFullAccess()){ bookmarkBoxHeader.addChild("#", " ["); - bookmarkBoxHeader.addChild("span", "id", "bookmarkedit").addChild("a", new String[] { "href", "class" }, new String[] { "?managebookmarks", "interfacelink" }, (bookmarks.getSize() == 0) ? "Add" : "Edit"); + bookmarkBoxHeader.addChild("span", "id", "bookmarkedit").addChild("a", new String[] { "href", "class" }, new String[] { "/bookmarkEditor/", "interfacelink" },"Edit"); bookmarkBoxHeader.addChild("#", "]"); } HTMLNode bookmarkBoxContent = bookmarkBox.addChild("div", "class", "infobox-content"); + HTMLNode bookmarksList = bookmarkBoxContent.addChild("ul", "id", "bookmarks"); + addCategoryToList(bookmarkManager.getMainCategory(), bookmarksList); - Enumeration e = bookmarks.getBookmarks(); - if (!e.hasMoreElements()) { - bookmarkBoxContent.addChild("#", "You currently do not have any bookmarks defined."); - } else { - HTMLNode bookmarkList = bookmarkBoxContent.addChild("ul", "id", "bookmarks"); - while (e.hasMoreElements()) { - Bookmark b = (Bookmark)e.nextElement(); - bookmarkList.addChild("li").addChild("a", "href", '/' + b.getKey(), b.getDesc()); - } - } - // Version info and Quit Form HTMLNode versionBox = contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-information", "Version Information & Node Control")); HTMLNode versionContent = ctx.getPageMaker().getContentNode(versionBox); @@ -651,45 +571,6 @@ this.writeReply(ctx, 200, "text/html", "OK", pageNode.generate()); } - private void sendBookmarkEditPage(ToadletContext ctx, Bookmark b) throws ToadletContextClosedException, IOException { - this.sendBookmarkEditPage(ctx, MODE_EDIT, b, b.getKey(), b.getDesc(), null); - } - - private void sendBookmarkEditPage(ToadletContext ctx, int mode, Bookmark b, String origKey, String origDesc, String message) throws ToadletContextClosedException, IOException { - HTMLNode pageNode = ctx.getPageMaker().getPageNode((mode == MODE_ADD) ? "Add a Bookmark" : "Edit a Bookmark", ctx); - HTMLNode contentNode = ctx.getPageMaker().getContentNode(pageNode); - - if (message != null) { // only used for error messages so far... - HTMLNode errorBox = contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-error", "An Error Occured")); - ctx.getPageMaker().getContentNode(errorBox).addChild("#", message); - } - - contentNode.addChild(createBookmarkEditForm(ctx, mode, b, origKey, origDesc)); - - this.writeReply(ctx, 200, "text/html", "OK", pageNode.generate()); - } - - private HTMLNode createBookmarkEditForm(ToadletContext ctx, int mode, Bookmark b, String origKey, String origDesc) { - PageMaker pageMaker = ctx.getPageMaker(); - HTMLNode infobox = pageMaker.getInfobox("infobox-normal bookmark-edit", (mode == MODE_ADD) ? "New Bookmark" : "Update Bookmark"); - HTMLNode content = pageMaker.getContentNode(infobox); - HTMLNode editForm = ctx.addFormChild(content, ".", mode == MODE_ADD ? "addBookmarkForm" : "editBookmarkForm"); - editForm.addChild("#", "Key: "); - editForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "text", "key", origKey }); - editForm.addChild("br"); - editForm.addChild("#", "Description: "); - editForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "text", "name", origDesc }); - editForm.addChild("br"); - if (mode == MODE_ADD) { - editForm.addChild("input", new String[] { "type", "name", "value", "class" }, new String[] { "submit", "addbookmark", "Add bookmark", "confirm" }); - } else { - editForm.addChild("input", new String[] { "type", "name", "value", "class" }, new String[] { "submit", "update_" + b.hashCode(), "Update bookmark", "confirm" }); - editForm.addChild("input", new String[] { "type", "value", "class" }, new String[] { "submit", "Cancel", "cancel" }); - } - editForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "hidden", "managebookmarks", "yes" }); - return infobox; - } - public String supportedMethods() { return "GET, POST"; } Copied: trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java (from rev 12707, trunk/freenet/src/freenet/clients/http/Bookmark.java) =================================================================== --- trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java (rev 0) +++ trunk/freenet/src/freenet/clients/http/bookmark/Bookmark.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -0,0 +1,35 @@ +package freenet.clients.http.bookmark; + +public abstract class Bookmark +{ + protected boolean privateBookmark; + protected String name; + protected String desc; + + public boolean isPrivate() + { + return privateBookmark; + } + + public abstract void setPrivate(boolean bool); + + public String getName() + { + return name; + } + + protected void setName(String s) + { + name = s; + } + + public String getDesc() + { + return desc; + } + + public void setDesc(String s) + { + desc = s; + } +} Added: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategories.java =================================================================== --- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategories.java (rev 0) +++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategories.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -0,0 +1,43 @@ + +package freenet.clients.http.bookmark; + +import java.util.Vector; +import java.util.Iterator; + + +public final class BookmarkCategories implements Iterable +{ + + Vector categories; + + public BookmarkCategories() + { + categories = new Vector(); + } + + public BookmarkCategory get(int i) + { + return (BookmarkCategory) categories.get(i); + } + + public void add(BookmarkCategory bc) + { + categories.add(bc); + } + + protected void extend(BookmarkCategories bc) + { + for(int i = 0; i < bc.size(); i++) + add(bc.get(i)); + } + + public int size() + { + return categories.size(); + } + + public Iterator iterator() + { + return categories.iterator(); + } +} Added: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java =================================================================== --- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java (rev 0) +++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkCategory.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -0,0 +1,155 @@ +package freenet.clients.http.bookmark; + +import java.util.Vector; +import java.util.Iterator; + +import freenet.support.StringArray; + + +public class BookmarkCategory extends Bookmark implements Iterable +{ + + private final Vector bookmarks; + + public BookmarkCategory(String name) + { + bookmarks = new Vector(); + setName(name); + } + + public BookmarkCategory(String name, String desc) + { + bookmarks = new Vector(); + setName(name); + setDesc(desc); + } + + protected Bookmark addBookmark(Bookmark b) + { + bookmarks.add(b); + return b; + } + + protected void removeBookmark(Bookmark b) + { + bookmarks.remove(b); + } + + public Bookmark get(int i) + { + return (Bookmark) bookmarks.get(i); + } + + protected void moveBookmarkUp(Bookmark b) + { + int index = bookmarks.indexOf(b); + if(index == -1) + return; + + Bookmark bk = get(index); + bookmarks.remove(index); + bookmarks.add((--index < 0) ? 0 : index , bk); + } + + protected void moveBookmarkDown(Bookmark b) + { + int index = bookmarks.indexOf(b); + if(index == -1) + return; + + Bookmark bk = get(index); + bookmarks.remove(index); + bookmarks.add((++index > size()) ? size() : index, bk); + } + + public int size() + { + return bookmarks.size(); + } + + public BookmarkItems getItems() + { + BookmarkItems items = new BookmarkItems(); + for(int i = 0; i < size(); i++) { + if(get(i) instanceof BookmarkItem) + items.add((BookmarkItem) get(i)); + } + + return items; + } + + public BookmarkItems getAllItems() + { + BookmarkItems items = getItems(); + BookmarkCategories subCategories = getSubCategories(); + + for(int i = 0; i < subCategories.size(); i++) { + items.extend(subCategories.get(i).getAllItems()); + } + return items; + } + + + public BookmarkCategories getSubCategories() + { + BookmarkCategories categories = new BookmarkCategories(); + for(int i = 0; i < size(); i++) { + if(get(i) instanceof BookmarkCategory) + categories.add((BookmarkCategory) get(i)); + } + + return categories; + } + + public BookmarkCategories getAllSubCategories() + { + BookmarkCategories categories = getSubCategories(); + BookmarkCategories subCategories = getSubCategories(); + + for(int i = 0; i < subCategories.size(); i++) { + categories.extend(subCategories.get(i).getAllSubCategories()); + } + + return categories; + } + + + public String[] toStrings() + { + return StringArray.toArray(toStrings("").toArray()); + } + + // Iternal use only + private Vector toStrings(String prefix) + { + Vector strings = new Vector(); + BookmarkItems items = getItems(); + BookmarkCategories subCategories = getSubCategories(); + prefix += this.name + "/"; + + for(int i = 0; i < items.size(); i++) + strings.add(prefix + items.get(i).toString()); + + for(int i = 0; i < subCategories.size(); i++) + strings.addAll(subCategories.get(i).toStrings(prefix)); + + return strings; + + } + + public void setPrivate(boolean bool) + { + privateBookmark = bool; + + BookmarkCategories subCategories = getSubCategories(); + for(int i = 0; i < size(); i++) + subCategories.get(i).setPrivate(bool); + } + + public Iterator iterator() + { + return bookmarks.iterator(); + } + +} + Added: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java =================================================================== --- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java (rev 0) +++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItem.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -0,0 +1,143 @@ +/* This code is part of Freenet. It is distributed under the GNU General + * Public License, version 2 (or at your option any later version). See + * http://www.gnu.org/ for further details of the GPL. */ +package freenet.clients.http.bookmark; + +import freenet.keys.FreenetURI; +import freenet.keys.USK; +import freenet.node.NodeClientCore; +import freenet.node.useralerts.UserAlert; +import freenet.node.useralerts.UserAlertManager; +import freenet.support.HTMLNode; + +import java.net.MalformedURLException; + +public class BookmarkItem extends Bookmark{ + + private FreenetURI key; + private boolean updated; + private final BookmarkUpdatedUserAlert alert; + private UserAlertManager alerts; + + + public BookmarkItem(FreenetURI k, String n, UserAlertManager uam) throws MalformedURLException { + this.key = k; + this.name = n; + this.alerts = uam; + alert = new BookmarkUpdatedUserAlert(); + } + + public BookmarkItem(FreenetURI k, String n, String d, UserAlertManager uam) throws MalformedURLException { + + this.key = k; + this.name = n; + this.desc = d; + this.alerts = uam; + alert = new BookmarkUpdatedUserAlert(); + } + + private class BookmarkUpdatedUserAlert implements UserAlert { + + public boolean userCanDismiss() { + return true; + } + + public String getTitle() { + return "Bookmark updated: "+ name; + } + + public String getText() { + return "The bookmarked site "+ name +" has been updated to edition "+key.getSuggestedEdition(); + } + + public HTMLNode getHTMLText() { + HTMLNode n = new HTMLNode("div"); + n.addChild("#", "The bookmarked site "); + n.addChild("a", "href", '/'+key.toString()).addChild("#", name); + n.addChild("#", " has been updated to edition "+key.getSuggestedEdition()+"."); + return n; + } + + public short getPriorityClass() { + return UserAlert.MINOR; + } + + public boolean isValid() { + synchronized(BookmarkItem.this) { + return updated; + } + } + + public void isValid(boolean validity) { + if(validity) return; + disableBookmark(); + } + + public String dismissButtonText() { + return "Delete notification"; + } + + public boolean shouldUnregisterOnDismiss() { + return true; + } + + public void onDismiss() { + disableBookmark(); + } + + } + + private synchronized void disableBookmark() { + updated = false; + alerts.unregister(alert); + } + + private synchronized void enableBookmark() { + if(updated) return; + updated = true; + alerts.register(alert); + } + + public String getKey() { + return key.toString(); + } + + public synchronized FreenetURI getURI() { + return key; + } + + public synchronized void setKey(FreenetURI uri) { + key = uri; + } + + public synchronized String getKeyType() { + return key.getKeyType(); + } + + public String getName() { + if (name.equals("")) { + return "Unnamed Bookmark"; + } else { + return name; + } + } + + public void setPrivate(boolean bool) + { + privateBookmark = bool; + } + + public String toString() { + return this.name + "=" + this.key.toString(); + } + + public synchronized void setEdition(long ed, NodeClientCore node) { + if(key.getSuggestedEdition() >= ed) return; + key = key.setSuggestedEdition(ed); + enableBookmark(); + } + + public USK getUSK() throws MalformedURLException { + return USK.create(key); + } +} Added: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItems.java =================================================================== --- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItems.java (rev 0) +++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkItems.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -0,0 +1,43 @@ +package freenet.clients.http.bookmark; + +import java.util.Vector; +import java.util.Iterator; + + +public class BookmarkItems implements Iterable +{ + + Vector items; + + + public BookmarkItems() + { + items = new Vector(); + } + + public BookmarkItem get(int i) + { + return (BookmarkItem) items.get(i); + } + + public void add(BookmarkItem bi) + { + items.add(bi); + } + + protected void extend(BookmarkItems bi) + { + for(int i = 0; i < bi.size(); i++) + add(bi.get(i)); + } + + public int size() + { + return items.size(); + } + + public Iterator iterator() + { + return (items).iterator(); + } +} Copied: trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java (from rev 12707, trunk/freenet/src/freenet/clients/http/BookmarkManager.java) =================================================================== --- trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java (rev 0) +++ trunk/freenet/src/freenet/clients/http/bookmark/BookmarkManager.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -0,0 +1,338 @@ +/* This code is part of Freenet. It is distributed under the GNU General + * Public License, version 2 (or at your option any later version). See + * http://www.gnu.org/ for further details of the GPL. */ + + +package freenet.clients.http.bookmark; + +import java.net.MalformedURLException; +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import freenet.client.async.USKCallback; +import freenet.config.InvalidConfigValueException; +import freenet.config.SubConfig; +import freenet.keys.FreenetURI; +import freenet.keys.USK; +import freenet.node.NodeClientCore; +import freenet.support.api.StringArrCallback; + + +public class BookmarkManager { + + private final NodeClientCore node; + private USKUpdatedCallback uskcb; + private boolean started; + private BookmarkCategory mainCategory; + private HashMap bookmarks; + + public BookmarkManager(NodeClientCore n, SubConfig sc) + { + + bookmarks = new HashMap(); + mainCategory = new BookmarkCategory("/"); + bookmarks.put("/", mainCategory); + + this.uskcb = new USKUpdatedCallback(); + this.node = n; + + try { + + BookmarkCategory defaultRoot = new BookmarkCategory("/"); + + BookmarkCategory indexes = (BookmarkCategory) defaultRoot.addBookmark(new BookmarkCategory("Indicies")); + indexes.addBookmark(new BookmarkItem(new FreenetURI("USK at 7H66rhYmxIFgMyw5Dl11JazXGHPhp7dSN7WMa1pbtEo,jQHUQUPTkeRcjmjgrc7t5cDRdDkK3uKkrSzuw5CO9uk,AQACAAE/ENTRY.POINT/20/full/page1.html"),"Entry point", node.alerts)); + indexes.addBookmark(new BookmarkItem(new FreenetURI("USK at BPZppy07RyID~NGihHgs4AAw3fUXxgtKIrwRu5rtpWE,k5yjkAFJC93JkydKl6vpY0Zy9D8ec1ymv2XP4Tx5Io0,AQABAAE/FreeHoo/6/"),"Free Hoo", node.alerts)); + + BookmarkCategory flog = (BookmarkCategory) defaultRoot.addBookmark(new BookmarkCategory("Freenet devel's flog")); + flog.addBookmark(new BookmarkItem(new FreenetURI("USK at J585KtAJ7UN2~4i17hf7C9XbufMnticJeUDYLcB0dvo,lxZhX2snsExxemocIlI~ZJRFVdVLBLIFZhqV3yswR9U,AQABAAE/toad/10/"),"Toad", node.alerts)); + flog.addBookmark(new BookmarkItem(new FreenetURI("USK at hM9XRwjXIzU8xTSBXNZvTn2KuvTSRFnVn4EER9FQnpM,gsth24O7ud4gL4NwNuYJDUqfaWASOG2zxZY~ChtgPxc,AQACAAE/Flog/2/"), "Nextgen$", node.alerts)); + + BookmarkCategory apps = (BookmarkCategory) defaultRoot.addBookmark(new BookmarkCategory("Software")); + apps.addBookmark(new BookmarkItem(new FreenetURI("USK at XeMBryjuEaxqazEuxwnn~G7wCUOXFOZlVWbscdCOUFs,209eycYVidlZvhgL5V2a3INFxrofxzQctEZvyJaFL7I,AQABAAE/frost/2/"),"Frost", node.alerts)); + + sc.register("bookmarks",defaultRoot.toStrings() , 0, true, false, "List of bookmarks", "A list of bookmarked freesites", makeCB()); + + makeCB().set((sc.getStringArr("bookmarks").length == 0 ? defaultRoot.toStrings() : sc.getStringArr("bookmarks"))); + + + } catch (MalformedURLException mue) { + // just ignore that one + } catch (InvalidConfigValueException icve){ + //TODO + icve.printStackTrace(); + } + + synchronized(this) { + started = true; + } + } + + public class BookmarkCallback implements StringArrCallback + { + public String[] get() + { + + synchronized(BookmarkManager.this) { + + return mainCategory.toStrings(); + + } + } + + public void set(String[] newVals) throws InvalidConfigValueException + { + clear(); + Pattern pattern = Pattern.compile("/(.*/)([^/]*)=([A-Z]{3}@.*).*"); + + FreenetURI key; + for (int i = 0; i < newVals.length; i++) { + try { + Matcher matcher = pattern.matcher(newVals[i]); + if(matcher.matches() && matcher.groupCount() == 3) { + + makeParents(matcher.group(1)); + key = new FreenetURI(matcher.group(3)); + addBookmark(matcher.group(1),new BookmarkItem(key, matcher.group(2), node.alerts), false); + + }else + throw new InvalidConfigValueException("Malformed Bookmark"); + + } catch (MalformedURLException mue) { + throw new InvalidConfigValueException(mue.getMessage()); + } + } + } + } + + private class USKUpdatedCallback implements USKCallback { + public void onFoundEdition(long edition, USK key) { + BookmarkItems items = mainCategory.getAllItems(); + for (int i = 0; i < items.size(); i++) { + + + if (!items.get(i).getKeyType().equals("USK")) + continue; + + try { + FreenetURI furi = new FreenetURI(items.get(i).getKey()); + USK usk = USK.create(furi); + + if (usk.equals(key, false)) { + items.get(i).setEdition(key.suggestedEdition, node); + break; + } + } catch (MalformedURLException mue) { + } + } + node.storeConfig(); + } + } + + public BookmarkCallback makeCB() { + return new BookmarkCallback(); + } + + public BookmarkCategory getMainCategory() + { + return mainCategory; + } + + public String parentPath(String path) + { + if(path.equals("/")) + return "/"; + + return path.substring(0, path.substring(0,path.length() -1).lastIndexOf("/")) + "/"; + } + + public Bookmark getBookmarkByPath(String path) + { + return (Bookmark) bookmarks.get(path); + } + + public BookmarkCategory getCategoryByPath(String path) + { + if(getBookmarkByPath(path) instanceof BookmarkCategory) + return (BookmarkCategory) getBookmarkByPath(path); + + return null; + } + + public BookmarkItem getItemByPath(String path) + { + if(getBookmarkByPath(path) instanceof BookmarkItem) + return (BookmarkItem) getBookmarkByPath(path); + + return null; + } + + public void addBookmark(String parentPath, Bookmark b, boolean store) throws NullPointerException + { + BookmarkCategory parent = getCategoryByPath(parentPath); + if(parent == null) + throw new NullPointerException(); + else { + parent.addBookmark(b); + bookmarks.put(parentPath + b.getName() + ((b instanceof BookmarkCategory) ? "/" : ""), b); + } + + if(store) + node.storeConfig(); + } + + // TODO + public void renameBookmark(String path, String newName) + { + Bookmark bookmark = getBookmarkByPath(path); + bookmark.setName(newName); + if(bookmark instanceof BookmarkCategory) { + try { + makeCB().set(makeCB().get()); + + } catch (InvalidConfigValueException icve) { } + } + + } + + public void removeBookmark(String path, boolean store) + { + Bookmark bookmark = getBookmarkByPath(path); + if(bookmark == null) + return; + + if(bookmark instanceof BookmarkCategory) { + BookmarkCategory cat = (BookmarkCategory) bookmark; + for(int i = 0; i < cat.size(); i++) { + removeBookmark(path + cat.get(i).getName() + ((cat.get(i) instanceof BookmarkCategory) ? "/" : ""), false); + } + } else { + if(((BookmarkItem) bookmark).getKeyType().equals("USK")) { + try { + USK u = ((BookmarkItem) bookmark).getUSK(); + this.node.uskManager.subscribe(u, this.uskcb, true, this); + } catch (MalformedURLException mue) { } + } + } + + getCategoryByPath(parentPath(path)).removeBookmark(getBookmarkByPath(path)); + bookmarks.remove(path); + + if(store) + node.storeConfig(); + + } + + public void moveBookmarkUp(String path, boolean store) + { + BookmarkCategory parent = getCategoryByPath(parentPath(path)); + parent.moveBookmarkUp(getBookmarkByPath(path)); + + if(store) + node.storeConfig(); + } + + public void moveBookmarkDown(String path, boolean store) + { + BookmarkCategory parent = getCategoryByPath(parentPath(path)); + parent.moveBookmarkDown(getBookmarkByPath(path)); + + if(store) + node.storeConfig(); + } + + private BookmarkCategory makeParents(String path) + { + if(bookmarks.containsKey(path)) + return getCategoryByPath(path); + else { + + int index = path.substring(0, path.length()-1).lastIndexOf("/"); + String name = path.substring(index +1, path.length() -1); + + BookmarkCategory cat = new BookmarkCategory(name); + makeParents(parentPath(path)); + addBookmark(parentPath(path), cat, false); + + return cat; + } + } + + public void clear() + { + + removeBookmark("/", false); + bookmarks.clear(); + + mainCategory = new BookmarkCategory("/"); + bookmarks.put("/", mainCategory); + + } + + public FreenetURI[] getBookmarkURIs() + { + BookmarkItems items = mainCategory.getAllItems(); + FreenetURI[] uris = new FreenetURI[items.size()]; + for(int i = 0; i < items.size(); i++) { + uris[i] = items.get(i).getURI(); + } + + return uris; + } + + + +/* + public void addBookmark(Bookmark b, boolean store) { + this.bookmarks.add(b); + if (b.getKeyType().equals("USK")) { + try { + USK u = b.getUSK(); + this.node.uskManager.subscribe(u, this.uskcb, true, this); + } catch (MalformedURLException mue) { + + } + } + if(store && started) node.storeConfig(); + } + + public void removeBookmark(Bookmark b, boolean store) { + if (b.getKeyType().equals("USK")) { + try { + USK u = b.getUSK(); + this.node.uskManager.unsubscribe(u, this.uskcb, true); + } catch (MalformedURLException mue) { + + } + } + this.bookmarks.remove(b); + if(store && started) node.storeConfig(); + } + + public void moveBookmarkDown (Bookmark b, boolean store) { + int i = this.bookmarks.indexOf(b); + if (i == -1) return; + + Bookmark bk = (Bookmark)this.bookmarks.get(i); + this.bookmarks.remove(i); + this.bookmarks.add((i+1)%(this.bookmarks.size()+1), bk); + + if(store && started) node.storeConfig(); + } + + public void moveBookmarkUp (Bookmark b, boolean store) { + int i = this.bookmarks.indexOf(b); + if (i == -1) return; + + Bookmark bk = (Bookmark)this.bookmarks.get(i); + this.bookmarks.remove(i); + if (--i < 0) i = this.bookmarks.size(); + this.bookmarks.add(i, bk); + + if(store && started) node.storeConfig(); + } + + public int getSize() { + return this.bookmarks.size(); + }*/ +} Added: trunk/freenet/src/freenet/clients/http/staticfiles/bookmark.css =================================================================== --- trunk/freenet/src/freenet/clients/http/staticfiles/bookmark.css (rev 0) +++ trunk/freenet/src/freenet/clients/http/staticfiles/bookmark.css 2007-04-23 22:41:07 UTC (rev 12908) @@ -0,0 +1,19 @@ +ul#bookmarks ul { + padding-left: 20px; +} + +ul#bookmarks li { + list-style-type: none; + margin-top: 1px; + margin-bottom: 1px; +} + +ul#bookmarks li.cat { + font-weight: bold; + margin-top: 7px; +} + +ul#bookmarks span.actions img { + border: 0; + margin-left: 3px; +} \ No newline at end of file Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/bookmark-new.png =================================================================== (Binary files differ) Property changes on: trunk/freenet/src/freenet/clients/http/staticfiles/icon/bookmark-new.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/delete.png =================================================================== (Binary files differ) Property changes on: trunk/freenet/src/freenet/clients/http/staticfiles/icon/delete.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit-delete.png =================================================================== (Binary files differ) Property changes on: trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit-delete.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit.png =================================================================== (Binary files differ) Property changes on: trunk/freenet/src/freenet/clients/http/staticfiles/icon/edit.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/folder-new.png =================================================================== (Binary files differ) Property changes on: trunk/freenet/src/freenet/clients/http/staticfiles/icon/folder-new.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-down.png =================================================================== (Binary files differ) Property changes on: trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-down.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-up.png =================================================================== (Binary files differ) Property changes on: trunk/freenet/src/freenet/clients/http/staticfiles/icon/go-up.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/freenet/src/freenet/clients/http/staticfiles/themes/boxed/theme.css =================================================================== --- trunk/freenet/src/freenet/clients/http/staticfiles/themes/boxed/theme.css 2007-04-23 22:28:38 UTC (rev 12907) +++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/boxed/theme.css 2007-04-23 22:41:07 UTC (rev 12908) @@ -1,3 +1,6 @@ +/* Bookmarks & bookmark editor */ + at import url(/static/bookmark.css); + body { font-family: tahoma; font-size: 11px; Modified: trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css =================================================================== --- trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css 2007-04-23 22:28:38 UTC (rev 12907) +++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/clean/theme.css 2007-04-23 22:41:07 UTC (rev 12908) @@ -1,3 +1,6 @@ +/* Bookmarks & bookmark editor */ + at import url(/static/bookmark.css); + /* overall settings */ p, span, div, td, th, li, h1, h2, h3, h4, h5 { @@ -582,3 +585,6 @@ td.n2ntm-send-failed { background-color: #ffb7b7; } + + + Modified: trunk/freenet/src/freenet/clients/http/staticfiles/themes/grayandblue/theme.css =================================================================== --- trunk/freenet/src/freenet/clients/http/staticfiles/themes/grayandblue/theme.css 2007-04-23 22:28:38 UTC (rev 12907) +++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/grayandblue/theme.css 2007-04-23 22:41:07 UTC (rev 12908) @@ -1,3 +1,5 @@ +/* Bookmarks & bookmark editor */ + at import url(/static/bookmark.css); /* [edward at rnahost.com] */ Modified: trunk/freenet/src/freenet/clients/http/staticfiles/themes/sky/theme.css =================================================================== --- trunk/freenet/src/freenet/clients/http/staticfiles/themes/sky/theme.css 2007-04-23 22:28:38 UTC (rev 12907) +++ trunk/freenet/src/freenet/clients/http/staticfiles/themes/sky/theme.css 2007-04-23 22:41:07 UTC (rev 12908) @@ -1,3 +1,6 @@ +/* Bookmarks & bookmark editor */ + at import url(/static/bookmark.css); + /* overall settings */ p, span, div, td, th, li, h1, h2, h3, h4, h5 { Modified: trunk/freenet/src/freenet/node/NodeClientCore.java =================================================================== --- trunk/freenet/src/freenet/node/NodeClientCore.java 2007-04-23 22:28:38 UTC (rev 12907) +++ trunk/freenet/src/freenet/node/NodeClientCore.java 2007-04-23 22:41:07 UTC (rev 12908) @@ -13,7 +13,7 @@ import freenet.client.async.SimpleHealingQueue; import freenet.client.async.USKManager; import freenet.client.events.SimpleEventProducer; -import freenet.clients.http.BookmarkManager; +import freenet.clients.http.bookmark.BookmarkManager; import freenet.clients.http.FProxyToadlet; import freenet.clients.http.SimpleToadletServer; import freenet.clients.http.filter.FilterCallback;
