Don’t set insert URI of a Sone, let it be generated from the identity.
[Sone.git] / src / main / java / net / pterodactylus / sone / core / SoneDownloaderImpl.java
index ca47132..1521eaf 100644 (file)
 
 package net.pterodactylus.sone.core;
 
+import static java.lang.String.format;
+import static java.lang.System.currentTimeMillis;
+import static java.util.concurrent.TimeUnit.DAYS;
+
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -46,9 +53,15 @@ import net.pterodactylus.util.xml.SimpleXML;
 import net.pterodactylus.util.xml.XML;
 
 import freenet.client.FetchResult;
+import freenet.client.async.ClientContext;
+import freenet.client.async.USKCallback;
 import freenet.keys.FreenetURI;
+import freenet.keys.USK;
+import freenet.node.RequestStarter;
 import freenet.support.api.Bucket;
 
+import com.db4o.ObjectContainer;
+
 import com.google.common.annotations.VisibleForTesting;
 import org.w3c.dom.Document;
 
@@ -99,22 +112,53 @@ public class SoneDownloaderImpl extends AbstractService implements SoneDownloade
         *              The Sone to add
         */
        @Override
-       public void addSone(Sone sone) {
+       public void addSone(final Sone sone) {
                if (!sones.add(sone)) {
                        freenetInterface.unregisterUsk(sone);
                }
-               freenetInterface.registerUsk(sone, this);
+               final USKCallback uskCallback = new USKCallback() {
+
+                       @Override
+                       @SuppressWarnings("synthetic-access")
+                       public void onFoundEdition(long edition, USK key,
+                                       ObjectContainer objectContainer,
+                                       ClientContext clientContext, boolean metadata,
+                                       short codec, byte[] data, boolean newKnownGood,
+                                       boolean newSlotToo) {
+                               logger.log(Level.FINE, format(
+                                               "Found USK update for Sone “%s” at %s, new known good: %s, new slot too: %s.",
+                                               sone, key, newKnownGood, newSlotToo));
+                               if (edition > sone.getLatestEdition()) {
+                                       sone.setLatestEdition(edition);
+                                       new Thread(fetchSoneAction(sone),
+                                                       "Sone Downloader").start();
+                               }
+                       }
+
+                       @Override
+                       public short getPollingPriorityProgress() {
+                               return RequestStarter.INTERACTIVE_PRIORITY_CLASS;
+                       }
+
+                       @Override
+                       public short getPollingPriorityNormal() {
+                               return RequestStarter.INTERACTIVE_PRIORITY_CLASS;
+                       }
+               };
+               if (soneHasBeenActiveRecently(sone)) {
+                       freenetInterface.registerActiveUsk(sone.getRequestUri(),
+                                       uskCallback);
+               } else {
+                       freenetInterface.registerPassiveUsk(sone.getRequestUri(),
+                                       uskCallback);
+               }
        }
 
-       /**
-        * Fetches the updated Sone. This method is a callback method for
-        * {@link FreenetInterface#registerUsk(Sone, SoneDownloader)}.
-        *
-        * @param sone
-        *              The Sone to fetch
-        */
-       @Override
-       public void fetchSone(Sone sone) {
+       private boolean soneHasBeenActiveRecently(Sone sone) {
+               return (currentTimeMillis() - sone.getTime()) < DAYS.toMillis(7);
+       }
+
+       private void fetchSone(Sone sone) {
                fetchSone(sone, sone.getRequestUri().sskForUSK());
        }
 
@@ -302,10 +346,6 @@ public class SoneDownloaderImpl extends AbstractService implements SoneDownloade
                        }
                }
 
-               if (originalSone.getInsertUri() != null) {
-                       sone.setInsertUri(originalSone.getInsertUri());
-               }
-
                SimpleXML profileXml = soneXml.getNode("profile");
                if (profileXml == null) {
                        /* TODO - mark Sone as bad. */
@@ -435,6 +475,7 @@ public class SoneDownloaderImpl extends AbstractService implements SoneDownloade
 
                /* parse albums. */
                SimpleXML albumsXml = soneXml.getNode("albums");
+               Map<String, Image> allImages = new HashMap<String, Image>();
                List<Album> topLevelAlbums = new ArrayList<Album>();
                if (albumsXml != null) {
                        for (SimpleXML albumXml : albumsXml.getNodes("album")) {
@@ -449,13 +490,20 @@ public class SoneDownloaderImpl extends AbstractService implements SoneDownloade
                                }
                                Album parent = null;
                                if (parentId != null) {
-                                       parent = core.getAlbum(parentId, false);
+                                       parent = core.getAlbum(parentId);
                                        if (parent == null) {
                                                logger.log(Level.WARNING, String.format("Downloaded Sone %s has album with invalid parent!", sone));
                                                return null;
                                        }
                                }
-                               Album album = core.getOrCreateAlbum(id).setSone(sone).modify().setTitle(title).setDescription(description).update();
+                               Album album = core.albumBuilder()
+                                               .withId(id)
+                                               .by(sone)
+                                               .build()
+                                               .modify()
+                                               .setTitle(title)
+                                               .setDescription(description)
+                                               .update();
                                if (parent != null) {
                                        parent.addAlbum(album);
                                } else {
@@ -482,10 +530,11 @@ public class SoneDownloaderImpl extends AbstractService implements SoneDownloade
                                                        logger.log(Level.WARNING, String.format("Downloaded Sone %s contains image %s with invalid dimensions (%s, %s)!", sone, imageId, imageWidthString, imageHeightString));
                                                        return null;
                                                }
-                                               Image image = core.getImage(imageId).modify().setSone(sone).setKey(imageKey).setCreationTime(creationTime).update();
+                                               Image image = core.imageBuilder().withId(imageId).build().modify().setSone(sone).setKey(imageKey).setCreationTime(creationTime).update();
                                                image = image.modify().setTitle(imageTitle).setDescription(imageDescription).update();
                                                image = image.modify().setWidth(imageWidth).setHeight(imageHeight).update();
                                                album.addImage(image);
+                                               allImages.put(imageId, image);
                                        }
                                }
                                album.modify().setAlbumImage(albumImageId).update();
@@ -494,7 +543,7 @@ public class SoneDownloaderImpl extends AbstractService implements SoneDownloade
 
                /* process avatar. */
                if (avatarId != null) {
-                       profile.setAvatar(core.getImage(avatarId, false));
+                       profile.setAvatar(allImages.get(avatarId));
                }
 
                /* okay, apparently everything was parsed correctly. Now import. */