X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FCore.java;h=7ecf0fa4e4b531dffb33eddbeb8bcf64e76cf8ab;hb=3fd7b8594c097f1448fe84f47f579fc9c85aaa25;hp=765b672e05f3a6e95d135d7d67764abaf5c8f4c8;hpb=aa94dcb712392b69cb431d1637e4948688d15791;p=Sone.git diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index 765b672..7ecf0fa 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -49,13 +49,18 @@ import net.pterodactylus.sone.freenet.wot.OwnIdentity; import net.pterodactylus.sone.freenet.wot.Trust; import net.pterodactylus.sone.freenet.wot.WebOfTrustException; import net.pterodactylus.sone.main.SonePlugin; +import net.pterodactylus.util.collection.Pair; import net.pterodactylus.util.config.Configuration; import net.pterodactylus.util.config.ConfigurationException; import net.pterodactylus.util.logging.Logging; import net.pterodactylus.util.number.Numbers; +import net.pterodactylus.util.thread.Ticker; +import net.pterodactylus.util.validation.EqualityValidator; import net.pterodactylus.util.validation.IntegerRangeValidator; +import net.pterodactylus.util.validation.OrValidator; import net.pterodactylus.util.validation.Validation; import net.pterodactylus.util.version.Version; +import freenet.client.FetchResult; import freenet.keys.FreenetURI; /** @@ -63,7 +68,7 @@ import freenet.keys.FreenetURI; * * @author David ‘Bombe’ Roden */ -public class Core implements IdentityListener, UpdateListener { +public class Core implements IdentityListener, UpdateListener, SoneProvider, PostProvider { /** * Enumeration for the possible states of a {@link Sone}. @@ -177,6 +182,9 @@ public class Core implements IdentityListener, UpdateListener { /** Trusted identities, sorted by own identities. */ private Map> trustedIdentities = Collections.synchronizedMap(new HashMap>()); + /** Ticker for threads that mark own elements as known. */ + private Ticker localElementTicker = new Ticker(); + /** * Creates a new core. * @@ -350,6 +358,7 @@ public class Core implements IdentityListener, UpdateListener { * @return The Sone with the given ID, or {@code null} if there is no such * Sone */ + @Override public Sone getSone(String id, boolean create) { if (isLocalSone(id)) { return getLocalSone(id); @@ -572,6 +581,7 @@ public class Core implements IdentityListener, UpdateListener { * exists, {@code false} to return {@code null} * @return The post, or {@code null} if there is no such post */ + @Override public Post getPost(String postId, boolean create) { synchronized (posts) { Post post = posts.get(postId); @@ -867,6 +877,14 @@ public class Core implements IdentityListener, UpdateListener { coreListenerManager.fireRescuingSone(sone); lockSone(sone); long edition = sone.getLatestEdition(); + /* find the latest edition the node knows about. */ + Pair currentUri = freenetInterface.fetchUri(sone.getRequestUri()); + if (currentUri != null) { + long currentEdition = currentUri.getLeft().getEdition(); + if (currentEdition > edition) { + edition = currentEdition; + } + } while (!stopped && (edition >= 0) && preferences.isSoneRescueMode()) { logger.log(Level.FINE, "Downloading edition " + edition + "…"); soneDownloader.fetchSone(sone, sone.getRequestUri().setKeyType("SSK").setDocName("Sone-" + edition)); @@ -933,6 +951,7 @@ public class Core implements IdentityListener, UpdateListener { for (Sone localSone : getLocalSones()) { if (localSone.getOptions().getBooleanOption("AutoFollow").get()) { localSone.addFriend(sone.getId()); + saveSone(localSone); } } } @@ -1489,7 +1508,7 @@ public class Core implements IdentityListener, UpdateListener { logger.log(Level.FINE, "Tried to create post for non-local Sone: %s", sone); return null; } - Post post = new Post(sone, time, text); + final Post post = new Post(sone, time, text); if (recipient != null) { post.setRecipient(recipient); } @@ -1502,6 +1521,16 @@ public class Core implements IdentityListener, UpdateListener { } sone.addPost(post); saveSone(sone); + localElementTicker.registerEvent(System.currentTimeMillis() + 10 * 1000, new Runnable() { + + /** + * {@inheritDoc} + */ + @Override + public void run() { + markPostKnown(post); + } + }, "Mark " + post + " read."); return post; } @@ -1622,7 +1651,7 @@ public class Core implements IdentityListener, UpdateListener { logger.log(Level.FINE, "Tried to create reply for non-local Sone: %s", sone); return null; } - Reply reply = new Reply(sone, post, System.currentTimeMillis(), text); + final Reply reply = new Reply(sone, post, System.currentTimeMillis(), text); synchronized (replies) { replies.put(reply.getId(), reply); } @@ -1632,6 +1661,16 @@ public class Core implements IdentityListener, UpdateListener { } sone.addReply(reply); saveSone(sone); + localElementTicker.registerEvent(System.currentTimeMillis() + 10 * 1000, new Runnable() { + + /** + * {@inheritDoc} + */ + @Override + public void run() { + markReplyKnown(reply); + } + }, "Mark " + reply + " read."); return reply; } @@ -1692,6 +1731,9 @@ public class Core implements IdentityListener, UpdateListener { for (SoneInserter soneInserter : soneInserters.values()) { soneInserter.stop(); } + for (Sone localSone : localSones.values()) { + saveSone(localSone); + } } updateChecker.stop(); updateChecker.removeUpdateListener(this); @@ -1717,6 +1759,7 @@ public class Core implements IdentityListener, UpdateListener { configuration.getIntValue("Option/ConfigurationVersion").setValue(0); configuration.getIntValue("Option/InsertionDelay").setValue(options.getIntegerOption("InsertionDelay").getReal()); configuration.getIntValue("Option/PostsPerPage").setValue(options.getIntegerOption("PostsPerPage").getReal()); + configuration.getIntValue("Option/CharactersPerPost").setValue(options.getIntegerOption("CharactersPerPost").getReal()); configuration.getBooleanValue("Option/RequireFullAccess").setValue(options.getBooleanOption("RequireFullAccess").getReal()); configuration.getIntValue("Option/PositiveTrust").setValue(options.getIntegerOption("PositiveTrust").getReal()); configuration.getIntValue("Option/NegativeTrust").setValue(options.getIntegerOption("NegativeTrust").getReal()); @@ -1794,6 +1837,7 @@ public class Core implements IdentityListener, UpdateListener { })); options.addIntegerOption("PostsPerPage", new DefaultOption(10, new IntegerRangeValidator(1, Integer.MAX_VALUE))); + options.addIntegerOption("CharactersPerPost", new DefaultOption(200, new OrValidator(new IntegerRangeValidator(50, Integer.MAX_VALUE), new EqualityValidator(-1)))); options.addBooleanOption("RequireFullAccess", new DefaultOption(false)); options.addIntegerOption("PositiveTrust", new DefaultOption(75, new IntegerRangeValidator(0, 100))); options.addIntegerOption("NegativeTrust", new DefaultOption(-25, new IntegerRangeValidator(-100, 100))); @@ -1832,6 +1876,7 @@ public class Core implements IdentityListener, UpdateListener { loadConfigurationValue("InsertionDelay"); loadConfigurationValue("PostsPerPage"); + loadConfigurationValue("CharactersPerPost"); options.getBooleanOption("RequireFullAccess").set(configuration.getBooleanValue("Option/RequireFullAccess").getValue(null)); loadConfigurationValue("PositiveTrust"); loadConfigurationValue("NegativeTrust"); @@ -2023,6 +2068,7 @@ public class Core implements IdentityListener, UpdateListener { } synchronized (newSones) { newSones.remove(identity.getId()); + coreListenerManager.fireSoneRemoved(sone); } } @@ -2127,6 +2173,41 @@ public class Core implements IdentityListener, UpdateListener { } /** + * Returns the number of characters per post, or -1 if the + * posts should not be cut off. + * + * @return The numbers of characters per post + */ + public int getCharactersPerPost() { + return options.getIntegerOption("CharactersPerPost").get(); + } + + /** + * Validates the number of characters per post. + * + * @param charactersPerPost + * The number of characters per post + * @return {@code true} if the number of characters per post was valid, + * {@code false} otherwise + */ + public boolean validateCharactersPerPost(Integer charactersPerPost) { + return options.getIntegerOption("CharactersPerPost").validate(charactersPerPost); + } + + /** + * Sets the number of characters per post. + * + * @param charactersPerPost + * The number of characters per post, or -1 to + * not cut off the posts + * @return This preferences objects + */ + public Preferences setCharactersPerPost(Integer charactersPerPost) { + options.getIntegerOption("CharactersPerPost").set(charactersPerPost); + return this; + } + + /** * Returns whether Sone requires full access to be even visible. * * @return {@code true} if Sone requires full access, {@code false}