view src/nabble/view/web/tools/SpamSearch.jtp @ 47:72765b66e2c3

remove mailing list code
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 18 Jun 2021 17:44:24 -0600
parents 7ecd1a4ef557
children
line wrap: on
line source

<%
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>
							<% } %>
						</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%> &ndash;
			<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 + "]"; }
    }
}


%>