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=17948c5276a7aaf719f490cab52c584b10e95147;hp=0000000000000000000000000000000000000000;hb=8ba1240d5e15059e7469b46163c6f640dedefabb;hpb=edd08819f1838b85fd9bf07683b7ee2716d55619 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..17948c5 --- /dev/null +++ b/src/main/kotlin/net/pterodactylus/sone/core/UpdatedSoneProcessor.kt @@ -0,0 +1,68 @@ +package net.pterodactylus.sone.core + +import com.google.common.eventbus.EventBus +import com.google.inject.ImplementedBy +import net.pterodactylus.sone.core.event.NewPostFoundEvent +import net.pterodactylus.sone.core.event.NewPostReplyFoundEvent +import net.pterodactylus.sone.core.event.PostRemovedEvent +import net.pterodactylus.sone.core.event.PostReplyRemovedEvent +import net.pterodactylus.sone.data.Sone +import net.pterodactylus.sone.data.Sone.SoneStatus +import net.pterodactylus.sone.database.Database +import net.pterodactylus.sone.utils.ifFalse +import net.pterodactylus.util.logging.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 + } + collectEventsForChanges(storedSone, sone) + .also { database.storeSone(sone) } + .forEach(eventBus::post) + 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 + + private fun collectEventsForChanges(oldSone: Sone, newSone: Sone): List = + SoneChangeCollector(oldSone) + .onNewPost { post -> if (post.time <= newSone.followingTime) post.isKnown = true } + .newPostEvent { post -> post.isKnown.ifFalse { NewPostFoundEvent(post) } } + .removedPostEvent { PostRemovedEvent(it) } + .onNewPostReply { postReply -> if (postReply.time <= newSone.followingTime) postReply.isKnown = true } + .newPostReplyEvent { postReply -> postReply.isKnown.ifFalse { NewPostReplyFoundEvent(postReply) } } + .onRemovedPostReply { PostReplyRemovedEvent(it) } + .detectChanges(newSone) + +} + +class DefaultUpdateSoneProcessor @Inject constructor(database: Database, eventBus: EventBus) : + BasicUpdateSoneProcessor(database, eventBus) { + + override fun soneCanBeUpdated(storedSone: Sone, newSone: Sone) = + newSone.time > storedSone.time + +}