mirror of
https://github.com/InsanusMokrassar/PlaguPoster.git
synced 2024-11-25 08:58:45 +00:00
add gc
This commit is contained in:
parent
53675ca598
commit
6d8bc0326f
7
common/src/commonMain/kotlin/DateTimeSerializer.kt
Normal file
7
common/src/commonMain/kotlin/DateTimeSerializer.kt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package dev.inmo.plaguposter.common
|
||||||
|
|
||||||
|
import com.soywiz.klock.DateTime
|
||||||
|
import kotlinx.serialization.Serializer
|
||||||
|
|
||||||
|
@Serializer(DateTime::class)
|
||||||
|
object DateTimeSerializer
|
@ -4,8 +4,8 @@ kotlin = "1.7.10"
|
|||||||
kotlin-serialization = "1.4.0"
|
kotlin-serialization = "1.4.0"
|
||||||
|
|
||||||
plagubot = "2.3.0"
|
plagubot = "2.3.0"
|
||||||
tgbotapi = "3.2.0"
|
tgbotapi = "3.2.1"
|
||||||
microutils = "0.12.6"
|
microutils = "0.12.11"
|
||||||
kslog = "0.5.1"
|
kslog = "0.5.1"
|
||||||
krontab = "0.8.0"
|
krontab = "0.8.0"
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package dev.inmo.plaguposter.posts.models
|
package dev.inmo.plaguposter.posts.models
|
||||||
|
|
||||||
|
import com.soywiz.klock.DateTime
|
||||||
|
import dev.inmo.plaguposter.common.DateTimeSerializer
|
||||||
import dev.inmo.tgbotapi.types.ChatId
|
import dev.inmo.tgbotapi.types.ChatId
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
@ -16,5 +18,7 @@ data class NewPost(
|
|||||||
@Serializable
|
@Serializable
|
||||||
data class RegisteredPost(
|
data class RegisteredPost(
|
||||||
val id: PostId,
|
val id: PostId,
|
||||||
|
@Serializable(DateTimeSerializer::class)
|
||||||
|
val created: DateTime,
|
||||||
override val content: List<PostContentInfo>
|
override val content: List<PostContentInfo>
|
||||||
) : Post
|
) : Post
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package dev.inmo.plaguposter.posts.repo
|
package dev.inmo.plaguposter.posts.repo
|
||||||
|
|
||||||
|
import com.soywiz.klock.DateTime
|
||||||
import dev.inmo.micro_utils.repos.ReadCRUDRepo
|
import dev.inmo.micro_utils.repos.ReadCRUDRepo
|
||||||
import dev.inmo.plaguposter.posts.models.*
|
import dev.inmo.plaguposter.posts.models.*
|
||||||
import dev.inmo.tgbotapi.types.ChatId
|
import dev.inmo.tgbotapi.types.ChatId
|
||||||
@ -7,4 +8,5 @@ import dev.inmo.tgbotapi.types.MessageIdentifier
|
|||||||
|
|
||||||
interface ReadPostsRepo : ReadCRUDRepo<RegisteredPost, PostId> {
|
interface ReadPostsRepo : ReadCRUDRepo<RegisteredPost, PostId> {
|
||||||
suspend fun getIdByChatAndMessage(chatId: ChatId, messageId: MessageIdentifier): PostId?
|
suspend fun getIdByChatAndMessage(chatId: ChatId, messageId: MessageIdentifier): PostId?
|
||||||
|
suspend fun getPostCreationTime(postId: PostId): DateTime?
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package dev.inmo.plaguposter.posts.exposed
|
package dev.inmo.plaguposter.posts.exposed
|
||||||
|
|
||||||
import com.benasher44.uuid.uuid4
|
import com.benasher44.uuid.uuid4
|
||||||
|
import com.soywiz.klock.DateTime
|
||||||
import dev.inmo.micro_utils.repos.KeyValuesRepo
|
import dev.inmo.micro_utils.repos.KeyValuesRepo
|
||||||
import dev.inmo.micro_utils.repos.exposed.AbstractExposedCRUDRepo
|
import dev.inmo.micro_utils.repos.exposed.AbstractExposedCRUDRepo
|
||||||
import dev.inmo.micro_utils.repos.exposed.initTable
|
import dev.inmo.micro_utils.repos.exposed.initTable
|
||||||
@ -21,6 +22,9 @@ 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 {
|
||||||
|
DateTime.nowUnix()
|
||||||
|
}
|
||||||
|
|
||||||
private val contentRepo by lazy {
|
private val contentRepo by lazy {
|
||||||
ExposedContentInfoRepo(
|
ExposedContentInfoRepo(
|
||||||
@ -38,6 +42,7 @@ class ExposedPostsRepo(
|
|||||||
val id = PostId(get(idColumn))
|
val id = PostId(get(idColumn))
|
||||||
return RegisteredPost(
|
return RegisteredPost(
|
||||||
id,
|
id,
|
||||||
|
DateTime(get(createdColumn)),
|
||||||
with(contentRepo) {
|
with(contentRepo) {
|
||||||
select { postIdColumn.eq(id.string) }.map {
|
select { postIdColumn.eq(id.string) }.map {
|
||||||
it.asObject
|
it.asObject
|
||||||
@ -70,6 +75,7 @@ class ExposedPostsRepo(
|
|||||||
|
|
||||||
return RegisteredPost(
|
return RegisteredPost(
|
||||||
id,
|
id,
|
||||||
|
DateTime(get(createdColumn)),
|
||||||
with(contentRepo) {
|
with(contentRepo) {
|
||||||
select { postIdColumn.eq(id.string) }.map {
|
select { postIdColumn.eq(id.string) }.map {
|
||||||
it.asObject
|
it.asObject
|
||||||
@ -130,4 +136,8 @@ class ExposedPostsRepo(
|
|||||||
} ?.let(::PostId)
|
} ?.let(::PostId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getPostCreationTime(postId: PostId): DateTime? = transaction(database) {
|
||||||
|
select { selectById(postId) }.limit(1).firstOrNull() ?.get(createdColumn) ?.let(::DateTime)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
23
ratings/gc/build.gradle
Normal file
23
ratings/gc/build.gradle
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
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")
|
||||||
|
api libs.krontab
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jvmMain {
|
||||||
|
dependencies {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
ratings/gc/src/commonMain/kotlin/PackageInfo.kt
Normal file
1
ratings/gc/src/commonMain/kotlin/PackageInfo.kt
Normal file
@ -0,0 +1 @@
|
|||||||
|
package dev.inmo.plaguposter.ratings.gc
|
62
ratings/gc/src/jvmMain/kotlin/Plugin.kt
Normal file
62
ratings/gc/src/jvmMain/kotlin/Plugin.kt
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package dev.inmo.plaguposter.ratings.gc
|
||||||
|
|
||||||
|
import com.soywiz.klock.milliseconds
|
||||||
|
import com.soywiz.klock.seconds
|
||||||
|
import dev.inmo.krontab.KrontabTemplate
|
||||||
|
import dev.inmo.krontab.toSchedule
|
||||||
|
import dev.inmo.krontab.utils.asFlow
|
||||||
|
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
|
||||||
|
import dev.inmo.micro_utils.repos.deleteById
|
||||||
|
import dev.inmo.micro_utils.repos.id
|
||||||
|
import dev.inmo.plagubot.Plugin
|
||||||
|
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.extensions.behaviour_builder.BehaviourContext
|
||||||
|
import dev.inmo.tgbotapi.types.MilliSeconds
|
||||||
|
import dev.inmo.tgbotapi.types.Seconds
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.*
|
||||||
|
import org.jetbrains.exposed.sql.Database
|
||||||
|
import org.koin.core.Koin
|
||||||
|
import org.koin.core.module.Module
|
||||||
|
|
||||||
|
object Plugin : Plugin {
|
||||||
|
@Serializable
|
||||||
|
internal data class Config(
|
||||||
|
val autoclear: AutoClearOptions? = null,
|
||||||
|
val immediateDrop: Rating? = null,
|
||||||
|
) {
|
||||||
|
@Serializable
|
||||||
|
data class AutoClearOptions(
|
||||||
|
val rating: Rating,
|
||||||
|
val autoClearKrontab: KrontabTemplate,
|
||||||
|
val skipPostAge: Seconds? = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
override fun Module.setupDI(database: Database, params: JsonObject) {
|
||||||
|
single { get<Json>().decodeFromJsonElement(Config.serializer(), params["gc"] ?: return@single null) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun BehaviourContext.setupBotPlugin(koin: Koin) {
|
||||||
|
val ratingsRepo = koin.get<RatingsRepo>()
|
||||||
|
val postsRepo = koin.get<PostsRepo>()
|
||||||
|
val config = koin.get<Config>()
|
||||||
|
|
||||||
|
config.immediateDrop ?.let { toDrop ->
|
||||||
|
ratingsRepo.onNewValue.subscribeSafelyWithoutExceptions(this) {
|
||||||
|
postsRepo.deleteById(it.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config.autoclear ?.let { autoclear ->
|
||||||
|
autoclear.autoClearKrontab.toSchedule().asFlow().subscribeSafelyWithoutExceptions(scope) {
|
||||||
|
val dropCreatedBefore = it - (autoclear.skipPostAge ?: 0).seconds
|
||||||
|
ratingsRepo.getPostsWithRatingLessEq(autoclear.rating).keys.forEach {
|
||||||
|
if ((postsRepo.getPostCreationTime(it) ?: return@forEach) < dropCreatedBefore) {
|
||||||
|
postsRepo.deleteById(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1
ratings/gc/src/main/AndroidManifest.xml
Normal file
1
ratings/gc/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1 @@
|
|||||||
|
<manifest package="dev.inmo.plaguposter.ratings.gc"/>
|
@ -17,7 +17,8 @@ import kotlin.random.Random
|
|||||||
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
|
||||||
) {
|
) {
|
||||||
suspend fun select(repo: RatingsRepo, exclude: List<PostId>): PostId? {
|
suspend fun select(repo: RatingsRepo, exclude: List<PostId>): PostId? {
|
||||||
var reversed: Boolean = false
|
var reversed: Boolean = false
|
||||||
@ -70,7 +71,7 @@ data class RatingConfig(
|
|||||||
Prefer.Max,
|
Prefer.Max,
|
||||||
Prefer.Min -> posts.firstOrNull()
|
Prefer.Min -> posts.firstOrNull()
|
||||||
Prefer.Random -> posts.randomOrNull()
|
Prefer.Random -> posts.randomOrNull()
|
||||||
}
|
} ?: otherwise ?.select(repo, exclude)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable(Prefer.Serializer::class)
|
@Serializable(Prefer.Serializer::class)
|
||||||
|
@ -16,6 +16,7 @@ dependencies {
|
|||||||
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")
|
||||||
|
api project(":plaguposter.ratings.gc")
|
||||||
|
|
||||||
api libs.psql
|
api libs.psql
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
"dev.inmo.plaguposter.ratings.Plugin",
|
"dev.inmo.plaguposter.ratings.Plugin",
|
||||||
"dev.inmo.plaguposter.ratings.source.Plugin",
|
"dev.inmo.plaguposter.ratings.source.Plugin",
|
||||||
"dev.inmo.plaguposter.ratings.selector.Plugin",
|
"dev.inmo.plaguposter.ratings.selector.Plugin",
|
||||||
"dev.inmo.plaguposter.triggers.selector_with_timer.Plugin"
|
"dev.inmo.plaguposter.triggers.selector_with_timer.Plugin",
|
||||||
|
"dev.inmo.plaguposter.ratings.gc.Plugin"
|
||||||
],
|
],
|
||||||
"posts": {
|
"posts": {
|
||||||
"targetChat": 12345678,
|
"targetChat": 12345678,
|
||||||
@ -66,5 +67,12 @@
|
|||||||
},
|
},
|
||||||
"timer_trigger": {
|
"timer_trigger": {
|
||||||
"krontab": "0 30 2/4 * *"
|
"krontab": "0 30 2/4 * *"
|
||||||
|
},
|
||||||
|
"gc": {
|
||||||
|
"autoclear": {
|
||||||
|
"rating": -2,
|
||||||
|
"autoClearKrontab": "0 0 0 * *",
|
||||||
|
"skipPostAge": 86400
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ String[] includes = [
|
|||||||
":ratings",
|
":ratings",
|
||||||
":ratings:source",
|
":ratings:source",
|
||||||
":ratings:selector",
|
":ratings:selector",
|
||||||
|
":ratings:gc",
|
||||||
":triggers:command",
|
":triggers:command",
|
||||||
":triggers:selector_with_timer",
|
":triggers:selector_with_timer",
|
||||||
// ":settings",
|
// ":settings",
|
||||||
|
Loading…
Reference in New Issue
Block a user