mirror of
https://github.com/yacy/yacy_search_server.git
synced 2024-09-19 00:01:41 +02:00
YMarks:
- 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:
parent
804e48888b
commit
5581be12fb
|
@ -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>
|
||||
<script src="/yacy/ui/js/jquery.treeview.async.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">
|
||||
|
|
|
@ -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)#" />
|
|
@ -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";
|
||||
|
|
84
htroot/api/ymarks/replace_tags.java
Normal file
84
htroot/api/ymarks/replace_tags.java
Normal 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;
|
||||
}
|
||||
}
|
2
htroot/api/ymarks/replace_tags.xml
Normal file
2
htroot/api/ymarks/replace_tags.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version='1.0' encoding="UTF-8" standalone='yes'?>
|
||||
<status code="#(status)#error::ok#(/status)#" />
|
20
htroot/jquery/js/jquery.multiselect.min.js
vendored
Normal file
20
htroot/jquery/js/jquery.multiselect.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -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,
|
||||
|
|
20
htroot/yacy/ui/js/jquery.multiselect.min.js
vendored
20
htroot/yacy/ui/js/jquery.multiselect.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -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 = "(?:,|$)";
|
||||
|
||||
|
@ -195,7 +195,7 @@ public class YMarkTables {
|
|||
final Pattern p = Pattern.compile(patternBuilder.toString());
|
||||
return this.worktables.iterator(bmk_table, YMarkEntry.BOOKMARK.FOLDERS.key(), p);
|
||||
}
|
||||
|
||||
|
||||
public Iterator<Tables.Row> getBookmarksByTag(final String bmk_user, final String[] tagArray) throws IOException {
|
||||
final String bmk_table = TABLES.BOOKMARKS.tablename(bmk_user);
|
||||
final StringBuilder patternBuilder = new StringBuilder(BUFFER_LENGTH);
|
||||
|
@ -208,14 +208,15 @@ public class YMarkTables {
|
|||
patternBuilder.append(p3);
|
||||
patternBuilder.append('|');
|
||||
}
|
||||
patternBuilder.deleteCharAt(patternBuilder.length()-1);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
public List<Row> orderBookmarksBy(final Iterator<Row> rowIterator, final String sortname, final String sortorder) {
|
||||
final List<Row> sortList = new ArrayList<Row>();
|
||||
Row row;
|
||||
|
@ -237,6 +238,51 @@ public class YMarkTables {
|
|||
addBookmark(bmk_user, bmk, merge, true);
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
|
|
|
@ -36,7 +36,8 @@ 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
|
||||
* @param url a string representation of a valid url
|
||||
|
|
Loading…
Reference in New Issue
Block a user