X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fweb%2FWebInterface.java;h=cabc44e0f8702f39089a847b39ef8fa3f05fc0dd;hb=8ee3de9a7ed7c65b5f695dd60da6e55d94c1125e;hp=a3f33525cbb83bf76c6b8d8b72ac9c061356bf78;hpb=2f21e4a2402f1c7a55175f223118521dbd2d27d8;p=Sone.git diff --git a/src/main/java/net/pterodactylus/sone/web/WebInterface.java b/src/main/java/net/pterodactylus/sone/web/WebInterface.java index a3f3352..cabc44e 100644 --- a/src/main/java/net/pterodactylus/sone/web/WebInterface.java +++ b/src/main/java/net/pterodactylus/sone/web/WebInterface.java @@ -1,5 +1,5 @@ /* - * Sone - WebInterface.java - Copyright © 2010–2013 David Roden + * Sone - WebInterface.java - Copyright © 2010–2015 David Roden * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,10 +17,10 @@ package net.pterodactylus.sone.web; +import static com.google.common.collect.FluentIterable.from; import static java.util.logging.Logger.getLogger; import static net.pterodactylus.util.template.TemplateParser.parse; -import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.Collection; @@ -35,8 +35,9 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import net.pterodactylus.sone.core.Core; import net.pterodactylus.sone.core.event.ImageInsertAbortedEvent; @@ -72,6 +73,9 @@ import net.pterodactylus.sone.main.Loaders; import net.pterodactylus.sone.main.ReparseFilter; import net.pterodactylus.sone.main.SonePlugin; import net.pterodactylus.sone.notify.ListNotification; +import net.pterodactylus.sone.notify.ListNotificationFilter; +import net.pterodactylus.sone.notify.PostVisibilityFilter; +import net.pterodactylus.sone.notify.ReplyVisibilityFilter; import net.pterodactylus.sone.template.AlbumAccessor; import net.pterodactylus.sone.template.CollectionAccessor; import net.pterodactylus.sone.template.CssClassNameFilter; @@ -129,7 +133,6 @@ import net.pterodactylus.sone.web.page.PageToadletFactory; import net.pterodactylus.util.notify.Notification; import net.pterodactylus.util.notify.NotificationManager; import net.pterodactylus.util.notify.TemplateNotification; -import net.pterodactylus.util.template.ClassPathTemplateProvider; import net.pterodactylus.util.template.CollectionSortFilter; import net.pterodactylus.util.template.ContainsFilter; import net.pterodactylus.util.template.DateFilter; @@ -146,14 +149,8 @@ import net.pterodactylus.util.template.TemplateContextFactory; import net.pterodactylus.util.template.TemplateProvider; import net.pterodactylus.util.template.XmlFilter; import net.pterodactylus.util.web.RedirectPage; -import net.pterodactylus.util.web.StaticPage; import net.pterodactylus.util.web.TemplatePage; -import com.google.common.collect.Collections2; -import com.google.common.collect.ImmutableSet; -import com.google.common.eventbus.Subscribe; -import com.google.inject.Inject; - import freenet.clients.http.SessionManager; import freenet.clients.http.SessionManager.Session; import freenet.clients.http.ToadletContainer; @@ -161,6 +158,12 @@ import freenet.clients.http.ToadletContext; import freenet.l10n.BaseL10n; import freenet.support.api.HTTPRequest; +import com.google.common.base.Optional; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableSet; +import com.google.common.eventbus.Subscribe; +import com.google.inject.Inject; + /** * Bundles functionality that a web interface of a Freenet plugin needs, e.g. * references to l10n helpers. @@ -196,6 +199,10 @@ public class WebInterface { /** The parser filter. */ private final ParserFilter parserFilter; + private final ListNotificationFilter listNotificationFilter; + private final PostVisibilityFilter postVisibilityFilter; + private final ReplyVisibilityFilter replyVisibilityFilter; + /** The “new Sone” notification. */ private final ListNotification newSoneNotification; @@ -245,9 +252,12 @@ public class WebInterface { * The Sone plugin */ @Inject - public WebInterface(SonePlugin sonePlugin, Loaders loaders) { + public WebInterface(SonePlugin sonePlugin, Loaders loaders, ListNotificationFilter listNotificationFilter, PostVisibilityFilter postVisibilityFilter, ReplyVisibilityFilter replyVisibilityFilter) { this.sonePlugin = sonePlugin; this.loaders = loaders; + this.listNotificationFilter = listNotificationFilter; + this.postVisibilityFilter = postVisibilityFilter; + this.replyVisibilityFilter = replyVisibilityFilter; formPassword = sonePlugin.pluginRespirator().getToadletContainer().getFormPassword(); soneTextParser = new SoneTextParser(getCore(), getCore()); @@ -286,7 +296,7 @@ public class WebInterface { templateContextFactory.addFilter("mod", new ModFilter()); templateContextFactory.addFilter("paginate", new PaginationFilter()); templateContextFactory.addProvider(TemplateProvider.TEMPLATE_CONTEXT_PROVIDER); - templateContextFactory.addProvider(new ClassPathTemplateProvider(WebInterface.class, "/templates/")); + templateContextFactory.addProvider(loaders.getTemplateProvider()); templateContextFactory.addTemplateObject("webInterface", this); templateContextFactory.addTemplateObject("formPassword", formPassword); @@ -456,6 +466,16 @@ public class WebInterface { return notificationManager; } + @Nonnull + public Optional getNotification(@Nonnull String notificationId) { + return Optional.fromNullable(notificationManager.getNotification(notificationId)); + } + + @Nonnull + public Collection getNotifications(@Nullable Sone currentSone) { + return listNotificationFilter.filterNotifications(notificationManager.getNotifications(), currentSone); + } + /** * Returns the l10n helper of the node. * @@ -493,6 +513,15 @@ public class WebInterface { return ImmutableSet. builder().addAll(newPostNotification.getElements()).addAll(localPostNotification.getElements()).build(); } + @Nonnull + public Collection getNewPosts(@Nullable Sone currentSone) { + Set allNewPosts = ImmutableSet. builder() + .addAll(newPostNotification.getElements()) + .addAll(localPostNotification.getElements()) + .build(); + return from(allNewPosts).filter(postVisibilityFilter.isVisible(currentSone)).toSet(); + } + /** * Returns the replies that have been announced as new in the * {@link #newReplyNotification}. @@ -503,6 +532,15 @@ public class WebInterface { return ImmutableSet. builder().addAll(newReplyNotification.getElements()).addAll(localReplyNotification.getElements()).build(); } + @Nonnull + public Collection getNewReplies(@Nullable Sone currentSone) { + Set allNewReplies = ImmutableSet.builder() + .addAll(newReplyNotification.getElements()) + .addAll(localReplyNotification.getElements()) + .build(); + return from(allNewReplies).filter(replyVisibilityFilter.isVisible(currentSone)).toSet(); + } + /** * Sets whether the current start of the plugin is the first start. It is * considered a first start if the configuration file does not exist. @@ -640,7 +678,7 @@ public class WebInterface { PageToadletFactory pageToadletFactory = new PageToadletFactory(sonePlugin.pluginRespirator().getHLSimpleClient(), "/Sone/"); pageToadlets.add(pageToadletFactory.createPageToadlet(new RedirectPage("", "index.html"))); - pageToadlets.add(pageToadletFactory.createPageToadlet(new IndexPage(indexTemplate, this), "Index")); + pageToadlets.add(pageToadletFactory.createPageToadlet(new IndexPage(indexTemplate, this, postVisibilityFilter), "Index")); pageToadlets.add(pageToadletFactory.createPageToadlet(new NewPage(newTemplate, this), "New")); pageToadlets.add(pageToadletFactory.createPageToadlet(new CreateSonePage(createSoneTemplate, this), "CreateSone")); pageToadlets.add(pageToadletFactory.createPageToadlet(new KnownSonesPage(knownSonesTemplate, this), "KnownSones")); @@ -685,9 +723,9 @@ public class WebInterface { pageToadlets.add(pageToadletFactory.createPageToadlet(new SoneTemplatePage("emptyAlbumTitle.html", emptyAlbumTitleTemplate, "Page.EmptyAlbumTitle.Title", this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new DismissNotificationPage(emptyTemplate, this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new SoneTemplatePage("invalid.html", invalidTemplate, "Page.Invalid.Title", this))); - pageToadlets.add(pageToadletFactory.createPageToadlet(new StaticPage("css/", "/static/css/", "text/css"))); - pageToadlets.add(pageToadletFactory.createPageToadlet(new StaticPage("javascript/", "/static/javascript/", "text/javascript"))); - pageToadlets.add(pageToadletFactory.createPageToadlet(new StaticPage("images/", "/static/images/", "image/png"))); + pageToadlets.add(pageToadletFactory.createPageToadlet(loaders.loadStaticPage("css/", "/static/css/", "text/css"))); + pageToadlets.add(pageToadletFactory.createPageToadlet(loaders.loadStaticPage("javascript/", "/static/javascript/", "text/javascript"))); + pageToadlets.add(pageToadletFactory.createPageToadlet(loaders.loadStaticPage("images/", "/static/images/", "image/png"))); pageToadlets.add(pageToadletFactory.createPageToadlet(new TemplatePage("OpenSearch.xml", "application/opensearchdescription+xml", templateContextFactory, openSearchTemplate))); pageToadlets.add(pageToadletFactory.createPageToadlet(new GetImagePage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new GetTranslationPage(this))); @@ -755,14 +793,10 @@ public class WebInterface { private Collection getMentionedSones(String text) { /* we need no context to find mentioned Sones. */ Set mentionedSones = new HashSet(); - try { - for (Part part : soneTextParser.parse(null, new StringReader(text))) { - if (part instanceof SonePart) { - mentionedSones.add(((SonePart) part).getSone()); - } + for (Part part : soneTextParser.parse(null, text)) { + if (part instanceof SonePart) { + mentionedSones.add(((SonePart) part).getSone()); } - } catch (IOException ioe1) { - logger.log(Level.WARNING, String.format("Could not parse post text: %s", text), ioe1); } return Collections2.filter(mentionedSones, Sone.LOCAL_SONE_FILTER); } @@ -886,72 +920,46 @@ public class WebInterface { newSoneNotification.remove(markSoneKnownEvent.sone()); } - /** - * Notifies the web interface that a {@link Post} was marked as known. - * - * @param markPostKnownEvent - * The event - */ @Subscribe public void markPostKnown(MarkPostKnownEvent markPostKnownEvent) { - newPostNotification.remove(markPostKnownEvent.post()); - localPostNotification.remove(markPostKnownEvent.post()); - if (!localSoneMentionedInNewPostOrReply(markPostKnownEvent.post())) { - mentionNotification.remove(markPostKnownEvent.post()); - } + removePost(markPostKnownEvent.post()); } - /** - * Notifies the web interface that a {@link PostReply} was marked as known. - * - * @param markPostReplyKnownEvent - * The event - */ @Subscribe public void markReplyKnown(MarkPostReplyKnownEvent markPostReplyKnownEvent) { - PostReply postReply = markPostReplyKnownEvent.postReply(); - newReplyNotification.remove(postReply); - localReplyNotification.remove(postReply); - if (postReply.getPost().isPresent() && !localSoneMentionedInNewPostOrReply(postReply.getPost().get())) { - mentionNotification.remove(postReply.getPost().get()); - } + removeReply(markPostReplyKnownEvent.postReply()); } - /** - * Notifies the web interface that a {@link Sone} was removed. - * - * @param soneRemovedEvent - * The event - */ @Subscribe public void soneRemoved(SoneRemovedEvent soneRemovedEvent) { newSoneNotification.remove(soneRemovedEvent.sone()); + for (Post post : soneRemovedEvent.sone().getPosts()) { + removePost(post); + } + for (PostReply postReply : soneRemovedEvent.sone().getReplies()) { + removeReply(postReply); + } } - /** - * Notifies the web interface that a {@link Post} was removed. - * - * @param postRemovedEvent - * The event - */ @Subscribe public void postRemoved(PostRemovedEvent postRemovedEvent) { - newPostNotification.remove(postRemovedEvent.post()); - localPostNotification.remove(postRemovedEvent.post()); - if (!localSoneMentionedInNewPostOrReply(postRemovedEvent.post())) { - mentionNotification.remove(postRemovedEvent.post()); + removePost(postRemovedEvent.post()); + } + + private void removePost(Post post) { + newPostNotification.remove(post); + localPostNotification.remove(post); + if (!localSoneMentionedInNewPostOrReply(post)) { + mentionNotification.remove(post); } } - /** - * Notifies the web interface that a {@link PostReply} was removed. - * - * @param postReplyRemovedEvent - * The event - */ @Subscribe public void replyRemoved(PostReplyRemovedEvent postReplyRemovedEvent) { - PostReply reply = postReplyRemovedEvent.postReply(); + removeReply(postReplyRemovedEvent.postReply()); + } + + private void removeReply(PostReply reply) { newReplyNotification.remove(reply); localReplyNotification.remove(reply); if (reply.getPost().isPresent() && !localSoneMentionedInNewPostOrReply(reply.getPost().get())) { @@ -1047,9 +1055,10 @@ public class WebInterface { */ @Subscribe public void updateFound(UpdateFoundEvent updateFoundEvent) { - newVersionNotification.getTemplateContext().set("latestVersion", updateFoundEvent.version()); - newVersionNotification.getTemplateContext().set("latestEdition", updateFoundEvent.latestEdition()); - newVersionNotification.getTemplateContext().set("releaseTime", updateFoundEvent.releaseTime()); + newVersionNotification.set("latestVersion", updateFoundEvent.version()); + newVersionNotification.set("latestEdition", updateFoundEvent.latestEdition()); + newVersionNotification.set("releaseTime", updateFoundEvent.releaseTime()); + newVersionNotification.set("disruptive", updateFoundEvent.disruptive()); notificationManager.addNotification(newVersionNotification); }