diff --git a/htroot/api/ymarks/get_xbel.java b/htroot/api/ymarks/get_xbel.java index 6444e23d3..ff095920a 100644 --- a/htroot/api/ymarks/get_xbel.java +++ b/htroot/api/ymarks/get_xbel.java @@ -162,8 +162,6 @@ public class get_xbel { } } } - if(root_depth < 3) - n--; while(n > root_depth) { prop.put("xbel_"+count+"_elements", YMarkXBELImporter.XBEL.FOLDER.endTag(false)); count++; diff --git a/htroot/api/ymarks/get_ymark.java b/htroot/api/ymarks/get_ymark.java index 91dcf63f9..d86a33990 100644 --- a/htroot/api/ymarks/get_ymark.java +++ b/htroot/api/ymarks/get_ymark.java @@ -1,14 +1,17 @@ import java.io.IOException; +import java.util.Collection; import java.util.Iterator; +import java.util.regex.Pattern; import net.yacy.cora.document.UTF8; import net.yacy.cora.protocol.RequestHeader; import net.yacy.kelondro.blob.Tables; +import net.yacy.kelondro.blob.Tables.Row; import net.yacy.kelondro.logging.Log; import de.anomic.data.UserDB; import de.anomic.data.ymark.YMarkEntry; import de.anomic.data.ymark.YMarkTables; -import de.anomic.data.ymark.YMarkUtil; +import de.anomic.data.ymark.YMarkTables.TABLES; import de.anomic.search.Switchboard; import de.anomic.server.serverObjects; import de.anomic.server.serverSwitch; @@ -23,7 +26,13 @@ public class get_ymark { sb = (Switchboard) env; prop = new serverObjects(); - //boolean tags = false; + int rp; // items per page + int page; // page + int total; + String sortorder; + String sortname; + String qtype; + String query; final UserDB.Entry user = sb.userDB.getUser(header); final boolean isAdmin = (sb.verifyAuthentication(header, true)); @@ -33,15 +42,53 @@ public class get_ymark { if(isAdmin || isAuthUser) { final String bmk_user = (isAuthUser ? user.getUserName() : YMarkTables.USER_ADMIN); - if(post.containsKey(YMarkEntry.BOOKMARK.TAGS.key())) { - //tags = true; + query = ".*"; + qtype = YMarkEntry.BOOKMARK.TITLE.key(); + page = 1; + rp = 10; + total = 0; + sortname = YMarkEntry.BOOKMARK.TITLE.key(); + sortorder = "asc"; + + if(post != null) { + rp = (post.containsKey("rp")) ? post.getInt("rp", 10) : 10; + page = (post.containsKey("page")) ? post.getInt("page", 1): 1; + query = (post.containsKey("query")) ? post.get("query", ".*") : ".*"; + qtype = (post.containsKey("qtype")) ? post.get("qtype", YMarkEntry.BOOKMARK.TAGS.key()) : YMarkEntry.BOOKMARK.TAGS.key(); + sortname = (post.containsKey("sortname")) ? post.get("sortname", YMarkEntry.BOOKMARK.TITLE.key()) : YMarkEntry.BOOKMARK.TITLE.key(); + sortorder = (post.containsKey("sortorder")) ? post.get("sortorder", "asc") : "asc"; + } + if (qtype.isEmpty()) + qtype = YMarkEntry.BOOKMARK.TITLE.key(); + if (query.isEmpty()) + query = ".*"; + try { + final String bmk_table = TABLES.BOOKMARKS.tablename(bmk_user); + final Collection result = sb.tables.bookmarks.orderBy(sb.tables.iterator(bmk_table, qtype, Pattern.compile(query)), sortname, sortorder); + total = result.size(); + bookmarks = result.iterator(); + } catch (IOException e) { + Log.logException(e); + } + + + + /* + if (qtype.equals(YMarkEntry.BOOKMARK.TAGS.key()) && !query.isEmpty()) { final String[] tagArray = YMarkUtil.cleanTagsString(post.get(YMarkEntry.BOOKMARK.TAGS.key())).split(YMarkUtil.TAGS_SEPARATOR); try { - bookmarks = sb.tables.bookmarks.getBookmarksByTag(bmk_user, tagArray); + bookmarks = YMarkTables.getPage(sb.tables.bookmarks.getBookmarksByTag(bmk_user, tagArray), sortname, itemsPerPage, page).iterator(); } catch (IOException e) { Log.logException(e); } + } else { + try { + bookmarks = YMarkTables.getPage(sb.tables.iterator(YMarkTables.TABLES.BOOKMARKS.tablename(bmk_user)), sortname, itemsPerPage, page).iterator(); + } catch (IOException e) { + Log.logException(e); + } } + */ /* if(post.containsKey(YMarkTables.BOOKMARK.FOLDERS.key())) { final String[] folderArray = YMarkTables.cleanFoldersString(post.get(YMarkTables.BOOKMARK.FOLDERS.key())).split(YMarkTables.TAGS_SEPARATOR); @@ -57,7 +104,9 @@ public class get_ymark { } } */ - putBookmarks(bookmarks); + prop.put("page", page); + prop.put("total", total); + putProp(bookmarks, rp, page); } else { prop.put(YMarkTables.USER_AUTHENTICATE,YMarkTables.USER_AUTHENTICATE_MSG); @@ -65,19 +114,46 @@ public class get_ymark { // return rewrite properties return prop; } - - private static void putBookmarks(final Iterator bit) { - int count = 0; - while(bit.hasNext()) { - Tables.Row bmk_row = bit.next(); + + private static void putProp(final Iterator bit, final int rp, final int page) { + Tables.Row bmk_row; + int count = 0; + int offset = 0; + if (page > 1) { + offset = ((page - 1) * rp) + 1; + } + while(count < offset && bit.hasNext()) { + bmk_row = bit.next(); + count++; + } + count = 0; + while (count < rp && bit.hasNext()) { + bmk_row = bit.next(); if (bmk_row != null) { - prop.putXML("bookmarks_"+count+"_id", UTF8.String(bmk_row.getPK())); - for (YMarkEntry.BOOKMARK bmk : YMarkEntry.BOOKMARK.values()) { - prop.putXML("bookmarks_"+count+"_"+bmk.key(), bmk_row.get(bmk.key(),bmk.deflt())); - } - count++; - } - } - prop.put("bookmarks", count); + + // put JSON + prop.put("json_"+count+"_id", count); + prop.put("json_"+count+"_hash", UTF8.String(bmk_row.getPK())); + for (YMarkEntry.BOOKMARK bmk : YMarkEntry.BOOKMARK.values()) { + if(bmk == YMarkEntry.BOOKMARK.PUBLIC) + prop.put("json_"+count+"_"+bmk.key(), bmk_row.get(bmk.key(),bmk.deflt()).equals("true") ? 1 : 0); + else + prop.putJSON("json_"+count+"_"+bmk.key(), bmk_row.get(bmk.key(),bmk.deflt())); + } + prop.put("json_"+count+"_comma", ","); + + // put XML + prop.putXML("xml_"+count+"_id", UTF8.String(bmk_row.getPK())); + for (YMarkEntry.BOOKMARK bmk : YMarkEntry.BOOKMARK.values()) { + prop.putXML("xml_"+count+"_"+bmk.key(), bmk_row.get(bmk.key(),bmk.deflt())); + } + + count++; + } + } + // eliminate the trailing comma for Json output + prop.put("json_" + (count - 1) + "_comma", ""); + prop.put("json", count); + prop.put("xml", count); } } diff --git a/htroot/api/ymarks/get_ymark.json b/htroot/api/ymarks/get_ymark.json new file mode 100644 index 000000000..660d63503 --- /dev/null +++ b/htroot/api/ymarks/get_ymark.json @@ -0,0 +1,15 @@ +{ +page: #[page]#, +total: #[total]#, +rows: [ +#{json}# +{id:"#[id]#",cell:[ +"#[hash]#", +#(public)#"public"::"private"#(/public)#, +"

#[title]#

#[desc]#

#[url]#", +"

#[tags]#

", +"

#[folders]#

", +"

#[date_added]#

"]}#[comma]# +#{/json}# +] +} \ No newline at end of file diff --git a/htroot/api/ymarks/get_ymark.xml b/htroot/api/ymarks/get_ymark.xml index fbc05ea0b..a28256206 100644 --- a/htroot/api/ymarks/get_ymark.xml +++ b/htroot/api/ymarks/get_ymark.xml @@ -1,6 +1,6 @@ -#{bookmarks}# +#{xml}# -#{/bookmarks}# +#{/xml}# \ No newline at end of file diff --git a/htroot/yacy/ui/yacyui-bookmarks.html b/htroot/yacy/ui/yacyui-bookmarks.html index d70db2448..482158902 100644 --- a/htroot/yacy/ui/yacyui-bookmarks.html +++ b/htroot/yacy/ui/yacyui-bookmarks.html @@ -7,7 +7,7 @@ var height=document.documentElement.clientHeight - 240; $('#ymarks').flexigrid({ - url: '/api/bookmarks/get_bookmarks.json?display=1', + url: '/api/ymarks/get_ymark.json', dataType: 'json', method: 'GET', colModel: [ @@ -34,18 +34,20 @@ {name: 'Help', bclass: 'help', onpress: bm_action}, ], searchitems : [ - {display: 'Tags', name : 'tags'} + {display: 'Tags', name : 'tags'}, + {display: 'Folders', name : 'folders'}, + {display: 'Title', name : 'title'}, ], useRp: true, rp: 15, - sortname: "date", + sortname: "title", sortorder: "asc", usepager: true, striped: true, nowrap: false, height: height, - query: qtag, - qtype: "tags", + query: ".*", + qtype: "title", title: 'YaCy Bookmarks: ' + HTMLenc(qtag) }); diff --git a/source/de/anomic/data/ymark/TablesRowComparator.java b/source/de/anomic/data/ymark/TablesRowComparator.java new file mode 100644 index 000000000..67daeea6a --- /dev/null +++ b/source/de/anomic/data/ymark/TablesRowComparator.java @@ -0,0 +1,29 @@ +package de.anomic.data.ymark; + +import java.util.Comparator; +import net.yacy.cora.document.UTF8; +import net.yacy.kelondro.blob.Tables; + +public class TablesRowComparator implements Comparator { + private String sortname; + + public TablesRowComparator(final String sortname) { + setSortName(sortname); + } + + public void setSortName(final String sortname) { + this.sortname = sortname; + } + + @Override + public int compare(Tables.Row row0, Tables.Row row1) { + if(row0 != null && row1 != null) { + if(row0.containsKey(this.sortname) && row1.containsKey(this.sortname)) { + String name1 = UTF8.String(row0.get(this.sortname)).toLowerCase(); + String name2 = UTF8.String(row1.get(this.sortname)).toLowerCase(); + return name1.compareTo(name2); + } + } + return 0; + } +} \ No newline at end of file diff --git a/source/de/anomic/data/ymark/YMarkTables.java b/source/de/anomic/data/ymark/YMarkTables.java index a316284d0..d70c49979 100644 --- a/source/de/anomic/data/ymark/YMarkTables.java +++ b/source/de/anomic/data/ymark/YMarkTables.java @@ -29,13 +29,14 @@ package de.anomic.data.ymark; import java.io.IOException; import java.util.HashSet; import java.util.Iterator; +import java.util.SortedSet; import java.util.TreeSet; import java.util.regex.Pattern; -import de.anomic.data.WorkTables; - import net.yacy.kelondro.blob.Tables; +import net.yacy.kelondro.blob.Tables.Row; import net.yacy.kelondro.index.RowSpaceExceededException; +import de.anomic.data.WorkTables; public class YMarkTables { @@ -182,6 +183,19 @@ public class YMarkTables { return this.worktables.iterator(bmk_table, YMarkEntry.BOOKMARK.TAGS.key(), p); } + public SortedSet orderBy(final Iterator rowIterator, final String sortname, final String sortorder) { + TreeSet sortTree = new TreeSet(new TablesRowComparator(sortname)); + Row row; + while (rowIterator.hasNext()) { + row = rowIterator.next(); + if(row != null) + sortTree.add(row); + } + if(sortorder.equals("desc")) + return sortTree.descendingSet(); + return sortTree; + } + public void addBookmark(final String bmk_user, final YMarkEntry bmk, final boolean importer) throws IOException, RowSpaceExceededException { final String bmk_table = TABLES.BOOKMARKS.tablename(bmk_user); final String date = String.valueOf(System.currentTimeMillis()); @@ -252,3 +266,4 @@ public class YMarkTables { } } } +