comparison src/nabble/view/web/more/ForumStart.jtp @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children 03e68185c2f5
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.Message;
9 import nabble.model.ModelException;
10 import nabble.model.ModelHome;
11 import nabble.model.Site;
12 import nabble.model.User;
13 import nabble.naml.compiler.Template;
14 import nabble.naml.compiler.TemplatePrintWriter;
15 import nabble.naml.namespaces.BasicNamespace;
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 import nabble.view.web.app.Languages;
23 import nabble.view.web.template.NabbleNamespace;
24
25 import javax.servlet.ServletException;
26 import javax.servlet.http.HttpServlet;
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletResponse;
29 import java.io.IOException;
30 import java.io.PrintWriter;
31 import java.io.StringWriter;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.Map;
35 import java.util.regex.Matcher;
36 import java.util.regex.Pattern;
37
38
39 public final class ForumStart extends HttpServlet implements UrlMappable, CanonicalUrl {
40
41 private static final Pattern URL_PATTERN = Pattern.compile("/free-(forum|gallery|newspaper|blog|mailing-list)\\.html$");
42
43 public static String url(String what) {
44 return Jtp.defaultContextUrl() + path(what);
45 }
46
47 public static String path(String what) {
48 return "/free-" + what + ".html";
49 }
50
51 public String getCanonicalUrl(HttpServletRequest request) {
52 return url( request.getParameter("what") );
53 }
54
55 public Map<String,String[]> getParameterMapFromUrl(HttpServletRequest request,String mappedUrl) {
56 Matcher m = URL_PATTERN.matcher(mappedUrl);
57 if( !m.find() )
58 throw new RuntimeException();
59 Map<String,String[]> params = new HashMap<String,String[]>();
60 String what = m.group(1);
61 params.put("what",new String[]{what});
62 return params;
63 }
64
65 public Pattern getUrlPattern() {
66 return URL_PATTERN;
67 }
68
69 protected void service(HttpServletRequest request,HttpServletResponse response)
70 throws ServletException, IOException
71 {
72 build(request, response, Collections.<String,String>emptyMap(), Collections.<String,String>emptyMap());
73 }
74
75 private static void build(HttpServletRequest request,HttpServletResponse response, Map<String,String> values, Map<String,String> errors)
76 throws ServletException, IOException
77 {
78 PrintWriter out = response.getWriter();
79 String what = request.getParameter("what");
80 if (what == null)
81 what = "Forum";
82 else if ("mailing-list".equals(what))
83 what = "Mailing List";
84 else
85 what = Jtp.capitalize(what);
86
87 String imgName = what.toLowerCase();
88 if ("Mailing List".equals(what))
89 imgName = "mailing-list";
90
91 %>
92 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
93 <html>
94 <head>
95 <% Shared.head(request,response); %>
96 <title>Nabble - Free <%=what%> Setup</title>
97 <meta name="robots" content="noindex"/>
98 <META NAME="description" CONTENT="Setting up a free <%=what.toLowerCase()%> on Nabble is quick and easy. Fill in one simple form and you are done.">
99 <META NAME="keywords" CONTENT="free <%=what.toLowerCase()%>, hosted <%=what.toLowerCase()%>, simple, embeddable <%=what.toLowerCase()%>, customizable">
100 <% /*Shared.canonical(request, response);*/ %>
101 <style type="text/css">
102 div.center-content {
103 margin:0px auto;
104 margin-bottom: 3em;
105 }
106 td.column1 {
107 text-align:right;
108 width:7em;
109 white-space:nowrap;
110 }
111 input[type=text],input[type=password] {
112 padding:.4em 0;
113 }
114 div.field-title {
115 margin-top:.3em;
116 }
117 .important { font-weight:bold }
118 label { vertical-align:-15%; }
119 </style>
120 <script type="text/javascript">
121 $(document).ready(function() {
122 $('#username').focus();
123 });
124
125 function singleFormSubmit(f) {
126 if (f.done)
127 return false;
128 f.done = true;
129 $('#submit-btn').hide();
130 var $div = $('#wait-message');
131 function loading1() { $div.fadeTo(300,0.3,loading2); };
132 function loading2() { $div.fadeTo(300,1,loading1); };
133 loading1();
134 return true;
135 };
136 </script>
137 <%= Recaptcha.JS %>
138 </head>
139 <body style="text-align:center">
140 <% Shared.minHeaderGlobal(request,response); %>
141
142 <div class="center-content">
143 <img src="/images/logo_nabble_home.png" border="0" alt="Nabble - free forums for everyone"/><br />
144 <h1 style="color:#979797">Start Your <%=what%></h1>
145
146 <% if (errors.size() > 0) { %>
147 <div class="error-message important" style="margin:1em;padding:.5em 0">
148 <% String generic = errors.get("generic"); %>
149 <%=generic != null? generic : errors.size() > 0? "Please check the errors below" : ""%>
150 </div>
151 <% } %>
152
153 <form action="/more/ForumStart$Save.jtp" method="post" accept-charset="UTF-8" onsubmit="return singleFormSubmit(this)">
154 <input type="hidden" name="type" value="<%=what.toLowerCase().replace(" ","")%>" />
155 <input type="hidden" name="what" value="<%=what%>" />
156
157 <div style="text-align:left;width:50em;margin:0 auto">
158 <div style="border-bottom:2px solid #eeeeee;padding:1em">
159 <div class="weak-color" style="width:12em;text-align:center;float:left">
160 <div style="font-weight:bold">Account</div>
161 <img src="/images/account.png" width="84" height="45"/>
162 <div style="margin-top:1em;font-size:80%">
163 You will receive an email with a link to activate your account
164 </div>
165 </div>
166 <table>
167 <tr>
168 <td class="column1"><div class="second-font field-title">User Name</div></td>
169 <td><input type="text" id="username" size="35" maxlength="30" name="username" value="<%=Jtp.hideNull(values.get("username"))%>" /></td>
170 <td class="important"><%=errors.containsKey("username")? errors.get("username"):""%></td>
171 </tr>
172 <tr>
173 <td class="column1"><div class="second-font field-title">Email</div></td>
174 <td><input type="text" size="35" maxlength="60" name="email" value="<%=Jtp.hideNull(values.get("email"))%>"/></td>
175 <td class="important"><%=errors.containsKey("email")? errors.get("email"):""%></td>
176 </tr>
177 <tr>
178 <td class="column1"><div class="second-font field-title">Password</div></td>
179 <td><input type="password" size="35" maxlength="15" name="password" value="<%=Jtp.hideNull(values.get("password"))%>"/></td>
180 <td class="important"><%=errors.containsKey("password")? errors.get("password"):""%></td>
181 </tr>
182 <tr>
183 <td class="column1"><input type="checkbox" id="terms" name="terms" value="y" <%="y".equals(values.get("terms"))?"checked":""%> /></td>
184 <td colspan=2><label for="terms">I have read and I agree to Nabble's <a href="<%=Jtp.termsUrl(true)%>">Terms of Use</a>.</label></td>
185 </tr>
186 </table>
187 </div>
188
189 <div style="padding:1em;overflow:hidden">
190 <div class="weak-color" style="width:12em;text-align:center;float:left;height:15em">
191 <div style="font-weight:bold"><%=what%></div>
192 <img src="/images/homepage/<%=imgName%>.png" alt="Free <%=what.toLowerCase()%>">
193 </div>
194 <table>
195 <tr>
196 <td class="column1"><div class="second-font field-title">Language</div></td>
197 <td>
198 <select name="lang">
199 <% for( Map.Entry<String,String> entry : Languages.languages.entrySet() ) { %>
200 <% String lang = request.getParameter("lang"); %>
201 <% boolean isEnglish = entry.getKey().equals("none"); %>
202 <% boolean isSelected = (lang == null && isEnglish) || entry.getKey().equals(lang); %>
203 <option value="<%=entry.getKey()%>" <%=isSelected?"selected=\"true\"":""%>><%=entry.getValue()%></option>
204 <% } %>
205 </select>
206 </td>
207 <td></td>
208 </tr>
209 <tr>
210 <td colspan="3" style="height:.6em"></td>
211 </tr>
212 <tr>
213 <td class="column1"><div class="second-font field-title"><%=what%> Name</div></td>
214 <td><input type="text" name="subject" size="30" maxlength="80" value="<%=Jtp.hideNull(values.get("subject"))%>"/></td>
215 <td class="important"><%=errors.containsKey("subject")? errors.get("subject"):""%></td>
216 </tr>
217 <tr>
218 <td colspan=3 style="padding:.4em 0 0 .6em">
219 <div class="second-font field-title">Description &nbsp;<span class="weak-color" style="font-weight:normal;">(optional)</span></div>
220 <textarea rows="7" name="message" wrap="SOFT" style="width:28em"><%=Jtp.hideNull(values.get("message"))%></textarea>
221 <br><%= Recaptcha.DIV %>
222 </td>
223 </tr>
224 </table>
225 </div>
226 <div class="weak-color" style="margin-top:.5em;text-align:center;">
227 <input id="submit-btn" type="submit" name="save" value="Create <%=what%>" style="padding:.5em .8em;font-size:110%;font-weight:bold"/>
228 <div id="wait-message" class="important invisible" style="margin:.1em 0">Creating <%=what%>... Please wait</div>
229 </div>
230 </div>
231 </form>
232 </div>
233
234 <% Shared.footer(request,response); %>
235 <% Shared.analytics(request,response); %>
236 </body>
237 </html>
238 <%
239 }
240
241 public static class Save extends HttpServlet {
242
243 private static String get(String name, HttpServletRequest request) {
244 String s = request.getParameter(name);
245 return s == null? null : s.trim();
246 }
247
248 protected void service(HttpServletRequest request, HttpServletResponse response)
249 throws ServletException, IOException
250 {
251 String username = get("username", request);
252 String email = get("email", request);
253 String password = get("password", request);
254 boolean agreed = "y".equals(get("terms", request));
255 String subject = get("subject", request);
256 String message = get("message", request);
257
258 Map<String,String> errors = new HashMap<String,String>();
259 if (username == null || username.trim().length() == 0)
260 errors.put("username", "required");
261 if (email == null || email.length() == 0)
262 errors.put("email", "required");
263 else if (!new MailAddress(email).isValid())
264 errors.put("email", "invalid email");
265 if (password == null || password.length() < 4)
266 errors.put("password", "too short");
267 if (!agreed)
268 errors.put("generic", "You must agree to the Terms and Conditions");
269 if (subject == null || subject.length() == 0)
270 errors.put("subject", "required");
271
272 String type = get("type", request);
273 type = "newspaper".equals(type)? "news" : type;
274
275 String extraMessage = "";
276 if ("mailinglist".equals(type)) {
277 type = "forum";
278 StringBuilder m = new StringBuilder();
279 m.append("\n\nMailing List Options\n");
280 m.append("Click \"Options > Subscribe via email\" to subscribe to this mailing list;\n");
281 m.append("Click \"Options > Post by email...\" to get the email address of this mailing list;\n");
282 m.append("You can post messages via email or through the forum interface below;\n");
283 m.append("All web posts and emails are archived here.");
284 extraMessage = m.toString();
285 }
286
287 if (errors.isEmpty()) {
288 DbDatabase db = Db.dbGlobal();
289 db.beginTransaction();
290 try {
291 Recaptcha.check(request);
292 Site site = ModelHome.newSite(type,subject, message + extraMessage, Message.Format.TEXT, email, username);
293 Permissions.addToGroup( (User)site.getRootNode().getOwner(), Permissions.ADMINISTRATORS_GROUP );
294 String key = site.newRegistration(email,password,username,"/");
295 db.commitTransaction();
296
297 // Track spam activities by IP
298 ModelHome.setRemoteAddr(site, Jtp.getClientIpAddr(request));
299
300 site = site.getGoodCopy();
301
302 String lang = request.getParameter("lang");
303 if (!"none".equals(lang)) {
304 site.setModuleEnabled(lang, true);
305 site = site.getGoodCopy();
306 }
307
308 sendRegisterMail(site, email, key);
309 NewSiteMail.send(site, request, response);
310 response.sendRedirect(site.getBaseUrl()+"/more/ForumStart$Redirection.jtp");
311 return;
312 } catch(ModelException e) {
313 errors.put("generic", e.getMessage());
314 } finally {
315 db.endTransaction();
316 }
317 }
318
319 Map<String,String> values = new HashMap<String,String>();
320 values.put("username", username);
321 values.put("email", email);
322 values.put("password", password);
323 values.put("terms", agreed?"y":"");
324 values.put("subject", subject);
325 values.put("message", message);
326 build(request, response, values, errors);
327 }
328 }
329
330 /** Sets cookies in the site domain */
331 public static class Redirection extends HttpServlet {
332
333 protected void service(HttpServletRequest request, HttpServletResponse response)
334 throws ServletException, IOException
335 {
336 Site site = Jtp.getSite(request);
337 Shared.javascriptRedirect(request, response, Jtp.url(site.getRootNode()), "Nabble.setVar('appnotice','true');");
338 }
339 }
340
341 public static void sendRegisterMail(Site site, String email, String key) {
342 Map<String,Object> args = new HashMap<String,Object>();
343 args.put("email",email);
344 args.put("next_url","/");
345 args.put("key",key);
346 Template template = site.getTemplate( "send_registration_email",
347 BasicNamespace.class, NabbleNamespace.class
348 );
349 template.run( TemplatePrintWriter.NULL, args,
350 new BasicNamespace(template), new NabbleNamespace(site)
351 );
352 }
353 }
354 %>