🎨 Remove template context factory from web interface API
[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         @Nullable
178         @Override
179         public Sone getCurrentSone(@Nonnull ToadletContext toadletContext) {
180                 return sessionProvider.getCurrentSone(toadletContext);
181         }
182
183         @Override
184         public void setCurrentSone(@Nonnull ToadletContext toadletContext, @Nullable Sone sone) {
185                 sessionProvider.setCurrentSone(toadletContext, sone);
186         }
187
188         /**
189          * Returns the notification manager.
190          *
191          * @return The notification manager
192          */
193         public NotificationManager getNotifications() {
194                 return notificationManager;
195         }
196
197         @Nonnull
198         public Optional<Notification> getNotification(@Nonnull String notificationId) {
199                 return Optional.fromNullable(notificationManager.getNotification(notificationId));
200         }
201
202         @Nonnull
203         public Collection<Notification> getNotifications(@Nullable Sone currentSone) {
204                 return listNotificationFilter.filterNotifications(notificationManager.getNotifications(), currentSone);
205         }
206
207         public Translation getTranslation() {
208                 return translation;
209         }
210
211         /**
212          * Returns the node’s form password.
213          *
214          * @return The form password
215          */
216         public String getFormPassword() {
217                 return formPassword;
218         }
219
220         //
221         // ACTIONS
222         //
223
224         /**
225          * Starts the web interface and registers all toadlets.
226          */
227         public void start() {
228                 registerToadlets();
229         }
230
231         /**
232          * Stops the web interface and unregisters all toadlets.
233          */
234         public void stop() {
235                 pageToadletRegistry.unregisterToadlets();
236         }
237
238         //
239         // PRIVATE METHODS
240         //
241
242         /**
243          * Register all toadlets.
244          */
245         private void registerToadlets() {
246                 Template postTemplate = loaders.loadTemplate("/templates/include/viewPost.html");
247                 Template replyTemplate = loaders.loadTemplate("/templates/include/viewReply.html");
248                 Template openSearchTemplate = loaders.loadTemplate("/templates/xml/OpenSearch.xml");
249
250                 pageToadletRegistry.addPage(new RedirectPage<FreenetRequest>("", "index.html"));
251                 pageToadletRegistry.addPage(new IndexPage(this, loaders, templateRenderer, postVisibilityFilter));
252                 pageToadletRegistry.addPage(new NewPage(this, loaders, templateRenderer, newElements));
253                 pageToadletRegistry.addPage(new CreateSonePage(this, loaders, templateRenderer));
254                 pageToadletRegistry.addPage(new KnownSonesPage(this, loaders, templateRenderer));
255                 pageToadletRegistry.addPage(new EditProfilePage(this, loaders, templateRenderer));
256                 pageToadletRegistry.addPage(new EditProfileFieldPage(this, loaders, templateRenderer));
257                 pageToadletRegistry.addPage(new DeleteProfileFieldPage(this, loaders, templateRenderer));
258                 pageToadletRegistry.addPage(new CreatePostPage(this, loaders, templateRenderer));
259                 pageToadletRegistry.addPage(new CreateReplyPage(this, loaders, templateRenderer));
260                 pageToadletRegistry.addPage(new ViewSonePage(this, loaders, templateRenderer));
261                 pageToadletRegistry.addPage(new ViewPostPage(this, loaders, templateRenderer));
262                 pageToadletRegistry.addPage(new LikePage(this, loaders, templateRenderer));
263                 pageToadletRegistry.addPage(new UnlikePage(this, loaders, templateRenderer));
264                 pageToadletRegistry.addPage(new DeletePostPage(this, loaders, templateRenderer));
265                 pageToadletRegistry.addPage(new DeleteReplyPage(this, loaders, templateRenderer));
266                 pageToadletRegistry.addPage(new LockSonePage(this, loaders, templateRenderer));
267                 pageToadletRegistry.addPage(new UnlockSonePage(this, loaders, templateRenderer));
268                 pageToadletRegistry.addPage(new FollowSonePage(this, loaders, templateRenderer));
269                 pageToadletRegistry.addPage(new UnfollowSonePage(this, loaders, templateRenderer));
270                 pageToadletRegistry.addPage(new ImageBrowserPage(this, loaders, templateRenderer));
271                 pageToadletRegistry.addPage(new CreateAlbumPage(this, loaders, templateRenderer));
272                 pageToadletRegistry.addPage(new EditAlbumPage(this, loaders, templateRenderer));
273                 pageToadletRegistry.addPage(new DeleteAlbumPage(this, loaders, templateRenderer));
274                 pageToadletRegistry.addPage(new UploadImagePage(this, loaders, templateRenderer));
275                 pageToadletRegistry.addPage(new EditImagePage(this, loaders, templateRenderer));
276                 pageToadletRegistry.addPage(new DeleteImagePage(this, loaders, templateRenderer));
277                 pageToadletRegistry.addPage(new MarkAsKnownPage(this, loaders, templateRenderer));
278                 pageToadletRegistry.addPage(new BookmarkPage(this, loaders, templateRenderer));
279                 pageToadletRegistry.addPage(new UnbookmarkPage(this, loaders, templateRenderer));
280                 pageToadletRegistry.addPage(new BookmarksPage(this, loaders, templateRenderer));
281                 pageToadletRegistry.addPage(new SearchPage(this, loaders, templateRenderer));
282                 pageToadletRegistry.addPage(new DeleteSonePage(this, loaders, templateRenderer));
283                 pageToadletRegistry.addPage(new LoginPage(this, loaders, templateRenderer));
284                 pageToadletRegistry.addPage(new LogoutPage(this, loaders, templateRenderer));
285                 pageToadletRegistry.addPage(new OptionsPage(this, loaders, templateRenderer));
286                 pageToadletRegistry.addPage(new RescuePage(this, loaders, templateRenderer));
287                 pageToadletRegistry.addPage(new AboutPage(this, loaders, templateRenderer, new PluginVersion(SonePlugin.getPluginVersion()), new PluginYear(sonePlugin.getYear()), new PluginHomepage(sonePlugin.getHomepage())));
288                 pageToadletRegistry.addPage(new InvalidPage(this, loaders, templateRenderer));
289                 pageToadletRegistry.addPage(new NoPermissionPage(this, loaders, templateRenderer));
290                 pageToadletRegistry.addPage(new EmptyImageTitlePage(this, loaders, templateRenderer));
291                 pageToadletRegistry.addPage(new EmptyAlbumTitlePage(this, loaders, templateRenderer));
292                 pageToadletRegistry.addPage(new DismissNotificationPage(this, loaders, templateRenderer));
293                 pageToadletRegistry.addPage(new DebugPage(this, loaders, templateRenderer));
294                 pageToadletRegistry.addDebugPage(new MetricsPage(this, loaders, templateRenderer, metricRegistry));
295                 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("css/", "/static/css/", "text/css"));
296                 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("javascript/", "/static/javascript/", "text/javascript"));
297                 pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("images/", "/static/images/", "image/png"));
298                 pageToadletRegistry.addPage(new TemplatePage<FreenetRequest>("OpenSearch.xml", "application/opensearchdescription+xml", templateContextFactory, openSearchTemplate));
299                 pageToadletRegistry.addPage(new GetImagePage(this));
300                 pageToadletRegistry.addPage(new GetTranslationAjaxPage(this));
301                 pageToadletRegistry.addPage(new GetStatusAjaxPage(this, elementLoader, newElements, timeTextConverter, l10nFilter, TimeZone.getDefault()));
302                 pageToadletRegistry.addPage(new GetNotificationsAjaxPage(this, templateContextFactory));
303                 pageToadletRegistry.addPage(new DismissNotificationAjaxPage(this));
304                 pageToadletRegistry.addPage(new CreatePostAjaxPage(this));
305                 pageToadletRegistry.addPage(new CreateReplyAjaxPage(this));
306                 pageToadletRegistry.addPage(new GetReplyAjaxPage(this, templateContextFactory, replyTemplate));
307                 pageToadletRegistry.addPage(new GetPostAjaxPage(this, templateContextFactory, postTemplate));
308                 pageToadletRegistry.addPage(new GetLinkedElementAjaxPage(this, elementLoader, linkedElementRenderFilter));
309                 pageToadletRegistry.addPage(new GetTimesAjaxPage(this, timeTextConverter, l10nFilter, TimeZone.getDefault()));
310                 pageToadletRegistry.addPage(new MarkAsKnownAjaxPage(this));
311                 pageToadletRegistry.addPage(new DeletePostAjaxPage(this));
312                 pageToadletRegistry.addPage(new DeleteReplyAjaxPage(this));
313                 pageToadletRegistry.addPage(new LockSoneAjaxPage(this));
314                 pageToadletRegistry.addPage(new UnlockSoneAjaxPage(this));
315                 pageToadletRegistry.addPage(new FollowSoneAjaxPage(this));
316                 pageToadletRegistry.addPage(new UnfollowSoneAjaxPage(this));
317                 pageToadletRegistry.addPage(new EditAlbumAjaxPage(this));
318                 pageToadletRegistry.addPage(new EditImageAjaxPage(this, parserFilter, shortenFilter, renderFilter));
319                 pageToadletRegistry.addPage(new LikeAjaxPage(this));
320                 pageToadletRegistry.addPage(new UnlikeAjaxPage(this));
321                 pageToadletRegistry.addPage(new GetLikesAjaxPage(this));
322                 pageToadletRegistry.addPage(new BookmarkAjaxPage(this));
323                 pageToadletRegistry.addPage(new UnbookmarkAjaxPage(this));
324                 pageToadletRegistry.addPage(new EditProfileFieldAjaxPage(this));
325                 pageToadletRegistry.addPage(new DeleteProfileFieldAjaxPage(this));
326                 pageToadletRegistry.addPage(new MoveProfileFieldAjaxPage(this));
327
328                 pageToadletRegistry.registerToadlets();
329         }
330
331         @Subscribe
332         public void debugActivated(@Nonnull DebugActivatedEvent debugActivatedEvent) {
333                 pageToadletRegistry.activateDebugMode();
334         }
335
336 }