001/* 002 * #%L 003 * Netarchivesuite - heritrix 3 monitor 004 * %% 005 * Copyright (C) 2005 - 2018 The Royal Danish Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023 024package dk.netarkivet.heritrix3.monitor.resources; 025 026import java.io.IOException; 027import java.util.Arrays; 028import java.util.List; 029import java.util.Locale; 030 031import javax.servlet.ServletContext; 032import javax.servlet.ServletOutputStream; 033import javax.servlet.http.HttpServletRequest; 034import javax.servlet.http.HttpServletResponse; 035 036import org.netarchivesuite.heritrix3wrapper.ScriptResult; 037 038import com.antiaction.common.filter.Caching; 039import com.antiaction.common.templateengine.TemplateBuilderFactory; 040 041import dk.netarkivet.heritrix3.monitor.Heritrix3JobMonitor; 042import dk.netarkivet.heritrix3.monitor.NASEnvironment; 043import dk.netarkivet.heritrix3.monitor.NASUser; 044import dk.netarkivet.heritrix3.monitor.ResourceAbstract; 045import dk.netarkivet.heritrix3.monitor.ResourceManagerAbstract; 046import dk.netarkivet.heritrix3.monitor.HttpLocaleHandler.HttpLocale; 047 048public class H3FilterResource implements ResourceAbstract { 049 050 private NASEnvironment environment; 051 052 protected int R_FILTER = -1; 053 054 protected int R_BUDGET = -1; 055 056 @Override 057 public void resources_init(NASEnvironment environment) { 058 this.environment = environment; 059 } 060 061 @Override 062 public void resources_add(ResourceManagerAbstract resourceManager) { 063 R_FILTER = resourceManager.resource_add(this, "/job/<numeric>/filter/", false); 064 } 065 066 @Override 067 public void resource_service(ServletContext servletContext, NASUser nas_user, HttpServletRequest req, HttpServletResponse resp, HttpLocale httpLocale, int resource_id, List<Integer> numerics, String pathInfo) throws IOException { 068 if (NASEnvironment.contextPath == null) { 069 NASEnvironment.contextPath = req.getContextPath(); 070 } 071 if (NASEnvironment.servicePath == null) { 072 NASEnvironment.servicePath = req.getContextPath() + req.getServletPath() + "/"; 073 } 074 String method = req.getMethod().toUpperCase(); 075 if(resource_id == R_FILTER) { 076 if ("GET".equals(method) || "POST".equals(method)) { 077 filter_add(req, resp, httpLocale, numerics); 078 } 079 } 080 } 081 082 public void filter_add(HttpServletRequest req, HttpServletResponse resp, HttpLocale httpLocale, List<Integer> numerics) throws IOException { 083 Locale locale = httpLocale.locale; 084 resp.setContentType("text/html; charset=UTF-8"); 085 ServletOutputStream out = resp.getOutputStream(); 086 Caching.caching_disable_headers(resp); 087 088 TemplateBuilderFactory<MasterTemplateBuilder> masterTplBuilderFactory = TemplateBuilderFactory.getInstance(environment.templateMaster, "master.tpl", "UTF-8", MasterTemplateBuilder.class); 089 MasterTemplateBuilder masterTplBuilder = masterTplBuilderFactory.getTemplateBuilder(); 090 091 StringBuilder sb = new StringBuilder(); 092 093 String regex = req.getParameter("regex"); 094 if (regex == null) { 095 regex = ""; 096 } 097 String[] removeIndexes = req.getParameterValues("removeIndex"); 098 if(removeIndexes == null) { 099 removeIndexes = new String[0]; 100 } 101 102 String initials = ""; 103 if(req.getParameter("add-filter") != null) { 104 initials = req.getParameter("initials1"); 105 } else if(req.getParameter("remove-filter") != null) { 106 initials = req.getParameter("initials2"); 107 } 108 if (initials == null) { 109 initials = ""; 110 } 111 112 String script = environment.NAS_GROOVY_SCRIPT; 113 114 if (regex.length() > 0 && !initials.isEmpty()) { 115 String[] lines = regex.split(System.getProperty("line.separator")); 116 for(String line : lines) { 117 if(line.endsWith(System.getProperty("line.separator")) || line.endsWith("\r") || line.endsWith("\n")) { 118 line = line.substring(0, line.length() - 1); 119 } 120 script += "\ninitials = \"" + initials + "\""; 121 script += "\naddFilter '" + line.replace("\\", "\\\\") + "'\n"; 122 } 123 } 124 if(removeIndexes.length > 0 && !initials.isEmpty()) { 125 script += "\ninitials = \"" + initials + "\""; 126 script += "\nremoveFilters("+Arrays.toString(removeIndexes)+")\n"; 127 } 128 script += "\nshowFilters()\n"; 129 130 long jobId = numerics.get(0); 131 Heritrix3JobMonitor h3Job = environment.h3JobMonitorThread.getRunningH3Job(jobId); 132 133 if (h3Job != null && h3Job.isReady()) { 134 /* form control */ 135 /* case submit for delete but no checked regex */ 136 boolean keepRegexTextArea = false; 137 if (req.getParameter("remove-filter") != null && removeIndexes.length == 0) { 138 sb.append("<div class=\"notify notify-red\"><span class=\"symbol icon-error\"></span> Check RejectRules to delete!</div>"); 139 } 140 /* case submit for add but no text */ 141 if (req.getParameter("add-filter") != null && regex.isEmpty()) { 142 sb.append("<div class=\"notify notify-red\"><span class=\"symbol icon-error\"></span> RejectRules cannot be empty!</div>"); 143 } 144 /* case no initials */ 145 if ((req.getParameter("remove-filter") != null || req.getParameter("add-filter") != null) && initials.isEmpty()) { 146 sb.append("<div class=\"notify notify-red\"><span class=\"symbol icon-error\"></span> Initials required to add/delete RejectRules!</div>"); 147 keepRegexTextArea = true; 148 } 149 150 sb.append("<p>All URIs matching any of the following regular expressions will be rejected from the current job.</p>"); 151 152 sb.append("<form class=\"form-horizontal\" action=\"?\" name=\"insert_form\" method=\"post\" enctype=\"application/x-www-form-urlencoded\" accept-charset=\"utf-8\">\n"); 153 sb.append("<label for=\"regex\" style=\"cursor: default;\">Expressions to reject:</label>"); 154 sb.append("<textarea rows=\"4\" cols=\"100\" id=\"regex\" name=\"regex\" placeholder=\"regex\">"); 155 if(keepRegexTextArea) { 156 sb.append(regex); 157 } 158 sb.append("</textarea>\n"); 159 sb.append("<label for=\"initials\">User initials:</label>"); 160 sb.append("<input type=\"text\" id=\"initials1\" name=\"initials1\" value=\"" + initials + "\" placeholder=\"initials\">\n"); 161 sb.append("<button type=\"submit\" name=\"add-filter\" value=\"1\" class=\"btn btn-success\"><i class=\"icon-white icon-thumbs-up\"></i> Add</button>\n"); 162 sb.append("<br/>\n"); 163 164 ScriptResult scriptResult = h3Job.h3wrapper.ExecuteShellScriptInJob(h3Job.jobResult.job.shortName, "groovy", script); 165 166 if (scriptResult != null && scriptResult.script != null && scriptResult.script.htmlOutput != null) { 167 sb.append("<div style=\"font-size: 14px; font-weight: normal; line-height: 20px;\">\n"); 168 sb.append("<p style=\"margin-top: 30px;\">Rejected regex:</p>\n"); 169 sb.append(scriptResult.script.htmlOutput); 170 sb.append("</div>\n"); 171 sb.append("<label for=\"initials\">User initials:</label>"); 172 sb.append("<input type=\"text\" id=\"initials2\" name=\"initials2\" value=\"" + initials + "\" placeholder=\"initials\">\n"); 173 sb.append("<button type=\"submit\" name=\"remove-filter\" value=\"1\" class=\"btn btn-success\"><i class=\"icon-white icon-remove\"></i> Remove</button>"); 174 } 175 176 sb.append("</form>\n"); 177 } else { 178 sb.append("Job "); 179 sb.append(jobId); 180 sb.append(" is not running."); 181 } 182 183 StringBuilder menuSb = masterTplBuilder.buildMenu(new StringBuilder(), req, locale, h3Job); 184 185 masterTplBuilder.insertContent("Job " + jobId + " RejectRules", menuSb.toString(), httpLocale.generateLanguageLinks(), 186 "Job " + jobId + " RejectRules", sb.toString(), "").write(out); 187 188 out.flush(); 189 out.close(); 190 } 191 192}