comparison src/nabble/view/web/tools/SpamSearch.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children 72765b66e2c3
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1
2 package nabble.view.web.tools;
3
4 import com.google.gson.Gson;
5 import nabble.model.ModelHome;
6 import nabble.model.Node;
7 import nabble.model.Site;
8 import nabble.view.lib.Jtp;
9 import nabble.view.lib.Shared;
10
11 import javax.servlet.http.HttpServlet;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 import java.io.IOException;
15 import java.io.InputStreamReader;
16 import java.io.PrintWriter;
17 import java.io.Reader;
18 import java.net.URL;
19 import java.net.URLEncoder;
20 import java.util.List;
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23
24
25 public final class SpamSearch extends HttpServlet {
26
27 private static final String GOOGLE_URL = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&key=AIzaSyCjUKhbJVpU83CiRPJ1WV1x7WyszYSntC0&q=";
28 private static final String CHARSET = "UTF-8";
29
30 private static final Pattern POST_PTN = Pattern.compile("/.*-t(d\\d+)|((p\\d+)(p\\d+)?)\\.html$");
31
32 /**
33 * Defines five blocks per page because google usually returns a block with four results.
34 * So it shows 20 results per page.
35 */
36 private static final int BLOCKS_PER_PAGE = 6;
37
38 static String extractDomain(String url) {
39 int posDoubleSlash = url.indexOf("://");
40 if (posDoubleSlash == -1)
41 return null;
42 int posNextSlash = url.indexOf('/', posDoubleSlash+3);
43 return url.substring(posDoubleSlash+3, posNextSlash);
44 }
45
46 private static Long getPostId(String url) {
47 Matcher m = POST_PTN.matcher(url);
48 if (m.find()) {
49 if (m.group(4) != null)
50 return Long.valueOf(m.group(4).substring(1));
51 else if (m.group(3) != null)
52 return Long.valueOf(m.group(3).substring(1));
53 else if (m.group(1) != null)
54 return Long.valueOf(m.group(1).substring(1));
55 }
56 return null;
57 }
58
59 private static Long getSiteId(String domain) {
60 if (domain.endsWith(Jtp.getDefaultHost())) {
61 domain = domain.replace('.'+Jtp.getDefaultHost(), "");
62 int dot = domain.lastIndexOf('.');
63 return Long.valueOf(domain.substring(dot+1));
64 }
65 return null;
66 }
67
68 public void printResult(GoogleResults results, int j, PrintWriter out) {
69 if (results.getResponseData() != null) {
70 GoogleResults.Result result = results.getResponseData().getResults().get(j);
71 String url = result.getUrl();
72 String title = result.getTitle();
73 String content = result.getContent();
74
75 Long siteId = null;
76 Long postId = getPostId(url);
77 if (postId != null) {
78 String domain = extractDomain(url);
79 if (domain != null) {
80 siteId = getSiteId(domain);
81 siteId = siteId == null? ModelHome.getSiteIdFromDomain(domain) : siteId;
82 }
83 }
84 Site site = siteId == null? null : ModelHome.getSite(siteId);
85 Node node = site == null? null : site.getNode(postId);
86
87 out.print( "\r\n" );
88 if (node != null && !node.getMessage().isDeleted()) {
89 out.print( "\r\n <tr>\r\n <td><input type=\"checkbox\" class=\"checkBox\" value=\"" );
90 out.print( (siteId) );
91 out.print( "|" );
92 out.print( (postId) );
93 out.print( "\" name=\"results\"/></td>\r\n <td>\r\n <a href=\"" );
94 out.print( (url) );
95 out.print( "\">" );
96 out.print( (title) );
97 out.print( "</a><br/>\r\n <div class=\"clickable\">\r\n <span class='url'>" );
98 out.print( (url) );
99 out.print( "</span><br/>\r\n " );
100 out.print( (content) );
101 out.print( "<br/>\r\n " );
102 if (node.getDescendantCount() > 1) {
103 out.print( "\r\n <span class=\"badge\" style=\"font-weight:bold;background:red;color:white\">Has Replies</span>\r\n " );
104 }
105 out.print( "\r\n " );
106 Node.MailToList mail = node.getMailToList();
107 out.print( "\r\n " );
108 if (mail != null && mail.isPending()) {
109 out.print( "\r\n <span class=\"badge\" style=\"font-weight:bold;background:green;color:white\">Pending</span>\r\n " );
110 }
111 out.print( "\r\n </div>\r\n </td>\r\n </tr>\r\n" );
112 } else {
113 out.print( "\r\n <tr>\r\n <td></td>\r\n <td class=\"grayP\">\r\n <a href='" );
114 out.print( (url) );
115 out.print( "'>" );
116 out.print( (title) );
117 out.print( "</a><br/>\r\n <span class='url'>" );
118 out.print( (url) );
119 out.print( "</span><br/>\r\n " );
120 out.print( (content) );
121 out.print( "\r\n </td>\r\n </tr>\r\n" );
122 }
123 out.print( "\r\n" );
124
125 }
126 }
127
128 public void getResults(String query, String site,HttpServletRequest request,PrintWriter out)
129 throws IOException
130 {
131 int start = 0;
132 int page = 0;
133
134 if(request.getParameter("start") != null)
135 start = Integer.parseInt(request.getParameter("start"));
136
137 if(request.getParameter("page") != null)
138 page = Integer.parseInt(request.getParameter("page"));
139
140 if(!"".equals(query)) {
141
142 out.print( "\r\n<div>Page " );
143 out.print( (page) );
144 out.print( "</div>\r\n<table>\r\n" );
145
146 for (int k = 0; k < BLOCKS_PER_PAGE; k++) {
147 URL url = new URL(GOOGLE_URL+ URLEncoder.encode("site:"+site+" "+query, CHARSET)+"&start="+start );
148 Reader reader = new InputStreamReader(url.openStream(), CHARSET);
149 GoogleResults results = new Gson().fromJson(reader, GoogleResults.class);
150 if (results.getResponseData() != null) {
151 int block_size = results.getResponseData().getResults().size();
152 start += block_size;
153 for (int j = 0; j < block_size; j++) {
154 printResult(results,j,out);
155 }
156 }
157 }
158
159 out.print( "\r\n</table>\r\n<br />\r\nPage " );
160 out.print( (page) );
161 out.print( " &ndash;\r\n<a href='?start=" );
162 out.print( (start) );
163 out.print( "&site=" );
164 out.print( (site) );
165 out.print( "&query=" );
166 out.print( (query) );
167 out.print( "&page=" );
168 out.print( ((page+1)) );
169 out.print( "'>Next</a>\r\n<br />\r\n<br />\r\n<input type=\"submit\" value=\"Delete Selected Posts\" />\r\n" );
170
171 }
172 }
173
174
175 protected void service(HttpServletRequest request,HttpServletResponse response)
176 throws IOException
177 {
178 String query = request.getParameter("query");
179 query = query == null? "" : query;
180
181 String site = request.getParameter("site");
182 site = site == null? Jtp.getDefaultHost() : site;
183
184 boolean isDelete = "POST".equals(request.getMethod()) && "delete".equals(request.getParameter("action"));
185 int deleteCounter = 0;
186 if (isDelete) {
187 String[] results = request.getParameterValues("results");
188 for (String r : results) {
189 String[] parts = r.split("\\|");
190 long siteId = Long.valueOf(parts[0]);
191 long nodeId = Long.valueOf(parts[1]);
192 Node n = ModelHome.getSite(siteId).getNode(nodeId);
193 if (n != null) {
194 n.deleteMessageOrNode();
195 deleteCounter++;
196 }
197 }
198 }
199
200 PrintWriter out = response.getWriter();
201
202 out.print( "\r\n<html>\r\n <head>\r\n <title>Nabble Search</title>\r\n " );
203 Shared.loadJavascript(request, out);
204 out.print( "\r\n " );
205 javascript(out);
206 out.print( "\r\n " );
207 css(out);
208 out.print( "\r\n </head>\r\n <body>\r\n <h1>Nabble Search</h1>\r\n <form action=\"SpamSearch.jtp\" method=\"get\">\r\n Search for <input type=\"text\" name=\"query\" value=\"" );
209 out.print( (query) );
210 out.print( "\" /> in <input type=\"text\" name=\"site\" value=\"" );
211 out.print( (site) );
212 out.print( "\" />\r\n <input type=\"submit\" value=\"Search\" />\r\n <input type=\"hidden\" value=\"0\" name=\"start\" />\r\n <input type=\"hidden\" value=\"1\" name=\"page\" />\r\n </form>\r\n " );
213 if (isDelete) {
214 out.print( "\r\n <div style=\"color:red;padding:.5em 0\">Deleted " );
215 out.print( (deleteCounter) );
216 out.print( " nodes.</div>\r\n " );
217 }
218 out.print( "\r\n <div id='results'>\r\n <form action=\"SpamSearch.jtp\" method=\"post\">\r\n <input type=\"hidden\" value=\"delete\" name=\"action\" />\r\n <input type=\"hidden\" name=\"query\" value=\"" );
219 out.print( (query) );
220 out.print( "\"/>\r\n <input type=\"hidden\" name=\"site\" value=\"" );
221 out.print( (site) );
222 out.print( "\" />\r\n " );
223 getResults(query,site,request,out);
224 out.print( "\r\n </form>\r\n </div>\r\n </body>\r\n</html>\r\n" );
225
226 }
227
228 private void javascript(PrintWriter out) {
229
230 out.print( "\r\n <script type=\"text/javascript\">\r\n $(document).ready(function() {\r\n $('div.clickable').each(function() {\r\n var $this = $(this);\r\n var $checkbox = $this.parent().prev().children().eq(0);\r\n $this.click(function() {\r\n var checked = $checkbox.attr('checked');\r\n if (checked) {\r\n $this.removeClass('selected-row');\r\n $checkbox.removeAttr('checked');\r\n } else {\r\n $this.addClass('selected-row');\r\n $checkbox.attr('checked', true);\r\n }\r\n });\r\n });\r\n });\r\n </script>\r\n" );
231
232 }
233 private void css(PrintWriter out) {
234
235 out.print( "\r\n<style type=\"text/css\">\r\n body {\r\n padding: 1em;\r\n font-family: Verdana, Sans-serif;\r\n font-size:.84em;\r\n }\r\n span.url{\r\n color: green;\r\n }\r\n #results table {\r\n width: 100%;\r\n }\r\n #results table td {\r\n vertical-align:top;\r\n padding-bottom: 1em;\r\n }\r\n #results td.grayP , td.grayP a , td.grayP span {\r\n color: #C8C8C8 !important;\r\n }\r\n form input {\r\n margin-bottom: 15px;\r\n }\r\n span.badge {\r\n font-size:90%;\r\n -moz-border-radius: 5px;\r\n -webkit-border-radius: 5px;\r\n border-radius: 5px;\r\n padding: .2em .4em;\r\n }\r\n div.clickable { cursor:pointer; }\r\n .selected-row { background:#ffffcc; }\r\n</style>\r\n" );
236
237 }
238 }
239
240
241 class GoogleResults {
242
243 private ResponseData responseData;
244 public ResponseData getResponseData() { return responseData; }
245 public void setResponseData(ResponseData responseData) { this.responseData = responseData; }
246 public String toString() { return "ResponseData[" + responseData + "]"; }
247
248 static class ResponseData {
249 private List<Result> results;
250 public List<Result> getResults() { return results; }
251 public void setResults(List<Result> results) { this.results = results; }
252 public String toString() { return "Results[" + results + "]"; }
253 }
254
255 static class Result {
256 private String url;
257 private String title;
258 private String content;
259 public String getUrl() { return url; }
260 public String getTitle() { return title; }
261 public String getContent() { return content; }
262 public void setUrl(String url) { this.url = url; }
263 public void setTitle(String title) { this.title = title; }
264 public String toString() { return "Result[url:" + url +",title:" + title + "]"; }
265 }
266 }
267
268
269