X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Fmain%2Fkotlin%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FUpdatedSoneProcessor.kt;fp=src%2Fmain%2Fkotlin%2Fnet%2Fpterodactylus%2Fsone%2Fcore%2FUpdatedSoneProcessor.kt;h=28bac6d0cbc2e31cfeab3bb3644aa6c73e654212;hp=0000000000000000000000000000000000000000;hb=03cec6a6772c2d836d94864adddaf544cbe9d72f;hpb=6f1f26e3998cfef155b0cf59152827accea70d30 diff --git a/src/main/kotlin/net/pterodactylus/sone/core/UpdatedSoneProcessor.kt b/src/main/kotlin/net/pterodactylus/sone/core/UpdatedSoneProcessor.kt new file mode 100644 index 0000000..28bac6d --- /dev/null +++ b/src/main/kotlin/net/pterodactylus/sone/core/UpdatedSoneProcessor.kt @@ -0,0 +1,70 @@ +package net.pterodactylus.sone.core + +import com.google.common.eventbus.* +import com.google.inject.* +import net.pterodactylus.sone.core.event.* +import net.pterodactylus.sone.data.* +import net.pterodactylus.sone.data.Sone.* +import net.pterodactylus.sone.database.* +import net.pterodactylus.sone.utils.* +import net.pterodactylus.util.logging.* +import javax.inject.Inject + +/** + * An `UpdatedSoneProcessor` is called to process a [Sone] after it has been + * downloaded from Freenet. + */ +@ImplementedBy(DefaultUpdateSoneProcessor::class) +interface UpdatedSoneProcessor { + + fun updateSone(sone: Sone) + +} + +abstract class BasicUpdateSoneProcessor(private val database: Database, private val eventBus: EventBus) : + UpdatedSoneProcessor { + + private val logger = Logging.getLogger(UpdatedSoneProcessor::javaClass.name)!! + + override fun updateSone(sone: Sone) { + val storedSone = database.getSone(sone.id) ?: return + if (!soneCanBeUpdated(storedSone, sone)) { + logger.fine("Downloaded Sone $sone can not update stored Sone $storedSone.") + return + } + + SoneComparison(storedSone, sone).apply { + newPosts + .onEach { post -> if (post.time <= sone.followingTime) post.isKnown = true } + .mapNotNull { post -> post.isKnown.ifFalse { NewPostFoundEvent(post) } } + .forEach(eventBus::post) + removedPosts + .map { PostRemovedEvent(it) } + .forEach(eventBus::post) + newPostReplies + .onEach { postReply -> if (postReply.time <= sone.followingTime) postReply.isKnown = true } + .mapNotNull { postReply -> postReply.isKnown.ifFalse { NewPostReplyFoundEvent(postReply) } } + .forEach(eventBus::post) + removedPostReplies + .map { PostReplyRemovedEvent(it) } + .forEach(eventBus::post) + } + database.storeSone(sone) + sone.options = storedSone.options + sone.isKnown = storedSone.isKnown + sone.status = if (sone.time != 0L) SoneStatus.idle else SoneStatus.unknown + } + + protected abstract fun soneCanBeUpdated(storedSone: Sone, newSone: Sone): Boolean + + private val Sone.followingTime get() = database.getFollowingTime(id) ?: 0 + +} + +class DefaultUpdateSoneProcessor @Inject constructor(database: Database, eventBus: EventBus) : + BasicUpdateSoneProcessor(database, eventBus) { + + override fun soneCanBeUpdated(storedSone: Sone, newSone: Sone) = + newSone.time > storedSone.time + +}