2022-09-06 17:56:58 +00:00
|
|
|
package dev.inmo.plaguposter.ratings.selector.models
|
|
|
|
|
2022-09-09 12:01:50 +00:00
|
|
|
import com.soywiz.klock.DateTime
|
|
|
|
import com.soywiz.klock.seconds
|
2022-09-06 17:56:58 +00:00
|
|
|
import dev.inmo.micro_utils.pagination.FirstPagePagination
|
|
|
|
import dev.inmo.micro_utils.pagination.Pagination
|
2022-09-09 12:01:50 +00:00
|
|
|
import dev.inmo.micro_utils.pagination.utils.getAllByWithNextPaging
|
|
|
|
import dev.inmo.micro_utils.repos.pagination.getAll
|
|
|
|
import dev.inmo.plaguposter.common.DateTimeSerializer
|
2022-09-06 17:56:58 +00:00
|
|
|
import dev.inmo.plaguposter.posts.models.PostId
|
2022-09-09 12:01:50 +00:00
|
|
|
import dev.inmo.plaguposter.posts.repo.PostsRepo
|
2022-09-06 17:56:58 +00:00
|
|
|
import dev.inmo.plaguposter.ratings.models.Rating
|
|
|
|
import dev.inmo.plaguposter.ratings.repo.RatingsRepo
|
2022-09-09 12:01:50 +00:00
|
|
|
import dev.inmo.tgbotapi.types.Seconds
|
2022-09-06 17:56:58 +00:00
|
|
|
import kotlinx.serialization.KSerializer
|
|
|
|
import kotlinx.serialization.Serializable
|
|
|
|
import kotlinx.serialization.builtins.serializer
|
|
|
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
|
|
|
import kotlinx.serialization.encoding.Decoder
|
|
|
|
import kotlinx.serialization.encoding.Encoder
|
|
|
|
|
|
|
|
@Serializable
|
|
|
|
data class RatingConfig(
|
|
|
|
val min: Rating?,
|
|
|
|
val max: Rating?,
|
2022-09-09 11:27:11 +00:00
|
|
|
val prefer: Prefer,
|
2022-09-09 12:01:50 +00:00
|
|
|
val otherwise: RatingConfig? = null,
|
|
|
|
val postAge: Seconds? = null
|
2022-09-06 17:56:58 +00:00
|
|
|
) {
|
2022-09-09 12:01:50 +00:00
|
|
|
suspend fun select(
|
|
|
|
ratingsRepo: RatingsRepo,
|
|
|
|
postsRepo: PostsRepo,
|
|
|
|
exclude: List<PostId>,
|
|
|
|
now: DateTime
|
|
|
|
): PostId? {
|
2022-09-06 17:56:58 +00:00
|
|
|
var reversed: Boolean = false
|
|
|
|
var count: Int? = null
|
2022-09-09 12:01:50 +00:00
|
|
|
val allowedCreationTime = now - (postAge ?: 0).seconds
|
2022-09-06 17:56:58 +00:00
|
|
|
|
|
|
|
when (prefer) {
|
|
|
|
Prefer.Max -> {
|
|
|
|
reversed = true
|
|
|
|
count = 1
|
|
|
|
}
|
|
|
|
Prefer.Min -> {
|
|
|
|
reversed = false
|
|
|
|
count = 1
|
|
|
|
}
|
|
|
|
Prefer.Random -> {
|
|
|
|
reversed = false
|
|
|
|
count = null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
val posts = when(min) {
|
|
|
|
null -> {
|
|
|
|
when (max) {
|
|
|
|
null -> {
|
2022-09-09 12:01:50 +00:00
|
|
|
ratingsRepo.getAllByWithNextPaging { keys(it) }
|
2022-09-06 17:56:58 +00:00
|
|
|
}
|
|
|
|
else -> {
|
2022-09-09 12:01:50 +00:00
|
|
|
ratingsRepo.getPostsWithRatingLessEq(max, exclude = exclude).keys
|
2022-09-06 17:56:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else -> {
|
|
|
|
when (max) {
|
|
|
|
null -> {
|
2022-09-09 12:01:50 +00:00
|
|
|
ratingsRepo.getPostsWithRatingGreaterEq(min, exclude = exclude).keys
|
2022-09-06 17:56:58 +00:00
|
|
|
}
|
|
|
|
else -> {
|
2022-09-09 12:01:50 +00:00
|
|
|
ratingsRepo.getPosts(min .. max, reversed, count, exclude = exclude).keys
|
2022-09-06 17:56:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-09-09 12:01:50 +00:00
|
|
|
}.filter {
|
|
|
|
it !in exclude && (postsRepo.getPostCreationTime(it) ?.let { it < allowedCreationTime } ?: true)
|
2022-09-06 17:56:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return when (prefer) {
|
|
|
|
Prefer.Max,
|
|
|
|
Prefer.Min -> posts.firstOrNull()
|
|
|
|
Prefer.Random -> posts.randomOrNull()
|
2022-09-09 12:01:50 +00:00
|
|
|
} ?: otherwise ?.select(ratingsRepo, postsRepo, exclude, now)
|
2022-09-06 17:56:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Serializable(Prefer.Serializer::class)
|
|
|
|
sealed interface Prefer {
|
|
|
|
val type: String
|
|
|
|
@Serializable(Serializer::class)
|
|
|
|
object Max : Prefer { override val type: String = "max" }
|
|
|
|
@Serializable(Serializer::class)
|
|
|
|
object Min : Prefer { override val type: String = "min" }
|
|
|
|
@Serializable(Serializer::class)
|
|
|
|
object Random : Prefer { override val type: String = "random" }
|
|
|
|
|
|
|
|
object Serializer : KSerializer<Prefer> {
|
|
|
|
override val descriptor: SerialDescriptor = String.serializer().descriptor
|
|
|
|
|
|
|
|
override fun deserialize(decoder: Decoder): Prefer {
|
|
|
|
val identifier = decoder.decodeString().lowercase()
|
|
|
|
return values.first { it.type.lowercase() == identifier }
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun serialize(encoder: Encoder, value: Prefer) {
|
|
|
|
encoder.encodeString(value.type.lowercase())
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
val values = arrayOf(Max, Min, Random)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|