Mercurial Hosting > nabble
view src/nabble/view/web/forum/SearchNamespace.java @ 19:18cf4872fd7f
remove anonymous posting
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 29 May 2020 22:58:25 -0600 |
parents | 7ecd1a4ef557 |
children |
line wrap: on
line source
package nabble.view.web.forum; import fschmidt.util.java.DateUtils; import fschmidt.util.servlet.ServletUtils; import nabble.model.Lucene; import nabble.model.Node; import nabble.model.NodeSearcher; import nabble.model.Person; import nabble.model.User; import nabble.naml.compiler.Command; import nabble.naml.compiler.CommandSpec; import nabble.naml.compiler.IPrintWriter; import nabble.naml.compiler.Interpreter; import nabble.naml.compiler.Namespace; import nabble.naml.compiler.ScopedInterpreter; import nabble.naml.namespaces.TemplateException; import nabble.view.lib.Jtp; import nabble.view.web.template.NabbleNamespace; import nabble.view.web.template.NodeList; import nabble.view.web.template.ServletNamespace; import nabble.view.web.template.UserNamespace; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.search.Filter; import javax.servlet.ServletException; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Set; @Namespace ( name = "search", global = true ) public final class SearchNamespace { private final Node node; private String query; private Person user; private int days; private int searchSize = 0; private List<Node> posts = Collections.emptyList(); public final NodeSearcher.Builder postQuery; private NodeSearcher postSearcher; private boolean hasQuery; private boolean sortByDate; private boolean didSearch = false; private final ServletNamespace servletNs; private boolean hasMore; public SearchNamespace(Node node,ServletNamespace servletNs) throws ServletException { this.node = node; this.servletNs = servletNs; postQuery = new NodeSearcher.Builder(node); User currentUser = Jtp.getUser(servletNs.request); postQuery.setCurrentUser(currentUser); } public static final CommandSpec query_author = CommandSpec.NO_OUTPUT() .dotParameter("author") .build() ; @Command public void query_author(IPrintWriter out,Interpreter interp) { if( user != null ) throw new RuntimeException("user already set"); String userId = interp.getArgString("author"); user = NabbleNamespace.current().site().getPerson(userId); postQuery.addUser(user); } public static final CommandSpec do_search = new CommandSpec.Builder() .parameters("length") .optionalParameters("query","days","start","sort") .build() ; @Command public void do_search(IPrintWriter out,Interpreter interp) throws TemplateException, ServletException { query = interp.getArgString("query"); days = interp.getArgAsInt("days",0); int start = interp.getArgAsInt("start",0); int length = interp.getArgAsInt("length"); Date startDate = days==0 ? null : DateUtils.addDays(new Date(), -days); hasQuery = query != null && query.length() > 0; sortByDate = hasQuery ? "date".equals(interp.getArgString("sort")) : true; try { postQuery.addLine(query); } catch(ParseException e) { throw TemplateException.newInstance("search_query_parse_error",e); } postQuery.addNodeKind(Node.Kind.POST); if (days != 0) { Filter filter = Lucene.getCachedFilter(Lucene.getRangeFilter(startDate, null)); postQuery.setFilter(filter); } if (sortByDate) { postQuery.setSort(NodeSearcher.SORT_BY_DATE); postQuery.setDateRange(startDate, null); } postSearcher = postQuery.build(); try { posts = postSearcher.getNodes(start, length); searchSize = postSearcher.getTotalHits(); } catch(NodeSearcher.TooManyClauses e) { throw TemplateException.newInstance("too_many_search_clauses",e); } hasMore = start + posts.size() < searchSize; didSearch = true; } public static final CommandSpec _user = CommandSpec.DO; @Command("user") public void _user(IPrintWriter out,ScopedInterpreter<UserNamespace> interp) { UserNamespace userNs = new UserNamespace(user); out.print( interp.getArg(userNs,"do") ); } @Command("days") public void _days(IPrintWriter out,Interpreter interp) { out.print(days); } @Command public void has_days(IPrintWriter out,Interpreter interp) { out.print( days > 0 ); } @Command public void total_posts(IPrintWriter out,Interpreter interp) { out.print(searchSize); } @Command public void has_results(IPrintWriter out,Interpreter interp) { out.print( searchSize > 0 ); } public static final CommandSpec highlight = CommandSpec.TEXT; @Command public void highlight(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); out.print( postSearcher.highlight(text,"<b>","</b>") ); } public static final CommandSpec results = CommandSpec.DO; @Command public void results(IPrintWriter out,ScopedInterpreter<NodeList> interp) { NodeList seq = new NodeList(posts,node,hasMore); out.print( interp.getArg(seq,"do") ); } @Command public void has_resort(IPrintWriter out,Interpreter interp) { out.print( hasQuery && searchSize > 1 ); } @Command public void has_query(IPrintWriter out,Interpreter interp) { out.print( hasQuery ); } @Command public void sorted_by_date(IPrintWriter out,Interpreter interp) { out.print( sortByDate ); } @Command public void search_terms(IPrintWriter out,Interpreter interp) { out.print( concatTerms(postSearcher.getSearchTerms()) ); } private static String concatTerms(Set<String> searchTerms) { StringBuilder buf = new StringBuilder(); for( String s : searchTerms ) { if (buf.length() > 0) buf.append('|'); buf.append(s.replaceAll("\\p{Punct}", "\\\\$0")); } return buf.toString(); } public static final CommandSpec fragment = new CommandSpec.Builder() .dotParameter("text") .parameters("size") .build() ; @Command public void fragment(IPrintWriter out,Interpreter interp) { String text = interp.getArgString("text"); String size = interp.getArgString("size"); int n; try { n = Integer.valueOf(size); } catch (NumberFormatException e) { throw new RuntimeException("Invalid \"size\" attribute: " + size); } out.print( Jtp.hideNull(postSearcher.getFragment(text, n, "...")) ); } @Command public void descendants_ids_matching_search_query(IPrintWriter out, Interpreter interp) throws TemplateException { String query = ServletUtils.getCookieValue(servletNs.request,"query"); String searchUserId = ServletUtils.getCookieValue(servletNs.request, "searchuser"); if ((query != null && !"".equals(query)) || searchUserId != null) { try { NodeSearcher.Builder luceneQuery = new NodeSearcher.Builder(NabbleNamespace.current().site(),node.getId()); luceneQuery.addLine(query); luceneQuery.addNodeKind(Node.Kind.POST); if( searchUserId != null && !"".equals(searchUserId) ) luceneQuery.addUser(searchUserId); final StringBuilder builder = new StringBuilder(); luceneQuery.build().forEach(new NodeSearcher.Handler(){ public void handle(long nodeId) { if (builder.length() > 0) builder.append(','); builder.append(nodeId); } }); out.print(builder.toString()); } catch (ParseException e) {} // ignore bad queries } } }