2 * Sone - WebInterface.java - Copyright © 2010–2020 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sone.web;
20 import static java.util.logging.Logger.getLogger;
22 import java.util.Collection;
23 import java.util.TimeZone;
24 import java.util.logging.Logger;
25 import javax.annotation.Nonnull;
26 import javax.annotation.Nullable;
28 import net.pterodactylus.sone.core.Core;
29 import net.pterodactylus.sone.core.ElementLoader;
30 import net.pterodactylus.sone.core.event.*;
31 import net.pterodactylus.sone.data.Post;
32 import net.pterodactylus.sone.data.PostReply;
33 import net.pterodactylus.sone.data.Sone;
34 import net.pterodactylus.sone.freenet.L10nFilter;
35 import net.pterodactylus.sone.freenet.Translation;
36 import net.pterodactylus.sone.main.Loaders;
37 import net.pterodactylus.sone.main.PluginHomepage;
38 import net.pterodactylus.sone.main.PluginVersion;
39 import net.pterodactylus.sone.main.PluginYear;
40 import net.pterodactylus.sone.main.SonePlugin;
41 import net.pterodactylus.sone.notify.ListNotificationFilter;
42 import net.pterodactylus.sone.notify.PostVisibilityFilter;
43 import net.pterodactylus.sone.template.LinkedElementRenderFilter;
44 import net.pterodactylus.sone.template.ParserFilter;
45 import net.pterodactylus.sone.template.RenderFilter;
46 import net.pterodactylus.sone.template.ShortenFilter;
47 import net.pterodactylus.sone.text.TimeTextConverter;
48 import net.pterodactylus.sone.web.ajax.BookmarkAjaxPage;
49 import net.pterodactylus.sone.web.ajax.CreatePostAjaxPage;
50 import net.pterodactylus.sone.web.ajax.CreateReplyAjaxPage;
51 import net.pterodactylus.sone.web.ajax.DeletePostAjaxPage;
52 import net.pterodactylus.sone.web.ajax.DeleteProfileFieldAjaxPage;
53 import net.pterodactylus.sone.web.ajax.DeleteReplyAjaxPage;
54 import net.pterodactylus.sone.web.ajax.DismissNotificationAjaxPage;
55 import net.pterodactylus.sone.web.ajax.EditAlbumAjaxPage;
56 import net.pterodactylus.sone.web.ajax.EditImageAjaxPage;
57 import net.pterodactylus.sone.web.ajax.EditProfileFieldAjaxPage;
58 import net.pterodactylus.sone.web.ajax.FollowSoneAjaxPage;
59 import net.pterodactylus.sone.web.ajax.GetLikesAjaxPage;
60 import net.pterodactylus.sone.web.ajax.GetLinkedElementAjaxPage;
61 import net.pterodactylus.sone.web.ajax.GetNotificationsAjaxPage;
62 import net.pterodactylus.sone.web.ajax.GetPostAjaxPage;
63 import net.pterodactylus.sone.web.ajax.GetReplyAjaxPage;
64 import net.pterodactylus.sone.web.ajax.GetStatusAjaxPage;
65 import net.pterodactylus.sone.web.ajax.GetTimesAjaxPage;
66 import net.pterodactylus.sone.web.ajax.GetTranslationAjaxPage;
67 import net.pterodactylus.sone.web.ajax.LikeAjaxPage;
68 import net.pterodactylus.sone.web.ajax.LockSoneAjaxPage;
69 import net.pterodactylus.sone.web.ajax.MarkAsKnownAjaxPage;
70 import net.pterodactylus.sone.web.ajax.MoveProfileFieldAjaxPage;
71 import net.pterodactylus.sone.web.ajax.UnbookmarkAjaxPage;
72 import net.pterodactylus.sone.web.ajax.UnfollowSoneAjaxPage;
73 import net.pterodactylus.sone.web.ajax.UnlikeAjaxPage;
74 import net.pterodactylus.sone.web.ajax.UnlockSoneAjaxPage;
75 import net.pterodactylus.sone.web.page.FreenetRequest;
76 import net.pterodactylus.sone.web.page.TemplateRenderer;
77 import net.pterodactylus.sone.web.pages.*;
78 import net.pterodactylus.util.notify.Notification;
79 import net.pterodactylus.util.notify.NotificationManager;
80 import net.pterodactylus.util.template.Template;
81 import net.pterodactylus.util.template.TemplateContextFactory;
82 import net.pterodactylus.util.web.RedirectPage;
83 import net.pterodactylus.util.web.TemplatePage;
85 import com.codahale.metrics.*;
86 import com.google.common.base.Optional;
87 import com.google.common.eventbus.Subscribe;
88 import com.google.inject.Inject;
89 import freenet.clients.http.ToadletContext;
92 * Bundles functionality that a web interface of a Freenet plugin needs, e.g.
93 * references to l10n helpers.
95 public class WebInterface implements SessionProvider {
97 /** The loaders for templates, pages, and classpath providers. */
98 private final Loaders loaders;
100 /** The notification manager. */
101 private final NotificationManager notificationManager;
103 /** The Sone plugin. */
104 private final SonePlugin sonePlugin;
106 /** The form password. */
107 private final String formPassword;
109 /** The template context factory. */
110 private final TemplateContextFactory templateContextFactory;
111 private final TemplateRenderer templateRenderer;
113 /** The parser filter. */
114 private final ParserFilter parserFilter;
115 private final ShortenFilter shortenFilter;
116 private final RenderFilter renderFilter;
118 private final ListNotificationFilter listNotificationFilter;
119 private final PostVisibilityFilter postVisibilityFilter;
121 private final ElementLoader elementLoader;
122 private final LinkedElementRenderFilter linkedElementRenderFilter;
123 private final TimeTextConverter timeTextConverter = new TimeTextConverter();
124 private final L10nFilter l10nFilter;
126 private final PageToadletRegistry pageToadletRegistry;
127 private final MetricRegistry metricRegistry;
128 private final Translation translation;
129 private final SessionProvider sessionProvider;
131 private final NewElements newElements;
134 public WebInterface(SonePlugin sonePlugin, Loaders loaders, ListNotificationFilter listNotificationFilter,
135 PostVisibilityFilter postVisibilityFilter,
136 ElementLoader elementLoader, TemplateContextFactory templateContextFactory,
137 TemplateRenderer templateRenderer,
138 ParserFilter parserFilter, ShortenFilter shortenFilter,
139 RenderFilter renderFilter,
140 LinkedElementRenderFilter linkedElementRenderFilter,
141 PageToadletRegistry pageToadletRegistry, MetricRegistry metricRegistry, Translation translation, L10nFilter l10nFilter,
142 NotificationManager notificationManager, SessionProvider sessionProvider,
143 NewElements newElements) {
144 this.sonePlugin = sonePlugin;
145 this.loaders = loaders;
146 this.listNotificationFilter = listNotificationFilter;
147 this.postVisibilityFilter = postVisibilityFilter;
148 this.elementLoader = elementLoader;
149 this.templateRenderer = templateRenderer;
150 this.parserFilter = parserFilter;
151 this.shortenFilter = shortenFilter;
152 this.renderFilter = renderFilter;
153 this.linkedElementRenderFilter = linkedElementRenderFilter;
154 this.pageToadletRegistry = pageToadletRegistry;
155 this.metricRegistry = metricRegistry;
156 this.l10nFilter = l10nFilter;
157 this.translation = translation;
158 this.notificationManager = notificationManager;
159 this.sessionProvider = sessionProvider;
160 this.newElements = newElements;
161 formPassword = sonePlugin.pluginRespirator().getToadletContainer().getFormPassword();
163 this.templateContextFactory = templateContextFactory;
164 templateContextFactory.addTemplateObject("webInterface", this);
165 templateContextFactory.addTemplateObject("formPassword", formPassword);
173 * Returns the Sone core used by the Sone plugin.
175 * @return The Sone core
178 public Core getCore() {
179 return sonePlugin.core();
183 * Returns the template context factory of the web interface.
185 * @return The template context factory
187 public TemplateContextFactory getTemplateContextFactory() {
188 return templateContextFactory;
193 public Sone getCurrentSone(@Nonnull ToadletContext toadletContext) {
194 return sessionProvider.getCurrentSone(toadletContext);
198 public void setCurrentSone(@Nonnull ToadletContext toadletContext, @Nullable Sone sone) {
199 sessionProvider.setCurrentSone(toadletContext, sone);
203 * Returns the notification manager.
205 * @return The notification manager
207 public NotificationManager getNotifications() {
208 return notificationManager;
212 public Optional<Notification> getNotification(@Nonnull String notificationId) {
213 return Optional.fromNullable(notificationManager.getNotification(notificationId));
217 public Collection<Notification> getNotifications(@Nullable Sone currentSone) {
218 return listNotificationFilter.filterNotifications(notificationManager.getNotifications(), currentSone);
221 public Translation getTranslation() {
226 * Returns the node’s form password.
228 * @return The form password
230 public String getFormPassword() {
235 public Collection<Post> getNewPosts(@Nullable Sone currentSone) {
236 return newElements.getNewPosts();
240 public Collection<PostReply> getNewReplies(@Nullable Sone currentSone) {
241 return newElements.getNewReplies();
249 * Starts the web interface and registers all toadlets.
251 public void start() {
256 * Stops the web interface and unregisters all toadlets.
259 pageToadletRegistry.unregisterToadlets();
267 * Register all toadlets.
269 private void registerToadlets() {
270 Template postTemplate = loaders.loadTemplate("/templates/include/viewPost.html");
271 Template replyTemplate = loaders.loadTemplate("/templates/include/viewReply.html");
272 Template openSearchTemplate = loaders.loadTemplate("/templates/xml/OpenSearch.xml");
274 pageToadletRegistry.addPage(new RedirectPage<FreenetRequest>("", "index.html"));
275 pageToadletRegistry.addPage(new IndexPage(this, loaders, templateRenderer, postVisibilityFilter));
276 pageToadletRegistry.addPage(new NewPage(this, loaders, templateRenderer, newElements));
277 pageToadletRegistry.addPage(new CreateSonePage(this, loaders, templateRenderer));
278 pageToadletRegistry.addPage(new KnownSonesPage(this, loaders, templateRenderer));
279 pageToadletRegistry.addPage(new EditProfilePage(this, loaders, templateRenderer));
280 pageToadletRegistry.addPage(new EditProfileFieldPage(this, loaders, templateRenderer));
281 pageToadletRegistry.addPage(new DeleteProfileFieldPage(this, loaders, templateRenderer));
282 pageToadletRegistry.addPage(new CreatePostPage(this, loaders, templateRenderer));
283 pageToadletRegistry.addPage(new CreateReplyPage(this, loaders, templateRenderer));
284 pageToadletRegistry.addPage(new ViewSonePage(this, loaders, templateRenderer));
285 pageToadletRegistry.addPage(new ViewPostPage(this, loaders, templateRenderer));
286 pageToadletRegistry.addPage(new LikePage(this, loaders, templateRenderer));
287 pageToadletRegistry.addPage(new UnlikePage(this, loaders, templateRenderer));
288 pageToadletRegistry.addPage(new DeletePostPage(this, loaders, templateRenderer));
289 pageToadletRegistry.addPage(new DeleteReplyPage(this, loaders, templateRenderer));
290 pageToadletRegistry.addPage(new LockSonePage(this, loaders, templateRenderer));
291 pageToadletRegistry.addPage(new UnlockSonePage(this, loaders, templateRenderer));
292 pageToadletRegistry.addPage(new FollowSonePage(this, loaders, templateRenderer));
293 pageToadletRegistry.addPage(new UnfollowSonePage(this, loaders, templateRenderer));
294 pageToadletRegistry.addPage(new ImageBrowserPage(this, loaders, templateRenderer));
295 pageToadletRegistry.addPage(new CreateAlbumPage(this, loaders, templateRenderer));
296 pageToadletRegistry.addPage(new EditAlbumPage(this, loaders, templateRenderer));
297 pageToadletRegistry.addPage(new DeleteAlbumPage(this, loaders, templateRenderer));
298 pageToadletRegistry.addPage(new UploadImagePage(this, loaders, templateRenderer));
299 pageToadletRegistry.addPage(new EditImagePage(this, loaders, templateRenderer));
300 pageToadletRegistry.addPage(new DeleteImagePage(this, loaders, templateRenderer));
301 pageToadletRegistry.addPage(new MarkAsKnownPage(this, loaders, templateRenderer));
302 pageToadletRegistry.addPage(new BookmarkPage(this, loaders, templateRenderer));
303 pageToadletRegistry.addPage(new UnbookmarkPage(this, loaders, templateRenderer));
304 pageToadletRegistry.addPage(new BookmarksPage(this, loaders, templateRenderer));
305 pageToadletRegistry.addPage(new SearchPage(this, loaders, templateRenderer));
306 pageToadletRegistry.addPage(new DeleteSonePage(this, loaders, templateRenderer));
307 pageToadletRegistry.addPage(new LoginPage(this, loaders, templateRenderer));
308 pageToadletRegistry.addPage(new LogoutPage(this, loaders, templateRenderer));
309 pageToadletRegistry.addPage(new OptionsPage(this, loaders, templateRenderer));
310 pageToadletRegistry.addPage(new RescuePage(this, loaders, templateRenderer));
311 pageToadletRegistry.addPage(new AboutPage(this, loaders, templateRenderer, new PluginVersion(SonePlugin.getPluginVersion()), new PluginYear(sonePlugin.getYear()), new PluginHomepage(sonePlugin.getHomepage())));
312 pageToadletRegistry.addPage(new InvalidPage(this, loaders, templateRenderer));
313 pageToadletRegistry.addPage(new NoPermissionPage(this, loaders, templateRenderer));
314 pageToadletRegistry.addPage(new EmptyImageTitlePage(this, loaders, templateRenderer));
315 pageToadletRegistry.addPage(new EmptyAlbumTitlePage(this, loaders, templateRenderer));
316 pageToadletRegistry.addPage(new DismissNotificationPage(this, loaders, templateRenderer));
317 pageToadletRegistry.addPage(new DebugPage(this, loaders, templateRenderer));
318 pageToadletRegistry.addDebugPage(new MetricsPage(this, loaders, templateRenderer, metricRegistry));
319 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("css/", "/static/css/", "text/css"));
320 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("javascript/", "/static/javascript/", "text/javascript"));
321 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("images/", "/static/images/", "image/png"));
322 pageToadletRegistry.addPage(new TemplatePage<FreenetRequest>("OpenSearch.xml", "application/opensearchdescription+xml", templateContextFactory, openSearchTemplate));
323 pageToadletRegistry.addPage(new GetImagePage(this));
324 pageToadletRegistry.addPage(new GetTranslationAjaxPage(this));
325 pageToadletRegistry.addPage(new GetStatusAjaxPage(this, elementLoader, newElements, timeTextConverter, l10nFilter, TimeZone.getDefault()));
326 pageToadletRegistry.addPage(new GetNotificationsAjaxPage(this));
327 pageToadletRegistry.addPage(new DismissNotificationAjaxPage(this));
328 pageToadletRegistry.addPage(new CreatePostAjaxPage(this));
329 pageToadletRegistry.addPage(new CreateReplyAjaxPage(this));
330 pageToadletRegistry.addPage(new GetReplyAjaxPage(this, replyTemplate));
331 pageToadletRegistry.addPage(new GetPostAjaxPage(this, postTemplate));
332 pageToadletRegistry.addPage(new GetLinkedElementAjaxPage(this, elementLoader, linkedElementRenderFilter));
333 pageToadletRegistry.addPage(new GetTimesAjaxPage(this, timeTextConverter, l10nFilter, TimeZone.getDefault()));
334 pageToadletRegistry.addPage(new MarkAsKnownAjaxPage(this));
335 pageToadletRegistry.addPage(new DeletePostAjaxPage(this));
336 pageToadletRegistry.addPage(new DeleteReplyAjaxPage(this));
337 pageToadletRegistry.addPage(new LockSoneAjaxPage(this));
338 pageToadletRegistry.addPage(new UnlockSoneAjaxPage(this));
339 pageToadletRegistry.addPage(new FollowSoneAjaxPage(this));
340 pageToadletRegistry.addPage(new UnfollowSoneAjaxPage(this));
341 pageToadletRegistry.addPage(new EditAlbumAjaxPage(this));
342 pageToadletRegistry.addPage(new EditImageAjaxPage(this, parserFilter, shortenFilter, renderFilter));
343 pageToadletRegistry.addPage(new LikeAjaxPage(this));
344 pageToadletRegistry.addPage(new UnlikeAjaxPage(this));
345 pageToadletRegistry.addPage(new GetLikesAjaxPage(this));
346 pageToadletRegistry.addPage(new BookmarkAjaxPage(this));
347 pageToadletRegistry.addPage(new UnbookmarkAjaxPage(this));
348 pageToadletRegistry.addPage(new EditProfileFieldAjaxPage(this));
349 pageToadletRegistry.addPage(new DeleteProfileFieldAjaxPage(this));
350 pageToadletRegistry.addPage(new MoveProfileFieldAjaxPage(this));
352 pageToadletRegistry.registerToadlets();
356 public void debugActivated(@Nonnull DebugActivatedEvent debugActivatedEvent) {
357 pageToadletRegistry.activateDebugMode();