<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>
*
* @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
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);
}
/**
- * 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
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));
*/
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));
}
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;
}
@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);
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;
*/
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;
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);
}
/** 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);
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;
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;
}
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
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
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)) {
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
<div class="backlinks">
<div class="backlink"><a href="imageBrowser.html?mode=gallery"><%= Page.ImageBrowser.Link.All|l10n|html></a></div>
<div class="separator">></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>
</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>