import static com.google.common.base.Preconditions.checkNotNull;
import java.net.MalformedURLException;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.eventbus.EventBus;
return posts;
}
- /**
- * Returns the album with the given ID, creating a new album if no album
- * with the given ID can be found.
- *
- * @param albumId
- * The ID of the album
- * @return The album with the given ID
- */
- public Album getAlbum(String albumId) {
- return getAlbum(albumId, true);
- }
-
- /**
- * Returns the album with the given ID, optionally creating a new album if
- * an album with the given ID can not be found.
- *
- * @param albumId
- * The ID of the album
- * @param create
- * {@code true} to create a new album if none exists for the
- * given ID
- * @return The album with the given ID, or {@code null} if no album with the
- * given ID exists and {@code create} is {@code false}
- */
- public Album getAlbum(String albumId, boolean create) {
- Optional<Album> album = database.getAlbum(albumId);
- if (album.isPresent()) {
- return album.get();
- }
- if (!create) {
- return null;
- }
- Album newAlbum = database.newAlbumBuilder().withId(albumId).build();
- database.storeAlbum(newAlbum);
- return newAlbum;
+ public Optional<Album> getAlbum(String albumId) {
+ return database.getAlbum(albumId);
}
public Optional<Image> getImage(String imageId) {
}
/* load albums. */
- List<Album> topLevelAlbums = new ArrayList<Album>();
+ Map<String, Album> albums = Maps.newHashMap();
int albumCounter = 0;
while (true) {
String albumPrefix = sonePrefix + "/Albums/" + albumCounter++;
logger.log(Level.WARNING, "Invalid album found, aborting load!");
return;
}
- Album album = getAlbum(albumId).setSone(sone).modify().setTitle(albumTitle).setDescription(albumDescription).setAlbumImage(albumImageId).update();
+ Album parentAlbum = sone.getRootAlbum();
if (albumParentId != null) {
- Album parentAlbum = getAlbum(albumParentId, false);
- if (parentAlbum == null) {
- logger.log(Level.WARNING, String.format("Invalid parent album ID: %s", albumParentId));
- return;
- }
- parentAlbum.addAlbum(album);
- } else {
- if (!topLevelAlbums.contains(album)) {
- topLevelAlbums.add(album);
- }
+ parentAlbum = albums.get(albumParentId);
}
+ Album album = parentAlbum.newAlbumBuilder().withId(albumId).build().modify().setTitle(albumTitle).setDescription(albumDescription).setAlbumImage(albumImageId).update();
+ albums.put(album.getId(), album);
}
/* load images. */
logger.log(Level.WARNING, "Invalid image found, aborting load!");
return;
}
- Album album = getAlbum(albumId, false);
+ Album album = albums.get(albumId);
if (album == null) {
logger.log(Level.WARNING, "Invalid album image encountered, aborting load!");
return;
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) {
}
/**
- * Creates a new top-level album for the given Sone.
- *
- * @param sone
- * The Sone to create the album for
- * @return The new album
- */
- public Album createAlbum(Sone sone) {
- return createAlbum(sone, sone.getRootAlbum());
- }
-
- /**
- * Creates a new album for the given Sone.
- *
- * @param sone
- * The Sone to create the album for
- * @param parent
- * The parent of the album (may be {@code null} to create a
- * top-level album)
- * @return The new album
- */
- public Album createAlbum(Sone sone, Album parent) {
- Album album = database.newAlbumBuilder().randomId().build();
- database.storeAlbum(album);
- album.setSone(sone);
- parent.addAlbum(album);
- return album;
- }
-
- /**
* Deletes the given album. The owner of the album has to be a local Sone,
* and the album has to be {@link Album#isEmpty() empty} to be deleted.
*
import java.io.InputStream;
import java.net.MalformedURLException;
-import java.util.ArrayList;
import java.util.HashSet;
-import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.pterodactylus.util.xml.SimpleXML;
import net.pterodactylus.util.xml.XML;
-import org.w3c.dom.Document;
-
import freenet.client.FetchResult;
import freenet.keys.FreenetURI;
import freenet.support.api.Bucket;
+import com.google.common.collect.Maps;
+import org.w3c.dom.Document;
+
/**
* The Sone downloader is responsible for download Sones as they are updated.
*
/* parse albums. */
SimpleXML albumsXml = soneXml.getNode("albums");
- List<Album> topLevelAlbums = new ArrayList<Album>();
+ Map<String, Album> albums = Maps.newHashMap();
if (albumsXml != null) {
for (SimpleXML albumXml : albumsXml.getNodes("album")) {
String id = albumXml.getValue("id", null);
logger.log(Level.WARNING, String.format("Downloaded Sone %s contains invalid album!", sone));
return null;
}
- Album parent = null;
+ Album parent = sone.getRootAlbum();
if (parentId != null) {
- parent = core.getAlbum(parentId, false);
+ parent = albums.get(parentId);
if (parent == null) {
logger.log(Level.WARNING, String.format("Downloaded Sone %s has album with invalid parent!", sone));
return null;
}
}
- Album album = core.getAlbum(id).setSone(sone).modify().setTitle(title).setDescription(description).update();
- if (parent != null) {
- parent.addAlbum(album);
- } else {
- topLevelAlbums.add(album);
- }
+ Album album = parent.newAlbumBuilder().withId(id).build().modify().setTitle(title).setDescription(description).update();
+ albums.put(album.getId(), album);
SimpleXML imagesXml = albumXml.getNode("images");
if (imagesXml != null) {
for (SimpleXML imageXml : imagesXml.getNodes("image")) {
sone.setReplies(replies);
sone.setLikePostIds(likedPostIds);
sone.setLikeReplyIds(likedReplyIds);
- for (Album album : topLevelAlbums) {
- sone.getRootAlbum().addAlbum(album);
- }
}
return sone;
import java.util.List;
import javax.annotation.Nonnull;
+import net.pterodactylus.sone.database.AlbumBuilder;
import net.pterodactylus.sone.database.ImageBuilder;
import com.google.common.base.Function;
*/
Sone getSone();
- /**
- * Sets the owner of the album. The owner can only be set as long as the
- * current owner is {@code null}.
- *
- * @param sone
- * The album owner
- * @return This album
- */
- Album setSone(Sone sone);
-
- /**
- * Returns the nested albums.
- *
- * @return The nested albums
- */
List<Album> getAlbums();
/**
- * Adds an album to this album.
- *
- * @param album
- * The album to add
- */
- void addAlbum(Album album);
-
- /**
* Removes an album from this album.
*
* @param album
*/
String getDescription();
+ AlbumBuilder newAlbumBuilder() throws IllegalStateException;
+
ImageBuilder newImageBuilder() throws IllegalStateException;
/**
private final Set<String> likedReplyIds = new CopyOnWriteArraySet<String>();
/** The root album containing all albums. */
- private final Album rootAlbum = new DefaultAlbum().setSone(this);
+ private final Album rootAlbum = new DefaultAlbum(this);
/** Sone-specific options. */
private Options options = new Options();
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 java.util.ArrayList;
import java.util.HashMap;
import net.pterodactylus.sone.data.Album;
import net.pterodactylus.sone.data.Image;
import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.database.AlbumBuilder;
import net.pterodactylus.sone.database.ImageBuilder;
import com.google.common.base.Function;
private Album parent;
/** Creates a new album with a random ID. */
- public DefaultAlbum() {
- this(UUID.randomUUID().toString());
+ public DefaultAlbum(Sone sone) {
+ this(UUID.randomUUID().toString(), sone);
}
/**
* @param id
* The ID of the album
*/
- public DefaultAlbum(String id) {
+ public DefaultAlbum(String id, Sone sone) {
super(id);
+ this.sone = sone;
}
//
}
@Override
- public Album setSone(Sone sone) {
- checkNotNull(sone, "sone must not be null");
- checkState((this.sone == null) || (this.sone.equals(sone)), "album owner must not already be set to some other Sone");
- this.sone = sone;
- return this;
- }
-
- @Override
public List<Album> getAlbums() {
return new ArrayList<Album>(albums);
}
@Override
- 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");
- album.setParent(this);
- if (!albums.contains(album)) {
- albums.add(album);
- }
- }
-
- @Override
public void removeAlbum(Album album) {
checkNotNull(album, "album must not be null");
checkArgument(album.getSone().equals(sone), "album must belong this album’s Sone");
}
@Override
+ public AlbumBuilder newAlbumBuilder() {
+ return new DefaultAlbumBuilder(sone) {
+ @Override
+ public Album build() throws IllegalStateException {
+ Album album = super.build();
+ albums.add(album);
+ return album;
+ }
+ };
+ }
+
+ @Override
public ImageBuilder newImageBuilder() throws IllegalStateException {
return new DefaultImageBuilder(sone, this) {
@Override
package net.pterodactylus.sone.data.impl;
import net.pterodactylus.sone.data.Album;
+import net.pterodactylus.sone.data.Sone;
import net.pterodactylus.sone.database.AlbumBuilder;
/**
*/
public class DefaultAlbumBuilder extends AbstractAlbumBuilder {
+ private final Sone sone;
+
+ public DefaultAlbumBuilder(Sone sone) {
+ this.sone = sone;
+ }
+
@Override
public Album build() throws IllegalStateException {
validate();
- return new DefaultAlbum(getId());
+ return new DefaultAlbum(getId(), sone);
}
}
*
* @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
*/
-public interface AlbumDatabase extends AlbumProvider, AlbumBuilderFactory, AlbumStore {
+public interface AlbumDatabase extends AlbumProvider, AlbumStore {
/* nothing here. */
import net.pterodactylus.sone.data.PostReply;
import net.pterodactylus.sone.data.Reply;
import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.data.impl.DefaultAlbumBuilder;
-import net.pterodactylus.sone.database.AlbumBuilder;
import net.pterodactylus.sone.database.Database;
import net.pterodactylus.sone.database.DatabaseException;
import net.pterodactylus.sone.database.PostBuilder;
}
//
- // ALBUMBUILDERFACTORY METHODS
- //
-
- @Override
- public AlbumBuilder newAlbumBuilder() {
- return new DefaultAlbumBuilder();
- }
-
- //
// ALBUMSTORE METHODS
//
String description = request.getHttpRequest().getPartAsStringFailsafe("description", 256).trim();
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 parent = parentId.equals("") ? currentSone.getRootAlbum() : webInterface.getCore().getAlbum(parentId).get();
+ Album album = parent.newAlbumBuilder().randomId().build();
album.modify().setTitle(name).setDescription(TextFilter.filter(request.getHttpRequest().getHeader("host"), description)).update();
webInterface.getCore().touchConfiguration();
throw new RedirectException("imageBrowser.html?album=" + album.getId());
import net.pterodactylus.util.template.TemplateContext;
import net.pterodactylus.util.web.Method;
+import com.google.common.base.Optional;
+
/**
* Page that lets the user delete an {@link Album}.
*
super.processTemplate(request, templateContext);
if (request.getMethod() == Method.POST) {
String albumId = request.getHttpRequest().getPartAsStringFailsafe("album", 36);
- Album album = webInterface.getCore().getAlbum(albumId, false);
- if (album == null) {
+ Optional<Album> album = webInterface.getCore().getAlbum(albumId);
+ if (!album.isPresent()) {
throw new RedirectException("invalid.html");
}
- if (!album.getSone().isLocal()) {
+ if (!album.get().getSone().isLocal()) {
throw new RedirectException("noPermission.html");
}
if (request.getHttpRequest().isPartSet("abortDelete")) {
- throw new RedirectException("imageBrowser.html?album=" + album.getId());
+ throw new RedirectException("imageBrowser.html?album=" + album.get().getId());
}
- Album parentAlbum = album.getParent();
- webInterface.getCore().deleteAlbum(album);
- if (parentAlbum.equals(album.getSone().getRootAlbum())) {
- throw new RedirectException("imageBrowser.html?sone=" + album.getSone().getId());
+ Album parentAlbum = album.get().getParent();
+ webInterface.getCore().deleteAlbum(album.get());
+ if (parentAlbum.equals(album.get().getSone().getRootAlbum())) {
+ throw new RedirectException("imageBrowser.html?sone=" + album.get().getSone().getId());
}
throw new RedirectException("imageBrowser.html?album=" + parentAlbum.getId());
}
String albumId = request.getHttpRequest().getParam("album");
- Album album = webInterface.getCore().getAlbum(albumId, false);
- if (album == null) {
+ Optional<Album> album = webInterface.getCore().getAlbum(albumId);
+ if (!album.isPresent()) {
throw new RedirectException("invalid.html");
}
templateContext.set("album", album);
import net.pterodactylus.util.template.TemplateContext;
import net.pterodactylus.util.web.Method;
+import com.google.common.base.Optional;
+
/**
* Page that lets the user edit the name and description of an album.
*
super.processTemplate(request, templateContext);
if (request.getMethod() == Method.POST) {
String albumId = request.getHttpRequest().getPartAsStringFailsafe("album", 36);
- Album album = webInterface.getCore().getAlbum(albumId, false);
- if (album == null) {
+ Optional<Album> album = webInterface.getCore().getAlbum(albumId);
+ if (!album.isPresent()) {
throw new RedirectException("invalid.html");
}
- if (!album.getSone().isLocal()) {
+ if (!album.get().getSone().isLocal()) {
throw new RedirectException("noPermission.html");
}
if ("true".equals(request.getHttpRequest().getPartAsStringFailsafe("moveLeft", 4))) {
- album.getParent().moveAlbumUp(album);
+ album.get().getParent().moveAlbumUp(album.get());
webInterface.getCore().touchConfiguration();
- throw new RedirectException("imageBrowser.html?album=" + album.getParent().getId());
+ throw new RedirectException("imageBrowser.html?album=" + album.get().getParent().getId());
} else if ("true".equals(request.getHttpRequest().getPartAsStringFailsafe("moveRight", 4))) {
- album.getParent().moveAlbumDown(album);
+ album.get().getParent().moveAlbumDown(album.get());
webInterface.getCore().touchConfiguration();
- throw new RedirectException("imageBrowser.html?album=" + album.getParent().getId());
+ throw new RedirectException("imageBrowser.html?album=" + album.get().getParent().getId());
}
String albumImageId = request.getHttpRequest().getPartAsStringFailsafe("album-image", 36);
if (!webInterface.getCore().getImage(albumImageId).isPresent()) {
albumImageId = null;
}
- album.modify().setAlbumImage(albumImageId).update();
+ album.get().modify().setAlbumImage(albumImageId).update();
String title = request.getHttpRequest().getPartAsStringFailsafe("title", 100).trim();
if (title.length() == 0) {
templateContext.set("titleMissing", true);
return;
}
String description = request.getHttpRequest().getPartAsStringFailsafe("description", 1000).trim();
- album.modify().setTitle(title).setDescription(TextFilter.filter(request.getHttpRequest().getHeader("host"), description)).update();
+ album.get().modify().setTitle(title).setDescription(TextFilter.filter(request.getHttpRequest().getHeader("host"), description)).update();
webInterface.getCore().touchConfiguration();
- throw new RedirectException("imageBrowser.html?album=" + album.getId());
+ throw new RedirectException("imageBrowser.html?album=" + album.get().getId());
}
}
super.processTemplate(request, templateContext);
String albumId = request.getHttpRequest().getParam("album", null);
if (albumId != null) {
- Album album = webInterface.getCore().getAlbum(albumId, false);
+ Optional<Album> album = webInterface.getCore().getAlbum(albumId);
templateContext.set("albumRequested", true);
- templateContext.set("album", album);
+ templateContext.set("album", album.orNull());
templateContext.set("page", request.getHttpRequest().getParam("page"));
return;
}
*/
private String getAlbumId(String phrase) {
String albumId = phrase.startsWith("album://") ? phrase.substring(8) : phrase;
- return (webInterface.getCore().getAlbum(albumId, false) != null) ? albumId : null;
+ return webInterface.getCore().getAlbum(albumId).isPresent() ? albumId : null;
}
/**
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
-
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import net.pterodactylus.util.template.TemplateContext;
import net.pterodactylus.util.web.Method;
-import com.google.common.io.ByteStreams;
-
import freenet.support.api.Bucket;
import freenet.support.api.HTTPUploadedFile;
+import com.google.common.base.Optional;
+import com.google.common.io.ByteStreams;
+
/**
* Page implementation that lets the user upload an image.
*
if (request.getMethod() == Method.POST) {
Sone currentSone = getCurrentSone(request.getToadletContext());
String parentId = request.getHttpRequest().getPartAsStringFailsafe("parent", 36);
- Album parent = webInterface.getCore().getAlbum(parentId, false);
- if (parent == null) {
+ Optional<Album> parent = webInterface.getCore().getAlbum(parentId);
+ if (!parent.isPresent()) {
/* TODO - signal error */
return;
}
- if (!currentSone.equals(parent.getSone())) {
+ if (!currentSone.equals(parent.get().getSone())) {
/* TODO - signal error. */
return;
}
String mimeType = getMimeType(imageData);
Dimension imageSize = getImageDimensions(uploadedImage);
TemporaryImage temporaryImage = webInterface.getCore().createTemporaryImage(mimeType, imageData, imageSize.width, imageSize.height);
- image = webInterface.getCore().createImage(currentSone, parent, temporaryImage);
+ image = webInterface.getCore().createImage(currentSone, parent.get(), temporaryImage);
image.modify().setTitle(name).setDescription(TextFilter.filter(request.getHttpRequest().getHeader("host"), description)).update();
} catch (IOException ioe1) {
logger.log(Level.WARNING, "Could not read uploaded image!", ioe1);
Closer.close(imageDataInputStream);
Closer.flush(uploadedImage);
}
- throw new RedirectException("imageBrowser.html?album=" + parent.getId());
+ throw new RedirectException("imageBrowser.html?album=" + parent.get().getId());
}
}
import net.pterodactylus.sone.web.WebInterface;
import net.pterodactylus.sone.web.page.FreenetRequest;
+import com.google.common.base.Optional;
+
/**
* Page that stores a user’s album modifications.
*
@Override
protected JsonReturnObject createJsonObject(FreenetRequest request) {
String albumId = request.getHttpRequest().getParam("album");
- Album album = webInterface.getCore().getAlbum(albumId, false);
- if (album == null) {
+ Optional<Album> album = webInterface.getCore().getAlbum(albumId);
+ if (!album.isPresent()) {
return createErrorJsonObject("invalid-album-id");
}
- if (!album.getSone().isLocal()) {
+ if (!album.get().getSone().isLocal()) {
return createErrorJsonObject("not-authorized");
}
if ("true".equals(request.getHttpRequest().getParam("moveLeft"))) {
- Album swappedAlbum = album.getParent().moveAlbumUp(album);
+ Album swappedAlbum = album.get().getParent().moveAlbumUp(album.get());
webInterface.getCore().touchConfiguration();
- return createSuccessJsonObject().put("sourceAlbumId", album.getId()).put("destinationAlbumId", swappedAlbum.getId());
+ return createSuccessJsonObject().put("sourceAlbumId", album.get().getId()).put("destinationAlbumId", swappedAlbum.getId());
}
if ("true".equals(request.getHttpRequest().getParam("moveRight"))) {
- Album swappedAlbum = album.getParent().moveAlbumDown(album);
+ Album swappedAlbum = album.get().getParent().moveAlbumDown(album.get());
webInterface.getCore().touchConfiguration();
- return createSuccessJsonObject().put("sourceAlbumId", album.getId()).put("destinationAlbumId", swappedAlbum.getId());
+ return createSuccessJsonObject().put("sourceAlbumId", album.get().getId()).put("destinationAlbumId", swappedAlbum.getId());
}
String title = request.getHttpRequest().getParam("title").trim();
String description = request.getHttpRequest().getParam("description").trim();
- album.modify().setTitle(title).setDescription(TextFilter.filter(request.getHttpRequest().getHeader("host"), description)).update();
+ album.get().modify().setTitle(title).setDescription(TextFilter.filter(request.getHttpRequest().getHeader("host"), description)).update();
webInterface.getCore().touchConfiguration();
- return createSuccessJsonObject().put("albumId", album.getId()).put("title", album.getTitle()).put("description", album.getDescription());
+ return createSuccessJsonObject().put("albumId", album.get().getId()).put("title", album.get().getTitle()).put("description", album.get().getDescription());
}
}