This commit is contained in:
InsanusMokrassar 2022-09-09 18:01:50 +06:00
parent 6d8bc0326f
commit 7549286c84
7 changed files with 41 additions and 21 deletions

View File

@ -1,7 +1,16 @@
package dev.inmo.plaguposter.common package dev.inmo.plaguposter.common
import com.soywiz.klock.DateTime import com.soywiz.klock.DateTime
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@Serializer(DateTime::class) @Serializer(DateTime::class)
object DateTimeSerializer object DateTimeSerializer : KSerializer<DateTime> {
override val descriptor: SerialDescriptor = Double.serializer().descriptor
override fun deserialize(decoder: Decoder): DateTime = DateTime(decoder.decodeDouble())
override fun serialize(encoder: Encoder, value: DateTime) = encoder.encodeDouble(value.unixMillis)
}

View File

@ -22,9 +22,7 @@ class ExposedPostsRepo(
tableName = "posts" tableName = "posts"
) { ) {
val idColumn = text("id").clientDefault { uuid4().toString() } val idColumn = text("id").clientDefault { uuid4().toString() }
val createdColumn = double("datetime").default(0.0).clientDefault { val createdColumn = double("datetime").default(0.0)
DateTime.nowUnix()
}
private val contentRepo by lazy { private val contentRepo by lazy {
ExposedContentInfoRepo( ExposedContentInfoRepo(

View File

@ -2,18 +2,20 @@ package dev.inmo.plaguposter.ratings.selector
import com.soywiz.klock.DateTime import com.soywiz.klock.DateTime
import dev.inmo.plaguposter.posts.models.PostId import dev.inmo.plaguposter.posts.models.PostId
import dev.inmo.plaguposter.posts.repo.PostsRepo
import dev.inmo.plaguposter.ratings.repo.RatingsRepo import dev.inmo.plaguposter.ratings.repo.RatingsRepo
import dev.inmo.plaguposter.ratings.selector.models.SelectorConfig import dev.inmo.plaguposter.ratings.selector.models.SelectorConfig
class DefaultSelector ( class DefaultSelector (
private val config: SelectorConfig, private val config: SelectorConfig,
private val repo: RatingsRepo private val ratingsRepo: RatingsRepo,
private val postsRepo: PostsRepo
) : Selector { ) : Selector {
override suspend fun take(n: Int, now: DateTime): List<PostId> { override suspend fun take(n: Int, now: DateTime): List<PostId> {
val result = mutableListOf<PostId>() val result = mutableListOf<PostId>()
do { do {
val selected = config.active(now.time) ?.ratings ?.select(repo, result) ?: break val selected = config.active(now.time) ?.rating ?.select(ratingsRepo, postsRepo, result, now) ?: break
result.add(selected) result.add(selected)
} while (result.size < n) } while (result.size < n)

View File

@ -1,28 +1,41 @@
package dev.inmo.plaguposter.ratings.selector.models package dev.inmo.plaguposter.ratings.selector.models
import com.soywiz.klock.DateTime
import com.soywiz.klock.seconds
import dev.inmo.micro_utils.pagination.FirstPagePagination import dev.inmo.micro_utils.pagination.FirstPagePagination
import dev.inmo.micro_utils.pagination.Pagination import dev.inmo.micro_utils.pagination.Pagination
import dev.inmo.micro_utils.pagination.utils.getAllByWithNextPaging
import dev.inmo.micro_utils.repos.pagination.getAll
import dev.inmo.plaguposter.common.DateTimeSerializer
import dev.inmo.plaguposter.posts.models.PostId import dev.inmo.plaguposter.posts.models.PostId
import dev.inmo.plaguposter.posts.repo.PostsRepo
import dev.inmo.plaguposter.ratings.models.Rating import dev.inmo.plaguposter.ratings.models.Rating
import dev.inmo.plaguposter.ratings.repo.RatingsRepo import dev.inmo.plaguposter.ratings.repo.RatingsRepo
import dev.inmo.tgbotapi.types.Seconds
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.serializer import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
import kotlin.random.Random
@Serializable @Serializable
data class RatingConfig( data class RatingConfig(
val min: Rating?, val min: Rating?,
val max: Rating?, val max: Rating?,
val prefer: Prefer, val prefer: Prefer,
val otherwise: RatingConfig? = null val otherwise: RatingConfig? = null,
val postAge: Seconds? = null
) { ) {
suspend fun select(repo: RatingsRepo, exclude: List<PostId>): PostId? { suspend fun select(
ratingsRepo: RatingsRepo,
postsRepo: PostsRepo,
exclude: List<PostId>,
now: DateTime
): PostId? {
var reversed: Boolean = false var reversed: Boolean = false
var count: Int? = null var count: Int? = null
val allowedCreationTime = now - (postAge ?: 0).seconds
when (prefer) { when (prefer) {
Prefer.Max -> { Prefer.Max -> {
@ -43,35 +56,32 @@ data class RatingConfig(
null -> { null -> {
when (max) { when (max) {
null -> { null -> {
repo.keys( ratingsRepo.getAllByWithNextPaging { keys(it) }
count ?.let { Pagination(0, it) } ?: FirstPagePagination(repo.count().toInt()),
reversed
).results.filterNot {
it in exclude
}
} }
else -> { else -> {
repo.getPostsWithRatingLessEq(max, exclude = exclude).keys ratingsRepo.getPostsWithRatingLessEq(max, exclude = exclude).keys
} }
} }
} }
else -> { else -> {
when (max) { when (max) {
null -> { null -> {
repo.getPostsWithRatingGreaterEq(min, exclude = exclude).keys ratingsRepo.getPostsWithRatingGreaterEq(min, exclude = exclude).keys
} }
else -> { else -> {
repo.getPosts(min .. max, reversed, count, exclude = exclude).keys ratingsRepo.getPosts(min .. max, reversed, count, exclude = exclude).keys
} }
} }
} }
}.filter {
it !in exclude && (postsRepo.getPostCreationTime(it) ?.let { it < allowedCreationTime } ?: true)
} }
return when (prefer) { return when (prefer) {
Prefer.Max, Prefer.Max,
Prefer.Min -> posts.firstOrNull() Prefer.Min -> posts.firstOrNull()
Prefer.Random -> posts.randomOrNull() Prefer.Random -> posts.randomOrNull()
} ?: otherwise ?.select(repo, exclude) } ?: otherwise ?.select(ratingsRepo, postsRepo, exclude, now)
} }
@Serializable(Prefer.Serializer::class) @Serializable(Prefer.Serializer::class)

View File

@ -5,5 +5,5 @@ import kotlinx.serialization.Serializable
@Serializable @Serializable
data class SelectorConfigItem( data class SelectorConfigItem(
val time: TimeConfig, val time: TimeConfig,
val ratings: RatingConfig val rating: RatingConfig
) )

View File

@ -9,6 +9,6 @@ import org.koin.core.module.Module
object Plugin : Plugin { object Plugin : Plugin {
override fun Module.setupDI(database: Database, params: JsonObject) { override fun Module.setupDI(database: Database, params: JsonObject) {
single { get<Json>().decodeFromJsonElement(SelectorConfig.serializer(), params["selector"] ?: return@single null) } single { get<Json>().decodeFromJsonElement(SelectorConfig.serializer(), params["selector"] ?: return@single null) }
single<Selector> { DefaultSelector(get(), get()) } single<Selector> { DefaultSelector(get(), get(), get()) }
} }
} }

View File

@ -13,6 +13,7 @@ dependencies {
api project(":plaguposter.posts") api project(":plaguposter.posts")
api project(":plaguposter.posts_registrar") api project(":plaguposter.posts_registrar")
api project(":plaguposter.triggers.command") api project(":plaguposter.triggers.command")
api project(":plaguposter.triggers.selector_with_timer")
api project(":plaguposter.ratings") api project(":plaguposter.ratings")
api project(":plaguposter.ratings.source") api project(":plaguposter.ratings.source")
api project(":plaguposter.ratings.selector") api project(":plaguposter.ratings.selector")