<modelVersion>4.0.0</modelVersion>
<groupId>net.pterodactylus</groupId>
<artifactId>sone</artifactId>
- <version>0.8.5</version>
+ <version>0.8.6</version>
<dependencies>
<dependency>
<groupId>net.pterodactylus</groupId>
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
-import com.google.common.collect.Collections2;
import com.google.common.collect.FluentIterable;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
private final Set<String> bookmarkedPosts = new HashSet<String>();
/** Trusted identities, sorted by own identities. */
- private final Map<OwnIdentity, Set<Identity>> trustedIdentities = Collections.synchronizedMap(new HashMap<OwnIdentity, Set<Identity>>());
+ private final Multimap<OwnIdentity, Identity> trustedIdentities = Multimaps.synchronizedSetMultimap(HashMultimap.<OwnIdentity, Identity>create());
/** All known albums. */
private final Map<String, Album> albums = new HashMap<String, Album>();
@Override
public Collection<Sone> getSones() {
synchronized (sones) {
- return Collections.unmodifiableCollection(sones.values());
+ return ImmutableSet.copyOf(sones.values());
}
}
@Override
public Collection<Sone> getLocalSones() {
synchronized (sones) {
- return Collections2.filter(sones.values(), new Predicate<Sone>() {
+ return FluentIterable.from(sones.values()).filter(new Predicate<Sone>() {
@Override
public boolean apply(Sone sone) {
return sone.isLocal();
}
- });
+ }).toSet();
}
}
@Override
public Collection<Sone> getRemoteSones() {
synchronized (sones) {
- return Collections2.filter(sones.values(), new Predicate<Sone>() {
+ return FluentIterable.from(sones.values()).filter(new Predicate<Sone>() {
@Override
public boolean apply(Sone sone) {
return !sone.isLocal();
}
- });
+ }).toSet();
}
}
checkNotNull(origin, "origin must not be null");
checkNotNull(target, "target must not be null");
checkArgument(origin.getIdentity() instanceof OwnIdentity, "origin’s identity must be an OwnIdentity");
- return trustedIdentities.containsKey(origin.getIdentity()) && trustedIdentities.get(origin.getIdentity()).contains(target.getIdentity());
+ return trustedIdentities.containsEntry(origin.getIdentity(), target.getIdentity());
}
/**
synchronized (bookmarkedPosts) {
for (String bookmarkedPostId : bookmarkedPosts) {
Optional<Post> post = getPost(bookmarkedPostId);
- if (!post.isPresent()) {
+ if (post.isPresent()) {
posts.add(post.get());
}
}
logger.log(Level.WARNING, "Given OwnIdentity is null!");
return null;
}
+ logger.info(String.format("Adding Sone from OwnIdentity: %s", ownIdentity));
synchronized (sones) {
final Sone sone;
try {
sone.setClient(new Client("Sone", SonePlugin.VERSION.toString()));
sone.setKnown(true);
/* TODO - load posts ’n stuff */
- trustedIdentities.put(ownIdentity, Collections.synchronizedSet(new HashSet<Identity>()));
sones.put(ownIdentity.getId(), sone);
final SoneInserter soneInserter = new SoneInserter(this, eventBus, freenetInterface, sone);
soneInserters.put(sone, soneInserter);
return null;
}
synchronized (sones) {
- final Sone sone = getRemoteSone(identity.getId(), true).setIdentity(identity);
+ final Sone sone = getRemoteSone(identity.getId(), true);
+ if (sone.isLocal()) {
+ return sone;
+ }
+ sone.setIdentity(identity);
boolean newSone = sone.getRequestUri() == null;
sone.setRequestUri(SoneUri.create(identity.getRequestUri()));
sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), (long) 0));
}
synchronized (sones) {
sone.setOptions(storedSone.get().getOptions());
+ sone.setKnown(storedSone.get().isKnown());
sones.put(sone.getId(), sone);
}
}
logger.log(Level.FINE, String.format("Tried to load non-local Sone: %s", sone));
return;
}
+ logger.info(String.format("Loading local Sone: %s", sone));
/* initialize options. */
sone.getOptions().addBooleanOption("AutoFollow", new DefaultOption<Boolean>(false));
for (PostReply reply : replies) {
reply.setKnown(true);
}
+
+ logger.info(String.format("Sone loaded successfully: %s", sone));
}
/**
public void ownIdentityRemoved(OwnIdentityRemovedEvent ownIdentityRemovedEvent) {
OwnIdentity ownIdentity = ownIdentityRemovedEvent.ownIdentity();
logger.log(Level.FINEST, String.format("Removing OwnIdentity: %s", ownIdentity));
- trustedIdentities.remove(ownIdentity);
+ trustedIdentities.removeAll(ownIdentity);
}
/**
public void identityAdded(IdentityAddedEvent identityAddedEvent) {
Identity identity = identityAddedEvent.identity();
logger.log(Level.FINEST, String.format("Adding Identity: %s", identity));
- trustedIdentities.get(identityAddedEvent.ownIdentity()).add(identity);
+ trustedIdentities.put(identityAddedEvent.ownIdentity(), identity);
addRemoteSone(identity);
}
@SuppressWarnings("synthetic-access")
public void run() {
Sone sone = getRemoteSone(identity.getId(), false);
+ if (sone.isLocal()) {
+ return;
+ }
sone.setIdentity(identity);
sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), sone.getLatestEdition()));
soneDownloader.addSone(sone);
public void identityRemoved(IdentityRemovedEvent identityRemovedEvent) {
OwnIdentity ownIdentity = identityRemovedEvent.ownIdentity();
Identity identity = identityRemovedEvent.identity();
- trustedIdentities.get(ownIdentity).remove(identity);
+ trustedIdentities.remove(ownIdentity, identity);
boolean foundIdentity = false;
- for (Entry<OwnIdentity, Set<Identity>> trustedIdentity : trustedIdentities.entrySet()) {
+ for (Entry<OwnIdentity, Collection<Identity>> trustedIdentity : trustedIdentities.asMap().entrySet()) {
if (trustedIdentity.getKey().equals(ownIdentity)) {
continue;
}
* The Sone to add
*/
public void addSone(Sone sone) {
- if (sones.add(sone)) {
- freenetInterface.registerUsk(sone, this);
+ if (!sones.add(sone)) {
+ freenetInterface.unregisterUsk(sone);
}
+ freenetInterface.registerUsk(sone, this);
}
/**
private static final String SONE_HOMEPAGE = "USK@nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI,DuQSUZiI~agF8c-6tjsFFGuZ8eICrzWCILB60nT8KKo,AQACAAE/sone/";
/** The current latest known edition. */
- private static final int LATEST_EDITION = 56;
+ private static final int LATEST_EDITION = 58;
/** The event bus. */
private final EventBus eventBus;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import static java.util.Arrays.asList;
import java.util.ArrayList;
import java.util.Comparator;
import com.google.common.base.Function;
import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.FluentIterable;
}
};
+ /**
+ * Filter that removes all albums that do not have any images in any album
+ * below it.
+ */
+ public static final Predicate<Album> NOT_EMPTY = new Predicate<Album>() {
+
+ @Override
+ public boolean apply(Album album) {
+ return FluentIterable.from(asList(album)).transformAndConcat(FLATTENER).anyMatch(new Predicate<Album>() {
+
+ @Override
+ public boolean apply(Album album) {
+ return !album.getImages().isEmpty();
+ }
+ });
+ }
+ };
+
/** The ID of this album. */
private final String id;
boolean identitiesLoaded = false;
try {
/* get all identities with the wanted context from WoT. */
+ logger.finer("Getting all Own Identities from WoT...");
ownIdentities = webOfTrustConnector.loadAllOwnIdentities();
+ logger.finest(String.format("Loaded %d Own Identities.", ownIdentities.size()));
/* load trusted identities. */
for (OwnIdentity ownIdentity : ownIdentities) {
}
/* load trusted identities. */
+ logger.finer(String.format("Getting trusted identities for %s...", ownIdentity.getId()));
Set<Identity> trustedIdentities = webOfTrustConnector.loadTrustedIdentities(ownIdentity, context);
+ logger.finest(String.format("Got %d trusted identities.", trustedIdentities.size()));
for (Identity identity : trustedIdentities) {
identities.put(identity.getId(), identity);
}
/* find new identities. */
for (Identity currentIdentity : currentIdentities.get(ownIdentity).values()) {
if (!oldIdentities.containsKey(ownIdentity) || !oldIdentities.get(ownIdentity).containsKey(currentIdentity.getId())) {
+ logger.finest(String.format("Identity added for %s: %s", ownIdentity.getId(), currentIdentity));
eventBus.post(new IdentityAddedEvent(ownIdentity, currentIdentity));
}
}
if (oldIdentities.containsKey(ownIdentity)) {
for (Identity oldIdentity : oldIdentities.get(ownIdentity).values()) {
if (!currentIdentities.get(ownIdentity).containsKey(oldIdentity.getId())) {
+ logger.finest(String.format("Identity removed for %s: %s", ownIdentity.getId(), oldIdentity));
eventBus.post(new IdentityRemovedEvent(ownIdentity, oldIdentity));
}
}
Set<String> oldContexts = oldIdentity.getContexts();
Set<String> newContexts = newIdentity.getContexts();
if (oldContexts.size() != newContexts.size()) {
+ logger.finest(String.format("Contexts changed for %s: was: %s, is now: %s", ownIdentity.getId(), oldContexts, newContexts));
eventBus.post(new IdentityUpdatedEvent(ownIdentity, newIdentity));
continue;
}
for (String oldContext : oldContexts) {
if (!newContexts.contains(oldContext)) {
+ logger.finest(String.format("Context was removed for %s: %s", ownIdentity.getId(), oldContext));
eventBus.post(new IdentityUpdatedEvent(ownIdentity, newIdentity));
break;
}
Map<String, String> oldProperties = oldIdentity.getProperties();
Map<String, String> newProperties = newIdentity.getProperties();
if (oldProperties.size() != newProperties.size()) {
+ logger.finest(String.format("Properties changed for %s: was: %s, is now: %s", ownIdentity.getId(), oldProperties, newProperties));
eventBus.post(new IdentityUpdatedEvent(ownIdentity, newIdentity));
continue;
}
for (Entry<String, String> oldProperty : oldProperties.entrySet()) {
if (!newProperties.containsKey(oldProperty.getKey()) || !newProperties.get(oldProperty.getKey()).equals(oldProperty.getValue())) {
+ logger.finest(String.format("Property was removed for %s: %s", ownIdentity.getId(), oldProperty));
eventBus.post(new IdentityUpdatedEvent(ownIdentity, newIdentity));
break;
}
for (OwnIdentity oldOwnIdentity : currentOwnIdentities.values()) {
OwnIdentity newOwnIdentity = newOwnIdentities.get(oldOwnIdentity.getId());
if ((newOwnIdentity == null) || ((context != null) && oldOwnIdentity.hasContext(context) && !newOwnIdentity.hasContext(context))) {
+ logger.finest(String.format("Own Identity removed: %s", oldOwnIdentity));
eventBus.post(new OwnIdentityRemovedEvent(new DefaultOwnIdentity(oldOwnIdentity)));
}
}
for (OwnIdentity currentOwnIdentity : newOwnIdentities.values()) {
OwnIdentity oldOwnIdentity = currentOwnIdentities.get(currentOwnIdentity.getId());
if (((oldOwnIdentity == null) && ((context == null) || currentOwnIdentity.hasContext(context))) || ((oldOwnIdentity != null) && (context != null) && (!oldOwnIdentity.hasContext(context) && currentOwnIdentity.hasContext(context)))) {
+ logger.finest(String.format("Own Identity added: %s", currentOwnIdentity));
eventBus.post(new OwnIdentityAddedEvent(new DefaultOwnIdentity(currentOwnIdentity)));
}
}
}
/** The version. */
- public static final Version VERSION = new Version(0, 8, 5);
+ public static final Version VERSION = new Version(0, 8, 6);
/** The logger. */
private static final Logger logger = Logging.getLogger(SonePlugin.class);
int cutOffLength = Numbers.safeParseInteger(parameters.get("cut-off-length"), Numbers.safeParseInteger(templateContext.get(String.valueOf(parameters.get("cut-off-length"))), length));
Object sone = parameters.get("sone");
if (sone instanceof String) {
- sone = core.getSone((String) sone);
+ sone = core.getSone((String) sone).orNull();
}
FreenetRequest request = (FreenetRequest) templateContext.get("request");
SoneTextParserContext context = new SoneTextParserContext(request, (Sone) sone);
package net.pterodactylus.sone.web;
+import static net.pterodactylus.sone.data.Album.FLATTENER;
+import static net.pterodactylus.sone.data.Album.NOT_EMPTY;
+import static net.pterodactylus.sone.data.Album.TITLE_COMPARATOR;
+
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
templateContext.set("galleryRequested", true);
List<Album> albums = new ArrayList<Album>();
for (Sone sone : webInterface.getCore().getSones()) {
- albums.addAll(FluentIterable.from(sone.getAlbums()).transformAndConcat(Album.FLATTENER).toList());
+ albums.addAll(FluentIterable.from(sone.getAlbums()).transformAndConcat(FLATTENER).filter(NOT_EMPTY).toList());
}
- Collections.sort(albums, Album.TITLE_COMPARATOR);
+ Collections.sort(albums, TITLE_COMPARATOR);
Pagination<Album> albumPagination = new Pagination<Album>(albums, 12).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("page"), 0));
templateContext.set("albumPagination", albumPagination);
templateContext.set("albums", albumPagination.getItems());
<%last><%= true|store key==endRow><%/last>
<%if endRow>
</div>
- <%include include/pagination.html pageParameter=="page">
<%/if>
+ <%last><%include include/pagination.html pageParameter=="page"><%/last>
<%/foreach>
<%if album.sone.local>