database.storePostReplies(sone, sone.getReplies());
synchronized (albums) {
synchronized (images) {
- for (Album album : storedSone.get().getAlbums()) {
+ for (Album album : storedSone.get().getRootAlbum().getAlbums()) {
albums.remove(album.getId());
for (Image image : album.getImages()) {
images.remove(image.getId());
}
}
- for (Album album : sone.getAlbums()) {
+ for (Album album : sone.getRootAlbum().getAlbums()) {
albums.put(album.getId(), album);
for (Image image : album.getImages()) {
images.put(image.getId(), image);
for (String friendId : friends) {
followSone(sone, friendId);
}
- sone.setAlbums(topLevelAlbums);
+ for (Album album : sone.getRootAlbum().getAlbums()) {
+ sone.getRootAlbum().removeAlbum(album);
+ }
+ for (Album album : topLevelAlbums) {
+ sone.getRootAlbum().addAlbum(album);
+ }
soneInserters.get(sone).setLastInsertFingerprint(lastInsertFingerprint);
}
synchronized (knownSones) {
* @return The new album
*/
public Album createAlbum(Sone sone) {
- return createAlbum(sone, null);
+ return createAlbum(sone, sone.getRootAlbum());
}
/**
albums.put(album.getId(), album);
}
album.setSone(sone);
- if (parent != null) {
- parent.addAlbum(album);
- } else {
- sone.addAlbum(album);
- }
+ parent.addAlbum(album);
return album;
}
if (!album.isEmpty()) {
return;
}
- if (album.getParent() == null) {
- album.getSone().removeAlbum(album);
- } else {
- album.getParent().removeAlbum(album);
- }
+ album.getParent().removeAlbum(album);
synchronized (albums) {
albums.remove(album.getId());
}
configuration.getStringValue(sonePrefix + "/Friends/" + friendCounter + "/ID").setValue(null);
/* save albums. first, collect in a flat structure, top-level first. */
- List<Album> albums = FluentIterable.from(sone.getAlbums()).transformAndConcat(Album.FLATTENER).toList();
+ List<Album> albums = FluentIterable.from(sone.getRootAlbum().getAlbums()).transformAndConcat(Album.FLATTENER).toList();
int albumCounter = 0;
for (Album album : albums) {
configuration.getStringValue(albumPrefix + "/ID").setValue(album.getId());
configuration.getStringValue(albumPrefix + "/Title").setValue(album.getTitle());
configuration.getStringValue(albumPrefix + "/Description").setValue(album.getDescription());
- configuration.getStringValue(albumPrefix + "/Parent").setValue(album.getParent() == null ? null : album.getParent().getId());
+ configuration.getStringValue(albumPrefix + "/Parent").setValue(album.getParent().equals(sone.getRootAlbum()) ? null : album.getParent().getId());
configuration.getStringValue(albumPrefix + "/AlbumImage").setValue(album.getAlbumImage() == null ? null : album.getAlbumImage().getId());
}
configuration.getStringValue(sonePrefix + "/Albums/" + albumCounter + "/ID").setValue(null);
sone.setReplies(replies);
sone.setLikePostIds(likedPostIds);
sone.setLikeReplyIds(likedReplyIds);
- sone.setAlbums(topLevelAlbums);
+ for (Album album : topLevelAlbums) {
+ sone.getRootAlbum().addAlbum(album);
+ }
}
return sone;
package net.pterodactylus.sone.core;
import static com.google.common.base.Preconditions.checkArgument;
+import static net.pterodactylus.sone.data.Album.NOT_EMPTY;
import java.io.InputStreamReader;
import java.io.StringWriter;
soneProperties.put("replies", Ordering.from(Reply.TIME_COMPARATOR).reverse().sortedCopy(sone.getReplies()));
soneProperties.put("likedPostIds", new HashSet<String>(sone.getLikedPostIds()));
soneProperties.put("likedReplyIds", new HashSet<String>(sone.getLikedReplyIds()));
- soneProperties.put("albums", FluentIterable.from(sone.getAlbums()).transformAndConcat(Album.FLATTENER).toList());
+ soneProperties.put("albums", FluentIterable.from(sone.getRootAlbum().getAlbums()).transformAndConcat(Album.FLATTENER).filter(NOT_EMPTY).toList());
}
//
}
};
+ /** Function that transforms an album into the images it contains. */
+ public static final Function<Album, List<Image>> IMAGES = new Function<Album, List<Image>>() {
+
+ @Override
+ public List<Image> apply(Album album) {
+ return album.getImages();
+ }
+ };
+
/**
* Filter that removes all albums that do not have any images in any album
* below it.
public void addAlbum(Album album) {
checkNotNull(album, "album must not be null");
checkArgument(album.getSone().equals(sone), "album must belong to the same Sone as this album");
- checkState((this.parent == null) || (this.parent.equals(album.parent)), "album must not already be set to some other Sone");
album.setParent(this);
if (!albums.contains(album)) {
albums.add(album);
package net.pterodactylus.sone.data;
import static com.google.common.base.Preconditions.*;
+import static com.google.common.collect.FluentIterable.from;
+import static java.util.Arrays.asList;
+import static net.pterodactylus.sone.data.Album.FLATTENER;
+import static net.pterodactylus.sone.data.Album.IMAGES;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Level;
import java.util.logging.Logger;
import freenet.keys.FreenetURI;
import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
+import com.google.common.primitives.Ints;
/**
* A Sone defines everything about a user: her profile, her status updates, her
*/
@Override
public int compare(Sone leftSone, Sone rightSone) {
- return rightSone.getAllImages().size() - leftSone.getAllImages().size();
+ int rightSoneImageCount = from(asList(rightSone.getRootAlbum())).transformAndConcat(FLATTENER).transformAndConcat(IMAGES).size();
+ int leftSoneImageCount = from(asList(leftSone.getRootAlbum())).transformAndConcat(FLATTENER).transformAndConcat(IMAGES).size();
+ /* sort descending. */
+ return Ints.compare(rightSoneImageCount, leftSoneImageCount);
}
};
@Override
public boolean apply(Sone sone) {
- return !sone.getAlbums().isEmpty();
+ return !sone.getRootAlbum().getAlbums().isEmpty();
}
};
/** The IDs of all liked replies. */
private final Set<String> likedReplyIds = new CopyOnWriteArraySet<String>();
- /** The albums of this Sone. */
- private final List<Album> albums = new CopyOnWriteArrayList<Album>();
+ /** The root album containing all albums. */
+ private final Album rootAlbum = new Album().setSone(this);
/** Sone-specific options. */
private Options options = new Options();
}
/**
- * Returns the albums of this Sone.
+ * Returns the root album that contains all visible albums of this Sone.
*
- * @return The albums of this Sone
+ * @return The root album of this Sone
*/
- public List<Album> getAlbums() {
- return Collections.unmodifiableList(albums);
- }
-
- /**
- * Returns all images of a Sone. Images of a album are inserted into this list
- * before images of all child albums.
- *
- * @return The list of all images
- */
- public List<Image> getAllImages() {
- List<Image> allImages = new ArrayList<Image>();
- for (Album album : FluentIterable.from(getAlbums()).transformAndConcat(Album.FLATTENER).toList()) {
- allImages.addAll(album.getImages());
- }
- return allImages;
- }
-
- /**
- * Adds an album to this Sone.
- *
- * @param album
- * The album to add
- */
- public void addAlbum(Album album) {
- checkNotNull(album, "album must not be null");
- checkArgument(album.getSone().equals(this), "album must belong to this Sone");
- if (!albums.contains(album)) {
- albums.add(album);
- }
- }
-
- /**
- * Sets the albums of this Sone.
- *
- * @param albums
- * The albums of this Sone
- */
- public void setAlbums(Collection<? extends Album> albums) {
- checkNotNull(albums, "albums must not be null");
- this.albums.clear();
- for (Album album : albums) {
- addAlbum(album);
- }
- }
-
- /**
- * Removes an album from this Sone.
- *
- * @param album
- * The album to remove
- */
- public void removeAlbum(Album album) {
- checkNotNull(album, "album must not be null");
- checkArgument(album.getSone().equals(this), "album must belong to this Sone");
- albums.remove(album);
- }
-
- /**
- * Moves the given album up in this album’s albums. If the album is already the
- * first album, nothing happens.
- *
- * @param album
- * The album to move up
- * @return The album that the given album swapped the place with, or
- * <code>null</code> if the album did not change its place
- */
- public Album moveAlbumUp(Album album) {
- checkNotNull(album, "album must not be null");
- checkArgument(album.getSone().equals(this), "album must belong to this Sone");
- checkArgument(album.getParent() == null, "album must not have a parent");
- int oldIndex = albums.indexOf(album);
- if (oldIndex <= 0) {
- return null;
- }
- albums.remove(oldIndex);
- albums.add(oldIndex - 1, album);
- return albums.get(oldIndex);
- }
-
- /**
- * Moves the given album down in this album’s albums. If the album is already
- * the last album, nothing happens.
- *
- * @param album
- * The album to move down
- * @return The album that the given album swapped the place with, or
- * <code>null</code> if the album did not change its place
- */
- public Album moveAlbumDown(Album album) {
- checkNotNull(album, "album must not be null");
- checkArgument(album.getSone().equals(this), "album must belong to this Sone");
- checkArgument(album.getParent() == null, "album must not have a parent");
- int oldIndex = albums.indexOf(album);
- if ((oldIndex < 0) || (oldIndex >= (albums.size() - 1))) {
- return null;
- }
- albums.remove(oldIndex);
- albums.add(oldIndex + 1, album);
- return albums.get(oldIndex);
+ public Album getRootAlbum() {
+ return rootAlbum;
}
/**
if ("backlinks".equals(member)) {
List<Map<String, String>> backlinks = new ArrayList<Map<String, String>>();
Album currentAlbum = album;
- while (currentAlbum != null) {
+ while (!currentAlbum.equals(album.getSone().getRootAlbum())) {
backlinks.add(0, createLink("imageBrowser.html?album=" + currentAlbum.getId(), currentAlbum.getTitle()));
currentAlbum = currentAlbum.getParent();
}
package net.pterodactylus.sone.template;
+import static com.google.common.collect.FluentIterable.from;
+import static java.util.Arrays.asList;
+import static net.pterodactylus.sone.data.Album.FLATTENER;
+import static net.pterodactylus.sone.data.Album.IMAGES;
+
import java.util.logging.Level;
import java.util.logging.Logger;
return new Trust(null, null, null);
}
return trust;
+ } else if (member.equals("allImages")) {
+ return from(asList(sone.getRootAlbum())).transformAndConcat(FLATTENER).transformAndConcat(IMAGES);
}
return super.get(templateContext, object, member);
}
Sone currentSone = getCurrentSone(request.getToadletContext());
String parentId = request.getHttpRequest().getPartAsStringFailsafe("parent", 36);
Album parent = webInterface.getCore().getAlbum(parentId, false);
+ if (parentId.equals("")) {
+ parent = currentSone.getRootAlbum();
+ }
Album album = webInterface.getCore().createAlbum(currentSone, parent);
album.setTitle(name).setDescription(TextFilter.filter(request.getHttpRequest().getHeader("host"), description));
webInterface.getCore().touchConfiguration();
}
Album parentAlbum = album.getParent();
webInterface.getCore().deleteAlbum(album);
- if (parentAlbum == null) {
+ if (parentAlbum.equals(album.getSone().getRootAlbum())) {
throw new RedirectException("imageBrowser.html?sone=" + album.getSone().getId());
}
throw new RedirectException("imageBrowser.html?album=" + parentAlbum.getId());
throw new RedirectException("noPermission.html");
}
if ("true".equals(request.getHttpRequest().getPartAsStringFailsafe("moveLeft", 4))) {
- if (album.getParent() == null) {
- currentSone.moveAlbumUp(album);
- webInterface.getCore().touchConfiguration();
- throw new RedirectException("imageBrowser.html?sone=" + currentSone.getId());
- }
album.getParent().moveAlbumUp(album);
webInterface.getCore().touchConfiguration();
throw new RedirectException("imageBrowser.html?album=" + album.getParent().getId());
} else if ("true".equals(request.getHttpRequest().getPartAsStringFailsafe("moveRight", 4))) {
- if (album.getParent() == null) {
- currentSone.moveAlbumDown(album);
- webInterface.getCore().touchConfiguration();
- throw new RedirectException("imageBrowser.html?sone=" + currentSone.getId());
- }
album.getParent().moveAlbumDown(album);
webInterface.getCore().touchConfiguration();
throw new RedirectException("imageBrowser.html?album=" + album.getParent().getId());
package net.pterodactylus.sone.web;
+import static com.google.common.collect.FluentIterable.from;
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.util.List;
import com.google.common.base.Optional;
-import com.google.common.collect.FluentIterable;
import net.pterodactylus.sone.data.Album;
import net.pterodactylus.sone.data.Image;
templateContext.set("galleryRequested", true);
List<Album> albums = new ArrayList<Album>();
for (Sone sone : webInterface.getCore().getSones()) {
- albums.addAll(FluentIterable.from(sone.getAlbums()).transformAndConcat(FLATTENER).filter(NOT_EMPTY).toList());
+ albums.addAll(from(sone.getRootAlbum().getAlbums()).transformAndConcat(FLATTENER).filter(NOT_EMPTY).toList());
}
Collections.sort(albums, TITLE_COMPARATOR);
Pagination<Album> albumPagination = new Pagination<Album>(albums, 12).setPage(Numbers.safeParseInteger(request.getHttpRequest().getParam("page"), 0));
return createErrorJsonObject("not-authorized");
}
if ("true".equals(request.getHttpRequest().getParam("moveLeft"))) {
- Album swappedAlbum = (album.getParent() != null) ? album.getParent().moveAlbumUp(album) : album.getSone().moveAlbumUp(album);
+ Album swappedAlbum = album.getParent().moveAlbumUp(album);
webInterface.getCore().touchConfiguration();
return createSuccessJsonObject().put("sourceAlbumId", album.getId()).put("destinationAlbumId", swappedAlbum.getId());
}
if ("true".equals(request.getHttpRequest().getParam("moveRight"))) {
- Album swappedAlbum = (album.getParent() != null) ? album.getParent().moveAlbumDown(album) : album.getSone().moveAlbumDown(album);
+ Album swappedAlbum = album.getParent().moveAlbumDown(album);
webInterface.getCore().touchConfiguration();
return createSuccessJsonObject().put("sourceAlbumId", album.getId()).put("destinationAlbumId", swappedAlbum.getId());
}
<div class="backlink"><a href="imageBrowser.html?sone=<%sone.id|html>"><%sone.niceName|html></a></div>
</div>
- <%include include/browseAlbums.html albums=sone.albums>
+ <%include include/browseAlbums.html albums=sone.rootAlbum.albums>
<%if sone.local>
<div class="show-create-album hidden toggle-link"><a class="small-link">» <%= View.CreateAlbum.Title|l10n|html></a></div>