Skip to content

Commit

Permalink
Devlogs: Support edits
Browse files Browse the repository at this point in the history
  • Loading branch information
gdude2002 committed May 8, 2023
1 parent 4830087 commit f0bd8dd
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/main/kotlin/org/quiltmc/community/_Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ suspend fun ExtensibleBotBuilder.database(migrate: Boolean = false) {
single { FilterCollection() } bind FilterCollection::class
single { FilterEventCollection() } bind FilterEventCollection::class
single { GlobalSettingsCollection() } bind GlobalSettingsCollection::class
single { LinkedMessagesCollection() } bind LinkedMessagesCollection::class
single { MetaCollection() } bind MetaCollection::class
single { OwnedThreadCollection() } bind OwnedThreadCollection::class
single { ServerSettingsCollection() } bind ServerSettingsCollection::class
Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/org/quiltmc/community/database/Migrations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ object Migrations : KordExKoinComponent {
@Suppress("TooGenericExceptionCaught")
try {
@Suppress("MagicNumber")
when (nextVersion) { // TODO: This should **REEEEEEEEEAAALLLLLLLLLLLLLLLLLLLLLLLY** be annotation-based
when (nextVersion) { // TODO: Someone please make this use annotations I don't have the spoons pls
1 -> ::v1
2 -> ::v2
3 -> ::v3
Expand All @@ -62,6 +62,7 @@ object Migrations : KordExKoinComponent {
19 -> ::v19
20 -> ::v20
21 -> ::v21
22 -> ::v22

else -> break
}(db.mongo)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

package org.quiltmc.community.database.collections

import com.kotlindiscord.kord.extensions.koin.KordExKoinComponent
import dev.kord.common.entity.Snowflake
import org.koin.core.component.inject
import org.litote.kmongo.contains
import org.litote.kmongo.eq
import org.quiltmc.community.database.Collection
import org.quiltmc.community.database.Database
import org.quiltmc.community.database.entities.LinkedMessages

class LinkedMessagesCollection : KordExKoinComponent {
private val database: Database by inject()
private val col = database.mongo.getCollection<LinkedMessages>(name)

suspend fun getBySource(id: Snowflake) =
col.findOne(LinkedMessages::_id eq id)

fun getByTarget(id: Snowflake) =
col.find(LinkedMessages::targets contains id).toFlow()

suspend fun set(linkedMessages: LinkedMessages) =
col.save(linkedMessages)

companion object : Collection("linked-messages")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

@file:Suppress("DataClassShouldBeImmutable", "DataClassContainsFunctions") // Well, yes, but actually no.

package org.quiltmc.community.database.entities

import com.kotlindiscord.kord.extensions.utils.getKoin
import dev.kord.common.entity.Snowflake
import kotlinx.serialization.Serializable
import org.quiltmc.community.database.Entity
import org.quiltmc.community.database.collections.LinkedMessagesCollection

@Serializable
data class LinkedMessages(
override val _id: Snowflake,

val targets: MutableList<Snowflake> = mutableListOf()
) : Entity<Snowflake> {
suspend fun save() {
val collection = getKoin().get<LinkedMessagesCollection>()

collection.set(this)
}
}
14 changes: 14 additions & 0 deletions src/main/kotlin/org/quiltmc/community/database/migrations/v22.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

package org.quiltmc.community.database.migrations

import org.litote.kmongo.coroutine.CoroutineDatabase
import org.quiltmc.community.database.collections.LinkedMessagesCollection

suspend fun v22(db: CoroutineDatabase) {
db.createCollection(LinkedMessagesCollection.name)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ import com.kotlindiscord.kord.extensions.extensions.Extension
import com.kotlindiscord.kord.extensions.extensions.ephemeralMessageCommand
import com.kotlindiscord.kord.extensions.extensions.ephemeralSlashCommand
import com.kotlindiscord.kord.extensions.extensions.event
import com.kotlindiscord.kord.extensions.modules.extra.pluralkit.events.PKMessageCreateEvent
import com.kotlindiscord.kord.extensions.modules.extra.pluralkit.events.PKMessageUpdateEvent
import com.kotlindiscord.kord.extensions.modules.unsafe.annotations.UnsafeAPI
import com.kotlindiscord.kord.extensions.modules.unsafe.extensions.unsafeSubCommand
import com.kotlindiscord.kord.extensions.modules.unsafe.types.InitialSlashCommandResponse
import com.kotlindiscord.kord.extensions.modules.unsafe.types.ackEphemeral
import com.kotlindiscord.kord.extensions.types.respond
import com.kotlindiscord.kord.extensions.utils.addReaction
import com.kotlindiscord.kord.extensions.utils.deleteOwnReaction
import com.kotlindiscord.kord.extensions.utils.ensureWebhook
import com.kotlindiscord.kord.extensions.utils.extraData
import dev.kord.common.annotation.KordUnsafe
Expand All @@ -47,14 +50,15 @@ import dev.kord.core.entity.channel.NewsChannel
import dev.kord.core.entity.channel.TopGuildMessageChannel
import dev.kord.core.entity.channel.thread.TextChannelThread
import dev.kord.core.entity.channel.thread.ThreadChannel
import dev.kord.core.event.message.MessageCreateEvent
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.request.*
import kotlinx.coroutines.delay
import org.koin.core.component.inject
import org.quiltmc.community.*
import org.quiltmc.community.database.collections.LinkedMessagesCollection
import org.quiltmc.community.database.collections.UserFlagsCollection
import org.quiltmc.community.database.entities.LinkedMessages
import org.quiltmc.community.database.entities.UserFlags
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
Expand All @@ -69,6 +73,7 @@ class ForumExtension : Extension() {
override val name: String = "forum"

private val userFlags: UserFlagsCollection by inject()
private val linkedMessages: LinkedMessagesCollection by inject()

override suspend fun setup() {
ephemeralSlashCommand {
Expand Down Expand Up @@ -396,15 +401,17 @@ class ForumExtension : Extension() {
}
}

event<MessageCreateEvent> {
event<PKMessageCreateEvent> {
check {
val parent = topChannelFor(event)
val message = messageFor(event)
val user = userFor(event)

if (
message == null || // No message to be found
parent?.id != DEVLOG_FORUM || // Wrong forum channel
message?.asMessageOrNull()?.author?.id == kord.selfId || // Cozy sent the message
message.asMessageOrNull()?.author?.id == kord.selfId || // Cozy sent the message
linkedMessages.getBySource(message.id) != null || // Already published
user == null // No user for the event
) {
fail()
Expand All @@ -427,12 +434,44 @@ class ForumExtension : Extension() {
event.message.publishDevlog()
}
}

event<PKMessageUpdateEvent> {
check {
val parent = topChannelFor(event)
val message = messageFor(event)
val user = userFor(event)

if (
message == null || // No message to be found
parent?.id != DEVLOG_FORUM || // Wrong forum channel
message.asMessageOrNull()?.author?.id == kord.selfId || // Cozy sent the message
linkedMessages.getBySource(message.id) == null || // Not published
user == null // No user for the event
) {
fail()

return@check
}

pass()
}

action {
event.message.asMessage().editDevlog()
}
}
}

private suspend fun Message.publishDevlog() {
val publishingChannel = kord.getChannelOf<TopGuildMessageChannel>(DEVLOG_CHANNEL)
?: throw DiscordRelayedException("Unable to get the publishing channel")

val existingLinkedMessage = linkedMessages.getBySource(id)

if (existingLinkedMessage != null) {
throw DiscordRelayedException("This message was already published.")
}

val thread = channel.asChannelOf<TextChannelThread>()
val firstMessage = thread.getFirstMessage()!!

Expand All @@ -454,13 +493,41 @@ class ForumExtension : Extension() {
this.content = this@publishDevlog.content
}

LinkedMessages(id, mutableListOf(message.id)).save()

if (publishingChannel is NewsChannel) {
message.publish()
}

addReaction("🚀")
}

private suspend fun Message.editDevlog() {
val publishingChannel = kord.getChannelOf<TopGuildMessageChannel>(DEVLOG_CHANNEL)
?: throw DiscordRelayedException("Unable to get the publishing channel")

val linkedMessage = linkedMessages.getBySource(id)
?: return // Hasn't been published yet

val webhook = ensureWebhook(publishingChannel, "Quilt Devlogs") {
HttpClient().get(TOOLCHAIN_LOGO).body()
}

linkedMessage.targets.forEach {
val message = webhook.getMessage(webhook.token!!, it)

message.edit(webhook.id, webhook.token!!) {
this.content = this@editDevlog.content
}
}

addReaction("")

delay(3.seconds)

deleteOwnReaction("")
}

inner class PostTagArgs : Arguments() {
override val parseForAutocomplete: Boolean = true

Expand Down

0 comments on commit f0bd8dd

Please sign in to comment.