mirror of
https://github.com/InsanusMokrassar/PlaguPoster.git
synced 2025-09-16 13:39:30 +00:00
add selector
This commit is contained in:
22
ratings/selector/build.gradle
Normal file
22
ratings/selector/build.gradle
Normal file
@@ -0,0 +1,22 @@
|
||||
plugins {
|
||||
id "org.jetbrains.kotlin.multiplatform"
|
||||
id "org.jetbrains.kotlin.plugin.serialization"
|
||||
id "com.android.library"
|
||||
}
|
||||
|
||||
apply from: "$mppProjectWithSerializationPresetPath"
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
api project(":plaguposter.common")
|
||||
api project(":plaguposter.ratings")
|
||||
}
|
||||
}
|
||||
jvmMain {
|
||||
dependencies {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
ratings/selector/src/commonMain/kotlin/DefaultSelector.kt
Normal file
21
ratings/selector/src/commonMain/kotlin/DefaultSelector.kt
Normal file
@@ -0,0 +1,21 @@
|
||||
package dev.inmo.plaguposter.ratings.selector
|
||||
|
||||
import dev.inmo.plaguposter.posts.models.PostId
|
||||
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
|
||||
) : Selector {
|
||||
override suspend fun take(n: Int): List<PostId> {
|
||||
val result = mutableListOf<PostId>()
|
||||
|
||||
do {
|
||||
val selected = config.active ?.ratings ?.select(repo, result) ?: break
|
||||
result.add(selected)
|
||||
} while (result.size < n)
|
||||
|
||||
return result.toList()
|
||||
}
|
||||
}
|
1
ratings/selector/src/commonMain/kotlin/PackageInfo.kt
Normal file
1
ratings/selector/src/commonMain/kotlin/PackageInfo.kt
Normal file
@@ -0,0 +1 @@
|
||||
package dev.inmo.plaguposter.ratings.selector
|
7
ratings/selector/src/commonMain/kotlin/Selector.kt
Normal file
7
ratings/selector/src/commonMain/kotlin/Selector.kt
Normal file
@@ -0,0 +1,7 @@
|
||||
package dev.inmo.plaguposter.ratings.selector
|
||||
|
||||
import dev.inmo.plaguposter.posts.models.PostId
|
||||
|
||||
interface Selector {
|
||||
suspend fun take(n: Int = 1): List<PostId>
|
||||
}
|
104
ratings/selector/src/commonMain/kotlin/models/RatingConfig.kt
Normal file
104
ratings/selector/src/commonMain/kotlin/models/RatingConfig.kt
Normal file
@@ -0,0 +1,104 @@
|
||||
package dev.inmo.plaguposter.ratings.selector.models
|
||||
|
||||
import dev.inmo.micro_utils.pagination.FirstPagePagination
|
||||
import dev.inmo.micro_utils.pagination.Pagination
|
||||
import dev.inmo.plaguposter.posts.models.PostId
|
||||
import dev.inmo.plaguposter.ratings.models.Rating
|
||||
import dev.inmo.plaguposter.ratings.repo.RatingsRepo
|
||||
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
|
||||
) {
|
||||
suspend fun select(repo: RatingsRepo, exclude: List<PostId>): PostId? {
|
||||
var reversed: Boolean = false
|
||||
var count: Int? = null
|
||||
|
||||
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 -> {
|
||||
repo.keys(
|
||||
count ?.let { Pagination(0, it) } ?: FirstPagePagination(repo.count().toInt()),
|
||||
reversed
|
||||
).results.filterNot {
|
||||
it in exclude
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
repo.getPostsWithRatingLessEq(max, exclude = exclude).keys
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
when (max) {
|
||||
null -> {
|
||||
repo.getPostsWithRatingGreaterEq(min, exclude = exclude).keys
|
||||
}
|
||||
else -> {
|
||||
repo.getPosts(min .. max, reversed, count, exclude = exclude).keys
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return when (prefer) {
|
||||
Prefer.Max,
|
||||
Prefer.Min -> posts.firstOrNull()
|
||||
Prefer.Random -> posts.randomOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
@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)
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package dev.inmo.plaguposter.ratings.selector.models
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class SelectorConfig(
|
||||
val items: List<SelectorConfigItem>
|
||||
) {
|
||||
val active: SelectorConfigItem?
|
||||
get() = items.firstOrNull { it.time.isActive }
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
package dev.inmo.plaguposter.ratings.selector.models
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class SelectorConfigItem(
|
||||
val time: TimeConfig,
|
||||
val ratings: RatingConfig
|
||||
)
|
36
ratings/selector/src/commonMain/kotlin/models/TimeConfig.kt
Normal file
36
ratings/selector/src/commonMain/kotlin/models/TimeConfig.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
package dev.inmo.plaguposter.ratings.selector.models
|
||||
|
||||
import com.soywiz.klock.*
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
|
||||
@Serializable
|
||||
class TimeConfig(
|
||||
@Serializable(TimeSerializer::class)
|
||||
val from: Time,
|
||||
@Serializable(TimeSerializer::class)
|
||||
val to: Time
|
||||
) {
|
||||
@Transient
|
||||
val range = from .. to
|
||||
|
||||
val isActive: Boolean
|
||||
get() = DateTime.now().time in range
|
||||
|
||||
|
||||
object TimeSerializer : KSerializer<Time> {
|
||||
val format = TimeFormat("HH:mm")
|
||||
override val descriptor: SerialDescriptor = String.serializer().descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): Time {
|
||||
return format.parseTime(decoder.decodeString())
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Time) {
|
||||
encoder.encodeString(format.format(value))
|
||||
}
|
||||
}
|
||||
}
|
14
ratings/selector/src/jvmMain/kotlin/Plugin.kt
Normal file
14
ratings/selector/src/jvmMain/kotlin/Plugin.kt
Normal file
@@ -0,0 +1,14 @@
|
||||
package dev.inmo.plaguposter.ratings.selector
|
||||
|
||||
import dev.inmo.plagubot.Plugin
|
||||
import dev.inmo.plaguposter.ratings.selector.models.SelectorConfig
|
||||
import kotlinx.serialization.json.*
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
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()) }
|
||||
}
|
||||
}
|
1
ratings/selector/src/main/AndroidManifest.xml
Normal file
1
ratings/selector/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1 @@
|
||||
<manifest package="dev.inmo.plaguposter.ratings.selector"/>
|
Reference in New Issue
Block a user