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
import com.soywiz.klock.DateTime
import kotlinx.serialization.KSerializer
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)
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"
) {
val idColumn = text("id").clientDefault { uuid4().toString() }
val createdColumn = double("datetime").default(0.0).clientDefault {
DateTime.nowUnix()
}
val createdColumn = double("datetime").default(0.0)
private val contentRepo by lazy {
ExposedContentInfoRepo(

View File

@ -2,18 +2,20 @@ package dev.inmo.plaguposter.ratings.selector
import com.soywiz.klock.DateTime
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.selector.models.SelectorConfig
class DefaultSelector (
private val config: SelectorConfig,
private val repo: RatingsRepo
private val ratingsRepo: RatingsRepo,
private val postsRepo: PostsRepo
) : Selector {
override suspend fun take(n: Int, now: DateTime): List<PostId> {
val result = mutableListOf<PostId>()
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)
} while (result.size < n)

View File

@ -1,28 +1,41 @@
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.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.repo.PostsRepo
import dev.inmo.plaguposter.ratings.models.Rating
import dev.inmo.plaguposter.ratings.repo.RatingsRepo
import dev.inmo.tgbotapi.types.Seconds
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
import kotlin.random.Random
@Serializable
data class RatingConfig(
val min: Rating?,
val max: Rating?,
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 count: Int? = null
val allowedCreationTime = now - (postAge ?: 0).seconds
when (prefer) {
Prefer.Max -> {
@ -43,35 +56,32 @@ data class RatingConfig(
null -> {
when (max) {
null -> {
repo.keys(
count ?.let { Pagination(0, it) } ?: FirstPagePagination(repo.count().toInt()),
reversed
).results.filterNot {
it in exclude
}
ratingsRepo.getAllByWithNextPaging { keys(it) }
}
else -> {
repo.getPostsWithRatingLessEq(max, exclude = exclude).keys
ratingsRepo.getPostsWithRatingLessEq(max, exclude = exclude).keys
}
}
}
else -> {
when (max) {
null -> {
repo.getPostsWithRatingGreaterEq(min, exclude = exclude).keys
ratingsRepo.getPostsWithRatingGreaterEq(min, exclude = exclude).keys
}
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) {
Prefer.Max,
Prefer.Min -> posts.firstOrNull()
Prefer.Random -> posts.randomOrNull()
} ?: otherwise ?.select(repo, exclude)
} ?: otherwise ?.select(ratingsRepo, postsRepo, exclude, now)
}
@Serializable(Prefer.Serializer::class)

View File

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

View File

@ -9,6 +9,6 @@ import org.koin.core.module.Module
object Plugin : Plugin {
override fun Module.setupDI(database: Database, params: JsonObject) {
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_registrar")
api project(":plaguposter.triggers.command")
api project(":plaguposter.triggers.selector_with_timer")
api project(":plaguposter.ratings")
api project(":plaguposter.ratings.source")
api project(":plaguposter.ratings.selector")