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 java.util.Collection;
21 import java.util.TimeZone;
22 import javax.annotation.Nonnull;
23 import javax.annotation.Nullable;
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;
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;
87 * Bundles functionality that a web interface of a Freenet plugin needs, e.g.
88 * references to l10n helpers.
90 public class WebInterface implements SessionProvider {
92 /** The loaders for templates, pages, and classpath providers. */
93 private final Loaders loaders;
95 /** The notification manager. */
96 private final NotificationManager notificationManager;
98 /** The Sone plugin. */
99 private final SonePlugin sonePlugin;
101 /** The form password. */
102 private final String formPassword;
104 /** The template context factory. */
105 private final TemplateContextFactory templateContextFactory;
106 private final TemplateRenderer templateRenderer;
108 /** The parser filter. */
109 private final ParserFilter parserFilter;
110 private final ShortenFilter shortenFilter;
111 private final RenderFilter renderFilter;
113 private final ListNotificationFilter listNotificationFilter;
114 private final PostVisibilityFilter postVisibilityFilter;
116 private final ElementLoader elementLoader;
117 private final LinkedElementRenderFilter linkedElementRenderFilter;
118 private final TimeTextConverter timeTextConverter = new TimeTextConverter();
119 private final L10nFilter l10nFilter;
121 private final PageToadletRegistry pageToadletRegistry;
122 private final MetricRegistry metricRegistry;
123 private final Translation translation;
124 private final SessionProvider sessionProvider;
126 private final NewElements newElements;
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();
158 this.templateContextFactory = templateContextFactory;
159 templateContextFactory.addTemplateObject("webInterface", this);
160 templateContextFactory.addTemplateObject("formPassword", formPassword);
168 * Returns the Sone core used by the Sone plugin.
170 * @return The Sone core
173 public Core getCore() {
174 return sonePlugin.core();
178 * Returns the template context factory of the web interface.
180 * @return The template context factory
182 public TemplateContextFactory getTemplateContextFactory() {
183 return templateContextFactory;
188 public Sone getCurrentSone(@Nonnull ToadletContext toadletContext) {
189 return sessionProvider.getCurrentSone(toadletContext);
193 public void setCurrentSone(@Nonnull ToadletContext toadletContext, @Nullable Sone sone) {
194 sessionProvider.setCurrentSone(toadletContext, sone);
198 * Returns the notification manager.
200 * @return The notification manager
202 public NotificationManager getNotifications() {
203 return notificationManager;
207 public Optional<Notification> getNotification(@Nonnull String notificationId) {
208 return Optional.fromNullable(notificationManager.getNotification(notificationId));
212 public Collection<Notification> getNotifications(@Nullable Sone currentSone) {
213 return listNotificationFilter.filterNotifications(notificationManager.getNotifications(), currentSone);
216 public Translation getTranslation() {
221 * Returns the node’s form password.
223 * @return The form password
225 public String getFormPassword() {
234 * Starts the web interface and registers all toadlets.
236 public void start() {
241 * Stops the web interface and unregisters all toadlets.
244 pageToadletRegistry.unregisterToadlets();
252 * Register all toadlets.
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");
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));
337 pageToadletRegistry.registerToadlets();
341 public void debugActivated(@Nonnull DebugActivatedEvent debugActivatedEvent) {
342 pageToadletRegistry.activateDebugMode();