X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fweb%2FWebInterface.java;h=c9547fbca28997c2943fb90cb894fce6f0138916;hb=a372629239706054eb03a2138274a644ee76fc04;hp=acfdc7f567ab26c349263c5a9b37228682ef96e7;hpb=2ee1747f28b213da04a98456aac925f315f52dac;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 acfdc7f..c9547fb 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 @@ /* - * FreenetSone - WebInterface.java - Copyright © 2010 David Roden + * Sone - WebInterface.java - Copyright © 2010 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,6 +17,7 @@ package net.pterodactylus.sone.web; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; @@ -49,15 +50,18 @@ import net.pterodactylus.sone.template.CssClassNameFilter; import net.pterodactylus.sone.template.HttpRequestAccessor; import net.pterodactylus.sone.template.IdentityAccessor; import net.pterodactylus.sone.template.JavascriptFilter; -import net.pterodactylus.sone.template.NotificationManagerAccessor; import net.pterodactylus.sone.template.ParserFilter; import net.pterodactylus.sone.template.PostAccessor; import net.pterodactylus.sone.template.ReplyAccessor; +import net.pterodactylus.sone.template.ReplyGroupFilter; import net.pterodactylus.sone.template.RequestChangeFilter; import net.pterodactylus.sone.template.SoneAccessor; import net.pterodactylus.sone.template.SubstringFilter; import net.pterodactylus.sone.template.TrustAccessor; import net.pterodactylus.sone.template.UnknownDateFilter; +import net.pterodactylus.sone.text.Part; +import net.pterodactylus.sone.text.SonePart; +import net.pterodactylus.sone.text.SoneTextParser; import net.pterodactylus.sone.web.ajax.BookmarkAjaxPage; import net.pterodactylus.sone.web.ajax.CreatePostAjaxPage; import net.pterodactylus.sone.web.ajax.CreateReplyAjaxPage; @@ -69,9 +73,11 @@ import net.pterodactylus.sone.web.ajax.DistrustAjaxPage; import net.pterodactylus.sone.web.ajax.EditProfileFieldAjaxPage; import net.pterodactylus.sone.web.ajax.FollowSoneAjaxPage; import net.pterodactylus.sone.web.ajax.GetLikesAjaxPage; +import net.pterodactylus.sone.web.ajax.GetNotificationAjaxPage; import net.pterodactylus.sone.web.ajax.GetPostAjaxPage; import net.pterodactylus.sone.web.ajax.GetReplyAjaxPage; import net.pterodactylus.sone.web.ajax.GetStatusAjaxPage; +import net.pterodactylus.sone.web.ajax.GetTimesAjaxPage; import net.pterodactylus.sone.web.ajax.GetTranslationPage; import net.pterodactylus.sone.web.ajax.LikeAjaxPage; import net.pterodactylus.sone.web.ajax.LockSoneAjaxPage; @@ -85,6 +91,7 @@ import net.pterodactylus.sone.web.ajax.UnlockSoneAjaxPage; import net.pterodactylus.sone.web.ajax.UntrustAjaxPage; import net.pterodactylus.sone.web.page.PageToadlet; import net.pterodactylus.sone.web.page.PageToadletFactory; +import net.pterodactylus.sone.web.page.RedirectPage; import net.pterodactylus.sone.web.page.StaticPage; import net.pterodactylus.sone.web.page.TemplatePage; import net.pterodactylus.util.cache.Cache; @@ -93,11 +100,13 @@ import net.pterodactylus.util.cache.CacheItem; import net.pterodactylus.util.cache.DefaultCacheItem; import net.pterodactylus.util.cache.MemoryCache; import net.pterodactylus.util.cache.ValueRetriever; +import net.pterodactylus.util.filter.Filters; import net.pterodactylus.util.logging.Logging; import net.pterodactylus.util.notify.Notification; import net.pterodactylus.util.notify.NotificationManager; import net.pterodactylus.util.notify.TemplateNotification; import net.pterodactylus.util.template.CollectionSortFilter; +import net.pterodactylus.util.template.ContainsFilter; import net.pterodactylus.util.template.DateFilter; import net.pterodactylus.util.template.FormatFilter; import net.pterodactylus.util.template.HtmlFilter; @@ -147,6 +156,9 @@ public class WebInterface implements CoreListener { /** The template context factory. */ private final TemplateContextFactory templateContextFactory; + /** The Sone text parser. */ + private final SoneTextParser soneTextParser; + /** The “new Sone” notification. */ private final ListNotification newSoneNotification; @@ -156,6 +168,9 @@ public class WebInterface implements CoreListener { /** The “new reply” notification. */ private final ListNotification newReplyNotification; + /** The “you have been mentioned” notification. */ + private final ListNotification mentionNotification; + /** The “rescuing Sone” notification. */ private final ListNotification rescuingSonesNotification; @@ -181,6 +196,7 @@ public class WebInterface implements CoreListener { public WebInterface(SonePlugin sonePlugin) { this.sonePlugin = sonePlugin; formPassword = sonePlugin.pluginRespirator().getToadletContainer().getFormPassword(); + soneTextParser = new SoneTextParser(getCore(), getCore()); templateContextFactory = new TemplateContextFactory(); templateContextFactory.addAccessor(Object.class, new ReflectionAccessor()); @@ -189,7 +205,6 @@ public class WebInterface implements CoreListener { templateContextFactory.addAccessor(Post.class, new PostAccessor(getCore())); templateContextFactory.addAccessor(Reply.class, new ReplyAccessor(getCore())); templateContextFactory.addAccessor(Identity.class, new IdentityAccessor(getCore())); - templateContextFactory.addAccessor(NotificationManager.class, new NotificationManagerAccessor()); templateContextFactory.addAccessor(Trust.class, new TrustAccessor()); templateContextFactory.addAccessor(HTTPRequest.class, new HttpRequestAccessor()); templateContextFactory.addFilter("date", new DateFilter()); @@ -203,23 +218,29 @@ public class WebInterface implements CoreListener { templateContextFactory.addFilter("match", new MatchFilter()); templateContextFactory.addFilter("css", new CssClassNameFilter()); templateContextFactory.addFilter("js", new JavascriptFilter()); - templateContextFactory.addFilter("parse", new ParserFilter(getCore(), templateContextFactory)); + templateContextFactory.addFilter("parse", new ParserFilter(getCore(), templateContextFactory, soneTextParser)); templateContextFactory.addFilter("unknown", new UnknownDateFilter(getL10n(), "View.Sone.Text.UnknownDate")); templateContextFactory.addFilter("format", new FormatFilter()); templateContextFactory.addFilter("sort", new CollectionSortFilter()); + templateContextFactory.addFilter("replyGroup", new ReplyGroupFilter()); + templateContextFactory.addFilter("in", new ContainsFilter()); templateContextFactory.addProvider(Provider.TEMPLATE_CONTEXT_PROVIDER); templateContextFactory.addProvider(new ClassPathTemplateProvider()); + templateContextFactory.addTemplateObject("webInterface", this); templateContextFactory.addTemplateObject("formPassword", formPassword); /* create notifications. */ Template newSoneNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/newSoneNotification.html")); - newSoneNotification = new ListNotification("new-sone-notification", "sones", newSoneNotificationTemplate); + newSoneNotification = new ListNotification("new-sone-notification", "sones", newSoneNotificationTemplate, false); Template newPostNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/newPostNotification.html")); - newPostNotification = new ListNotification("new-post-notification", "posts", newPostNotificationTemplate); + newPostNotification = new ListNotification("new-post-notification", "posts", newPostNotificationTemplate, false); Template newReplyNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/newReplyNotification.html")); - newReplyNotification = new ListNotification("new-replies-notification", "replies", newReplyNotificationTemplate); + newReplyNotification = new ListNotification("new-reply-notification", "replies", newReplyNotificationTemplate, false); + + Template mentionNotificationTemplate = TemplateParser.parse(createReader("/templates/notify/mentionNotification.html")); + mentionNotification = new ListNotification("mention-notification", "posts", mentionNotificationTemplate, false); Template rescuingSonesTemplate = TemplateParser.parse(createReader("/templates/notify/rescuingSonesNotification.html")); rescuingSonesNotification = new ListNotification("sones-being-rescued-notification", "sones", rescuingSonesTemplate); @@ -541,6 +562,7 @@ public class WebInterface implements CoreListener { Template openSearchTemplate = TemplateParser.parse(createReader("/templates/xml/OpenSearch.xml")); 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 CreateSonePage(createSoneTemplate, this), "CreateSone")); pageToadlets.add(pageToadletFactory.createPageToadlet(new KnownSonesPage(knownSonesTemplate, this), "KnownSones")); @@ -581,11 +603,13 @@ public class WebInterface implements CoreListener { pageToadlets.add(pageToadletFactory.createPageToadlet(new TemplatePage("OpenSearch.xml", "application/opensearchdescription+xml", templateContextFactory, openSearchTemplate))); pageToadlets.add(pageToadletFactory.createPageToadlet(new GetTranslationPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new GetStatusAjaxPage(this))); + pageToadlets.add(pageToadletFactory.createPageToadlet(new GetNotificationAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new DismissNotificationAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new CreatePostAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new CreateReplyAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new GetReplyAjaxPage(this, replyTemplate))); pageToadlets.add(pageToadletFactory.createPageToadlet(new GetPostAjaxPage(this, postTemplate))); + pageToadlets.add(pageToadletFactory.createPageToadlet(new GetTimesAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new MarkAsKnownAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new DeletePostAjaxPage(this))); pageToadlets.add(pageToadletFactory.createPageToadlet(new DeleteReplyAjaxPage(this))); @@ -640,11 +664,34 @@ public class WebInterface implements CoreListener { try { return new InputStreamReader(getClass().getResourceAsStream(resourceName), "UTF-8"); } catch (UnsupportedEncodingException uee1) { - System.out.println(" fail."); return null; } } + /** + * Returns all {@link Core#isLocalSone(Sone) local Sone}s that are + * referenced by {@link SonePart}s in the given text (after parsing it using + * {@link SoneTextParser}). + * + * @param text + * The text to parse + * @return All mentioned local Sones + */ + private Set 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()); + } + } + } catch (IOException ioe1) { + logger.log(Level.WARNING, "Could not parse post text: " + text, ioe1); + } + return Filters.filteredSet(mentionedSones, Sone.LOCAL_SONE_FILTER); + } + // // CORELISTENER METHODS // @@ -687,6 +734,10 @@ public class WebInterface implements CoreListener { newPostNotification.add(post); if (!hasFirstStartNotification()) { notificationManager.addNotification(newPostNotification); + if (!getMentionedSones(post.getText()).isEmpty()) { + mentionNotification.add(post); + notificationManager.addNotification(mentionNotification); + } } else { getCore().markPostKnown(post); } @@ -703,6 +754,10 @@ public class WebInterface implements CoreListener { newReplyNotification.add(reply); if (!hasFirstStartNotification()) { notificationManager.addNotification(newReplyNotification); + if (!getMentionedSones(reply.getText()).isEmpty()) { + mentionNotification.add(reply.getPost()); + notificationManager.addNotification(mentionNotification); + } } else { getCore().markReplyKnown(reply); } @@ -722,6 +777,7 @@ public class WebInterface implements CoreListener { @Override public void markPostKnown(Post post) { newPostNotification.remove(post); + mentionNotification.remove(post); } /** @@ -730,6 +786,15 @@ public class WebInterface implements CoreListener { @Override public void markReplyKnown(Reply reply) { newReplyNotification.remove(reply); + mentionNotification.remove(reply.getPost()); + } + + /** + * {@inheritDoc} + */ + @Override + public void soneRemoved(Sone sone) { + newSoneNotification.remove(sone); } /**