Mercurial Hosting > nabble
diff src/nabble/view/web/tools/SpamSearch.jtp @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children | 72765b66e2c3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nabble/view/web/tools/SpamSearch.jtp Thu Mar 21 19:15:52 2019 -0600 @@ -0,0 +1,308 @@ +<% +package nabble.view.web.tools; + +import com.google.gson.Gson; +import nabble.model.ModelHome; +import nabble.model.Node; +import nabble.model.Site; +import nabble.view.lib.Jtp; +import nabble.view.lib.Shared; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.Reader; +import java.net.URL; +import java.net.URLEncoder; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public final class SpamSearch extends HttpServlet { + + private static final String GOOGLE_URL = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&key=AIzaSyCjUKhbJVpU83CiRPJ1WV1x7WyszYSntC0&q="; + private static final String CHARSET = "UTF-8"; + + private static final Pattern POST_PTN = Pattern.compile("/.*-t(d\\d+)|((p\\d+)(p\\d+)?)\\.html$"); + + /** + * Defines five blocks per page because google usually returns a block with four results. + * So it shows 20 results per page. + */ + private static final int BLOCKS_PER_PAGE = 6; + + static String extractDomain(String url) { + int posDoubleSlash = url.indexOf("://"); + if (posDoubleSlash == -1) + return null; + int posNextSlash = url.indexOf('/', posDoubleSlash+3); + return url.substring(posDoubleSlash+3, posNextSlash); + } + + private static Long getPostId(String url) { + Matcher m = POST_PTN.matcher(url); + if (m.find()) { + if (m.group(4) != null) + return Long.valueOf(m.group(4).substring(1)); + else if (m.group(3) != null) + return Long.valueOf(m.group(3).substring(1)); + else if (m.group(1) != null) + return Long.valueOf(m.group(1).substring(1)); + } + return null; + } + + private static Long getSiteId(String domain) { + if (domain.endsWith(Jtp.getDefaultHost())) { + domain = domain.replace('.'+Jtp.getDefaultHost(), ""); + int dot = domain.lastIndexOf('.'); + return Long.valueOf(domain.substring(dot+1)); + } + return null; + } + + public void printResult(GoogleResults results, int j, PrintWriter out) { + if (results.getResponseData() != null) { + GoogleResults.Result result = results.getResponseData().getResults().get(j); + String url = result.getUrl(); + String title = result.getTitle(); + String content = result.getContent(); + + Long siteId = null; + Long postId = getPostId(url); + if (postId != null) { + String domain = extractDomain(url); + if (domain != null) { + siteId = getSiteId(domain); + siteId = siteId == null? ModelHome.getSiteIdFromDomain(domain) : siteId; + } + } + Site site = siteId == null? null : ModelHome.getSite(siteId); + Node node = site == null? null : site.getNode(postId); + %> + <% if (node != null && !node.getMessage().isDeleted()) { %> + <tr> + <td><input type="checkbox" class="checkBox" value="<%=siteId%>|<%=postId%>" name="results"/></td> + <td> + <a href="<%=url%>"><%=title%></a><br/> + <div class="clickable"> + <span class='url'><%=url%></span><br/> + <%=content%><br/> + <% if (node.getDescendantCount() > 1) { %> + <span class="badge" style="font-weight:bold;background:red;color:white">Has Replies</span> + <% } %> + <% Node.MailToList mail = node.getMailToList(); %> + <% if (mail != null && mail.isPending()) { %> + <span class="badge" style="font-weight:bold;background:green;color:white">Pending</span> + <% } %> + </div> + </td> + </tr> + <% } else { %> + <tr> + <td></td> + <td class="grayP"> + <a href='<%=url%>'><%=title%></a><br/> + <span class='url'><%=url%></span><br/> + <%=content%> + </td> + </tr> + <% } %> + <% + } + } + + public void getResults(String query, String site,HttpServletRequest request,PrintWriter out) + throws IOException + { + int start = 0; + int page = 0; + + if(request.getParameter("start") != null) + start = Integer.parseInt(request.getParameter("start")); + + if(request.getParameter("page") != null) + page = Integer.parseInt(request.getParameter("page")); + + if(!"".equals(query)) { + %> + <div>Page <%=page%></div> + <table> + <% + for (int k = 0; k < BLOCKS_PER_PAGE; k++) { + URL url = new URL(GOOGLE_URL+ URLEncoder.encode("site:"+site+" "+query, CHARSET)+"&start="+start ); + Reader reader = new InputStreamReader(url.openStream(), CHARSET); + GoogleResults results = new Gson().fromJson(reader, GoogleResults.class); + if (results.getResponseData() != null) { + int block_size = results.getResponseData().getResults().size(); + start += block_size; + for (int j = 0; j < block_size; j++) { + printResult(results,j,out); + } + } + } + %> + </table> + <br /> + Page <%=page%> – + <a href='?start=<%=start%>&site=<%=site%>&query=<%=query%>&page=<%=(page+1)%>'>Next</a> + <br /> + <br /> + <input type="submit" value="Delete Selected Posts" /> + <% + } + } + + + protected void service(HttpServletRequest request,HttpServletResponse response) + throws IOException + { + String query = request.getParameter("query"); + query = query == null? "" : query; + + String site = request.getParameter("site"); + site = site == null? Jtp.getDefaultHost() : site; + + boolean isDelete = "POST".equals(request.getMethod()) && "delete".equals(request.getParameter("action")); + int deleteCounter = 0; + if (isDelete) { + String[] results = request.getParameterValues("results"); + for (String r : results) { + String[] parts = r.split("\\|"); + long siteId = Long.valueOf(parts[0]); + long nodeId = Long.valueOf(parts[1]); + Node n = ModelHome.getSite(siteId).getNode(nodeId); + if (n != null) { + n.deleteMessageOrNode(); + deleteCounter++; + } + } + } + + PrintWriter out = response.getWriter(); + %> + <html> + <head> + <title>Nabble Search</title> + <% Shared.loadJavascript(request, out); %> + <% javascript(out); %> + <% css(out); %> + </head> + <body> + <h1>Nabble Search</h1> + <form action="SpamSearch.jtp" method="get"> + Search for <input type="text" name="query" value="<%=query%>" /> in <input type="text" name="site" value="<%=site%>" /> + <input type="submit" value="Search" /> + <input type="hidden" value="0" name="start" /> + <input type="hidden" value="1" name="page" /> + </form> + <% if (isDelete) { %> + <div style="color:red;padding:.5em 0">Deleted <%=deleteCounter%> nodes.</div> + <% } %> + <div id='results'> + <form action="SpamSearch.jtp" method="post"> + <input type="hidden" value="delete" name="action" /> + <input type="hidden" name="query" value="<%=query%>"/> + <input type="hidden" name="site" value="<%=site%>" /> + <% getResults(query,site,request,out); %> + </form> + </div> + </body> + </html> + <% + } + + private void javascript(PrintWriter out) { + %> + <script type="text/javascript"> + $(document).ready(function() { + $('div.clickable').each(function() { + var $this = $(this); + var $checkbox = $this.parent().prev().children().eq(0); + $this.click(function() { + var checked = $checkbox.attr('checked'); + if (checked) { + $this.removeClass('selected-row'); + $checkbox.removeAttr('checked'); + } else { + $this.addClass('selected-row'); + $checkbox.attr('checked', true); + } + }); + }); + }); + </script> + <% + } + private void css(PrintWriter out) { + %> + <style type="text/css"> + body { + padding: 1em; + font-family: Verdana, Sans-serif; + font-size:.84em; + } + span.url{ + color: green; + } + #results table { + width: 100%; + } + #results table td { + vertical-align:top; + padding-bottom: 1em; + } + #results td.grayP , td.grayP a , td.grayP span { + color: #C8C8C8 !important; + } + form input { + margin-bottom: 15px; + } + span.badge { + font-size:90%; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + padding: .2em .4em; + } + div.clickable { cursor:pointer; } + .selected-row { background:#ffffcc; } + </style> + <% + } +} + + +class GoogleResults { + + private ResponseData responseData; + public ResponseData getResponseData() { return responseData; } + public void setResponseData(ResponseData responseData) { this.responseData = responseData; } + public String toString() { return "ResponseData[" + responseData + "]"; } + + static class ResponseData { + private List<Result> results; + public List<Result> getResults() { return results; } + public void setResults(List<Result> results) { this.results = results; } + public String toString() { return "Results[" + results + "]"; } + } + + static class Result { + private String url; + private String title; + private String content; + public String getUrl() { return url; } + public String getTitle() { return title; } + public String getContent() { return content; } + public void setUrl(String url) { this.url = url; } + public void setTitle(String title) { this.title = title; } + public String toString() { return "Result[url:" + url +",title:" + title + "]"; } + } +} + + +%> \ No newline at end of file