8585650e0cfcef1cccc32543a9655896c6c501c0
[Sone.git] / src / main / java / net / pterodactylus / sone / web / WebInterface.java
1 /*
2  * Sone - WebInterface.java - Copyright © 2010–2020 David Roden
3  *
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.
8  *
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.
13  *
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/>.
16  */
17
18 package net.pterodactylus.sone.web;
19
20 import java.util.Collection;
21 import java.util.TimeZone;
22 import javax.annotation.Nonnull;
23 import javax.annotation.Nullable;
24
25 import net.pterodactylus.sone.core.Core;
26 import net.pterodactylus.sone.core.ElementLoader;
27 import net.pterodactylus.sone.core.event.*;
28 import net.pterodactylus.sone.data.Sone;
29 import net.pterodactylus.sone.freenet.L10nFilter;
30 import net.pterodactylus.sone.freenet.Translation;
31 import net.pterodactylus.sone.main.Loaders;
32 import net.pterodactylus.sone.main.PluginHomepage;
33 import net.pterodactylus.sone.main.PluginVersion;
34 import net.pterodactylus.sone.main.PluginYear;
35 import net.pterodactylus.sone.main.SonePlugin;
36 import net.pterodactylus.sone.notify.ListNotificationFilter;
37 import net.pterodactylus.sone.notify.PostVisibilityFilter;
38 import net.pterodactylus.sone.template.LinkedElementRenderFilter;
39 import net.pterodactylus.sone.template.ParserFilter;
40 import net.pterodactylus.sone.template.RenderFilter;
41 import net.pterodactylus.sone.template.ShortenFilter;
42 import net.pterodactylus.sone.text.TimeTextConverter;
43 import net.pterodactylus.sone.web.ajax.BookmarkAjaxPage;
44 import net.pterodactylus.sone.web.ajax.CreatePostAjaxPage;
45 import net.pterodactylus.sone.web.ajax.CreateReplyAjaxPage;
46 import net.pterodactylus.sone.web.ajax.DeletePostAjaxPage;
47 import net.pterodactylus.sone.web.ajax.DeleteProfileFieldAjaxPage;
48 import net.pterodactylus.sone.web.ajax.DeleteReplyAjaxPage;
49 import net.pterodactylus.sone.web.ajax.DismissNotificationAjaxPage;
50 import net.pterodactylus.sone.web.ajax.EditAlbumAjaxPage;
51 import net.pterodactylus.sone.web.ajax.EditImageAjaxPage;
52 import net.pterodactylus.sone.web.ajax.EditProfileFieldAjaxPage;
53 import net.pterodactylus.sone.web.ajax.FollowSoneAjaxPage;
54 import net.pterodactylus.sone.web.ajax.GetLikesAjaxPage;
55 import net.pterodactylus.sone.web.ajax.GetLinkedElementAjaxPage;
56 import net.pterodactylus.sone.web.ajax.GetNotificationsAjaxPage;
57 import net.pterodactylus.sone.web.ajax.GetPostAjaxPage;
58 import net.pterodactylus.sone.web.ajax.GetReplyAjaxPage;
59 import net.pterodactylus.sone.web.ajax.GetStatusAjaxPage;
60 import net.pterodactylus.sone.web.ajax.GetTimesAjaxPage;
61 import net.pterodactylus.sone.web.ajax.GetTranslationAjaxPage;
62 import net.pterodactylus.sone.web.ajax.LikeAjaxPage;
63 import net.pterodactylus.sone.web.ajax.LockSoneAjaxPage;
64 import net.pterodactylus.sone.web.ajax.MarkAsKnownAjaxPage;
65 import net.pterodactylus.sone.web.ajax.MoveProfileFieldAjaxPage;
66 import net.pterodactylus.sone.web.ajax.UnbookmarkAjaxPage;
67 import net.pterodactylus.sone.web.ajax.UnfollowSoneAjaxPage;
68 import net.pterodactylus.sone.web.ajax.UnlikeAjaxPage;
69 import net.pterodactylus.sone.web.ajax.UnlockSoneAjaxPage;
70 import net.pterodactylus.sone.web.page.FreenetRequest;
71 import net.pterodactylus.sone.web.page.TemplateRenderer;
72 import net.pterodactylus.sone.web.pages.*;
73 import net.pterodactylus.util.notify.Notification;
74 import net.pterodactylus.util.notify.NotificationManager;
75 import net.pterodactylus.util.template.Template;
76 import net.pterodactylus.util.template.TemplateContextFactory;
77 import net.pterodactylus.util.web.RedirectPage;
78 import net.pterodactylus.util.web.TemplatePage;
79
80 import com.codahale.metrics.*;
81 import com.google.common.base.Optional;
82 import com.google.common.eventbus.Subscribe;
83 import com.google.inject.Inject;
84 import freenet.clients.http.ToadletContext;
85
86 /**
87  * Bundles functionality that a web interface of a Freenet plugin needs, e.g.
88  * references to l10n helpers.
89  */
90 public class WebInterface implements SessionProvider {
91
92         /** The loaders for templates, pages, and classpath providers. */
93         private final Loaders loaders;
94
95         /** The notification manager. */
96         private final NotificationManager notificationManager;
97
98         /** The Sone plugin. */
99         private final SonePlugin sonePlugin;
100
101         /** The form password. */
102         private final String formPassword;
103
104         /** The template context factory. */
105         private final TemplateContextFactory templateContextFactory;
106         private final TemplateRenderer templateRenderer;
107
108         /** The parser filter. */
109         private final ParserFilter parserFilter;
110         private final ShortenFilter shortenFilter;
111         private final RenderFilter renderFilter;
112
113         private final ListNotificationFilter listNotificationFilter;
114         private final PostVisibilityFilter postVisibilityFilter;
115
116         private final ElementLoader elementLoader;
117         private final LinkedElementRenderFilter linkedElementRenderFilter;
118         private final TimeTextConverter timeTextConverter = new TimeTextConverter();
119         private final L10nFilter l10nFilter;
120
121         private final PageToadletRegistry pageToadletRegistry;
122         private final MetricRegistry metricRegistry;
123         private final Translation translation;
124         private final SessionProvider sessionProvider;
125
126         private final NewElements newElements;
127
128         @Inject
129         public WebInterface(SonePlugin sonePlugin, Loaders loaders, ListNotificationFilter listNotificationFilter,
130                                                 PostVisibilityFilter postVisibilityFilter,
131                                                 ElementLoader elementLoader, TemplateContextFactory templateContextFactory,
132                                                 TemplateRenderer templateRenderer,
133                                                 ParserFilter parserFilter, ShortenFilter shortenFilter,
134                                                 RenderFilter renderFilter,
135                                                 LinkedElementRenderFilter linkedElementRenderFilter,
136                                                 PageToadletRegistry pageToadletRegistry, MetricRegistry metricRegistry, Translation translation, L10nFilter l10nFilter,
137                                                 NotificationManager notificationManager, SessionProvider sessionProvider,
138                                                 NewElements newElements) {
139                 this.sonePlugin = sonePlugin;
140                 this.loaders = loaders;
141                 this.listNotificationFilter = listNotificationFilter;
142                 this.postVisibilityFilter = postVisibilityFilter;
143                 this.elementLoader = elementLoader;
144                 this.templateRenderer = templateRenderer;
145                 this.parserFilter = parserFilter;
146                 this.shortenFilter = shortenFilter;
147                 this.renderFilter = renderFilter;
148                 this.linkedElementRenderFilter = linkedElementRenderFilter;
149                 this.pageToadletRegistry = pageToadletRegistry;
150                 this.metricRegistry = metricRegistry;
151                 this.l10nFilter = l10nFilter;
152                 this.translation = translation;
153                 this.notificationManager = notificationManager;
154                 this.sessionProvider = sessionProvider;
155                 this.newElements = newElements;
156                 formPassword = sonePlugin.pluginRespirator().getToadletContainer().getFormPassword();
157
158                 this.templateContextFactory = templateContextFactory;
159                 templateContextFactory.addTemplateObject("webInterface", this);
160                 templateContextFactory.addTemplateObject("formPassword", formPassword);
161         }
162
163         //
164         // ACCESSORS
165         //
166
167         /**
168          * Returns the Sone core used by the Sone plugin.
169          *
170          * @return The Sone core
171          */
172         @Nonnull
173         public Core getCore() {
174                 return sonePlugin.core();
175         }
176
177         /**
178          * Returns the template context factory of the web interface.
179          *
180          * @return The template context factory
181          */
182         public TemplateContextFactory getTemplateContextFactory() {
183                 return templateContextFactory;
184         }
185
186         @Nullable
187         @Override
188         public Sone getCurrentSone(@Nonnull ToadletContext toadletContext) {
189                 return sessionProvider.getCurrentSone(toadletContext);
190         }
191
192         @Override
193         public void setCurrentSone(@Nonnull ToadletContext toadletContext, @Nullable Sone sone) {
194                 sessionProvider.setCurrentSone(toadletContext, sone);
195         }
196
197         /**
198          * Returns the notification manager.
199          *
200          * @return The notification manager
201          */
202         public NotificationManager getNotifications() {
203                 return notificationManager;
204         }
205
206         @Nonnull
207         public Optional<Notification> getNotification(@Nonnull String notificationId) {
208                 return Optional.fromNullable(notificationManager.getNotification(notificationId));
209         }
210
211         @Nonnull
212         public Collection<Notification> getNotifications(@Nullable Sone currentSone) {
213                 return listNotificationFilter.filterNotifications(notificationManager.getNotifications(), currentSone);
214         }
215
216         public Translation getTranslation() {
217                 return translation;
218         }
219
220         /**
221          * Returns the node’s form password.
222          *
223          * @return The form password
224          */
225         public String getFormPassword() {
226                 return formPassword;
227         }
228
229         //
230         // ACTIONS
231         //
232
233         /**
234          * Starts the web interface and registers all toadlets.
235          */
236         public void start() {
237                 registerToadlets();
238         }
239
240         /**
241          * Stops the web interface and unregisters all toadlets.
242          */
243         public void stop() {
244                 pageToadletRegistry.unregisterToadlets();
245         }
246
247         //
248         // PRIVATE METHODS
249         //
250
251         /**
252          * Register all toadlets.
253          */
254         private void registerToadlets() {
255                 Template postTemplate = loaders.loadTemplate("/templates/include/viewPost.html");
256                 Template replyTemplate = loaders.loadTemplate("/templates/include/viewReply.html");
257                 Template openSearchTemplate = loaders.loadTemplate("/templates/xml/OpenSearch.xml");
258
259                 pageToadletRegistry.addPage(new RedirectPage<FreenetRequest>("", "index.html"));
260                 pageToadletRegistry.addPage(new IndexPage(this, loaders, templateRenderer, postVisibilityFilter));
261                 pageToadletRegistry.addPage(new NewPage(this, loaders, templateRenderer, newElements));
262                 pageToadletRegistry.addPage(new CreateSonePage(this, loaders, templateRenderer));
263                 pageToadletRegistry.addPage(new KnownSonesPage(this, loaders, templateRenderer));
264                 pageToadletRegistry.addPage(new EditProfilePage(this, loaders, templateRenderer));
265                 pageToadletRegistry.addPage(new EditProfileFieldPage(this, loaders, templateRenderer));
266                 pageToadletRegistry.addPage(new DeleteProfileFieldPage(this, loaders, templateRenderer));
267                 pageToadletRegistry.addPage(new CreatePostPage(this, loaders, templateRenderer));
268                 pageToadletRegistry.addPage(new CreateReplyPage(this, loaders, templateRenderer));
269                 pageToadletRegistry.addPage(new ViewSonePage(this, loaders, templateRenderer));
270                 pageToadletRegistry.addPage(new ViewPostPage(this, loaders, templateRenderer));
271                 pageToadletRegistry.addPage(new LikePage(this, loaders, templateRenderer));
272                 pageToadletRegistry.addPage(new UnlikePage(this, loaders, templateRenderer));
273                 pageToadletRegistry.addPage(new DeletePostPage(this, loaders, templateRenderer));
274                 pageToadletRegistry.addPage(new DeleteReplyPage(this, loaders, templateRenderer));
275                 pageToadletRegistry.addPage(new LockSonePage(this, loaders, templateRenderer));
276                 pageToadletRegistry.addPage(new UnlockSonePage(this, loaders, templateRenderer));
277                 pageToadletRegistry.addPage(new FollowSonePage(this, loaders, templateRenderer));
278                 pageToadletRegistry.addPage(new UnfollowSonePage(this, loaders, templateRenderer));
279                 pageToadletRegistry.addPage(new ImageBrowserPage(this, loaders, templateRenderer));
280                 pageToadletRegistry.addPage(new CreateAlbumPage(this, loaders, templateRenderer));
281                 pageToadletRegistry.addPage(new EditAlbumPage(this, loaders, templateRenderer));
282                 pageToadletRegistry.addPage(new DeleteAlbumPage(this, loaders, templateRenderer));
283                 pageToadletRegistry.addPage(new UploadImagePage(this, loaders, templateRenderer));
284                 pageToadletRegistry.addPage(new EditImagePage(this, loaders, templateRenderer));
285                 pageToadletRegistry.addPage(new DeleteImagePage(this, loaders, templateRenderer));
286                 pageToadletRegistry.addPage(new MarkAsKnownPage(this, loaders, templateRenderer));
287                 pageToadletRegistry.addPage(new BookmarkPage(this, loaders, templateRenderer));
288                 pageToadletRegistry.addPage(new UnbookmarkPage(this, loaders, templateRenderer));
289                 pageToadletRegistry.addPage(new BookmarksPage(this, loaders, templateRenderer));
290                 pageToadletRegistry.addPage(new SearchPage(this, loaders, templateRenderer));
291                 pageToadletRegistry.addPage(new DeleteSonePage(this, loaders, templateRenderer));
292                 pageToadletRegistry.addPage(new LoginPage(this, loaders, templateRenderer));
293                 pageToadletRegistry.addPage(new LogoutPage(this, loaders, templateRenderer));
294                 pageToadletRegistry.addPage(new OptionsPage(this, loaders, templateRenderer));
295                 pageToadletRegistry.addPage(new RescuePage(this, loaders, templateRenderer));
296                 pageToadletRegistry.addPage(new AboutPage(this, loaders, templateRenderer, new PluginVersion(SonePlugin.getPluginVersion()), new PluginYear(sonePlugin.getYear()), new PluginHomepage(sonePlugin.getHomepage())));
297                 pageToadletRegistry.addPage(new InvalidPage(this, loaders, templateRenderer));
298                 pageToadletRegistry.addPage(new NoPermissionPage(this, loaders, templateRenderer));
299                 pageToadletRegistry.addPage(new EmptyImageTitlePage(this, loaders, templateRenderer));
300                 pageToadletRegistry.addPage(new EmptyAlbumTitlePage(this, loaders, templateRenderer));
301                 pageToadletRegistry.addPage(new DismissNotificationPage(this, loaders, templateRenderer));
302                 pageToadletRegistry.addPage(new DebugPage(this, loaders, templateRenderer));
303                 pageToadletRegistry.addDebugPage(new MetricsPage(this, loaders, templateRenderer, metricRegistry));
304                 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("css/", "/static/css/", "text/css"));
305                 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("javascript/", "/static/javascript/", "text/javascript"));
306                 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("images/", "/static/images/", "image/png"));
307                 pageToadletRegistry.addPage(new TemplatePage<FreenetRequest>("OpenSearch.xml", "application/opensearchdescription+xml", templateContextFactory, openSearchTemplate));
308                 pageToadletRegistry.addPage(new GetImagePage(this));
309                 pageToadletRegistry.addPage(new GetTranslationAjaxPage(this));
310                 pageToadletRegistry.addPage(new GetStatusAjaxPage(this, elementLoader, newElements, timeTextConverter, l10nFilter, TimeZone.getDefault()));
311                 pageToadletRegistry.addPage(new GetNotificationsAjaxPage(this));
312                 pageToadletRegistry.addPage(new DismissNotificationAjaxPage(this));
313                 pageToadletRegistry.addPage(new CreatePostAjaxPage(this));
314                 pageToadletRegistry.addPage(new CreateReplyAjaxPage(this));
315                 pageToadletRegistry.addPage(new GetReplyAjaxPage(this, replyTemplate));
316                 pageToadletRegistry.addPage(new GetPostAjaxPage(this, postTemplate));
317                 pageToadletRegistry.addPage(new GetLinkedElementAjaxPage(this, elementLoader, linkedElementRenderFilter));
318                 pageToadletRegistry.addPage(new GetTimesAjaxPage(this, timeTextConverter, l10nFilter, TimeZone.getDefault()));
319                 pageToadletRegistry.addPage(new MarkAsKnownAjaxPage(this));
320                 pageToadletRegistry.addPage(new DeletePostAjaxPage(this));
321                 pageToadletRegistry.addPage(new DeleteReplyAjaxPage(this));
322                 pageToadletRegistry.addPage(new LockSoneAjaxPage(this));
323                 pageToadletRegistry.addPage(new UnlockSoneAjaxPage(this));
324                 pageToadletRegistry.addPage(new FollowSoneAjaxPage(this));
325                 pageToadletRegistry.addPage(new UnfollowSoneAjaxPage(this));
326                 pageToadletRegistry.addPage(new EditAlbumAjaxPage(this));
327                 pageToadletRegistry.addPage(new EditImageAjaxPage(this, parserFilter, shortenFilter, renderFilter));
328                 pageToadletRegistry.addPage(new LikeAjaxPage(this));
329                 pageToadletRegistry.addPage(new UnlikeAjaxPage(this));
330                 pageToadletRegistry.addPage(new GetLikesAjaxPage(this));
331                 pageToadletRegistry.addPage(new BookmarkAjaxPage(this));
332                 pageToadletRegistry.addPage(new UnbookmarkAjaxPage(this));
333                 pageToadletRegistry.addPage(new EditProfileFieldAjaxPage(this));
334                 pageToadletRegistry.addPage(new DeleteProfileFieldAjaxPage(this));
335                 pageToadletRegistry.addPage(new MoveProfileFieldAjaxPage(this));
336
337                 pageToadletRegistry.registerToadlets();
338         }
339
340         @Subscribe
341         public void debugActivated(@Nonnull DebugActivatedEvent debugActivatedEvent) {
342                 pageToadletRegistry.activateDebugMode();
343         }
344
345 }