comparison src/nabble/view/web/more/MailingListRequest.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children 157eac0dee34
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1
2 package nabble.view.web.more;
3
4 import fschmidt.db.DbDatabase;
5 import fschmidt.util.mail.MailAddress;
6 import fschmidt.util.servlet.CanonicalUrl;
7 import nabble.model.Db;
8 import nabble.model.ListServer;
9 import nabble.model.MailingList;
10 import nabble.model.Message;
11 import nabble.model.ModelException;
12 import nabble.model.ModelHome;
13 import nabble.model.Node;
14 import nabble.model.Site;
15 import nabble.model.User;
16 import nabble.view.lib.Jtp;
17 import nabble.view.lib.NewSiteMail;
18 import nabble.view.lib.Permissions;
19 import nabble.view.lib.Shared;
20 import nabble.view.lib.UrlMappable;
21 import nabble.view.lib.Recaptcha;
22
23 import javax.servlet.ServletException;
24 import javax.servlet.http.HttpServlet;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27 import java.io.IOException;
28 import java.io.PrintWriter;
29 import java.net.MalformedURLException;
30 import java.net.URL;
31 import java.util.Collections;
32 import java.util.HashMap;
33 import java.util.Map;
34 import java.util.regex.Matcher;
35 import java.util.regex.Pattern;
36
37
38 public final class MailingListRequest extends HttpServlet implements UrlMappable, CanonicalUrl {
39
40 private static final Pattern URL_PATTERN = Pattern.compile("/archive-your-mailing-list\\.html$");
41
42 public static String url() {
43 return Jtp.defaultContextUrl() + path();
44 }
45
46 public static String path() {
47 return "/archive-your-mailing-list.html";
48 }
49
50 public String getCanonicalUrl(HttpServletRequest request) {
51 return url();
52 }
53
54 public Map<String,String[]> getParameterMapFromUrl(HttpServletRequest request,String mappedUrl) {
55 Matcher m = URL_PATTERN.matcher(mappedUrl);
56 if( !m.find() )
57 throw new RuntimeException();
58 return new HashMap<String,String[]>();
59 }
60
61 public Pattern getUrlPattern() {
62 return URL_PATTERN;
63 }
64
65 protected void service(HttpServletRequest request,HttpServletResponse response)
66 throws ServletException, IOException
67 {
68 build(request, response, Collections.<String,String>emptyMap(), Collections.<String,String>emptyMap());
69 }
70
71 private static void build(HttpServletRequest request,HttpServletResponse response, Map<String,String> values, Map<String,String> errors)
72 throws ServletException, IOException
73 {
74 PrintWriter out = response.getWriter();
75
76 out.print( "\r\n<html>\r\n <head>\r\n " );
77 Shared.title(request,response,"Archive Your Mailing List");
78 out.print( "\r\n <META NAME=\"description\" CONTENT=\"Archiving a mailing list at Nabble is quick and easy. Fill in one simple form and you're done.\">\r\n <META NAME=\"keywords\" CONTENT=\"free, mailing list archive, forum interface, gateway, customizable, easy, quick setup\">\r\n <style type=\"text/css\">\r\n div.field-title {\r\n margin-top: 0;\r\n }\r\n td.column1 {\r\n text-align:right;\r\n width:7em;\r\n white-space:nowrap;\r\n }\r\n div.field-box {\r\n border:none;\r\n margin:0;\r\n }\r\n input[type=text],input[type=password],select {\r\n padding:.3em 0;\r\n }\r\n .important { font-weight:bold }\r\n </style>\r\n <script type=\"text/javascript\">\r\n $(document).ready(function() {\r\n $('#username').focus();\r\n });\r\n </script>\r\n " );
79 out.print( ( Recaptcha.JS ) );
80 out.print( "\r\n </head>\r\n <body>\r\n " );
81 Shared.minHeaderGlobal(request,response);
82 out.print( "\r\n\r\n <h1>Archive Your Mailing List</h1>\r\n <p>\r\n <img src=\"/images/homepage/archive.png\" style=\"float:left;margin: 0 1em 1em 1em\"/>\r\n You can archive your mailing list to a fully functional forum at Nabble by filling out\r\n the form below. This makes it easy for users to browse and search archived emails.\r\n Users can even post to the Nabble forum and we will forward these posts to your mailing list.\r\n </p>\r\n\r\n " );
83 if (errors.size() > 0) {
84 out.print( "\r\n <div class=\"error-message important\" style=\"margin:1em;padding:.5em 0 .5em 12em\">\r\n " );
85 String generic = errors.get("generic");
86 out.print( "\r\n " );
87 out.print( (generic != null? generic : errors.size() > 0? "Please check the errors below" : "") );
88 out.print( "\r\n </div>\r\n " );
89 }
90 out.print( "\r\n\r\n <form method=\"post\" action=\"/more/MailingListRequest$Save.jtp\" accept-charset=\"UTF-8\">\r\n <input type=\"hidden\" name=\"Action\" value=\"save\">\r\n\r\n <div style=\"border-bottom:2px solid #eeeeee;padding:1em;width:50em\">\r\n <div class=\"weak-color\" style=\"width:11.5em;text-align:center;float:left\">\r\n <div style=\"font-weight:bold\">Account</div>\r\n <img src=\"/images/account.png\"/>\r\n <div style=\"margin-top:1em;font-size:80%\">\r\n You will receive an email with a link to activate your account\r\n </div>\r\n </div>\r\n <table>\r\n <tr>\r\n <td><div class=\"second-font field-title\">User Name</div></td>\r\n <td><input type=\"text\" id=\"username\" size=\"35\" maxlength=\"30\" name=\"username\" value=\"" );
91 out.print( (Jtp.hideNull(values.get("username"))) );
92 out.print( "\" /></td>\r\n <td class=\"important\">" );
93 out.print( (errors.containsKey("username")? errors.get("username"):"") );
94 out.print( "</td>\r\n </tr>\r\n <tr>\r\n <td><div class=\"second-font field-title\">Email</div></td>\r\n <td><input type=\"text\" size=\"35\" maxlength=\"60\" name=\"email\" value=\"" );
95 out.print( (Jtp.hideNull(values.get("email"))) );
96 out.print( "\"/></td>\r\n <td class=\"important\">" );
97 out.print( (errors.containsKey("email")? errors.get("email"):"") );
98 out.print( "</td>\r\n </tr>\r\n <tr>\r\n <td><div class=\"second-font field-title\">Password</div></td>\r\n <td><input type=\"password\" size=\"35\" maxlength=\"15\" name=\"password\" value=\"" );
99 out.print( (Jtp.hideNull(values.get("password"))) );
100 out.print( "\"/></td>\r\n <td class=\"important\">" );
101 out.print( (errors.containsKey("password")? errors.get("password"):"") );
102 out.print( "</td>\r\n </tr>\r\n <tr>\r\n <td class=\"column1\"><input type=\"checkbox\" id=\"terms\" name=\"terms\" value=\"y\" " );
103 out.print( ("y".equals(values.get("terms"))?"checked":"") );
104 out.print( " /></td>\r\n <td colspan=2><label for=\"terms\">I have read and I agree to Nabble's <a href=\"" );
105 out.print( (Jtp.termsUrl(true)) );
106 out.print( "\">Terms of Use</a>.</label></td>\r\n </tr>\r\n </table>\r\n </div>\r\n\r\n <div style=\"padding:.5em;width:50em\">\r\n <div class=\"weak-color\" style=\"width:12em;text-align:center;float:left;height:50em;padding-top:1em\">\r\n <div style=\"font-weight:bold\">Mailing List</div>\r\n <img src=\"/images/homepage/mailing-list.png\" alt=\"Free Mailing List Archive\">\r\n </div>\r\n\r\n <div class=\"field-box\">\r\n <div class=\"second-font field-title\">Mailing List Address</div>\r\n <div class=\"weak-color\">\r\n <input id=\"mailingList\" type=\"text\" name=\"ml-address\" value=\"" );
107 out.print( (Jtp.hideNull(values.get("ml-address"))) );
108 out.print( "\" size=\"46\" />\r\n <span class=\"important\">" );
109 out.print( (errors.containsKey("ml-address")? errors.get("ml-address"):"") );
110 out.print( "</span>\r\n <div class=\"weak-color\">e.g., mygroup@yahoogroups.com</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"field-box light-border-color\">\r\n <div class=\"second-font field-title\">Mailing List URL</div>\r\n <div class=\"weak-color\">\r\n Enter the homepage of this mailing list, where other users can find more information.<br/>\r\n <input type=\"text\" name=\"ml-url\" size=\"55\" value=\"" );
111 out.print( (Jtp.hideNull(values.get("ml-url"))) );
112 out.print( "\" />\r\n <span class=\"important\">" );
113 out.print( (errors.containsKey("ml-url")? errors.get("ml-url"):"") );
114 out.print( "</span>\r\n <div class=\"weak-color\">e.g., http://www.mailinglist.com/list</div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"field-box light-border-color\">\r\n <div class=\"second-font field-title\">Forum Name</div>\r\n <div class=\"weak-color\">\r\n Enter the name of the forum for this mailing list.<br/>\r\n <input type=\"text\" name=\"subject\" size=\"46\" value=\"" );
115 out.print( (Jtp.hideNull(values.get("subject"))) );
116 out.print( "\" />\r\n <span class=\"important\">" );
117 out.print( (errors.containsKey("subject")? errors.get("subject"):"") );
118 out.print( "</span>\r\n </div>\r\n </div>\r\n\r\n <div class=\"field-box light-border-color\">\r\n <div class=\"second-font field-title\">Forum Description</div>\r\n <div class=\"weak-color\">\r\n <textarea cols=46 rows=5 name=\"message\" id=\"nabble.desc\" wrap=\"SOFT\">" );
119 out.print( (Jtp.hideNull(values.get("message"))) );
120 out.print( "</textarea>\r\n </div>\r\n </div>\r\n\r\n <div class=\"field-box light-border-color\">\r\n <div class=\"second-font field-title\">List Server and Version</div>\r\n <div class=\"weak-color\">\r\n If you know, please select the mailing list server application.<br/>\r\n <select name=\"server-type\">\r\n " );
121
122 String[] serverTypes = ListServer.getAllServerTypes();
123 ListServer selectedServer = ListServer.getServer(values.get("server-type"));
124 for (String s : serverTypes) {
125 ListServer currentServer = ListServer.getServer(s);
126 if(currentServer.showInInitialSetup()) {
127
128 out.print( "<option value=\"" );
129 out.print( (currentServer.getType()) );
130 out.print( "\" " );
131 out.print( (currentServer == selectedServer?"selected":"") );
132 out.print( ">" );
133 out.print( (currentServer.getViewName()) );
134 out.print( "</option>" );
135
136 }
137 }
138
139 out.print( "\r\n</select>\r\n<div class=\"weak-color\">If you are not absolutely sure about the version of the list server, it is better if you leave it as Unknown</div>\r\n</div>\r\n</div>\r\n\r\n<div class=\"field-box light-border-color\">\r\n<div class=\"second-font field-title\">Other Settings</div>\r\n<table>\r\n<tr>\r\n<td><input id=\"plain-text\" name=\"plain-text\" type=\"checkbox\" value=\"y\" " );
140 out.print( ("y".equals(values.get("plain-text"))?"checked":"") );
141 out.print( " /></td>\r\n<td><label for=\"plain-text\">This list accepts only plain-text emails</label>.</td>\r\n</tr>\r\n<tr>\r\n<td><input id=\"ignore-x-noarchive\" name=\"ignore-x-noarchive\" type=\"checkbox\" value=\"y\" " );
142 out.print( ("y".equals(values.get("ignore-x-noarchive"))?"checked":"") );
143 out.print( " /></td>\r\n<td><label for=\"ignore-x-noarchive\">Ignore X-No-Archive Header</label>.</td>\r\n</tr>\r\n<tr>\r\n<td colspan=2 style=\"padding-top:1em\">\r\n " );
144 out.print( ( Recaptcha.DIV ) );
145 out.print( "\r\n</td>\r\n</tr>\r\n</table>\r\n</div>\r\n\r\n<input type=\"submit\" value=\"Create Mailing List Archive\" style=\"padding:.5em .8em;font-size:110%;font-weight:bold\"/>\r\n</div>\r\n</form>\r\n\r\n" );
146 Shared.footer(request,response);
147 out.print( "\r\n" );
148 Shared.analytics(request,response);
149 out.print( "\r\n</body>\r\n</html>\r\n" );
150
151 }
152
153 public static class Save extends HttpServlet {
154
155 private static String get(String name, HttpServletRequest request) {
156 String s = request.getParameter(name);
157 return s == null? null : s.trim();
158 }
159
160 protected void service(HttpServletRequest request, HttpServletResponse response)
161 throws ServletException, IOException
162 {
163 String username = get("username", request);
164 String email = get("email", request);
165 String password = get("password", request);
166 boolean agreed = "y".equals(get("terms", request));
167
168 String mlAddress = get("ml-address", request);
169 String mlUrl = get("ml-url", request);
170 String subject = get("subject", request);
171 String message = get("message", request);
172 String serverType = get("server-type", request);
173 boolean isPlainText = "y".equals(get("plain-text", request));
174 boolean isIgnoreXNoArchive = "y".equals(get("ignore-x-noarchive", request));
175
176 Map<String,String> errors = new HashMap<String,String>();
177 if (username == null || username.trim().length() == 0)
178 errors.put("username", "required");
179 if (email == null || email.length() == 0)
180 errors.put("email", "required");
181 else if (!new MailAddress(email).isValid())
182 errors.put("email", "invalid email");
183 if (password == null || password.length() < 4)
184 errors.put("password", "too short");
185 if (!agreed)
186 errors.put("generic", "You must agree to the Terms and Conditions");
187 if (subject == null || subject.length() == 0)
188 errors.put("subject", "required");
189 if (mlAddress == null || mlAddress.length() == 0)
190 errors.put("ml-address", "required");
191 else if (!new MailAddress(mlAddress).isValid())
192 errors.put("ml-address", "invalid email");
193 if (mlUrl == null || mlUrl.length() == 0)
194 errors.put("ml-url", "required");
195 else {
196 try {
197 new URL(mlUrl);
198 } catch (MalformedURLException e) {
199 errors.put("ml-url", "invalid URL");
200 }
201 }
202
203 if (errors.isEmpty()) {
204 DbDatabase db = Db.dbGlobal();
205 db.beginTransaction();
206 try {
207 Recaptcha.check(request);
208 Site site = ModelHome.newSite(Node.Type.FORUM,subject, message, Message.Format.TEXT, email, username);
209 Permissions.addToGroup( (User)site.getRootNode().getOwner(), Permissions.ADMINISTRATORS_GROUP );
210 String key = site.newRegistration(email,password,username,"/mailing_list/SubscribeToMailingList.jtp?node="+site.getRootNode().getId());
211
212 MailingList ml = site.getRootNode().newMailingList(ListServer.getServer(serverType), mlAddress, mlUrl);
213 ml.setPlainTextOnly(isPlainText);
214 ml.setIgnoreNoArchive(isIgnoreXNoArchive);
215 ml.update();
216
217 db.commitTransaction();
218
219 site = site.getGoodCopy();
220 ForumStart.sendRegisterMail(site, email, key);
221 NewSiteMail.send(site, request, response);
222 response.sendRedirect(site.getBaseUrl()+"/more/MailingListRequest$FinalSteps.jtp");
223 return;
224 } catch(ModelException e) {
225 errors.put("generic", e.getMessage());
226 } finally {
227 db.endTransaction();
228 }
229 }
230
231 Map<String,String> values = new HashMap<String,String>();
232 values.put("username", username);
233 values.put("email", email);
234 values.put("password", password);
235 values.put("terms", agreed?"y":"");
236
237 values.put("ml-address", mlAddress);
238 values.put("ml-url", mlUrl);
239 values.put("subject", subject);
240 values.put("message", message);
241 values.put("server-type", serverType);
242 values.put("plain-text", isPlainText?"y":"");
243 values.put("ignore-x-noarchive", isIgnoreXNoArchive?"y":"");
244 build(request, response, values, errors);
245 }
246 }
247
248 public static class FinalSteps extends HttpServlet {
249
250 protected void service(HttpServletRequest request, HttpServletResponse response)
251 throws ServletException, IOException
252 {
253 PrintWriter out = response.getWriter();
254
255 out.print( "\r\n<html>\r\n <head>\r\n " );
256 Shared.title(request,response,"Archive Created, But Subscription is Needed");
257 out.print( "\r\n </head>\r\n <body>\r\n " );
258 Shared.minHeaderGlobal(request,response);
259 out.print( "\r\n <h1>Success</h1>\r\n <p>Your mailing list archive has been successfully created.</p>\r\n <h2>What should I do now?</h2>\r\n <p>\r\n You should now check your email and click on the activation link sent to you.\r\n That link will complete your account registration and take you to the page where you can subscribe the Nabble archive to the mailing list.\r\n <b>If you don't subscribe the archive to the mailing list, it will NOT work properly!</b>\r\n </p>\r\n <p>You can contact <a href=\"" );
260 out.print( (Jtp.supportUrl()) );
261 out.print( "\">Nabble Support</a> if you have questions.</p>\r\n " );
262 Shared.footer(request,response);
263 out.print( "\r\n " );
264 Shared.analytics(request,response);
265 out.print( "\r\n </body>\r\n</html>\r\n" );
266
267 }
268 }
269 }
270