- added backend and api for tag management


git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@8058 6c8d7289-2bf4-0310-a012-ef5d649a1542
This commit is contained in:
apfelmaennchen 2011-11-19 20:59:21 +00:00
parent 804e48888b
commit 5581be12fb
11 changed files with 221 additions and 47 deletions

View File

@ -3,22 +3,21 @@
<head>
<title>YaCy Bookmarks</title>
#%env/templates/metas.template%#
<link media="screen" type="text/css" href="/jquery/flexigrid/css/flexigrid.pack.css" rel="stylesheet" />
<link media="screen" type="text/css" href="/yacy/ui/css/jquery.treeview.css" rel="stylesheet" />
<link media="screen" type="text/css" href="/yacy/ui/css/jquery.multiselect.css" rel="stylesheet" />
<link media="screen" type="text/css" href="/env/yacy-ymarks.css" rel="stylesheet" />
<script src="/jquery/flexigrid/js/flexigrid.pack.js" type="text/javascript"></script>
<link media="screen" type="text/css" href="/jquery/css/jquery.multiselect.css" rel="stylesheet" />
<script src="/jquery/js/jquery.multiselect.min.js" type="text/javascript"></script>
<link media="screen" type="text/css" href="/yacy/ui/css/jquery.treeview.css" rel="stylesheet" />
<script src="/yacy/ui/js/jquery.treeview.min.js" type="text/javascript"></script>
<script src="/yacy/ui/js/jquery.treeview.async.js" type="text/javascript"></script>
<script src="/yacy/ui/js/jquery.multiselect.min.js" type="text/javascript"></script>
<script src="/js/yacy-ymarks.js" type="text/javascript"></script>
<link media="screen" type="text/css" href="/env/yacy-ymarks.css" rel="stylesheet" />
<script src="/js/yacy-ymarks.js" type="text/javascript"></script>
<script src="/js/yacy-ymarks-bookmark-actions.js" type="text/javascript"></script>
<script src="/js/yacy-ymarks-tag-actions.js" type="text/javascript"></script>
</head>
<body id="ymarks_body">
#%env/templates/header.template%#
@ -68,16 +67,17 @@
<img src="/yacy/ui/img-2/question_blue.png" alt="Help" style="padding-right:4px; padding-left:25px;"/>Help
</div>
-->
<select id="example" name="example" multiple="multiple">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
<option value="4">Option 4</option>
<option value="5">Option 5</option>
</select>
<div>
<h3>Tag Filter:</h3>
<p>
<select id="tag_include" name="tag_include" multiple="multiple"></select>
</p>
</div>
<hr />
<div>
<p id="ymarks_tagcloud"></p>
</div>
</div>
<div id="ymarks_import_tab">
<form action="/api/ymarks/import_ymark.html" method="post" enctype="multipart/form-data" accept-charset="UTF-8">

View File

@ -1,2 +1,2 @@
<?xml version='1.0' encoding="UTF-8" standalone='yes'?>
<result code="#(result)#something went wrong::done#(/result)#" />
<status code="#(result)#error::ok#(/result)#" />

View File

@ -49,7 +49,7 @@ public class get_ymark {
query = ".*";
qtype = YMarkEntry.BOOKMARK.TITLE.key();
page = 1;
rp = 10;
rp = 100;
total = 0;
sortname = YMarkEntry.BOOKMARK.TITLE.key();
sortorder = "asc";

View File

@ -0,0 +1,84 @@
import java.io.IOException;
import java.util.Iterator;
import java.util.regex.Pattern;
import net.yacy.cora.protocol.RequestHeader;
import net.yacy.kelondro.blob.Tables.Row;
import net.yacy.kelondro.index.RowSpaceExceededException;
import net.yacy.kelondro.logging.Log;
import net.yacy.search.Switchboard;
import de.anomic.data.UserDB;
import de.anomic.data.ymark.YMarkTables;
import de.anomic.data.ymark.YMarkTables.TABLES;
import de.anomic.data.ymark.YMarkUtil;
import de.anomic.server.serverObjects;
import de.anomic.server.serverSwitch;
public class replace_tags {
private static Switchboard sb = null;
private static serverObjects prop = null;
public static serverObjects respond(final RequestHeader header, final serverObjects post, final serverSwitch env) {
sb = (Switchboard) env;
prop = new serverObjects();
String qtype;
String query;
String tags;
String replace;
final UserDB.Entry user = sb.userDB.getUser(header);
final boolean isAdmin = (sb.verifyAuthentication(header, true));
final boolean isAuthUser = user!= null && user.hasRight(UserDB.AccessRight.BOOKMARK_RIGHT);
if(isAdmin || isAuthUser) {
final String bmk_user = (isAuthUser ? user.getUserName() : YMarkTables.USER_ADMIN);
if(post != null) {
query = post.get("query", post.get("tags", YMarkUtil.EMPTY_STRING));
qtype = post.get("qtype", "_tags");
tags = post.get("tags", YMarkUtil.EMPTY_STRING);
replace = post.get("replace", YMarkUtil.EMPTY_STRING);
} else {
query = ".*";
qtype = YMarkUtil.EMPTY_STRING;
tags = YMarkUtil.EMPTY_STRING;
replace = YMarkUtil.EMPTY_STRING;
}
try {
final String bmk_table = TABLES.BOOKMARKS.tablename(bmk_user);
final Iterator<Row> row_iter;
if(!query.isEmpty()) {
if(!qtype.isEmpty()) {
if(qtype.equals("_tags")) {
final String[] tagArray = YMarkUtil.cleanTagsString(query).split(YMarkUtil.TAGS_SEPARATOR);
row_iter = sb.tables.bookmarks.getBookmarksByTag(bmk_user, tagArray);
} else if(qtype.equals("_folder")) {
row_iter = sb.tables.bookmarks.getBookmarksByFolder(bmk_user, query);
} else {
row_iter = sb.tables.iterator(bmk_table, qtype, Pattern.compile(query));
}
} else {
row_iter = sb.tables.iterator(bmk_table, Pattern.compile(query));
}
} else {
row_iter = sb.tables.iterator(bmk_table);
}
sb.tables.bookmarks.replaceTags(row_iter, bmk_user, tags, replace);
prop.put("status", 1);
} catch (IOException e) {
Log.logException(e);
} catch (RowSpaceExceededException e) {
Log.logException(e);
}
} else {
prop.put(YMarkTables.USER_AUTHENTICATE,YMarkTables.USER_AUTHENTICATE_MSG);
}
// return rewrite properties
return prop;
}
}

View File

@ -0,0 +1,2 @@
<?xml version='1.0' encoding="UTF-8" standalone='yes'?>
<status code="#(status)#error::ok#(/status)#" />

File diff suppressed because one or more lines are too long

View File

@ -4,6 +4,7 @@ HTMLenc = function(s) {
$(document).ready(function() {
var height=document.documentElement.clientHeight - 200;
qtag = "";
/* Initialize Bookmark Dialog */
bm_dialog();
@ -113,14 +114,54 @@ $(document).ready(function() {
}
});
$("#example").multiselect();
loadTags();
});
function loadTags() {
$("#tag_include").empty();
$.ajax({
type: "GET",
url: "/api/ymarks/get_tags.xml?sort=alpha",
dataType: "xml",
cache: false,
success: function(xml) {
$(xml).find('tag').each(function(){
var count = $(this).attr('count');
var tag = $(this).attr('tag');
$('<option value="'+tag+'">'+tag+' ['+count+']</option>').appendTo('#tag_include');
}); //close each(
$("#tag_include").multiselect({
noneSelectedText: "Select tags ...",
height: "400",
click: function(event, ui) {
if(ui.checked) {
qtag = qtag + "," + ui.value;
}
},
close: function() {
$('#ymarks_flexigrid').flexOptions({
query: qtag,
qtype: "_tags",
newp: 1
});
$('#ymarks_flexigrid').flexReload();
},
beforeopen: function() {
$(this).multiselect("uncheckAll");
},
open: function() {
qtag = "";
}
});
}
}); //close $.ajax(
}
function loadTagCloud() {
$("#ymarks_tagcloud *").remove();
$.ajax({
type: "POST",
type: "GET",
url: "/api/ymarks/get_tags.xml?top=25&sort=alpha",
dataType: "xml",
cache: false,

File diff suppressed because one or more lines are too long

View File

@ -89,7 +89,7 @@ public class YMarkTables {
public final static String p3 = "\\E";
public final static String p4 = "(?:,.*|$)";
public final static String p5 = "((?:";
public final static String p6 = "),.*){";
public final static String p6 = ")(?:,.*|$)){";
public final static String p7 = "/.*)";
public final static String p8 = "(?:,|$)";
@ -210,9 +210,10 @@ public class YMarkTables {
}
patternBuilder.deleteCharAt(patternBuilder.length()-1);
patternBuilder.append(p6);
patternBuilder.append(tagArray.length);
patternBuilder.append('}');
final Pattern p = Pattern.compile(patternBuilder.toString());
final Pattern p = Pattern.compile(patternBuilder.toString(), Pattern.CASE_INSENSITIVE);
return this.worktables.iterator(bmk_table, YMarkEntry.BOOKMARK.TAGS.key(), p);
}
@ -238,6 +239,51 @@ public class YMarkTables {
}
}
public void replaceTags(final Iterator<Row> rowIterator, final String bmk_user, final String tagString, final String replaceString) throws IOException, RowSpaceExceededException {
final String[] tagArray = YMarkUtil.cleanTagsString(tagString).split(YMarkUtil.TAGS_SEPARATOR);
final StringBuilder tagStringBuilder = new StringBuilder(BUFFER_LENGTH);
Row row;
while (rowIterator.hasNext()) {
row = rowIterator.next();
if(row != null) {
for(int i=0; i<tagArray.length; i++) {
tagStringBuilder.setLength(0);
tagStringBuilder.append(row.get(YMarkEntry.BOOKMARK.TAGS.key(), YMarkEntry.BOOKMARK.TAGS.deflt()));
int start = tagStringBuilder.indexOf(tagArray[i]);
int end = start;
while (end<=tagStringBuilder.length() && end != -1) {
if (end == (tagStringBuilder.length())) {
if (end-start == tagArray[i].length()) {
if (start > 0)
start--; // also replace the tag separator
tagStringBuilder.replace(start, end, YMarkUtil.EMPTY_STRING);
}
break;
} else if (tagStringBuilder.charAt(end) == ',') {
if (end-start == tagArray[i].length()) {
if (start > 0)
start--; // also replace the tag separator
tagStringBuilder.replace(start, end, YMarkUtil.EMPTY_STRING);
} else {
start = tagStringBuilder.indexOf(tagArray[i], end+1);
end = start;
}
} else if (tagStringBuilder.charAt(end) == ' ') {
start = tagStringBuilder.indexOf(tagArray[i], end);
end = start;
} else {
end++;
}
}
tagStringBuilder.append(YMarkUtil.TAGS_SEPARATOR);
tagStringBuilder.append(replaceString);
row.put(YMarkEntry.BOOKMARK.TAGS.key(), YMarkUtil.cleanTagsString(tagStringBuilder.toString()));
this.worktables.update(TABLES.BOOKMARKS.tablename(bmk_user), row);
}
}
}
}
public void addFolder(final String bmk_user, final String url, final String folder) throws IOException, RowSpaceExceededException {
if(!folder.isEmpty()) {
// do not set defaults as we only want to add a folder

View File

@ -36,6 +36,7 @@ import net.yacy.kelondro.data.word.Word;
public class YMarkUtil {
public final static String TAGS_SEPARATOR = ",";
public final static String FOLDERS_SEPARATOR = "/";
public final static String EMPTY_STRING = "";
/**
* conveniance function to generate url hashes for YMark bookmarks