package plugins.Librarian; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Random; import java.util.Vector; import freenet.client.FetchException; import freenet.client.FetchResult; import freenet.client.HighLevelSimpleClient; import freenet.clients.http.filter.CommentException; import freenet.clients.http.filter.FilterCallback; import freenet.keys.FreenetURI; import freenet.pluginmanager.FredPlugin; import freenet.pluginmanager.FredPluginHTTP; import freenet.pluginmanager.FredPluginThreadless; import freenet.pluginmanager.PluginHTTPException; import freenet.pluginmanager.PluginRespirator; import freenet.support.HTMLEncoder; import freenet.support.api.HTTPRequest; public class Librarian implements FredPlugin, FredPluginHTTP, FredPluginThreadless { private static final String DEFAULT_INDEX_URI = "USK@7H66rhYmxIFgMyw5Dl11JazXGHPhp7dSN7WMa1pbtEo,jQHUQUPTkeRcjmjgrc7t5cDRdDkK3uKkrSzuw5CO9uk,AQACAAE/ENTRY.POINT/11/librarian.idx"; private volatile boolean goon = true; Random rnd = new Random(); PluginRespirator pr; private static final String plugName = "Librarian"; public void terminate() { goon = false; } public String handleHTTPPost(HTTPRequest request) throws PluginHTTPException { return null; } private void appendDefaultPageStart(StringBuilder out, String stylesheet) { out.append("" + plugName + ""); if(stylesheet != null) out.append(""); out.append("\n"); out.append("

" + plugName + "




\n"); } private void appendDefaultPageEnd(StringBuilder out) { out.append("
"); } private void appendDefaultPostFields(StringBuilder out, String search, String index) { search = HTMLEncoder.encode(search); index = HTMLEncoder.encode(index); out.append("Search for:
"); out.append("


"); out.append("Using the index:
"); out.append(""); out.append("
\n"); // index - key to index // search - text to search for } private HashMap getFullIndex(String uri) throws Exception { HighLevelSimpleClient hlsc = pr.getHLSimpleClient(); FreenetURI u = new FreenetURI(uri); FetchResult res; while(true) { try { res = hlsc.fetch(u); break; } catch (FetchException e) { if(e.newURI != null) { u = e.newURI; continue; } else throw e; } } String index[] = new String(res.asByteArray()).trim().split("\n"); Vector uris = new Vector(); HashMap keywords = new HashMap(); int i; URIWrapper uriw = new URIWrapper(); for (i = 0 ; i < index.length ; i++) { if (index[i].startsWith("!")) { /* Start new */ uriw = new URIWrapper(); uriw.URI = index[i].substring(1); uris.add(uriw); } else if (index[i].startsWith("+")) { /* Continue old */ if (uriw.descr==null) uriw.descr = index[i].substring(1); else uriw.descr += '\n' + index[i].substring(1); } else break; } for ( ; i < index.length ; i++) { if (!index[i].startsWith("?")) break; String parts[] = index[i].split(" "); Vector keyuris = new Vector(); //System.err.println(":::" + + ":::"); for (int j = 1 ; j < parts.length ; j++) { int uriNumber = Integer.parseInt(parts[j]); URIWrapper uw = (URIWrapper) uris.get(uriNumber); // Yes I know this is O(n), but there shouldn't be that many hits for a single word. // FIXME If there are, use a LinkedHashSet (note that this will cost far more memory). // Don't use a plain HashSet, because we want the results returned IN ORDER. if(!keyuris.contains(uw)) keyuris.add(uw); //System.err.println(); } keywords.put(parts[0].substring(1), keyuris); } return keywords; } public String handleHTTPGet(HTTPRequest request) throws PluginHTTPException { StringBuilder out = new StringBuilder(); //int page = request.getIntParam("page", 1); String indexuri = request.getParam("index", DEFAULT_INDEX_URI); String search = request.getParam("search"); String stylesheet = request.getParam("stylesheet", null); if(stylesheet != null) { FilterCallback cb = pr.makeFilterCallback(request.getPath()); try { stylesheet = cb.processURI(stylesheet, "text/css"); } catch (CommentException e) { return "Invalid stylesheet: "+e.getMessage(); } } if (search.equals("")) { appendDefaultPageStart(out, stylesheet); //appendDefaultPostFields(out); appendDefaultPostFields(out, search, indexuri); appendDefaultPageEnd(out); return out.toString(); } try { /* Cache later! */ //HighLevelSimpleClient hlsc = pr.getHLSimpleClient(); //String index = new String(hlsc.fetch(new FreenetURI(indexuri)).asByteArray()).trim(); /* /Cache!? */ //imglist = imglist.replaceAll("\r","\n"); /*do { i = imglist.hashCode(); imglist = imglist.replaceAll("\n\n", "\n"); } while (i != imglist.hashCode());*/ //String[] imgarr = imglist.split("\n"); HashMap index = getFullIndex(indexuri); appendDefaultPageStart(out, stylesheet); appendDefaultPostFields(out, search, indexuri); out.append("

Searching for: ").append(HTMLEncoder.encode(search)).append("

\n"); //String searchWords[] = search.replaceAll("%20", "+").split("+"); // Get search result String searchWords[] = search.split(" "); // Return results in order. LinkedHashSet hs = new LinkedHashSet(); synchronized (hs) { // add all for the first word Vector keyuris = (Vector)index.get(searchWords[0].toLowerCase().trim()); if (keyuris != null) { Iterator it = keyuris.iterator(); while (it.hasNext()) hs.add(it.next()); } } synchronized (hs) { for (int i = 1 ; i < searchWords.length ; i++) { Vector keyuris = (Vector)index.get(searchWords[i].toLowerCase().trim()); Iterator it = hs.iterator(); while (it.hasNext()) { Object o = it.next(); if (!keyuris.contains(o)) it.remove(); } } } // Output results int results = 0; out.append("\n"); Iterator it = hs.iterator(); while (it.hasNext()) { URIWrapper o = (URIWrapper)it.next(); String showurl = o.URI; String description = HTMLEncoder.encode(o.descr); description=description.replaceAll("(\n|<(b|B)(r|R)>)", "
"); description=description.replaceAll(" ", "  "); description=description.replaceAll("</?[a-zA-Z].*/?>", ""); showurl = HTMLEncoder.encode(showurl); if (showurl.length() > 60) showurl = showurl.substring(0,15) + "…" + showurl.replaceFirst("[^/]*/", "/"); String realurl = (o.URI.startsWith("/")?"":"/") + o.URI; realurl = HTMLEncoder.encode(realurl); out.append("

\n

\n"); out.append(" ").append(showurl).append("\n"); out.append("
\n"); out.append("").append(description).append("\n"); out.append("
\n"); results++; } out.append("\n"); out.append("

Found: ").append(results).append(" results

\n"); appendDefaultPageEnd(out); return out.toString(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return e.toString(); } } public void runPlugin(PluginRespirator pr) { this.pr = pr; //int i = (int)System.currentTimeMillis()%1000; //while(goon) { /* FetchResult fr; try { fr = pr.getHLSimpleClient().fetch(new FreenetURI("freenet:CHK@j-v1zc0cuN3wlaCpxlKd6vT6c1jAnT9KiscVjfzLu54,q9FIlJSh8M1I1ymRBz~A0fsIcGkvUYZahZb5j7uepLA,AAEA--8")); System.err.println(" Got data from key, length = " + fr.size() + " Message: " + new String(fr.asByteArray()).trim()); } catch (Exception e) { } */ // try { // Thread.sleep(300000); // } catch (InterruptedException e) { // TODO Auto-generated catch block //e.printStackTrace(); // } //} } private class URIWrapper implements Comparable { public String URI; public String descr; public int compareTo(Object o) { if (o instanceof URIWrapper) return URI.compareTo(((URIWrapper)o).URI); return -1; } } }