+ public SessionManager getSessionManager() {
+ return sonePlugin.pluginRespirator().getSessionManager("Sone");
+ }
+
+ /**
+ * Returns the node’s form password.
+ *
+ * @return The form password
+ */
+ public String getFormPassword() {
+ return formPassword;
+ }
+
+ /**
+ * Returns the posts that have been announced as new in the
+ * {@link #newPostNotification}.
+ *
+ * @return The new posts
+ */
+ public Set<Post> getNewPosts() {
+ return ImmutableSet.<Post> builder().addAll(newPostNotification.getElements()).addAll(localPostNotification.getElements()).build();
+ }
+
+ @Nonnull
+ public Collection<Post> getNewPosts(@Nullable Sone currentSone) {
+ Set<Post> allNewPosts = ImmutableSet.<Post> 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}.
+ *
+ * @return The new replies
+ */
+ public Set<PostReply> getNewReplies() {
+ return ImmutableSet.<PostReply> builder().addAll(newReplyNotification.getElements()).addAll(localReplyNotification.getElements()).build();
+ }
+
+ @Nonnull
+ public Collection<PostReply> getNewReplies(@Nullable Sone currentSone) {
+ Set<PostReply> allNewReplies = ImmutableSet.<PostReply>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.
+ *
+ * @param firstStart
+ * {@code true} if no configuration file existed when Sone was
+ * loaded, {@code false} otherwise
+ */
+ public void setFirstStart(boolean firstStart) {
+ if (firstStart) {
+ Template firstStartNotificationTemplate = loaders.loadTemplate("/templates/notify/firstStartNotification.html");
+ Notification firstStartNotification = new TemplateNotification("first-start-notification", firstStartNotificationTemplate);
+ notificationManager.addNotification(firstStartNotification);
+ }
+ }
+
+ /**
+ * Sets whether Sone was started with a fresh configuration file.
+ *
+ * @param newConfig
+ * {@code true} if Sone was started with a fresh configuration,
+ * {@code false} if the existing configuration could be read
+ */
+ public void setNewConfig(boolean newConfig) {
+ if (newConfig && !hasFirstStartNotification()) {
+ Template configNotReadNotificationTemplate = loaders.loadTemplate("/templates/notify/configNotReadNotification.html");
+ Notification configNotReadNotification = new TemplateNotification("config-not-read-notification", configNotReadNotificationTemplate);
+ notificationManager.addNotification(configNotReadNotification);
+ }
+ }
+
+ //
+ // PRIVATE ACCESSORS
+ //
+
+ /**
+ * Returns whether the first start notification is currently displayed.
+ *
+ * @return {@code true} if the first-start notification is currently
+ * displayed, {@code false} otherwise
+ */
+ private boolean hasFirstStartNotification() {
+ return notificationManager.getNotification("first-start-notification") != null;
+ }
+
+ //
+ // ACTIONS
+ //
+
+ /**
+ * Starts the web interface and registers all toadlets.
+ */
+ public void start() {
+ registerToadlets();
+
+ /* notification templates. */
+ Template startupNotificationTemplate = loaders.loadTemplate("/templates/notify/startupNotification.html");
+
+ final TemplateNotification startupNotification = new TemplateNotification("startup-notification", startupNotificationTemplate);
+ notificationManager.addNotification(startupNotification);
+
+ ticker.schedule(new Runnable() {
+
+ @Override
+ public void run() {
+ startupNotification.dismiss();
+ }
+ }, 2, TimeUnit.MINUTES);
+
+ Template wotMissingNotificationTemplate = loaders.loadTemplate("/templates/notify/wotMissingNotification.html");
+ final TemplateNotification wotMissingNotification = new TemplateNotification("wot-missing-notification", wotMissingNotificationTemplate);
+ ticker.scheduleAtFixedRate(new Runnable() {
+
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() {
+ if (getCore().getIdentityManager().isConnected()) {
+ wotMissingNotification.dismiss();
+ } else {
+ notificationManager.addNotification(wotMissingNotification);
+ }
+ }
+
+ }, 15, 15, TimeUnit.SECONDS);
+ }
+
+ /**
+ * Stops the web interface and unregisters all toadlets.
+ */
+ public void stop() {
+ pageToadletRegistry.unregisterToadlets();
+ ticker.shutdownNow();
+ }
+
+ //
+ // PRIVATE METHODS
+ //
+
+ /**
+ * Register all toadlets.
+ */
+ private void registerToadlets() {
+ Template emptyTemplate = parse(new StringReader(""));
+ Template loginTemplate = loaders.loadTemplate("/templates/login.html");
+ Template indexTemplate = loaders.loadTemplate("/templates/index.html");
+ Template newTemplate = loaders.loadTemplate("/templates/new.html");
+ Template knownSonesTemplate = loaders.loadTemplate("/templates/knownSones.html");
+ Template createSoneTemplate = loaders.loadTemplate("/templates/createSone.html");
+ Template createPostTemplate = loaders.loadTemplate("/templates/createPost.html");
+ Template createReplyTemplate = loaders.loadTemplate("/templates/createReply.html");
+ Template bookmarksTemplate = loaders.loadTemplate("/templates/bookmarks.html");
+ Template searchTemplate = loaders.loadTemplate("/templates/search.html");
+ Template editProfileTemplate = loaders.loadTemplate("/templates/editProfile.html");
+ Template editProfileFieldTemplate = loaders.loadTemplate("/templates/editProfileField.html");
+ Template deleteProfileFieldTemplate = loaders.loadTemplate("/templates/deleteProfileField.html");
+ Template viewSoneTemplate = loaders.loadTemplate("/templates/viewSone.html");
+ Template viewPostTemplate = loaders.loadTemplate("/templates/viewPost.html");
+ Template deletePostTemplate = loaders.loadTemplate("/templates/deletePost.html");
+ Template deleteReplyTemplate = loaders.loadTemplate("/templates/deleteReply.html");
+ Template deleteSoneTemplate = loaders.loadTemplate("/templates/deleteSone.html");
+ Template imageBrowserTemplate = loaders.loadTemplate("/templates/imageBrowser.html");
+ Template createAlbumTemplate = loaders.loadTemplate("/templates/createAlbum.html");
+ Template deleteAlbumTemplate = loaders.loadTemplate("/templates/deleteAlbum.html");
+ Template deleteImageTemplate = loaders.loadTemplate("/templates/deleteImage.html");
+ Template noPermissionTemplate = loaders.loadTemplate("/templates/noPermission.html");
+ Template emptyImageTitleTemplate = loaders.loadTemplate("/templates/emptyImageTitle.html");
+ Template emptyAlbumTitleTemplate = loaders.loadTemplate("/templates/emptyAlbumTitle.html");
+ Template optionsTemplate = loaders.loadTemplate("/templates/options.html");
+ Template rescueTemplate = loaders.loadTemplate("/templates/rescue.html");
+ Template aboutTemplate = loaders.loadTemplate("/templates/about.html");
+ Template invalidTemplate = loaders.loadTemplate("/templates/invalid.html");
+ Template postTemplate = loaders.loadTemplate("/templates/include/viewPost.html");
+ Template replyTemplate = loaders.loadTemplate("/templates/include/viewReply.html");
+ Template openSearchTemplate = loaders.loadTemplate("/templates/xml/OpenSearch.xml");
+
+ pageToadletRegistry.addPage(new RedirectPage<FreenetRequest>("", "index.html"));
+ pageToadletRegistry.addPage(new IndexPage(indexTemplate, this, loaders, postVisibilityFilter));
+ pageToadletRegistry.addPage(new NewPage(newTemplate, this, loaders));
+ pageToadletRegistry.addPage(new CreateSonePage(createSoneTemplate, this, loaders));
+ pageToadletRegistry.addPage(new KnownSonesPage(knownSonesTemplate, this, loaders));
+ pageToadletRegistry.addPage(new EditProfilePage(editProfileTemplate, this, loaders));
+ pageToadletRegistry.addPage(new EditProfileFieldPage(editProfileFieldTemplate, this, loaders));
+ pageToadletRegistry.addPage(new DeleteProfileFieldPage(deleteProfileFieldTemplate, this, loaders));
+ pageToadletRegistry.addPage(new CreatePostPage(createPostTemplate, this, loaders));
+ pageToadletRegistry.addPage(new CreateReplyPage(createReplyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new ViewSonePage(viewSoneTemplate, this, loaders));
+ pageToadletRegistry.addPage(new ViewPostPage(viewPostTemplate, this, loaders));
+ pageToadletRegistry.addPage(new LikePage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new UnlikePage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new DeletePostPage(deletePostTemplate, this, loaders));
+ pageToadletRegistry.addPage(new DeleteReplyPage(deleteReplyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new LockSonePage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new UnlockSonePage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new FollowSonePage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new UnfollowSonePage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new ImageBrowserPage(imageBrowserTemplate, this, loaders));
+ pageToadletRegistry.addPage(new CreateAlbumPage(createAlbumTemplate, this, loaders));
+ pageToadletRegistry.addPage(new EditAlbumPage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new DeleteAlbumPage(deleteAlbumTemplate, this, loaders));
+ pageToadletRegistry.addPage(new UploadImagePage(invalidTemplate, this, loaders));
+ pageToadletRegistry.addPage(new EditImagePage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new DeleteImagePage(deleteImageTemplate, this, loaders));
+ pageToadletRegistry.addPage(new TrustPage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new DistrustPage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new UntrustPage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new MarkAsKnownPage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new BookmarkPage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new UnbookmarkPage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new BookmarksPage(bookmarksTemplate, this, loaders));
+ pageToadletRegistry.addPage(new SearchPage(searchTemplate, this, loaders));
+ pageToadletRegistry.addPage(new DeleteSonePage(deleteSoneTemplate, this, loaders));
+ pageToadletRegistry.addPage(new LoginPage(loginTemplate, this, loaders));
+ pageToadletRegistry.addPage(new LogoutPage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new OptionsPage(optionsTemplate, this, loaders));
+ pageToadletRegistry.addPage(new RescuePage(rescueTemplate, this, loaders));
+ pageToadletRegistry.addPage(new AboutPage(aboutTemplate, this, loaders, new PluginVersion(SonePlugin.getPluginVersion()), new PluginYear(sonePlugin.getYear()), new PluginHomepage(sonePlugin.getHomepage())));
+ pageToadletRegistry.addPage(new SoneTemplatePage("noPermission.html", this, loaders, noPermissionTemplate, "Page.NoPermission.Title"));
+ pageToadletRegistry.addPage(new SoneTemplatePage("emptyImageTitle.html", this, loaders, emptyImageTitleTemplate, "Page.EmptyImageTitle.Title"));
+ pageToadletRegistry.addPage(new SoneTemplatePage("emptyAlbumTitle.html", this, loaders, emptyAlbumTitleTemplate, "Page.EmptyAlbumTitle.Title"));
+ pageToadletRegistry.addPage(new DismissNotificationPage(emptyTemplate, this, loaders));
+ pageToadletRegistry.addPage(new SoneTemplatePage("invalid.html", this, loaders, invalidTemplate, "Page.Invalid.Title"));
+ pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("css/", "/static/css/", "text/css"));
+ pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("javascript/", "/static/javascript/", "text/javascript"));
+ pageToadletRegistry.addPage(loaders.<FreenetRequest>loadStaticPage("images/", "/static/images/", "image/png"));
+ pageToadletRegistry.addPage(new TemplatePage<FreenetRequest>("OpenSearch.xml", "application/opensearchdescription+xml", templateContextFactory, openSearchTemplate));
+ pageToadletRegistry.addPage(new GetImagePage(this));
+ pageToadletRegistry.addPage(new GetTranslationAjaxPage(this));
+ pageToadletRegistry.addPage(new GetStatusAjaxPage(this, elementLoader, timeTextConverter, l10nFilter, TimeZone.getDefault()));
+ pageToadletRegistry.addPage(new GetNotificationsAjaxPage(this));
+ pageToadletRegistry.addPage(new DismissNotificationAjaxPage(this));
+ pageToadletRegistry.addPage(new CreatePostAjaxPage(this));
+ pageToadletRegistry.addPage(new CreateReplyAjaxPage(this));
+ pageToadletRegistry.addPage(new GetReplyAjaxPage(this, replyTemplate));
+ pageToadletRegistry.addPage(new GetPostAjaxPage(this, postTemplate));
+ pageToadletRegistry.addPage(new GetLinkedElementAjaxPage(this, elementLoader, linkedElementRenderFilter));
+ pageToadletRegistry.addPage(new GetTimesAjaxPage(this, timeTextConverter, l10nFilter, TimeZone.getDefault()));
+ pageToadletRegistry.addPage(new MarkAsKnownAjaxPage(this));
+ pageToadletRegistry.addPage(new DeletePostAjaxPage(this));
+ pageToadletRegistry.addPage(new DeleteReplyAjaxPage(this));
+ pageToadletRegistry.addPage(new LockSoneAjaxPage(this));
+ pageToadletRegistry.addPage(new UnlockSoneAjaxPage(this));
+ pageToadletRegistry.addPage(new FollowSoneAjaxPage(this));
+ pageToadletRegistry.addPage(new UnfollowSoneAjaxPage(this));
+ pageToadletRegistry.addPage(new EditAlbumAjaxPage(this));
+ pageToadletRegistry.addPage(new EditImageAjaxPage(this, parserFilter, shortenFilter, renderFilter));
+ pageToadletRegistry.addPage(new TrustAjaxPage(this));
+ pageToadletRegistry.addPage(new DistrustAjaxPage(this));
+ pageToadletRegistry.addPage(new UntrustAjaxPage(this));
+ pageToadletRegistry.addPage(new LikeAjaxPage(this));
+ pageToadletRegistry.addPage(new UnlikeAjaxPage(this));
+ pageToadletRegistry.addPage(new GetLikesAjaxPage(this));
+ pageToadletRegistry.addPage(new BookmarkAjaxPage(this));
+ pageToadletRegistry.addPage(new UnbookmarkAjaxPage(this));
+ pageToadletRegistry.addPage(new EditProfileFieldAjaxPage(this));
+ pageToadletRegistry.addPage(new DeleteProfileFieldAjaxPage(this));
+ pageToadletRegistry.addPage(new MoveProfileFieldAjaxPage(this));
+
+ pageToadletRegistry.registerToadlets();
+ }
+
+ /**
+ * Returns all {@link Sone#isLocal() 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 Collection<Sone> getMentionedSones(String text) {
+ /* we need no context to find mentioned Sones. */
+ Set<Sone> mentionedSones = new HashSet<>();
+ for (Part part : soneTextParser.parse(text, null)) {
+ if (part instanceof SonePart) {
+ mentionedSones.add(((SonePart) part).getSone());
+ }
+ }
+ return Collections2.filter(mentionedSones, Sone.LOCAL_SONE_FILTER);
+ }
+
+ /**
+ * Returns the Sone insert notification for the given Sone. If no
+ * notification for the given Sone exists, a new notification is created and
+ * cached.
+ *
+ * @param sone
+ * The Sone to get the insert notification for
+ * @return The Sone insert notification
+ */
+ private TemplateNotification getSoneInsertNotification(Sone sone) {
+ synchronized (soneInsertNotifications) {
+ TemplateNotification templateNotification = soneInsertNotifications.get(sone);
+ if (templateNotification == null) {
+ templateNotification = new TemplateNotification(loaders.loadTemplate("/templates/notify/soneInsertNotification.html"));
+ templateNotification.set("insertSone", sone);
+ soneInsertNotifications.put(sone, templateNotification);
+ }
+ return templateNotification;
+ }
+ }
+
+ private boolean localSoneMentionedInNewPostOrReply(Post post) {
+ if (!post.getSone().isLocal()) {
+ if (!getMentionedSones(post.getText()).isEmpty() && !post.isKnown()) {
+ return true;
+ }
+ }
+ for (PostReply postReply : getCore().getReplies(post.getId())) {
+ if (postReply.getSone().isLocal()) {
+ continue;
+ }
+ if (!getMentionedSones(postReply.getText()).isEmpty() && !postReply.isKnown()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //
+ // EVENT HANDLERS
+ //
+
+ /**
+ * Notifies the web interface that a new {@link Sone} was found.
+ *
+ * @param newSoneFoundEvent
+ * The event
+ */
+ @Subscribe
+ public void newSoneFound(NewSoneFoundEvent newSoneFoundEvent) {
+ newSoneNotification.add(newSoneFoundEvent.sone());
+ if (!hasFirstStartNotification()) {
+ notificationManager.addNotification(newSoneNotification);
+ }
+ }
+
+ /**
+ * Notifies the web interface that a new {@link Post} was found.
+ *
+ * @param newPostFoundEvent
+ * The event
+ */
+ @Subscribe
+ public void newPostFound(NewPostFoundEvent newPostFoundEvent) {
+ Post post = newPostFoundEvent.post();
+ boolean isLocal = post.getSone().isLocal();
+ if (isLocal) {
+ localPostNotification.add(post);
+ } else {
+ newPostNotification.add(post);
+ }
+ if (!hasFirstStartNotification()) {
+ notificationManager.addNotification(isLocal ? localPostNotification : newPostNotification);
+ if (!getMentionedSones(post.getText()).isEmpty() && !isLocal) {
+ mentionNotification.add(post);
+ notificationManager.addNotification(mentionNotification);
+ }
+ } else {
+ getCore().markPostKnown(post);
+ }
+ }
+
+ /**
+ * Notifies the web interface that a new {@link PostReply} was found.
+ *
+ * @param newPostReplyFoundEvent
+ * The event
+ */
+ @Subscribe
+ public void newReplyFound(NewPostReplyFoundEvent newPostReplyFoundEvent) {
+ PostReply reply = newPostReplyFoundEvent.postReply();
+ boolean isLocal = reply.getSone().isLocal();
+ if (isLocal) {
+ localReplyNotification.add(reply);
+ } else {
+ newReplyNotification.add(reply);
+ }
+ if (!hasFirstStartNotification()) {
+ notificationManager.addNotification(isLocal ? localReplyNotification : newReplyNotification);
+ if (reply.getPost().isPresent() && localSoneMentionedInNewPostOrReply(reply.getPost().get())) {
+ mentionNotification.add(reply.getPost().get());
+ notificationManager.addNotification(mentionNotification);
+ }
+ } else {
+ getCore().markReplyKnown(reply);
+ }
+ }
+
+ /**
+ * Notifies the web interface that a {@link Sone} was marked as known.
+ *
+ * @param markSoneKnownEvent
+ * The event
+ */
+ @Subscribe
+ public void markSoneKnown(MarkSoneKnownEvent markSoneKnownEvent) {
+ newSoneNotification.remove(markSoneKnownEvent.sone());
+ }
+
+ @Subscribe
+ public void markPostKnown(MarkPostKnownEvent markPostKnownEvent) {
+ removePost(markPostKnownEvent.post());
+ }
+
+ @Subscribe
+ public void markReplyKnown(MarkPostReplyKnownEvent markPostReplyKnownEvent) {
+ removeReply(markPostReplyKnownEvent.postReply());
+ }
+
+ @Subscribe
+ public void soneRemoved(SoneRemovedEvent soneRemovedEvent) {
+ newSoneNotification.remove(soneRemovedEvent.sone());
+ }
+
+ @Subscribe
+ public void postRemoved(PostRemovedEvent postRemovedEvent) {
+ removePost(postRemovedEvent.post());
+ }
+
+ private void removePost(Post post) {
+ newPostNotification.remove(post);
+ localPostNotification.remove(post);
+ if (!localSoneMentionedInNewPostOrReply(post)) {
+ mentionNotification.remove(post);
+ }
+ }
+
+ @Subscribe
+ public void replyRemoved(PostReplyRemovedEvent postReplyRemovedEvent) {
+ removeReply(postReplyRemovedEvent.postReply());
+ }
+
+ private void removeReply(PostReply reply) {
+ newReplyNotification.remove(reply);
+ localReplyNotification.remove(reply);
+ if (reply.getPost().isPresent() && !localSoneMentionedInNewPostOrReply(reply.getPost().get())) {
+ mentionNotification.remove(reply.getPost().get());
+ }
+ }
+
+ /**
+ * Notifies the web interface that a Sone was locked.
+ *
+ * @param soneLockedEvent
+ * The event
+ */
+ @Subscribe
+ public void soneLocked(SoneLockedEvent soneLockedEvent) {
+ final Sone sone = soneLockedEvent.sone();
+ ScheduledFuture<?> tickerObject = ticker.schedule(new Runnable() {
+
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public void run() {
+ lockedSonesNotification.add(sone);
+ notificationManager.addNotification(lockedSonesNotification);
+ }
+ }, 5, TimeUnit.MINUTES);
+ lockedSonesTickerObjects.put(sone, tickerObject);
+ }
+
+ /**
+ * Notifies the web interface that a Sone was unlocked.
+ *
+ * @param soneUnlockedEvent
+ * The event
+ */
+ @Subscribe
+ public void soneUnlocked(SoneUnlockedEvent soneUnlockedEvent) {
+ lockedSonesNotification.remove(soneUnlockedEvent.sone());
+ lockedSonesTickerObjects.remove(soneUnlockedEvent.sone()).cancel(false);
+ }
+
+ /**
+ * Notifies the web interface that a {@link Sone} is being inserted.
+ *
+ * @param soneInsertingEvent
+ * The event
+ */
+ @Subscribe
+ public void soneInserting(SoneInsertingEvent soneInsertingEvent) {
+ TemplateNotification soneInsertNotification = getSoneInsertNotification(soneInsertingEvent.sone());
+ soneInsertNotification.set("soneStatus", "inserting");
+ if (soneInsertingEvent.sone().getOptions().isSoneInsertNotificationEnabled()) {
+ notificationManager.addNotification(soneInsertNotification);
+ }
+ }
+
+ /**
+ * Notifies the web interface that a {@link Sone} was inserted.
+ *
+ * @param soneInsertedEvent
+ * The event
+ */
+ @Subscribe
+ public void soneInserted(SoneInsertedEvent soneInsertedEvent) {
+ TemplateNotification soneInsertNotification = getSoneInsertNotification(soneInsertedEvent.sone());
+ soneInsertNotification.set("soneStatus", "inserted");
+ soneInsertNotification.set("insertDuration", soneInsertedEvent.insertDuration() / 1000);
+ if (soneInsertedEvent.sone().getOptions().isSoneInsertNotificationEnabled()) {
+ notificationManager.addNotification(soneInsertNotification);
+ }
+ }
+
+ /**
+ * Notifies the web interface that a {@link Sone} insert was aborted.
+ *
+ * @param soneInsertAbortedEvent
+ * The event
+ */
+ @Subscribe
+ public void soneInsertAborted(SoneInsertAbortedEvent soneInsertAbortedEvent) {
+ TemplateNotification soneInsertNotification = getSoneInsertNotification(soneInsertAbortedEvent.sone());
+ soneInsertNotification.set("soneStatus", "insert-aborted");
+ soneInsertNotification.set("insert-error", soneInsertAbortedEvent.cause());
+ if (soneInsertAbortedEvent.sone().getOptions().isSoneInsertNotificationEnabled()) {
+ notificationManager.addNotification(soneInsertNotification);
+ }
+ }
+
+ /**
+ * Notifies the web interface that a new Sone version was found.
+ *
+ * @param updateFoundEvent
+ * The event
+ */
+ @Subscribe
+ public void updateFound(UpdateFoundEvent updateFoundEvent) {
+ newVersionNotification.set("latestVersion", updateFoundEvent.version());
+ newVersionNotification.set("latestEdition", updateFoundEvent.latestEdition());
+ newVersionNotification.set("releaseTime", updateFoundEvent.releaseTime());
+ newVersionNotification.set("disruptive", updateFoundEvent.disruptive());
+ notificationManager.addNotification(newVersionNotification);
+ }
+
+ /**
+ * Notifies the web interface that an image insert was started
+ *
+ * @param imageInsertStartedEvent
+ * The event
+ */
+ @Subscribe
+ public void imageInsertStarted(ImageInsertStartedEvent imageInsertStartedEvent) {
+ insertingImagesNotification.add(imageInsertStartedEvent.image());
+ notificationManager.addNotification(insertingImagesNotification);
+ }
+
+ /**
+ * Notifies the web interface that an {@link Image} insert was aborted.
+ *
+ * @param imageInsertAbortedEvent
+ * The event
+ */
+ @Subscribe
+ public void imageInsertAborted(ImageInsertAbortedEvent imageInsertAbortedEvent) {
+ insertingImagesNotification.remove(imageInsertAbortedEvent.image());
+ }
+
+ /**
+ * Notifies the web interface that an {@link Image} insert is finished.
+ *
+ * @param imageInsertFinishedEvent
+ * The event
+ */
+ @Subscribe
+ public void imageInsertFinished(ImageInsertFinishedEvent imageInsertFinishedEvent) {
+ insertingImagesNotification.remove(imageInsertFinishedEvent.image());
+ insertedImagesNotification.add(imageInsertFinishedEvent.image());
+ notificationManager.addNotification(insertedImagesNotification);
+ }
+
+ /**
+ * Notifies the web interface that an {@link Image} insert has failed.
+ *
+ * @param imageInsertFailedEvent
+ * The event
+ */
+ @Subscribe
+ public void imageInsertFailed(ImageInsertFailedEvent imageInsertFailedEvent) {
+ insertingImagesNotification.remove(imageInsertFailedEvent.image());
+ imageInsertFailedNotification.add(imageInsertFailedEvent.image());
+ notificationManager.addNotification(imageInsertFailedNotification);