X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FCore.java;h=a51a189c9c0fa903d98341008873cf8e522a776c;hp=c5452368dd026e8ea30d43c3ef03ed1778e49a1f;hb=cb1cac49eee468cf29124601f8822b78e919258b;hpb=21f2757fa8afc1d121a34679727ebe1beb25440f diff --git a/src/main/java/net/pterodactylus/sone/core/Core.java b/src/main/java/net/pterodactylus/sone/core/Core.java index c545236..a51a189 100644 --- a/src/main/java/net/pterodactylus/sone/core/Core.java +++ b/src/main/java/net/pterodactylus/sone/core/Core.java @@ -42,6 +42,7 @@ import net.pterodactylus.sone.data.PostReply; import net.pterodactylus.sone.data.Profile; import net.pterodactylus.sone.data.Reply; import net.pterodactylus.sone.data.Sone; +import net.pterodactylus.sone.data.Sone.ShowCustomAvatars; import net.pterodactylus.sone.data.TemporaryImage; import net.pterodactylus.sone.data.Profile.Field; import net.pterodactylus.sone.fcp.FcpInterface; @@ -509,17 +510,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis * * @param id * The ID of the remote Sone to get - * @return The Sone with the given ID - */ - public Sone getRemoteSone(String id) { - return getRemoteSone(id, true); - } - - /** - * Returns the remote Sone with the given ID. - * - * @param id - * The ID of the remote Sone to get * @param create * {@code true} to always create a Sone, {@code false} to return * {@code null} if no Sone with the given ID exists @@ -528,7 +518,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis public Sone getRemoteSone(String id, boolean create) { synchronized (remoteSones) { Sone sone = remoteSones.get(id); - if ((sone == null) && create) { + if ((sone == null) && create && (id != null) && (id.length() == 43)) { sone = new Sone(id); remoteSones.put(id, sone); setSoneStatus(sone, SoneStatus.unknown); @@ -956,29 +946,6 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** - * Adds a local Sone from the given ID which has to be the ID of an own - * identity. - * - * @param id - * The ID of an own identity to add a Sone for - * @return The added (or already existing) Sone - */ - public Sone addLocalSone(String id) { - synchronized (localSones) { - if (localSones.containsKey(id)) { - logger.log(Level.FINE, "Tried to add known local Sone: %s", id); - return localSones.get(id); - } - OwnIdentity ownIdentity = identityManager.getOwnIdentity(id); - if (ownIdentity == null) { - logger.log(Level.INFO, "Invalid Sone ID: %s", id); - return null; - } - return addLocalSone(ownIdentity); - } - } - - /** * Adds a local Sone from the given own identity. * * @param ownIdentity @@ -1032,7 +999,9 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis sone.getOptions().addBooleanOption("ShowNotification/NewSones", new DefaultOption(true)); sone.getOptions().addBooleanOption("ShowNotification/NewPosts", new DefaultOption(true)); sone.getOptions().addBooleanOption("ShowNotification/NewReplies", new DefaultOption(true)); - sone.addFriend("nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI"); + sone.getOptions().addEnumOption("ShowCustomAvatars", new DefaultOption(ShowCustomAvatars.NEVER)); + + followSone(sone, getSone("nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI")); touchConfiguration(); return sone; } @@ -1050,7 +1019,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis return null; } synchronized (remoteSones) { - final Sone sone = getRemoteSone(identity.getId()).setIdentity(identity); + final Sone sone = getRemoteSone(identity.getId(), true).setIdentity(identity); boolean newSone = sone.getRequestUri() == null; sone.setRequestUri(getSoneUri(identity.getRequestUri())); sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), (long) 0)); @@ -1065,13 +1034,11 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis coreListenerManager.fireNewSoneFound(sone); for (Sone localSone : getLocalSones()) { if (localSone.getOptions().getBooleanOption("AutoFollow").get()) { - localSone.addFriend(sone.getId()); - touchConfiguration(); + followSone(localSone, sone); } } } } - remoteSones.put(identity.getId(), sone); soneDownloader.addSone(sone); setSoneStatus(sone, SoneStatus.unknown); soneDownloaders.execute(new Runnable() { @@ -1088,6 +1055,95 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis } /** + * Lets the given local Sone follow the Sone with the given ID. + * + * @param sone + * The local Sone that should follow another Sone + * @param soneId + * The ID of the Sone to follow + */ + public void followSone(Sone sone, String soneId) { + Validation.begin().isNotNull("Sone", sone).isNotNull("Sone ID", soneId).check(); + Sone followedSone = getSone(soneId, true); + if (followedSone == null) { + logger.log(Level.INFO, String.format("Ignored Sone with invalid ID: %s", soneId)); + return; + } + followSone(sone, getSone(soneId)); + } + + /** + * Lets the given local Sone follow the other given Sone. If the given Sone + * was not followed by any local Sone before, this will mark all elements of + * the followed Sone as read that have been created before the current + * moment. + * + * @param sone + * The local Sone that should follow the other Sone + * @param followedSone + * The Sone that should be followed + */ + public void followSone(Sone sone, Sone followedSone) { + Validation.begin().isNotNull("Sone", sone).isNotNull("Followed Sone", followedSone).check(); + sone.addFriend(followedSone.getId()); + synchronized (soneFollowingTimes) { + if (!soneFollowingTimes.containsKey(followedSone)) { + long now = System.currentTimeMillis(); + soneFollowingTimes.put(followedSone, now); + for (Post post : followedSone.getPosts()) { + if (post.getTime() < now) { + markPostKnown(post); + } + } + for (PostReply reply : followedSone.getReplies()) { + if (reply.getTime() < now) { + markReplyKnown(reply); + } + } + } + } + touchConfiguration(); + } + + /** + * Lets the given local Sone unfollow the Sone with the given ID. + * + * @param sone + * The local Sone that should unfollow another Sone + * @param soneId + * The ID of the Sone being unfollowed + */ + public void unfollowSone(Sone sone, String soneId) { + Validation.begin().isNotNull("Sone", sone).isNotNull("Sone ID", soneId).check(); + unfollowSone(sone, getSone(soneId, false)); + } + + /** + * Lets the given local Sone unfollow the other given Sone. If the given + * local Sone is the last local Sone that followed the given Sone, its + * following time will be removed. + * + * @param sone + * The local Sone that should unfollow another Sone + * @param unfollowedSone + * The Sone being unfollowed + */ + public void unfollowSone(Sone sone, Sone unfollowedSone) { + Validation.begin().isNotNull("Sone", sone).isNotNull("Unfollowed Sone", unfollowedSone).check(); + sone.removeFriend(unfollowedSone.getId()); + boolean unfollowedSoneStillFollowed = false; + for (Sone localSone : getLocalSones()) { + unfollowedSoneStillFollowed |= localSone.hasFriend(unfollowedSone.getId()); + } + if (!unfollowedSoneStillFollowed) { + synchronized (soneFollowingTimes) { + soneFollowingTimes.remove(unfollowedSone); + } + } + touchConfiguration(); + } + + /** * Retrieves the trust relationship from the origin to the target. If the * trust relationship can not be retrieved, {@code null} is returned. * @@ -1219,9 +1275,13 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis synchronized (newPosts) { for (Post post : sone.getPosts()) { post.setSone(storedSone); - if (!storedPosts.contains(post) && !knownPosts.contains(post.getId())) { - newPosts.add(post.getId()); - coreListenerManager.fireNewPostFound(post); + if (!storedPosts.contains(post)) { + if (post.getTime() < getSoneFollowingTime(sone)) { + knownPosts.add(post.getId()); + } else if (!knownPosts.contains(post.getId())) { + newPosts.add(post.getId()); + coreListenerManager.fireNewPostFound(post); + } } posts.put(post.getId(), post); } @@ -1240,9 +1300,13 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis synchronized (newReplies) { for (PostReply reply : sone.getReplies()) { reply.setSone(storedSone); - if (!storedReplies.contains(reply) && !knownReplies.contains(reply.getId())) { - newReplies.add(reply.getId()); - coreListenerManager.fireNewReplyFound(reply); + if (!storedReplies.contains(reply)) { + if (reply.getTime() < getSoneFollowingTime(sone)) { + knownReplies.add(reply.getId()); + } else if (!knownReplies.contains(reply.getId())) { + newReplies.add(reply.getId()); + coreListenerManager.fireNewReplyFound(reply); + } } replies.put(reply.getId(), reply); } @@ -1370,6 +1434,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis sone.getOptions().addBooleanOption("ShowNotification/NewSones", new DefaultOption(true)); sone.getOptions().addBooleanOption("ShowNotification/NewPosts", new DefaultOption(true)); sone.getOptions().addBooleanOption("ShowNotification/NewReplies", new DefaultOption(true)); + sone.getOptions().addEnumOption("ShowCustomAvatars", new DefaultOption(ShowCustomAvatars.NEVER)); /* load Sone. */ String sonePrefix = "Sone/" + sone.getId(); @@ -1381,7 +1446,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis String lastInsertFingerprint = configuration.getStringValue(sonePrefix + "/LastInsertFingerprint").getValue(""); /* load profile. */ - Profile profile = new Profile(); + Profile profile = new Profile(sone); profile.setFirstName(configuration.getStringValue(sonePrefix + "/Profile/FirstName").getValue(null)); profile.setMiddleName(configuration.getStringValue(sonePrefix + "/Profile/MiddleName").getValue(null)); profile.setLastName(configuration.getStringValue(sonePrefix + "/Profile/LastName").getValue(null)); @@ -1529,12 +1594,19 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis album.addImage(image); } + /* load avatar. */ + String avatarId = configuration.getStringValue(sonePrefix + "/Profile/Avatar").getValue(null); + if (avatarId != null) { + profile.setAvatar(getImage(avatarId, false)); + } + /* load options. */ sone.getOptions().getBooleanOption("AutoFollow").set(configuration.getBooleanValue(sonePrefix + "/Options/AutoFollow").getValue(null)); sone.getOptions().getBooleanOption("EnableSoneInsertNotifications").set(configuration.getBooleanValue(sonePrefix + "/Options/EnableSoneInsertNotifications").getValue(null)); sone.getOptions().getBooleanOption("ShowNotification/NewSones").set(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewSones").getValue(null)); sone.getOptions().getBooleanOption("ShowNotification/NewPosts").set(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewPosts").getValue(null)); sone.getOptions().getBooleanOption("ShowNotification/NewReplies").set(configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewReplies").getValue(null)); + sone.getOptions(). getEnumOption("ShowCustomAvatars").set(ShowCustomAvatars.valueOf(configuration.getStringValue(sonePrefix + "/Options/ShowCustomAvatars").getValue(ShowCustomAvatars.NEVER.name()))); /* if we’re still here, Sone was loaded successfully. */ synchronized (sone) { @@ -1544,7 +1616,9 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis sone.setReplies(replies); sone.setLikePostIds(likedPostIds); sone.setLikeReplyIds(likedReplyIds); - sone.setFriends(friends); + for (String friendId : friends) { + followSone(sone, friendId); + } sone.setAlbums(topLevelAlbums); soneInserters.get(sone).setLastInsertFingerprint(lastInsertFingerprint); } @@ -2072,6 +2146,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis configuration.getIntValue(sonePrefix + "/Profile/BirthDay").setValue(profile.getBirthDay()); configuration.getIntValue(sonePrefix + "/Profile/BirthMonth").setValue(profile.getBirthMonth()); configuration.getIntValue(sonePrefix + "/Profile/BirthYear").setValue(profile.getBirthYear()); + configuration.getStringValue(sonePrefix + "/Profile/Avatar").setValue(profile.getAvatar()); /* save profile fields. */ int fieldCounter = 0; @@ -2165,6 +2240,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewPosts").setValue(sone.getOptions().getBooleanOption("ShowNotification/NewPosts").getReal()); configuration.getBooleanValue(sonePrefix + "/Options/ShowNotification/NewReplies").setValue(sone.getOptions().getBooleanOption("ShowNotification/NewReplies").getReal()); configuration.getBooleanValue(sonePrefix + "/Options/EnableSoneInsertNotifications").setValue(sone.getOptions().getBooleanOption("EnableSoneInsertNotifications").getReal()); + configuration.getStringValue(sonePrefix + "/Options/ShowCustomAvatars").setValue(sone.getOptions(). getEnumOption("ShowCustomAvatars").get().name()); configuration.save(); @@ -2351,8 +2427,13 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis break; } long time = configuration.getLongValue("SoneFollowingTimes/" + soneCounter + "/Time").getValue(Long.MAX_VALUE); - synchronized (soneFollowingTimes) { - soneFollowingTimes.put(getSone(soneId), time); + Sone followedSone = getSone(soneId); + if (followedSone == null) { + logger.log(Level.WARNING, String.format("Ignoring Sone with invalid ID: %s", soneId)); + } else { + synchronized (soneFollowingTimes) { + soneFollowingTimes.put(getSone(soneId), time); + } } ++soneCounter; } @@ -2472,7 +2553,7 @@ public class Core extends AbstractService implements IdentityListener, UpdateLis @Override @SuppressWarnings("synthetic-access") public void run() { - Sone sone = getRemoteSone(identity.getId()); + Sone sone = getRemoteSone(identity.getId(), false); sone.setIdentity(identity); sone.setLatestEdition(Numbers.safeParseLong(identity.getProperty("Sone.LatestEdition"), sone.getLatestEdition())); soneDownloader.addSone(sone);