Merge branch 'release-0.7.4' 0.7.4
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Mon, 21 Nov 2011 18:10:53 +0000 (19:10 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Mon, 21 Nov 2011 18:10:53 +0000 (19:10 +0100)
pom.xml
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/data/Album.java
src/main/java/net/pterodactylus/sone/fcp/GetPostFeedCommand.java
src/main/java/net/pterodactylus/sone/main/SonePlugin.java
src/main/java/net/pterodactylus/sone/web/ImageBrowserPage.java
src/main/java/net/pterodactylus/sone/web/KnownSonesPage.java
src/main/resources/i18n/sone.en.properties
src/main/resources/templates/imageBrowser.html
src/main/resources/templates/knownSones.html

diff --git a/pom.xml b/pom.xml
index a0a267d..3afca0e 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -2,12 +2,12 @@
        <modelVersion>4.0.0</modelVersion>
        <groupId>net.pterodactylus</groupId>
        <artifactId>sone</artifactId>
-       <version>0.7.3</version>
+       <version>0.7.4</version>
        <dependencies>
                <dependency>
                        <groupId>net.pterodactylus</groupId>
                        <artifactId>utils</artifactId>
-                       <version>0.11.2</version>
+                       <version>0.11.3</version>
                </dependency>
                <dependency>
                        <groupId>junit</groupId>
index d3f50a1..81c5185 100644 (file)
@@ -509,17 +509,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         *
         * @param id
         *            The ID of the remote Sone to get
-        * @return The Sone with the given ID
-        */
-       public Sone getRemoteSone(String id) {
-               return getRemoteSone(id, true);
-       }
-
-       /**
-        * Returns the remote Sone with the given ID.
-        *
-        * @param id
-        *            The ID of the remote Sone to get
         * @param create
         *            {@code true} to always create a Sone, {@code false} to return
         *            {@code null} if no Sone with the given ID exists
@@ -528,7 +517,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
        public Sone getRemoteSone(String id, boolean create) {
                synchronized (remoteSones) {
                        Sone sone = remoteSones.get(id);
-                       if ((sone == null) && create) {
+                       if ((sone == null) && create && (id != null) && (id.length() == 43)) {
                                sone = new Sone(id);
                                remoteSones.put(id, sone);
                                setSoneStatus(sone, SoneStatus.unknown);
@@ -956,29 +945,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
        }
 
        /**
-        * Adds a local Sone from the given ID which has to be the ID of an own
-        * identity.
-        *
-        * @param id
-        *            The ID of an own identity to add a Sone for
-        * @return The added (or already existing) Sone
-        */
-       public Sone addLocalSone(String id) {
-               synchronized (localSones) {
-                       if (localSones.containsKey(id)) {
-                               logger.log(Level.FINE, "Tried to add known local Sone: %s", id);
-                               return localSones.get(id);
-                       }
-                       OwnIdentity ownIdentity = identityManager.getOwnIdentity(id);
-                       if (ownIdentity == null) {
-                               logger.log(Level.INFO, "Invalid Sone ID: %s", id);
-                               return null;
-                       }
-                       return addLocalSone(ownIdentity);
-               }
-       }
-
-       /**
         * Adds a local Sone from the given own identity.
         *
         * @param ownIdentity
@@ -1050,7 +1016,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                        return null;
                }
                synchronized (remoteSones) {
-                       final Sone sone = getRemoteSone(identity.getId()).setIdentity(identity);
+                       final Sone sone = getRemoteSone(identity.getId(), true).setIdentity(identity);
                        boolean newSone = sone.getRequestUri() == null;
                        sone.setRequestUri(getSoneUri(identity.getRequestUri()));
                        sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), (long) 0));
@@ -1095,6 +1061,11 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
         */
        public void followSone(Sone sone, String soneId) {
                Validation.begin().isNotNull("Sone", sone).isNotNull("Sone ID", soneId).check();
+               Sone followedSone = getSone(soneId, true);
+               if (followedSone == null) {
+                       logger.log(Level.INFO, String.format("Ignored Sone with invalid ID: %s", soneId));
+                       return;
+               }
                followSone(sone, getSone(soneId));
        }
 
@@ -2443,8 +2414,13 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                                break;
                        }
                        long time = configuration.getLongValue("SoneFollowingTimes/" + soneCounter + "/Time").getValue(Long.MAX_VALUE);
-                       synchronized (soneFollowingTimes) {
-                               soneFollowingTimes.put(getSone(soneId), time);
+                       Sone followedSone = getSone(soneId);
+                       if (followedSone == null) {
+                               logger.log(Level.WARNING, String.format("Ignoring Sone with invalid ID: %s", soneId));
+                       } else {
+                               synchronized (soneFollowingTimes) {
+                                       soneFollowingTimes.put(getSone(soneId), time);
+                               }
                        }
                        ++soneCounter;
                }
@@ -2564,7 +2540,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis
                        @Override
                        @SuppressWarnings("synthetic-access")
                        public void run() {
-                               Sone sone = getRemoteSone(identity.getId());
+                               Sone sone = getRemoteSone(identity.getId(), false);
                                sone.setIdentity(identity);
                                sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), sone.getLatestEdition()));
                                soneDownloader.addSone(sone);
index b15bc00..0bdf3a9 100644 (file)
@@ -18,6 +18,7 @@
 package net.pterodactylus.sone.data;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -35,6 +36,15 @@ import net.pterodactylus.util.validation.Validation;
  */
 public class Album implements Fingerprintable {
 
+       /** Compares two {@link Album}s by {@link #getTitle()}. */
+       public static final Comparator<Album> TITLE_COMPARATOR = new Comparator<Album>() {
+
+               @Override
+               public int compare(Album leftAlbum, Album rightAlbum) {
+                       return leftAlbum.getTitle().compareToIgnoreCase(rightAlbum.getTitle());
+               }
+       };
+
        /** The ID of this album. */
        private final String id;
 
index d4b175c..4c07359 100644 (file)
@@ -64,7 +64,7 @@ public class GetPostFeedCommand extends AbstractSoneCommand {
                        if (!getCore().hasSone(friendSoneId)) {
                                continue;
                        }
-                       allPosts.addAll(getCore().getSone(friendSoneId).getPosts());
+                       allPosts.addAll(getCore().getSone(friendSoneId, false).getPosts());
                }
                allPosts.addAll(getCore().getDirectedPosts(sone));
                allPosts = Filters.filteredSet(allPosts, Post.FUTURE_POSTS_FILTER);
index b35c556..5e52b0e 100644 (file)
@@ -83,7 +83,7 @@ public class SonePlugin implements FredPlugin, FredPluginFCP, FredPluginL10n, Fr
        }
 
        /** The version. */
-       public static final Version VERSION = new Version(0, 7, 3);
+       public static final Version VERSION = new Version(0, 7, 4);
 
        /** The logger. */
        private static final Logger logger = Logging.getLogger(SonePlugin.class);
index 406a762..5bb75d1 100644 (file)
@@ -18,8 +18,9 @@
 package net.pterodactylus.sone.web;
 
 import java.net.URI;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 import net.pterodactylus.sone.data.Album;
 import net.pterodactylus.sone.data.Image;
@@ -81,10 +82,11 @@ public class ImageBrowserPage extends SoneTemplatePage {
                String mode = request.getHttpRequest().getParam("mode", null);
                if ("gallery".equals(mode)) {
                        templateContext.set("galleryRequested", true);
-                       Set<Album> albums = new HashSet<Album>();
+                       List<Album> albums = new ArrayList<Album>();
                        for (Sone sone : webInterface.getCore().getSones()) {
                                albums.addAll(sone.getAllAlbums());
                        }
+                       Collections.sort(albums, Album.TITLE_COMPARATOR);
                        templateContext.set("albums", albums);
                        return;
                }
index 0e27265..6ed5667 100644 (file)
@@ -62,13 +62,13 @@ public class KnownSonesPage extends SoneTemplatePage {
                super.processTemplate(request, templateContext);
                String sortField = request.getHttpRequest().getParam("sort");
                String sortOrder = request.getHttpRequest().getParam("order");
-               String followedSones = request.getHttpRequest().getParam("followedSones");
+               String filter = request.getHttpRequest().getParam("filter");
                templateContext.set("sort", (sortField != null) ? sortField : "name");
                templateContext.set("order", (sortOrder != null) ? sortOrder : "asc");
-               templateContext.set("followedSones", followedSones);
+               templateContext.set("filter", filter);
                final Sone currentSone = getCurrentSone(request.getToadletContext(), false);
                List<Sone> knownSones = Filters.filteredList(new ArrayList<Sone>(webInterface.getCore().getSones()), Sone.EMPTY_SONE_FILTER);
-               if ((currentSone != null) && "show-only".equals(followedSones)) {
+               if ((currentSone != null) && "followed".equals(filter)) {
                        knownSones = Filters.filteredList(knownSones, new Filter<Sone>() {
 
                                @Override
@@ -76,7 +76,7 @@ public class KnownSonesPage extends SoneTemplatePage {
                                        return currentSone.hasFriend(sone.getId());
                                }
                        });
-               } else if ((currentSone != null) && "hide".equals(followedSones)) {
+               } else if ((currentSone != null) && "not-followed".equals(filter)) {
                        knownSones = Filters.filteredList(knownSones, new Filter<Sone>() {
 
                                @Override
@@ -84,6 +84,26 @@ public class KnownSonesPage extends SoneTemplatePage {
                                        return !currentSone.hasFriend(sone.getId());
                                }
                        });
+               } else if ("new".equals(filter)) {
+                       knownSones = Filters.filteredList(knownSones, new Filter<Sone>() {
+                               /**
+                                * {@inheritDoc}
+                                */
+                               @Override
+                               public boolean filterObject(Sone sone) {
+                                       return webInterface.getCore().isNewSone(sone.getId());
+                               }
+                       });
+               } else if ("not-new".equals(filter)) {
+                       knownSones = Filters.filteredList(knownSones, new Filter<Sone>() {
+                               /**
+                                * {@inheritDoc}
+                                */
+                               @Override
+                               public boolean filterObject(Sone sone) {
+                                       return !webInterface.getCore().isNewSone(sone.getId());
+                               }
+                       });
                }
                if ("activity".equals(sortField)) {
                        if ("asc".equals(sortOrder)) {
index afc445a..3bb04b7 100644 (file)
@@ -89,17 +89,19 @@ Page.Index.PostList.Text.NoPostYet=Nobody has written any posts yet. You should
 
 Page.KnownSones.Title=Known Sones - Sone
 Page.KnownSones.Page.Title=Known Sones
-Page.KnownSones.Text.NoKnownSones=There are currently no known Sones.
+Page.KnownSones.Text.NoKnownSones=There are currently no known Sones that match the given filter.
 Page.KnownSones.Label.Sort=Sort:
-Page.KnownSones.Label.FollowedSones=Followed Sones:
+Page.KnownSones.Label.FilterSones=Filter Sones:
 Page.KnownSones.Sort.Field.Name=Name
 Page.KnownSones.Sort.Field.LastActivity=Last activity
 Page.KnownSones.Sort.Field.Posts=Number of posts
 Page.KnownSones.Sort.Field.Images=Number of images
 Page.KnownSones.Sort.Order.Ascending=Ascending
 Page.KnownSones.Sort.Order.Descending=Descending
-Page.KnownSones.FollowedSones.ShowOnly=Show only followed Sones
-Page.KnownSones.FollowedSones.Hide=Hide followed Sones
+Page.KnownSones.Filter.Followed=Show only followed Sones
+Page.KnownSones.Filter.NotFollowed=Hide followed Sones
+Page.KnownSones.Filter.New=Show only new Sones
+Page.KnownSones.Filter.NotNew=Hide new Sones
 Page.KnownSones.Button.Apply=Apply
 Page.KnownSones.Button.FollowAllSones=Follow all Sones on this page
 Page.KnownSones.Button.UnfollowAllSones=Unfollow all Sones on this page
index 58ed8ab..55705e1 100644 (file)
                        <div class="backlinks">
                                <div class="backlink"><a href="imageBrowser.html?mode=gallery"><%= Page.ImageBrowser.Link.All|l10n|html></a></div>
                                <div class="separator">&gt;</div>
-                               <div class="backlink"><a href="imageBrowser.html?sone=<%sone.id|html>"><%sone.niceName|l10n|html></a></div>
+                               <div class="backlink"><a href="imageBrowser.html?sone=<%sone.id|html>"><%sone.niceName|html></a></div>
                        </div>
 
                        <%include include/browseAlbums.html albums=sone.albums>
index 7b42d53..afd40df 100644 (file)
                        </div>
                        <%ifnull !currentSone>
                                <div>
-                                       <%= Page.KnownSones.Label.FollowedSones|l10n|html>
-                                       <select name="followedSones">
+                                       <%= Page.KnownSones.Label.FilterSones|l10n|html>
+                                       <select name="filter">
                                                <option value="none"></option>
-                                               <option value="show-only"<%if followedSones|match value="show-only"> selected="selected"<%/if>><%= Page.KnownSones.FollowedSones.ShowOnly|l10n|html></option>
-                                               <option value="hide"<%if followedSones|match value="hide"> selected="selected"<%/if>><%= Page.KnownSones.FollowedSones.Hide|l10n|html></option>
+                                               <%ifnull !currentSone>
+                                                       <option value="followed"<%if filter|match value="followed"> selected="selected"<%/if>><%= Page.KnownSones.Filter.Followed|l10n|html></option>
+                                                       <option value="not-followed"<%if filter|match value="not-followed"> selected="selected"<%/if>><%= Page.KnownSones.Filter.NotFollowed|l10n|html></option>
+                                               <%/if>
+                                               <option value="new"<%if filter|match value="new"> selected="selected"<%/if>><%= Page.KnownSones.Filter.New|l10n|html></option>
+                                               <option value="not-new"<%if filter|match value="not-new"> selected="selected"<%/if>><%= Page.KnownSones.Filter.NotNew|l10n|html></option>
                                        </select>
                                </div>
                        <%/if>
                </form>
        </div>
 
-       <div>
-               <form action="followSone.html" method="post">
-                       <input type="hidden" name="formPassword" value="<%formPassword|html>" />
-                       <input type="hidden" name="returnPage" value="<%request.uri|html>" />
-                       <input type="hidden" name="sone" value="<%foreach pagination.items sone><%if !sone.friend><%if !sone.current><%sone.id> <%/if><%/if><%/foreach>" />
-                       <button type="submit"><%= Page.KnownSones.Button.FollowAllSones|l10n|html></button>
-               </form>
-       </div>
+       <%if !pagination.items.empty>
+               <div>
+                       <form action="followSone.html" method="post">
+                               <input type="hidden" name="formPassword" value="<%formPassword|html>" />
+                               <input type="hidden" name="returnPage" value="<%request.uri|html>" />
+                               <input type="hidden" name="sone" value="<%foreach pagination.items sone><%if !sone.friend><%if !sone.current><%sone.id> <%/if><%/if><%/foreach>" />
+                               <button type="submit"><%= Page.KnownSones.Button.FollowAllSones|l10n|html></button>
+                       </form>
+               </div>
 
-       <div>
-               <form action="unfollowSone.html" method="post">
-                       <input type="hidden" name="formPassword" value="<%formPassword|html>" />
-                       <input type="hidden" name="returnPage" value="<%request.uri|html>" />
-                       <input type="hidden" name="sone" value="<%foreach pagination.items sone><%if sone.friend><%sone.id> <%/if><%/foreach>" />
-                       <button type="submit"><%= Page.KnownSones.Button.UnfollowAllSones|l10n|html></button>
-               </form>
-       </div>
+               <div>
+                       <form action="unfollowSone.html" method="post">
+                               <input type="hidden" name="formPassword" value="<%formPassword|html>" />
+                               <input type="hidden" name="returnPage" value="<%request.uri|html>" />
+                               <input type="hidden" name="sone" value="<%foreach pagination.items sone><%if sone.friend><%sone.id> <%/if><%/foreach>" />
+                               <button type="submit"><%= Page.KnownSones.Button.UnfollowAllSones|l10n|html></button>
+                       </form>
+               </div>
+       <%/if>
 
        <div id="known-sones">
                <%= page|store key=pageParameter>