added new interactive search feature:

- during the user types search queries, the local database is searched
- results are presented interactively

This was implemented using a new JSON result format for search results in YaCy
- added JSON as file format for servlets
- refactoring of current search servlets (xml and html)
- added JSON output format for search results
- added AJAX-based search page, that uses the yacysearch.json selrvlet to print results as a query is typed

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@5373 6c8d7289-2bf4-0310-a012-ef5d649a1542
pull/1/head
orbiter 16 years ago
parent 74a3d86114
commit 0b4808ba3d

@ -7,6 +7,7 @@
<ul class="menu">
<li><a href="/index.html?display=1" accesskey="s" class="MenuItemLink">Search Page</a></li>
<li><a href="/yacy/ui/" accesskey="s" class="MenuItemLink">Rich Client Search</a></li>
<li><a href="/interactivesearch.html?display=1" class="MenuItemLink">Interactive local Search</a></li>
<!--<li><a href="/yacy/user/ysearch.html?display=1" accesskey="s" class="MenuItemLink">Search Page (alternative)</a></li>-->
<li><a href="/compare_yacy.html?display=1" class="MenuItemLink">Compare Search</a></li>
<li><a href="/Ranking_p.html" class="MenuItemLink lock">Ranking Config</a></li>

@ -0,0 +1,62 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>YaCy Interactive Search</title>
#%env/templates/metas.template%#
<script language="Javascript">
function xmlhttpPost() {
var xmlHttpReq = false;
var self = this;
if (window.XMLHttpRequest) { // Mozilla/Safari
self.xmlHttpReq = new XMLHttpRequest();
}
else if (window.ActiveXObject) { // IE
self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
var searchform = document.forms['searchform'];
self.xmlHttpReq.open('GET', "yacysearch.json?verify=false&resource=local&maximumRecords=100&query=" + searchform.query.value, true);
self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
updatepage(self.xmlHttpReq.responseText);
}
}
self.xmlHttpReq.send(null);
}
function updatepage(str){
var raw = document.getElementById("raw");
if (raw != null) raw.innerHTML = str;
var rsp = eval("("+str+")");
var firstChannel = rsp.channels[0];
var totalResults = firstChannel.totalResults;
var startIndex = firstChannel.startIndex;
var itemsPerPage = firstChannel.itemsPerPage;
var html = "<br>total results = " + totalResults;
var item;
html += "<table class=\"networkTable\" border=\"0\" cellpadding=\"2\" cellspacing=\"1\">";
html += "<tr class=\"TableHeader\" valign=\"bottom\"><td>Name</td><td>Description</td><td>Link</td></tr>";
for (var i = 0; i < firstChannel.items.length; i++) {
item = firstChannel.items[i];
html += "<tr class=\"TableCellLight\"><td>"+ item.title + "</td>";
html += "<td>" + item.description + "</td>";
html += "<td><a href=\"" + item.link + "\">" + item.link + "</a></td></tr>";
}
html += "</table>";
document.getElementById("result").innerHTML = html;
}
</script>
</head>
<body>
#%env/templates/header.template%#
<form name="searchform" onkeyup='xmlhttpPost(); return false;'>
<p>Query: <input name="query" type="text">
<!--<input value="Search" type="submit">--></p>
<div id="result"></div>
<!--<pre>Raw JSON String: <div id="raw"></div></pre>-->
</form>
#%env/templates/footer.template%#
</body>
</html>

@ -117,11 +117,11 @@ var progressbar = new Progressbar(#[results]#, document.getElementById("results"
<!-- linklist begin -->
#(resultTable)#::<table width="100%"><tr class="TableHeader"><td width="30%">Media</td><td width="70%">URL</tr>#(/resultTable)#
#{results}#
<!--#include virtual="yacysearchitem.html?rss=false&item=#[item]#&eventID=#[eventID]#&display=#[display]#" -->
<!--#include virtual="yacysearchitem.html?item=#[item]#&eventID=#[eventID]#&display=#[display]#" -->
#{/results}#
#(resultTable)#::</table>#(/resultTable)#
<!-- linklist end -->
<!-- attach the bottomline -->
<!--#include virtual="yacysearchitem.html?bottomline=true&eventID=#[eventID]#&display=#[display]#" -->
<!--#include virtual="yacysearchtrailer.html?eventID=#[eventID]#&display=#[display]#" -->
</body>
</html>

@ -80,7 +80,7 @@ public class yacysearch {
boolean fetchSnippets = (post != null && post.get("verify", "false").equals("true"));
final serverObjects prop = new serverObjects();
final boolean rss = (post == null) ? false : post.get("rss", "false").equals("true");
//final boolean rss = (post == null) ? false : post.get("rss", "false").equals("true");
prop.put("input_promoteSearchPageGreeting", promoteSearchPageGreeting);
prop.put("input_promoteSearchPageGreeting.homepage", sb.getConfig("promoteSearchPageGreeting.homepage", ""));
prop.put("input_promoteSearchPageGreeting.smallImage", sb.getConfig("promoteSearchPageGreeting.smallImage", ""));
@ -348,12 +348,12 @@ public class yacysearch {
prop.put("num-results_offset", offset);
prop.put("num-results_itemscount", "0");
prop.put("num-results_itemsPerPage", itemsPerPage);
prop.put("num-results_totalcount", yFormatter.number(totalcount, !rss));
prop.put("num-results_totalcount", yFormatter.number(totalcount, true));
prop.put("num-results_globalresults", (globalsearch) ? "1" : "0");
prop.put("num-results_globalresults_localResourceSize", yFormatter.number(theSearch.getRankingResult().getLocalResourceSize(), !rss));
prop.put("num-results_globalresults_remoteResourceSize", yFormatter.number(theSearch.getRankingResult().getRemoteResourceSize(), !rss));
prop.put("num-results_globalresults_remoteIndexCount", yFormatter.number(theSearch.getRankingResult().getRemoteIndexCount(), !rss));
prop.put("num-results_globalresults_remotePeerCount", yFormatter.number(theSearch.getRankingResult().getRemotePeerCount(), !rss));
prop.put("num-results_globalresults_localResourceSize", yFormatter.number(theSearch.getRankingResult().getLocalResourceSize(), true));
prop.put("num-results_globalresults_remoteResourceSize", yFormatter.number(theSearch.getRankingResult().getRemoteResourceSize(), true));
prop.put("num-results_globalresults_remoteIndexCount", yFormatter.number(theSearch.getRankingResult().getRemoteIndexCount(), true));
prop.put("num-results_globalresults_remotePeerCount", yFormatter.number(theSearch.getRankingResult().getRemotePeerCount(), true));
// compose page navigation
final StringBuffer resnav = new StringBuffer();

@ -0,0 +1,25 @@
{
"xmlns$yacy": "http://www.yacy.net/",
"xmlns$os": "http://a9.com/-/spec/opensearch/1.1/",
"channels": [{
"title": "YaCy P2P-Search for #[rss_query]#",
"description": "Search for #[rss_query]#",
"link": "#[searchBaseURL]#?query=#[rss_queryenc]#&amp;resource=#[input_resource]#&amp;contentdom=#[input_contentdom]#&amp;verify=#[input_verify]#",
"image": {
"url": "#[rssYacyImageURL]#",
"title": "Search for #[rss_query]#",
"link": "#[searchBaseURL]#?query=#[rss_queryenc]#&amp;resource=#[input_resource]#&amp;contentdom=#[input_contentdom]#&amp;verify=#[input_verify]#"
},
"totalResults": "#[num-results_totalcount]#",
"startIndex": "#[num-results_offset]#",
"itemsPerPage": "#[num-results_itemsPerPage]#",
"searchTerms": "#[rss_queryenc]#",
"items": [
#{results}#
<!--#include virtual="yacysearchitem.json?item=#[item]#&eventID=#[eventID]#" -->
#{/results}#
{}],
<!--#include virtual="yacysearchtrailer.json?eventID=#[eventID]#" -->
}]
}

@ -21,9 +21,9 @@
<opensearch:Query role="request" searchTerms="#[rss_queryenc]#" />
#{results}#
<!--#include virtual="yacysearchitem.html?rss=true&item=#[item]#&eventID=#[eventID]#" -->
<!--#include virtual="yacysearchitem.xml?item=#[item]#&eventID=#[eventID]#" -->
#{/results}#
<!--#include virtual="yacysearchitem.html?rss=true&bottomline=true&eventID=#[eventID]#" -->
<!--#include virtual="yacysearchtrailer.xml?eventID=#[eventID]#" -->
</channel>
</rss>

@ -2,7 +2,7 @@
<div class="searchresults">
<h4 class="linktitle">
<img src="ViewImage.png?width=16&height=16&code=#[faviconCode]#" id="f#[urlhash]#" class="favicon" width="16" height="16" alt="" />
<a href="#[url]#" target="_parent">#[description]#</a></h4>
<a href="#[link]#" target="_parent">#[title]#</a></h4>
#(authorized)#::
<div class="urlactions">
<a href="/Bookmarks.html?edit=#[urlhash]#" class="bookmarklink" title="bookmark"><img src="/env/grafics/empty.gif" title="bookmark" alt="bookmark" class="bookmarkIcon" /></a>
@ -15,9 +15,9 @@
#(/recommend)#
</div>
#(/authorized)#
<p class="snippet"><span class="snippetLoaded" id="h#[urlhash]#">#[snippet]#</span></p>
<p class="url"><a href="#[url]#" id="url#[urlhash]#" target="_parent">#[urlname]#</a></p>
<p class="urlinfo">#[date]# | YBR-#[ybr]# | <a href="ViewFile.html?urlHash=#[urlhash]#&amp;words=#[words]#&amp;display=#[display]#">Info</a> | <a href="yacysearch.html?cat=image&amp;url=#[url]#&amp;search=#[former]#&amp;display=#[display]#">Pictures</a></p>
<p class="snippet"><span class="snippetLoaded" id="h#[urlhash]#">#[description]#</span></p>
<p class="url"><a href="#[link]#" id="url#[urlhash]#" target="_parent">#[urlname]#</a></p>
<p class="urlinfo">#[date]# | YBR-#[ybr]# | <a href="ViewFile.html?urlHash=#[urlhash]#&amp;words=#[words]#&amp;display=#[display]#">Info</a> | <a href="yacysearch.html?cat=image&amp;url=#[link]#&amp;search=#[former]#&amp;display=#[display]#">Pictures</a></p>
</div>
::
#{items}#
@ -42,31 +42,9 @@
<tr class="#(col)#TableCellLight::TableCellDark#(/col)#"><td>#[name]#</td><td><a href="#[href]#">#[hrefshort]#</a></tr>
#{/items}#
#(/content)#
#(rss)#::
<item>
<title>#[title]#</title>
<link>#[link]#</link>
<description>#[description]#</description>
<pubDate>#[date]#</pubDate>
<guid isPermaLink="false">#[urlhash]#</guid>
</item>
#(/rss)#
#(references)#::
<p><strong>Topwords</strong>:
#{words}#&nbsp;<a href="yacysearch.html?search=#[newsearch]#&amp;Enter=Search&amp;count=#[count]#&amp;offset=#[offset]#&amp;resource=#[resource]#&amp;contentdom=#[contentdom]#">#[word]#</a>&nbsp;|#{/words}#
</p>
#(/references)#
#(rssreferences)#::
<yacy:topwords>
#{words}#
<yacy:item>#[word]#</yacy:item>
#{/words}#
</yacy:topwords>
#(/rssreferences)#
#(dynamic)#::
<script type="text/javascript">
statistics("#[offset]#", "#[itemscount]#", "#[totalcount]#", "#[localResourceSize]#", "#[remoteResourceSize]#", "#[remoteIndexCount]#", "#[remotePeerCount]#");
progressbar.step(1);
</script>
#(/dynamic)#

@ -28,13 +28,9 @@ import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import de.anomic.http.httpRequestHeader;
import de.anomic.kelondro.kelondroMSetTools;
import de.anomic.kelondro.kelondroNaturalOrder;
import de.anomic.plasma.plasmaProfiling;
import de.anomic.plasma.plasmaSearchEvent;
import de.anomic.plasma.plasmaSearchQuery;
@ -57,15 +53,12 @@ public class yacysearchitem {
private static boolean col = true;
private static final int namelength = 60;
private static final int urllength = 120;
private static final int MAX_TOPWORDS = 24;
public static serverObjects respond(final httpRequestHeader header, final serverObjects post, final serverSwitch<?> env) {
final plasmaSwitchboard sb = (plasmaSwitchboard) env;
final serverObjects prop = new serverObjects();
final String eventID = post.get("eventID", "");
final boolean bottomline = post.get("bottomline", "false").equals("true");
final boolean rss = post.get("rss", "false").equals("true");
final boolean authenticated = sb.adminAuthenticated(header) >= 2;
final int item = post.getInt("item", -1);
final boolean auth = ((String) header.get(httpRequestHeader.CONNECTION_PROP_CLIENTIP, "")).equals("localhost") || sb.verifyAuthentication(header, true);
@ -87,88 +80,14 @@ public class yacysearchitem {
final plasmaSearchQuery theQuery = theSearch.getQuery();
// dynamically update count values
if (!rss) {
final int offset = theQuery.neededResults() - theQuery.displayResults() + 1;
prop.put("dynamic_offset", offset);
prop.put("dynamic_itemscount", (item < 0) ? theQuery.neededResults() : item + 1);
prop.put("dynamic_totalcount", yFormatter.number(theSearch.getRankingResult().getLocalResourceSize() + theSearch.getRankingResult().getRemoteResourceSize(), !rss));
prop.put("dynamic_localResourceSize", yFormatter.number(theSearch.getRankingResult().getLocalResourceSize(), !rss));
prop.put("dynamic_remoteResourceSize", yFormatter.number(theSearch.getRankingResult().getRemoteResourceSize(), !rss));
prop.put("dynamic_remoteIndexCount", yFormatter.number(theSearch.getRankingResult().getRemoteIndexCount(), !rss));
prop.put("dynamic_remotePeerCount", yFormatter.number(theSearch.getRankingResult().getRemotePeerCount(), !rss));
prop.put("dynamic", "1");
}
if (bottomline) {
// attach the bottom line with search references (topwords)
final Set<String> references = theSearch.references(20);
if (references.size() > 0) {
// get the topwords
final TreeSet<String> topwords = new TreeSet<String>(kelondroNaturalOrder.naturalComparator);
String tmp = "";
final Iterator<String> i = references.iterator();
while (i.hasNext()) {
tmp = i.next();
if (tmp.matches("[a-z]+")) {
topwords.add(tmp);
}
}
// filter out the badwords
final TreeSet<String> filteredtopwords = kelondroMSetTools.joinConstructive(topwords, plasmaSwitchboard.badwords);
if (filteredtopwords.size() > 0) {
kelondroMSetTools.excludeDestructive(topwords, plasmaSwitchboard.badwords);
}
// avoid stopwords being topwords
if (env.getConfig("filterOutStopwordsFromTopwords", "true").equals("true")) {
if ((plasmaSwitchboard.stopwords != null) && (plasmaSwitchboard.stopwords.size() > 0)) {
kelondroMSetTools.excludeDestructive(topwords, plasmaSwitchboard.stopwords);
}
}
if (rss) {
String word;
int hintcount = 0;
final Iterator<String> iter = topwords.iterator();
while (iter.hasNext()) {
word = iter.next();
if (word != null) {
prop.putHTML("rssreferences_words_" + hintcount + "_word", word);
}
prop.put("rssreferences_words", hintcount);
if (hintcount++ > MAX_TOPWORDS) {
break;
}
}
prop.put("rssreferences", "1");
} else {
String word;
int hintcount = 0;
final Iterator<String> iter = topwords.iterator();
while (iter.hasNext()) {
word = iter.next();
if (/*(theQuery == null) ||*/ (theQuery.queryString == null)) break;
if (word != null) {
prop.putHTML("references_words_" + hintcount + "_word", word);
prop.putHTML("references_words_" + hintcount + "_newsearch", theQuery.queryString.replace(' ', '+') + "+" + word);
prop.put("references_words_" + hintcount + "_count", theQuery.displayResults());
prop.put("references_words_" + hintcount + "_offset", "0");
prop.put("references_words_" + hintcount + "_contentdom", theQuery.contentdom());
prop.put("references_words_" + hintcount + "_resource", ((theQuery.isLocal()) ? "local" : "global"));
}
prop.put("references_words", hintcount);
if (hintcount++ > MAX_TOPWORDS) {
break;
}
}
prop.put("references", "1");
}
}
serverProfiling.update("SEARCH", new plasmaProfiling.searchEvent(theQuery.id(true), plasmaSearchEvent.FINALIZATION + "-" + "bottomline", 0, 0));
return prop;
}
prop.put("offset", offset);
prop.put("itemscount", (item < 0) ? theQuery.neededResults() : item + 1);
prop.put("totalcount", yFormatter.number(theSearch.getRankingResult().getLocalResourceSize() + theSearch.getRankingResult().getRemoteResourceSize(), true));
prop.put("localResourceSize", yFormatter.number(theSearch.getRankingResult().getLocalResourceSize(), true));
prop.put("remoteResourceSize", yFormatter.number(theSearch.getRankingResult().getRemoteResourceSize(), true));
prop.put("remoteIndexCount", yFormatter.number(theSearch.getRankingResult().getRemoteIndexCount(), true));
prop.put("remotePeerCount", yFormatter.number(theSearch.getRankingResult().getRemotePeerCount(), true));
prop.put("rss", "0");
@ -179,27 +98,6 @@ public class yacysearchitem {
final plasmaSearchEvent.ResultEntry result = theSearch.oneResult(item);
if (result == null) return prop; // no content
if (rss) {
// text search for rss output
prop.put("rss", "1"); // switch on specific content
prop.putXML("rss_title", result.title());
final plasmaSnippetCache.TextSnippet snippet = result.textSnippet();
prop.putXML("rss_description", (snippet == null) ? "" : snippet.getLineRaw());
prop.putXML("rss_link", result.urlstring());
prop.put("rss_urlhash", result.hash());
prop.put("rss_date", plasmaSwitchboard.dateString822(result.modified()));
return prop;
}
prop.put("content", theQuery.contentdom + 1); // switch on specific content
prop.put("content_authorized", authenticated ? "1" : "0");
prop.put("content_authorized_recommend", (sb.webIndex.newsPool.getSpecific(yacyNewsPool.OUTGOING_DB, yacyNewsPool.CATEGORY_SURFTIPP_ADD, "url", result.urlstring()) == null) ? "1" : "0");
prop.putHTML("content_authorized_recommend_deletelink", "/yacysearch.html?search=" + theQuery.queryString + "&Enter=Search&count=" + theQuery.displayResults() + "&offset=" + (theQuery.neededResults() - theQuery.displayResults()) + "&order=" + crypt.simpleEncode(theQuery.ranking.toExternalString()) + "&resource=local&time=3&deleteref=" + result.hash() + "&urlmaskfilter=.*");
prop.putHTML("content_authorized_recommend_recommendlink", "/yacysearch.html?search=" + theQuery.queryString + "&Enter=Search&count=" + theQuery.displayResults() + "&offset=" + (theQuery.neededResults() - theQuery.displayResults()) + "&order=" + crypt.simpleEncode(theQuery.ranking.toExternalString()) + "&resource=local&time=3&recommendref=" + result.hash() + "&urlmaskfilter=.*");
prop.put("content_authorized_urlhash", result.hash());
prop.putHTML("content_description", result.title());
prop.putHTML("content_url", result.urlstring());
prop.put("content_display", display);
final int port=result.url().getPort();
yacyURL faviconURL;
@ -209,11 +107,23 @@ public class yacysearchitem {
faviconURL = null;
}
prop.put("content", 1); // switch on specific content
prop.put("content_authorized", authenticated ? "1" : "0");
prop.put("content_authorized_recommend", (sb.webIndex.newsPool.getSpecific(yacyNewsPool.OUTGOING_DB, yacyNewsPool.CATEGORY_SURFTIPP_ADD, "url", result.urlstring()) == null) ? "1" : "0");
prop.putHTML("content_authorized_recommend_deletelink", "/yacysearch.html?search=" + theQuery.queryString + "&Enter=Search&count=" + theQuery.displayResults() + "&offset=" + (theQuery.neededResults() - theQuery.displayResults()) + "&order=" + crypt.simpleEncode(theQuery.ranking.toExternalString()) + "&resource=local&time=3&deleteref=" + result.hash() + "&urlmaskfilter=.*");
prop.putHTML("content_authorized_recommend_recommendlink", "/yacysearch.html?search=" + theQuery.queryString + "&Enter=Search&count=" + theQuery.displayResults() + "&offset=" + (theQuery.neededResults() - theQuery.displayResults()) + "&order=" + crypt.simpleEncode(theQuery.ranking.toExternalString()) + "&resource=local&time=3&recommendref=" + result.hash() + "&urlmaskfilter=.*");
prop.put("content_authorized_urlhash", result.hash());
prop.putHTML("content_title", result.title());
prop.putHTML("content_link", result.urlstring());
prop.put("content_display", display);
prop.putHTML("content_faviconCode", sb.licensedURLs.aquireLicense(faviconURL)); // aquire license for favicon url loading
prop.put("content_urlhash", result.hash());
prop.put("content_urlhexhash", yacySeed.b64Hash2hexHash(result.hash()));
prop.putHTML("content_urlname", nxTools.shortenURLString(result.urlname(), urllength));
prop.put("content_date", plasmaSwitchboard.dateString(result.modified()));
prop.put("content_date822", plasmaSwitchboard.dateString822(result.modified()));
prop.put("content_ybr", plasmaSearchRankingProcess.ybr(result.hash()));
prop.putNum("content_size", result.filesize());
@ -227,7 +137,7 @@ public class yacysearchitem {
((yacyURL.probablyRootURL(result.hash())) ? ", probablyRootURL" : "") +
(((wordURL = yacyURL.probablyWordURL(result.hash(), query[0])) != null) ? ", probablyWordURL=" + wordURL.toNormalform(false, true) : ""));
final plasmaSnippetCache.TextSnippet snippet = result.textSnippet();
prop.put("content_snippet", (snippet == null) ? "" : snippet.getLineMarked(theQuery.fullqueryHashes));
prop.put("content_description", (snippet == null) ? "" : snippet.getLineMarked(theQuery.fullqueryHashes));
serverProfiling.update("SEARCH", new plasmaProfiling.searchEvent(theQuery.id(true), plasmaSearchEvent.FINALIZATION + "-" + item, 0, 0));
return prop;

@ -0,0 +1,7 @@
#(content)#:: {
"title": "#[title]#",
"link": "#[link]#",
"description": "#[description]#",
"pubDate": "#[date822]#",
"guid": "#[urlhash]#"
},#(/content)#

@ -0,0 +1,7 @@
#(content)#::<item>
<title>#[title]#</title>
<link>#[link]#</link>
<description>#[description]#</description>
<pubDate>#[date822]#</pubDate>
<guid isPermaLink="false">#[urlhash]#</guid>
</item>#(/content)#

@ -0,0 +1,3 @@
<p><strong>Topwords</strong>:
#{words}#&nbsp;<a href="yacysearch.html?search=#[newsearch]#&amp;Enter=Search&amp;count=#[count]#&amp;offset=#[offset]#&amp;resource=#[resource]#&amp;contentdom=#[contentdom]#">#[word]#</a>&nbsp;|#{/words}#
</p>

@ -0,0 +1,116 @@
// yacysearchitem.java
// (C) 2007 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany
// first published 28.08.2007 on http://yacy.net
//
// This is a part of YaCy, a peer-to-peer based web search engine
//
// $LastChangedDate: 2006-04-02 22:40:07 +0200 (So, 02 Apr 2006) $
// $LastChangedRevision: 1986 $
// $LastChangedBy: orbiter $
//
// LICENSE
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import de.anomic.http.httpRequestHeader;
import de.anomic.kelondro.kelondroMSetTools;
import de.anomic.kelondro.kelondroNaturalOrder;
import de.anomic.plasma.plasmaProfiling;
import de.anomic.plasma.plasmaSearchEvent;
import de.anomic.plasma.plasmaSearchQuery;
import de.anomic.plasma.plasmaSwitchboard;
import de.anomic.server.serverObjects;
import de.anomic.server.serverProfiling;
import de.anomic.server.serverSwitch;
public class yacysearchtrailer {
private static final int MAX_TOPWORDS = 24;
public static serverObjects respond(final httpRequestHeader header, final serverObjects post, final serverSwitch<?> env) {
final serverObjects prop = new serverObjects();
final String eventID = post.get("eventID", "");
// default settings for blank item
prop.put("words", "0");
// find search event
final plasmaSearchEvent theSearch = plasmaSearchEvent.getEvent(eventID);
if (theSearch == null) {
// the event does not exist, show empty page
return prop;
}
final plasmaSearchQuery theQuery = theSearch.getQuery();
// attach the bottom line with search references (topwords)
final Set<String> references = theSearch.references(20);
if (references.size() > 0) {
// get the topwords
final TreeSet<String> topwords = new TreeSet<String>(kelondroNaturalOrder.naturalComparator);
String tmp = "";
final Iterator<String> i = references.iterator();
while (i.hasNext()) {
tmp = i.next();
if (tmp.matches("[a-z]+")) {
topwords.add(tmp);
}
}
// filter out the badwords
final TreeSet<String> filteredtopwords = kelondroMSetTools.joinConstructive(topwords, plasmaSwitchboard.badwords);
if (filteredtopwords.size() > 0) {
kelondroMSetTools.excludeDestructive(topwords, plasmaSwitchboard.badwords);
}
// avoid stopwords being topwords
if (env.getConfig("filterOutStopwordsFromTopwords", "true").equals("true")) {
if ((plasmaSwitchboard.stopwords != null) && (plasmaSwitchboard.stopwords.size() > 0)) {
kelondroMSetTools.excludeDestructive(topwords, plasmaSwitchboard.stopwords);
}
}
String word;
int hintcount = 0;
final Iterator<String> iter = topwords.iterator();
while (iter.hasNext()) {
word = iter.next();
if (/*(theQuery == null) ||*/ (theQuery.queryString == null)) break;
if (word != null) {
prop.putHTML("words_" + hintcount + "_word", word);
prop.putHTML("words_" + hintcount + "_newsearch", theQuery.queryString.replace(' ', '+') + "+" + word);
prop.put("words_" + hintcount + "_count", theQuery.displayResults());
prop.put("words_" + hintcount + "_offset", "0");
prop.put("words_" + hintcount + "_contentdom", theQuery.contentdom());
prop.put("words_" + hintcount + "_resource", ((theQuery.isLocal()) ? "local" : "global"));
}
prop.put("words", hintcount);
if (hintcount++ > MAX_TOPWORDS) {
break;
}
}
}
serverProfiling.update("SEARCH", new plasmaProfiling.searchEvent(theQuery.id(true), plasmaSearchEvent.FINALIZATION + "-" + "bottomline", 0, 0));
return prop;
}
}

@ -0,0 +1,5 @@
"yacy$topwords": [
#{words}#
{ "word": "#[word]#" },
#{/words}#
{}]

@ -0,0 +1,5 @@
<yacy:topwords>
#{words}#
<yacy:item>#[word]#</yacy:item>
#{/words}#
</yacy:topwords>

@ -48,7 +48,6 @@ import de.anomic.plasma.plasmaSwitchboard;
import de.anomic.server.serverCore;
// The Naming of the functions is a bit strange...
import java.io.FileFilter;
public class listManager {
public static plasmaSwitchboard switchboard = null;

@ -571,6 +571,7 @@ public final class httpdFileHandler {
if (path.endsWith("html") ||
path.endsWith("htm") ||
path.endsWith("xml") ||
path.endsWith("json") ||
path.endsWith("rdf") ||
path.endsWith("rss") ||
path.endsWith("csv") ||

Loading…
Cancel
Save