From e963cb8ab1be8be5b15f563d2f4c26d2769ef2bf Mon Sep 17 00:00:00 2001 From: nikky Date: Wed, 4 Sep 2024 11:32:10 +0200 Subject: [PATCH] update kordex --- build.gradle.kts | 64 +-- settings.gradle.kts | 7 + src/main/kotlin/moe/nikky/BotInfoExtension.kt | 14 +- .../moe/nikky/ConfigurationExtension.kt | 26 +- src/main/kotlin/moe/nikky/DiceExtension.kt | 8 +- src/main/kotlin/moe/nikky/Json5DataAdapter.kt | 8 +- src/main/kotlin/moe/nikky/JsonDataAdapter.kt | 8 +- src/main/kotlin/moe/nikky/KloggingExt.kt | 54 +-- .../kotlin/moe/nikky/LocalTimeExtension.kt | 22 +- src/main/kotlin/moe/nikky/Main.kt | 18 +- .../kotlin/moe/nikky/RoleChooserConfig.kt | 2 +- .../moe/nikky/RoleManagementExtension.kt | 40 +- .../kotlin/moe/nikky/SchedulingExtension.kt | 38 +- src/main/kotlin/moe/nikky/TestExtension.kt | 28 +- src/main/kotlin/moe/nikky/checks/BotChecks.kt | 8 +- .../kotlin/moe/nikky/checks/RoleChecks.kt | 11 +- .../nikky/converter/ReactionEmojiConverter.kt | 15 +- src/main/kotlin/moe/nikky/relayError.kt | 2 +- src/main/kotlin/moe/nikky/twitch/TwitchApi.kt | 2 +- .../moe/nikky/twitch/TwitchChannelConfig.kt | 2 +- .../kotlin/moe/nikky/twitch/TwitchConfig.kt | 2 +- .../moe/nikky/twitch/TwitchEntryConfig.kt | 2 +- .../moe/nikky/twitch/TwitchExtension.kt | 435 ++++++++---------- versions.properties | 18 +- 24 files changed, 388 insertions(+), 446 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 42e81e5..ff6b391 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,30 +1,36 @@ @file:Suppress("GradlePackageUpdate") +import dev.kordex.gradle.plugins.kordex.DataCollection + + plugins { kotlin("jvm") kotlin("plugin.serialization") - id("com.google.devtools.ksp") id("com.github.johnrengelman.shadow") - application + id("dev.kordex.gradle.kordex") } group = "moe.nikky" version = "1.0-SNAPSHOT" repositories { - google() - mavenCentral() - - maven(url = "https://oss.sonatype.org/content/repositories/snapshots") { - name = "Sonatype Snapshots (Legacy)" - } - maven(url = "https://s01.oss.sonatype.org/content/repositories/snapshots/") { - name = "Sonatype Snapshots" - } +// google() +// mavenCentral() } -application { - mainClass.set("moe.nikky.MainKt") +kordEx { + bot { + mainClass.set("moe.nikky.MainKt") + processDotEnv.set(true) + voice.set(false) + dataCollection.set(DataCollection.None) + } + addDependencies.set(true) + addRepositories.set(true) +// kordVersion.set("latest") +// kordExVersion.set("latest") +// module("extra-phishing") +// module("extra-pluralkit") } kotlin { @@ -37,18 +43,16 @@ kotlin { } dependencies { - implementation("com.kotlindiscord.kord.extensions:kord-extensions:_") - implementation("com.kotlindiscord.kord.extensions:annotations:_") - implementation("com.kotlindiscord.kord.extensions:extra-phishing:_") - implementation("com.kotlindiscord.kord.extensions:extra-pluralkit:_") - ksp("com.kotlindiscord.kord.extensions:annotation-processor:_") +// implementation("com.kotlindiscord.kord.extensions:kord-extensions:_") +// implementation("com.kotlindiscord.kord.extensions:annotations:_") +// implementation("com.kotlindiscord.kord.extensions:extra-phishing:_") +// implementation("com.kotlindiscord.kord.extensions:extra-pluralkit:_") +// ksp("com.kotlindiscord.kord.extensions:annotation-processor:_") // implementation("dev.kord:kord-core:_") implementation("dev.kord.x:emoji:_") -// implementation("dev.kord.cache:cache-map:_") - implementation("org.jetbrains.kotlinx:kotlinx-datetime:_") implementation(KotlinX.serialization.json) @@ -65,28 +69,8 @@ dependencies { implementation("io.ktor:ktor-client-logging:_") implementation("org.slf4j:slf4j-api:_") - - testImplementation(Testing.Junit.jupiter.api) - testRuntimeOnly(Testing.Junit.jupiter.engine) -} - -java { -// sourceCompatibility = JavaVersion.VERSION_16 -// targetCompatibility = JavaVersion.VERSION_16 } -//tasks.named("compileKotlin", org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask::class.java) { -// compilerOptions { -// freeCompilerArgs.add("-Xexport-kdoc") -// } -//} - -//tasks.withType { -// compilerOptions { -// jvmTarget = "16" -// } -//} - tasks { test { useJUnitPlatform() diff --git a/settings.gradle.kts b/settings.gradle.kts index ba1b3a8..ff82f35 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,6 +8,13 @@ pluginManagement { plugins { id("com.gradle.develocity") version "3.17" +//// # available:"3.17.1" +//// # available:"3.17.2" +//// # available:"3.17.3" +//// # available:"3.17.4" +//// # available:"3.17.5" +//// # available:"3.17.6" +//// # available:"3.18" id("de.fayard.refreshVersions") version "0.60.5" } diff --git a/src/main/kotlin/moe/nikky/BotInfoExtension.kt b/src/main/kotlin/moe/nikky/BotInfoExtension.kt index e8b6984..4aaf28f 100644 --- a/src/main/kotlin/moe/nikky/BotInfoExtension.kt +++ b/src/main/kotlin/moe/nikky/BotInfoExtension.kt @@ -1,12 +1,12 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.DISCORD_FUCHSIA -import com.kotlindiscord.kord.extensions.DISCORD_GREEN -import com.kotlindiscord.kord.extensions.commands.Arguments -import com.kotlindiscord.kord.extensions.commands.application.slash.ephemeralSubCommand -import com.kotlindiscord.kord.extensions.commands.converters.impl.role -import com.kotlindiscord.kord.extensions.extensions.Extension -import com.kotlindiscord.kord.extensions.extensions.ephemeralSlashCommand +import dev.kordex.core.DISCORD_FUCHSIA +import dev.kordex.core.DISCORD_GREEN +import dev.kordex.core.commands.Arguments +import dev.kordex.core.commands.application.slash.ephemeralSubCommand +import dev.kordex.core.commands.converters.impl.role +import dev.kordex.core.extensions.Extension +import dev.kordex.core.extensions.ephemeralSlashCommand import dev.kord.common.entity.Permission import dev.kord.common.entity.Permissions import dev.kord.rest.builder.message.embed diff --git a/src/main/kotlin/moe/nikky/ConfigurationExtension.kt b/src/main/kotlin/moe/nikky/ConfigurationExtension.kt index 46c21bc..58ad526 100644 --- a/src/main/kotlin/moe/nikky/ConfigurationExtension.kt +++ b/src/main/kotlin/moe/nikky/ConfigurationExtension.kt @@ -1,18 +1,18 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.checks.guildFor -import com.kotlindiscord.kord.extensions.checks.hasPermission -import com.kotlindiscord.kord.extensions.checks.types.CheckContext -import com.kotlindiscord.kord.extensions.commands.Arguments -import com.kotlindiscord.kord.extensions.commands.application.slash.ephemeralSubCommand -import com.kotlindiscord.kord.extensions.commands.converters.impl.role -import com.kotlindiscord.kord.extensions.extensions.Extension -import com.kotlindiscord.kord.extensions.extensions.ephemeralSlashCommand -import com.kotlindiscord.kord.extensions.storage.Data -import com.kotlindiscord.kord.extensions.storage.StorageType -import com.kotlindiscord.kord.extensions.storage.StorageUnit -import com.kotlindiscord.kord.extensions.utils.getLocale -import com.kotlindiscord.kord.extensions.utils.translate +import dev.kordex.core.checks.guildFor +import dev.kordex.core.checks.hasPermission +import dev.kordex.core.checks.types.CheckContext +import dev.kordex.core.commands.Arguments +import dev.kordex.core.commands.application.slash.ephemeralSubCommand +import dev.kordex.core.commands.converters.impl.role +import dev.kordex.core.extensions.Extension +import dev.kordex.core.extensions.ephemeralSlashCommand +import dev.kordex.core.storage.Data +import dev.kordex.core.storage.StorageType +import dev.kordex.core.storage.StorageUnit +import dev.kordex.core.utils.getLocale +import dev.kordex.core.utils.translate import dev.kord.common.entity.Permission import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.GuildBehavior diff --git a/src/main/kotlin/moe/nikky/DiceExtension.kt b/src/main/kotlin/moe/nikky/DiceExtension.kt index 266270f..827bb56 100644 --- a/src/main/kotlin/moe/nikky/DiceExtension.kt +++ b/src/main/kotlin/moe/nikky/DiceExtension.kt @@ -5,10 +5,10 @@ import br.com.colman.dicehelper.DiceNotation import br.com.colman.dicehelper.FixedDice import br.com.colman.dicehelper.RandomDice import br.com.colman.dicehelper.diceNotation -import com.kotlindiscord.kord.extensions.commands.Arguments -import com.kotlindiscord.kord.extensions.commands.converters.impl.string -import com.kotlindiscord.kord.extensions.extensions.Extension -import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import dev.kordex.core.commands.Arguments +import dev.kordex.core.commands.converters.impl.string +import dev.kordex.core.extensions.Extension +import dev.kordex.core.extensions.publicSlashCommand import io.klogging.Klogging class DiceExtension() : Extension(), Klogging { diff --git a/src/main/kotlin/moe/nikky/Json5DataAdapter.kt b/src/main/kotlin/moe/nikky/Json5DataAdapter.kt index 61d3854..5398526 100644 --- a/src/main/kotlin/moe/nikky/Json5DataAdapter.kt +++ b/src/main/kotlin/moe/nikky/Json5DataAdapter.kt @@ -2,10 +2,10 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.storage.Data -import com.kotlindiscord.kord.extensions.storage.DataAdapter -import com.kotlindiscord.kord.extensions.storage.StorageUnit -import com.kotlindiscord.kord.extensions.storage.storageFileRoot +import dev.kordex.core.storage.Data +import dev.kordex.core.storage.DataAdapter +import dev.kordex.core.storage.StorageUnit +import dev.kordex.core.storage.storageFileRoot import io.github.xn32.json5k.Json5 import java.io.File import java.nio.file.Path diff --git a/src/main/kotlin/moe/nikky/JsonDataAdapter.kt b/src/main/kotlin/moe/nikky/JsonDataAdapter.kt index 8406813..087678c 100644 --- a/src/main/kotlin/moe/nikky/JsonDataAdapter.kt +++ b/src/main/kotlin/moe/nikky/JsonDataAdapter.kt @@ -2,10 +2,10 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.storage.Data -import com.kotlindiscord.kord.extensions.storage.DataAdapter -import com.kotlindiscord.kord.extensions.storage.StorageUnit -import com.kotlindiscord.kord.extensions.storage.storageFileRoot +import dev.kordex.core.storage.Data +import dev.kordex.core.storage.DataAdapter +import dev.kordex.core.storage.StorageUnit +import dev.kordex.core.storage.storageFileRoot import kotlinx.serialization.json.Json import java.io.File import java.nio.file.Path diff --git a/src/main/kotlin/moe/nikky/KloggingExt.kt b/src/main/kotlin/moe/nikky/KloggingExt.kt index 56de637..5d5032d 100644 --- a/src/main/kotlin/moe/nikky/KloggingExt.kt +++ b/src/main/kotlin/moe/nikky/KloggingExt.kt @@ -1,6 +1,6 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.extensions.Extension +import dev.kordex.core.extensions.Extension import dev.kord.core.behavior.GuildBehavior import dev.kord.core.entity.Guild import dev.kord.core.entity.channel.GuildChannel @@ -26,38 +26,32 @@ import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import java.io.File -val DOCKER_RENDERER: RenderString = object: RenderString { - override fun invoke(e: LogEvent): String { - val loggerOrFile = e.items["file"] ?: e.logger - val message = "${e.level.colour5} $loggerOrFile : ${e.evalTemplate()}" - val cleanedItems = e.items - "file" - val maybeItems = if (cleanedItems.isNotEmpty()) " : $cleanedItems" else "" - val maybeStackTrace = if (e.stackTrace != null) "\n${e.stackTrace}" else "" - return message + maybeItems + maybeStackTrace - } +val DOCKER_RENDERER: RenderString = RenderString { e -> + val loggerOrFile = e.items["file"] ?: e.logger + val message = "${e.level.colour5} $loggerOrFile : ${e.evalTemplate()}" + val cleanedItems = e.items - "file" + val maybeItems = if (cleanedItems.isNotEmpty()) " : $cleanedItems" else "" + val maybeStackTrace = if (e.stackTrace != null) "\n${e.stackTrace}" else "" + message + maybeItems + maybeStackTrace } -val CUSTOM_RENDERER: RenderString = object: RenderString { - override fun invoke(e: LogEvent): String { - val loggerOrFile = e.items["file"]?.let { ".($it)" } ?: e.logger - val time = e.timestamp.localString.substring(0..22) - val message = "$time ${e.level} $loggerOrFile : ${e.evalTemplate()}" - val cleanedItems = e.items - "file" - val maybeItems = if (cleanedItems.isNotEmpty()) " : $cleanedItems" else "" - val maybeStackTrace = if (e.stackTrace != null) "\n${e.stackTrace}" else "" - return message + maybeItems + maybeStackTrace - } +val CUSTOM_RENDERER: RenderString = RenderString { e -> + val loggerOrFile = e.items["file"]?.let { ".($it)" } ?: e.logger + val time = e.timestamp.localString.substring(0..22) + val message = "$time ${e.level} $loggerOrFile : ${e.evalTemplate()}" + val cleanedItems = e.items - "file" + val maybeItems = if (cleanedItems.isNotEmpty()) " : $cleanedItems" else "" + val maybeStackTrace = if (e.stackTrace != null) "\n${e.stackTrace}" else "" + message + maybeItems + maybeStackTrace } -val CUSTOM_RENDERER_ANSI: RenderString = object: RenderString { - override fun invoke(e: LogEvent): String { - val loggerOrFile = e.items["file"]?.let { ".($it)" } ?: e.logger - val time = e.timestamp.localString.substring(0..22) - val message = "$time ${e.level.colour5} $loggerOrFile : ${e.evalTemplate()}" - val cleanedItems = e.items - "file" - val maybeItems = if (cleanedItems.isNotEmpty()) " : $cleanedItems" else "" - val maybeStackTrace = if (e.stackTrace != null) "\n${e.stackTrace}" else "" - return message + maybeItems + maybeStackTrace - } +val CUSTOM_RENDERER_ANSI: RenderString = RenderString { e -> + val loggerOrFile = e.items["file"]?.let { ".($it)" } ?: e.logger + val time = e.timestamp.localString.substring(0..22) + val message = "$time ${e.level.colour5} $loggerOrFile : ${e.evalTemplate()}" + val cleanedItems = e.items - "file" + val maybeItems = if (cleanedItems.isNotEmpty()) " : $cleanedItems" else "" + val maybeStackTrace = if (e.stackTrace != null) "\n${e.stackTrace}" else "" + message + maybeItems + maybeStackTrace } //fun logFile(file: File, append: Boolean = false): SendString { diff --git a/src/main/kotlin/moe/nikky/LocalTimeExtension.kt b/src/main/kotlin/moe/nikky/LocalTimeExtension.kt index 5b34c6a..2c5ad95 100644 --- a/src/main/kotlin/moe/nikky/LocalTimeExtension.kt +++ b/src/main/kotlin/moe/nikky/LocalTimeExtension.kt @@ -1,16 +1,16 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.commands.Arguments -import com.kotlindiscord.kord.extensions.commands.application.slash.ephemeralSubCommand -import com.kotlindiscord.kord.extensions.commands.converters.impl.string -import com.kotlindiscord.kord.extensions.commands.converters.impl.user -import com.kotlindiscord.kord.extensions.extensions.Extension -import com.kotlindiscord.kord.extensions.extensions.ephemeralSlashCommand -import com.kotlindiscord.kord.extensions.extensions.ephemeralUserCommand -import com.kotlindiscord.kord.extensions.storage.Data -import com.kotlindiscord.kord.extensions.storage.StorageType -import com.kotlindiscord.kord.extensions.storage.StorageUnit -import com.kotlindiscord.kord.extensions.utils.suggestStringMap +import dev.kordex.core.commands.Arguments +import dev.kordex.core.commands.application.slash.ephemeralSubCommand +import dev.kordex.core.commands.converters.impl.string +import dev.kordex.core.commands.converters.impl.user +import dev.kordex.core.extensions.Extension +import dev.kordex.core.extensions.ephemeralSlashCommand +import dev.kordex.core.extensions.ephemeralUserCommand +import dev.kordex.core.storage.Data +import dev.kordex.core.storage.StorageType +import dev.kordex.core.storage.StorageUnit +import dev.kordex.core.utils.suggestStringMap import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.GuildBehavior import dev.kord.core.entity.User diff --git a/src/main/kotlin/moe/nikky/Main.kt b/src/main/kotlin/moe/nikky/Main.kt index 8e964dd..49298e4 100644 --- a/src/main/kotlin/moe/nikky/Main.kt +++ b/src/main/kotlin/moe/nikky/Main.kt @@ -1,12 +1,11 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.ExtensibleBot -import com.kotlindiscord.kord.extensions.i18n.SupportedLocales -import com.kotlindiscord.kord.extensions.modules.extra.phishing.extPhishing -import com.kotlindiscord.kord.extensions.storage.DataAdapter -import com.kotlindiscord.kord.extensions.utils.env -import com.kotlindiscord.kord.extensions.utils.envOrNull -import com.kotlindiscord.kord.extensions.utils.getKoin +import dev.kordex.core.ExtensibleBot +import dev.kordex.core.i18n.SupportedLocales +import dev.kordex.core.storage.DataAdapter +import dev.kordex.core.utils.env +import dev.kordex.core.utils.envOrNull +import dev.kordex.core.utils.getKoin import dev.kord.common.entity.PresenceStatus import dev.kord.common.entity.Snowflake import dev.kord.gateway.PrivilegedIntent @@ -75,9 +74,10 @@ suspend fun main() { deletePaginatorOnTimeout = true pingInReply = true } - extPhishing { + +// extPhishing { // appName = "Yuno" - } +// } // extPluralKit() } presence { diff --git a/src/main/kotlin/moe/nikky/RoleChooserConfig.kt b/src/main/kotlin/moe/nikky/RoleChooserConfig.kt index e0ab0a6..94c2040 100644 --- a/src/main/kotlin/moe/nikky/RoleChooserConfig.kt +++ b/src/main/kotlin/moe/nikky/RoleChooserConfig.kt @@ -1,6 +1,6 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.storage.Data +import dev.kordex.core.storage.Data import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.GuildBehavior import dev.kord.core.behavior.getChannelOfOrNull diff --git a/src/main/kotlin/moe/nikky/RoleManagementExtension.kt b/src/main/kotlin/moe/nikky/RoleManagementExtension.kt index 6992c62..aea10e9 100644 --- a/src/main/kotlin/moe/nikky/RoleManagementExtension.kt +++ b/src/main/kotlin/moe/nikky/RoleManagementExtension.kt @@ -1,25 +1,25 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.DiscordRelayedException -import com.kotlindiscord.kord.extensions.commands.Arguments -import com.kotlindiscord.kord.extensions.commands.CommandContext -import com.kotlindiscord.kord.extensions.commands.application.slash.ephemeralSubCommand -import com.kotlindiscord.kord.extensions.commands.converters.impl.defaultingBoolean -import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalChannel -import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalColor -import com.kotlindiscord.kord.extensions.commands.converters.impl.role -import com.kotlindiscord.kord.extensions.commands.converters.impl.string -import com.kotlindiscord.kord.extensions.extensions.Extension -import com.kotlindiscord.kord.extensions.extensions.ephemeralSlashCommand -import com.kotlindiscord.kord.extensions.extensions.event -import com.kotlindiscord.kord.extensions.parsers.ColorParser -import com.kotlindiscord.kord.extensions.storage.Data -import com.kotlindiscord.kord.extensions.storage.StorageType -import com.kotlindiscord.kord.extensions.storage.StorageUnit -import com.kotlindiscord.kord.extensions.utils.any -import com.kotlindiscord.kord.extensions.utils.botHasPermissions -import com.kotlindiscord.kord.extensions.utils.getJumpUrl -import com.kotlindiscord.kord.extensions.utils.translate +import dev.kordex.core.DiscordRelayedException +import dev.kordex.core.commands.Arguments +import dev.kordex.core.commands.CommandContext +import dev.kordex.core.commands.application.slash.ephemeralSubCommand +import dev.kordex.core.commands.converters.impl.defaultingBoolean +import dev.kordex.core.commands.converters.impl.optionalChannel +import dev.kordex.core.commands.converters.impl.optionalColor +import dev.kordex.core.commands.converters.impl.role +import dev.kordex.core.commands.converters.impl.string +import dev.kordex.core.extensions.Extension +import dev.kordex.core.extensions.ephemeralSlashCommand +import dev.kordex.core.extensions.event +import dev.kordex.core.parsers.ColorParser +import dev.kordex.core.storage.Data +import dev.kordex.core.storage.StorageType +import dev.kordex.core.storage.StorageUnit +import dev.kordex.core.utils.any +import dev.kordex.core.utils.botHasPermissions +import dev.kordex.core.utils.getJumpUrl +import dev.kordex.core.utils.translate import dev.kord.common.Color import dev.kord.common.annotation.KordPreview import dev.kord.common.asJavaLocale diff --git a/src/main/kotlin/moe/nikky/SchedulingExtension.kt b/src/main/kotlin/moe/nikky/SchedulingExtension.kt index ee556ef..3ca45a7 100644 --- a/src/main/kotlin/moe/nikky/SchedulingExtension.kt +++ b/src/main/kotlin/moe/nikky/SchedulingExtension.kt @@ -1,24 +1,24 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.commands.Arguments -import com.kotlindiscord.kord.extensions.commands.application.slash.converters.impl.stringChoice -import com.kotlindiscord.kord.extensions.commands.application.slash.ephemeralSubCommand -import com.kotlindiscord.kord.extensions.commands.converters.impl.long -import com.kotlindiscord.kord.extensions.commands.converters.impl.string -import com.kotlindiscord.kord.extensions.components.buttons.EphemeralInteractionButton -import com.kotlindiscord.kord.extensions.components.components -import com.kotlindiscord.kord.extensions.components.ephemeralButton -import com.kotlindiscord.kord.extensions.components.ephemeralStringSelectMenu -import com.kotlindiscord.kord.extensions.components.forms.ModalForm -import com.kotlindiscord.kord.extensions.components.menus.string.EphemeralStringSelectMenu -import com.kotlindiscord.kord.extensions.extensions.Extension -import com.kotlindiscord.kord.extensions.extensions.ephemeralSlashCommand -import com.kotlindiscord.kord.extensions.storage.Data -import com.kotlindiscord.kord.extensions.storage.StorageType -import com.kotlindiscord.kord.extensions.storage.StorageUnit -import com.kotlindiscord.kord.extensions.time.TimestampType -import com.kotlindiscord.kord.extensions.utils.suggestLongMap -import com.kotlindiscord.kord.extensions.utils.suggestStringMap +import dev.kordex.core.commands.Arguments +import dev.kordex.core.commands.application.slash.converters.impl.stringChoice +import dev.kordex.core.commands.application.slash.ephemeralSubCommand +import dev.kordex.core.commands.converters.impl.long +import dev.kordex.core.commands.converters.impl.string +import dev.kordex.core.components.buttons.EphemeralInteractionButton +import dev.kordex.core.components.components +import dev.kordex.core.components.ephemeralButton +import dev.kordex.core.components.ephemeralStringSelectMenu +import dev.kordex.core.components.forms.ModalForm +import dev.kordex.core.components.menus.string.EphemeralStringSelectMenu +import dev.kordex.core.extensions.Extension +import dev.kordex.core.extensions.ephemeralSlashCommand +import dev.kordex.core.storage.Data +import dev.kordex.core.storage.StorageType +import dev.kordex.core.storage.StorageUnit +import dev.kordex.core.time.TimestampType +import dev.kordex.core.utils.suggestLongMap +import dev.kordex.core.utils.suggestStringMap import dev.kord.common.entity.ButtonStyle import dev.kord.common.entity.Permission import dev.kord.common.entity.Snowflake diff --git a/src/main/kotlin/moe/nikky/TestExtension.kt b/src/main/kotlin/moe/nikky/TestExtension.kt index ce6b08c..217d1f0 100644 --- a/src/main/kotlin/moe/nikky/TestExtension.kt +++ b/src/main/kotlin/moe/nikky/TestExtension.kt @@ -1,19 +1,19 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.commands.Arguments -import com.kotlindiscord.kord.extensions.commands.application.slash.converters.ChoiceEnum -import com.kotlindiscord.kord.extensions.commands.application.slash.converters.impl.optionalEnumChoice -import com.kotlindiscord.kord.extensions.commands.application.slash.ephemeralSubCommand -import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalDuration -import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalString -import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalUser -import com.kotlindiscord.kord.extensions.commands.converters.impl.string -import com.kotlindiscord.kord.extensions.commands.converters.impl.user -import com.kotlindiscord.kord.extensions.extensions.Extension -import com.kotlindiscord.kord.extensions.extensions.ephemeralSlashCommand -import com.kotlindiscord.kord.extensions.extensions.event -import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import com.kotlindiscord.kord.extensions.utils.respond +import dev.kordex.core.commands.Arguments +import dev.kordex.core.commands.application.slash.converters.ChoiceEnum +import dev.kordex.core.commands.application.slash.converters.impl.optionalEnumChoice +import dev.kordex.core.commands.application.slash.ephemeralSubCommand +import dev.kordex.core.commands.converters.impl.optionalDuration +import dev.kordex.core.commands.converters.impl.optionalString +import dev.kordex.core.commands.converters.impl.optionalUser +import dev.kordex.core.commands.converters.impl.string +import dev.kordex.core.commands.converters.impl.user +import dev.kordex.core.extensions.Extension +import dev.kordex.core.extensions.ephemeralSlashCommand +import dev.kordex.core.extensions.event +import dev.kordex.core.extensions.publicSlashCommand +import dev.kordex.core.utils.respond import dev.kord.common.entity.GuildScheduledEventEntityMetadata import dev.kord.common.entity.GuildScheduledEventPrivacyLevel import dev.kord.common.entity.Permission diff --git a/src/main/kotlin/moe/nikky/checks/BotChecks.kt b/src/main/kotlin/moe/nikky/checks/BotChecks.kt index e7de6ed..9f24f3d 100644 --- a/src/main/kotlin/moe/nikky/checks/BotChecks.kt +++ b/src/main/kotlin/moe/nikky/checks/BotChecks.kt @@ -1,9 +1,9 @@ package moe.nikky.checks -import com.kotlindiscord.kord.extensions.checks.hasPermission -import com.kotlindiscord.kord.extensions.checks.types.CheckContext -import com.kotlindiscord.kord.extensions.utils.getLocale -import com.kotlindiscord.kord.extensions.utils.translate +import dev.kordex.core.checks.hasPermission +import dev.kordex.core.checks.types.CheckContext +import dev.kordex.core.utils.getLocale +import dev.kordex.core.utils.translate import dev.kord.common.entity.Permission import dev.kord.core.event.Event import dev.kord.core.event.interaction.InteractionCreateEvent diff --git a/src/main/kotlin/moe/nikky/checks/RoleChecks.kt b/src/main/kotlin/moe/nikky/checks/RoleChecks.kt index 2e87845..d2f522c 100644 --- a/src/main/kotlin/moe/nikky/checks/RoleChecks.kt +++ b/src/main/kotlin/moe/nikky/checks/RoleChecks.kt @@ -1,11 +1,12 @@ package moe.nikky.checks -import com.kotlindiscord.kord.extensions.checks.failed -import com.kotlindiscord.kord.extensions.checks.nullMember -import com.kotlindiscord.kord.extensions.checks.passed -import com.kotlindiscord.kord.extensions.checks.types.CheckContext +import dev.kordex.core.checks.failed +import dev.kordex.core.checks.nullMember +import dev.kordex.core.checks.passed +import dev.kordex.core.checks.types.CheckContext import dev.kord.core.behavior.RoleBehavior import dev.kord.core.event.Event +import dev.kordex.core.checks.memberFor import io.github.oshai.kotlinlogging.KotlinLogging import kotlinx.coroutines.flow.toList @@ -16,7 +17,7 @@ public suspend fun CheckContext.hasRoleNullable(builder: suspend } val logger = KotlinLogging.logger("moe.nikky.checks.hasRoleNullable") - val member = com.kotlindiscord.kord.extensions.checks.memberFor(event) + val member = memberFor(event) if (member == null) { diff --git a/src/main/kotlin/moe/nikky/converter/ReactionEmojiConverter.kt b/src/main/kotlin/moe/nikky/converter/ReactionEmojiConverter.kt index e3b0726..eb0f0da 100644 --- a/src/main/kotlin/moe/nikky/converter/ReactionEmojiConverter.kt +++ b/src/main/kotlin/moe/nikky/converter/ReactionEmojiConverter.kt @@ -7,13 +7,10 @@ package moe.nikky.converter -import com.kotlindiscord.kord.extensions.DiscordRelayedException -import com.kotlindiscord.kord.extensions.commands.Argument -import com.kotlindiscord.kord.extensions.commands.CommandContext -import com.kotlindiscord.kord.extensions.commands.converters.* -import com.kotlindiscord.kord.extensions.modules.annotations.converters.Converter -import com.kotlindiscord.kord.extensions.modules.annotations.converters.ConverterType -import com.kotlindiscord.kord.extensions.parser.StringParser +import dev.kordex.core.DiscordRelayedException +import dev.kordex.core.commands.Argument +import dev.kordex.core.commands.CommandContext +import dev.kordex.core.commands.converters.* import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.Snowflake import dev.kord.core.entity.ReactionEmoji @@ -22,6 +19,9 @@ import dev.kord.core.entity.interaction.StringOptionValue import dev.kord.rest.builder.interaction.OptionsBuilder import dev.kord.rest.builder.interaction.StringChoiceBuilder import dev.kord.x.emoji.Emojis +import dev.kordex.core.annotations.converters.Converter +import dev.kordex.core.annotations.converters.ConverterType +import dev.kordex.parser.StringParser import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.mapNotNull @@ -43,7 +43,6 @@ import kotlinx.coroutines.flow.mapNotNull types = [ConverterType.LIST, ConverterType.OPTIONAL, ConverterType.SINGLE] ) -@OptIn(KordPreview::class) public class ReactionEmojiConverter( override var validator: Validator = null, ) : SingleConverter() { diff --git a/src/main/kotlin/moe/nikky/relayError.kt b/src/main/kotlin/moe/nikky/relayError.kt index 4ac297b..0ad9c98 100644 --- a/src/main/kotlin/moe/nikky/relayError.kt +++ b/src/main/kotlin/moe/nikky/relayError.kt @@ -1,6 +1,6 @@ package moe.nikky -import com.kotlindiscord.kord.extensions.DiscordRelayedException +import dev.kordex.core.DiscordRelayedException fun relayError(message: String): Nothing { throw DiscordRelayedException("A **error** occurred: $message") diff --git a/src/main/kotlin/moe/nikky/twitch/TwitchApi.kt b/src/main/kotlin/moe/nikky/twitch/TwitchApi.kt index a9ff003..ba8634c 100644 --- a/src/main/kotlin/moe/nikky/twitch/TwitchApi.kt +++ b/src/main/kotlin/moe/nikky/twitch/TwitchApi.kt @@ -1,6 +1,6 @@ package moe.nikky.twitch -import com.kotlindiscord.kord.extensions.utils.envOrNull +import dev.kordex.core.utils.envOrNull import io.klogging.Klogging import io.ktor.client.* import io.ktor.client.call.* diff --git a/src/main/kotlin/moe/nikky/twitch/TwitchChannelConfig.kt b/src/main/kotlin/moe/nikky/twitch/TwitchChannelConfig.kt index 16ff5af..d648fcd 100644 --- a/src/main/kotlin/moe/nikky/twitch/TwitchChannelConfig.kt +++ b/src/main/kotlin/moe/nikky/twitch/TwitchChannelConfig.kt @@ -1,6 +1,6 @@ package moe.nikky.twitch -import com.kotlindiscord.kord.extensions.storage.Data +import dev.kordex.core.storage.Data import kotlinx.serialization.Serializable import net.peanuuutz.tomlkt.TomlBlockArray diff --git a/src/main/kotlin/moe/nikky/twitch/TwitchConfig.kt b/src/main/kotlin/moe/nikky/twitch/TwitchConfig.kt index 97b2976..16d1e4e 100644 --- a/src/main/kotlin/moe/nikky/twitch/TwitchConfig.kt +++ b/src/main/kotlin/moe/nikky/twitch/TwitchConfig.kt @@ -1,6 +1,5 @@ package moe.nikky.twitch; -import com.kotlindiscord.kord.extensions.storage.Data import dev.kord.common.entity.Snowflake; import dev.kord.core.behavior.GuildBehavior import dev.kord.core.behavior.getChannelOfOrNull @@ -9,6 +8,7 @@ import dev.kord.core.entity.Role import dev.kord.core.entity.channel.NewsChannel import dev.kord.core.entity.channel.TextChannel import dev.kord.core.entity.channel.TopGuildMessageChannel +import dev.kordex.core.storage.Data import io.klogging.context.logContext import kotlinx.coroutines.withContext import kotlinx.serialization.ExperimentalSerializationApi diff --git a/src/main/kotlin/moe/nikky/twitch/TwitchEntryConfig.kt b/src/main/kotlin/moe/nikky/twitch/TwitchEntryConfig.kt index cbf4cc1..f594751 100644 --- a/src/main/kotlin/moe/nikky/twitch/TwitchEntryConfig.kt +++ b/src/main/kotlin/moe/nikky/twitch/TwitchEntryConfig.kt @@ -1,6 +1,6 @@ package moe.nikky.twitch -import com.kotlindiscord.kord.extensions.storage.Data +import dev.kordex.core.storage.Data import dev.kord.common.entity.Snowflake import kotlinx.serialization.Serializable import net.peanuuutz.tomlkt.TomlComment diff --git a/src/main/kotlin/moe/nikky/twitch/TwitchExtension.kt b/src/main/kotlin/moe/nikky/twitch/TwitchExtension.kt index 92a21ce..e3edb0f 100644 --- a/src/main/kotlin/moe/nikky/twitch/TwitchExtension.kt +++ b/src/main/kotlin/moe/nikky/twitch/TwitchExtension.kt @@ -1,22 +1,5 @@ package moe.nikky.twitch -import com.kotlindiscord.kord.extensions.DiscordRelayedException -import com.kotlindiscord.kord.extensions.commands.Arguments -import com.kotlindiscord.kord.extensions.commands.application.slash.ephemeralSubCommand -import com.kotlindiscord.kord.extensions.commands.converters.impl.defaultingBoolean -import com.kotlindiscord.kord.extensions.commands.converters.impl.defaultingInt -import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalChannel -import com.kotlindiscord.kord.extensions.commands.converters.impl.role -import com.kotlindiscord.kord.extensions.commands.converters.impl.string -import com.kotlindiscord.kord.extensions.extensions.Extension -import com.kotlindiscord.kord.extensions.extensions.ephemeralSlashCommand -import com.kotlindiscord.kord.extensions.storage.StorageType -import com.kotlindiscord.kord.extensions.storage.StorageUnit -import com.kotlindiscord.kord.extensions.time.TimestampType.RelativeTime -import com.kotlindiscord.kord.extensions.utils.getJumpUrl -import com.kotlindiscord.kord.extensions.utils.isPublished -import com.kotlindiscord.kord.extensions.utils.scheduling.Scheduler -import com.kotlindiscord.kord.extensions.utils.scheduling.Task import dev.kord.common.Color import dev.kord.common.entity.ChannelType import dev.kord.common.entity.GuildScheduledEventEntityMetadata @@ -49,6 +32,24 @@ import dev.kord.rest.builder.message.EmbedBuilder import dev.kord.rest.builder.message.embed import dev.kord.rest.request.KtorRequestException import dev.kord.rest.request.RestRequestException +import dev.kordex.core.DiscordRelayedException +import dev.kordex.core.commands.Arguments +import dev.kordex.core.commands.application.slash.ephemeralSubCommand +import dev.kordex.core.commands.application.slash.group +import dev.kordex.core.commands.converters.impl.defaultingBoolean +import dev.kordex.core.commands.converters.impl.defaultingInt +import dev.kordex.core.commands.converters.impl.optionalChannel +import dev.kordex.core.commands.converters.impl.string +import dev.kordex.core.commands.converters.impl.role +import dev.kordex.core.extensions.Extension +import dev.kordex.core.extensions.ephemeralSlashCommand +import dev.kordex.core.storage.StorageType +import dev.kordex.core.storage.StorageUnit +import dev.kordex.core.time.TimestampType +import dev.kordex.core.utils.getJumpUrl +import dev.kordex.core.utils.isPublished +import dev.kordex.core.utils.scheduling.Scheduler +import dev.kordex.core.utils.scheduling.Task import io.klogging.Klogging import io.klogging.context.logContext import io.ktor.client.* @@ -271,7 +272,7 @@ class TwitchExtension() : Extension(), Klogging { } } val includeCancelled by defaultingBoolean { - name = "include-cancelled" + name = "include_cancelled" description = "also list cancelled events" defaultValue = false } @@ -493,246 +494,216 @@ class TwitchExtension() : Extension(), Klogging { } } } - } - - /* - ephemeralSlashCommand { - name = "twitchSchedule" - description = "twitch schedule sync" - allowInDms = false - ephemeralSubCommand(::TwitchScheduleSyncArgs) { - name = "sync" - description = "synchronize schedule" - - requireBotPermissions( - Permission.ManageEvents, - ) - check { - with(configurationExtension) { requiresBotControl() } - } - - action { - withLogContext(event, guild) { guild -> - val token = httpClient.getToken() - val userData = httpClient.getUsers( - logins = listOf(arguments.twitchUserName), - token = token, - )[arguments.twitchUserName] - ?: relayError("cannot get user data for ${arguments.twitchUserName}") - - val segments = httpClient.getSchedule( - token = token, - broadcasterId = userData.id, - ).filter { it.canceledUntil == null && it.vacationCancelledUntil == null } - .take(arguments.amount).toList().distinct() - - val existingEvents = guild.scheduledEvents - .filter { event -> event.entityType == ScheduledEntityType.External } - .filter { event -> - event.location?.contains("https://twitch.tv/${userData.login}") ?: false - } - .toList() - - val segmentsWithEvents = segments.associateWith { segment -> - val now = Clock.System.now() - val title = segment.title + (segment.category?.name?.let { " - $it" } ?: "") - existingEvents - .filter { event -> event.name == title } + group("schedule") { + description = "twitch schedule sync" + ephemeralSubCommand(::TwitchScheduleSyncArgs) { + name = "sync" + description = "synchronize schedule" + requireBotPermissions( + Permission.ManageEvents, + ) + check { + with(configurationExtension) { requiresBotControl() } + } + action { + withLogContext(event, guild) { guild -> + val token = httpClient.getToken() + val userData = httpClient.getUsers( + logins = listOf(arguments.twitchUserName), + token = token, + )[arguments.twitchUserName] + ?: relayError("cannot get user data for ${arguments.twitchUserName}") + val segments = httpClient.getSchedule( + token = token, + broadcasterId = userData.id, + ).filter { it.canceledUntil == null && it.vacationCancelledUntil == null } + .take(arguments.amount).toList().distinct() + val existingEvents = guild.scheduledEvents + .filter { event -> event.entityType == ScheduledEntityType.External } .filter { event -> - (event.scheduledStartTime < now && event.status == GuildScheduledEventStatus.Active) - || (event.scheduledStartTime == segment.startTime && event.status == GuildScheduledEventStatus.Scheduled) + event.location?.contains("https://twitch.tv/${userData.login}") ?: false } - .filter { event -> event.scheduledEndTime == segment.endTime } - .filter { event -> event.description?.contains(segment.id) ?: false } - .also { - if (it.size > 1) { - this@TwitchExtension.logger.warnF { "found ${it.size} events for segment $segment" } - } - } - } - - val notMatchingEvents = existingEvents - .filter { event -> event.creatorId == this@TwitchExtension.kord.selfId } - .toSet() - segmentsWithEvents.values.flatten().toSet() - - - var followUp = respond { - content = listOfNotNull( - "found ${segments.size} segments", - notMatchingEvents.takeIf { it.isNotEmpty() }?.let { - "deleting ${it.size} events" - }, - ).joinToString("\n") - } - - notMatchingEvents.forEach { - it.delete() - } - - val now = Clock.System.now() - val segmentsToCreateEventsFor = segments.filter { segment -> - val existingEventsForSegment = segmentsWithEvents[segment] ?: emptyList() - existingEventsForSegment.isEmpty() && segment.endTime > now - } - - followUp = followUp.edit { - content = listOfNotNull( - "found ${segments.size} segments", - notMatchingEvents.takeIf { it.isNotEmpty() }?.let { - "deleted ${it.size} events ✅" - }, - segmentsWithEvents.takeIf { it.isNotEmpty() }?.let { - "creating ${it.size} events ... (this may take about ${((it.size - 5) / 5).minutes}" - }, - ).joinToString("\n") - } - - launch( - this@TwitchExtension.kord.coroutineContext - + CoroutineName("events-create-${userData.login}") - ) { - val createdEvents = segmentsToCreateEventsFor.map { segment -> - val startTime = segment.startTime.takeIf { it > now } ?: (now + 5.seconds) + .toList() + val segmentsWithEvents = segments.associateWith { segment -> + val now = Clock.System.now() val title = segment.title + (segment.category?.name?.let { " - $it" } ?: "") - guild.createScheduledEvent( - name = title, - privacyLevel = GuildScheduledEventPrivacyLevel.GuildOnly, - scheduledStartTime = startTime, - entityType = ScheduledEntityType.External, - ) { - description = """ - automatically created by ${event.interaction.user.mention} at ${now.toMessageFormat()} - id: ${segment.id} - """.trimIndent() - scheduledEndTime = segment.endTime - entityMetadata = GuildScheduledEventEntityMetadata( - location = "https://twitch.tv/${userData.login}".optional() - ) - }.also { event -> - this@TwitchExtension.logger.infoF { "created event ${event.id} for segment $segment" } - } + existingEvents + .filter { event -> event.name == title } + .filter { event -> + (event.scheduledStartTime < now && event.status == GuildScheduledEventStatus.Active) + || (event.scheduledStartTime == segment.startTime && event.status == GuildScheduledEventStatus.Scheduled) + } + .filter { event -> event.scheduledEndTime == segment.endTime } + .filter { event -> event.description?.contains(segment.id) ?: false } + .also { + if (it.size > 1) { + this@TwitchExtension.logger.warnF { "found ${it.size} events for segment $segment" } + } + } } - - this@TwitchExtension.logger.infoF { "done creating events" } - followUp.edit { + val notMatchingEvents = existingEvents + .filter { event -> event.creatorId == this@TwitchExtension.kord.selfId } + .toSet() - segmentsWithEvents.values.flatten().toSet() + var followUp = respond { + content = listOfNotNull( + "found ${segments.size} segments", + notMatchingEvents.takeIf { it.isNotEmpty() }?.let { + "deleting ${it.size} events" + }, + ).joinToString("\n") + } + notMatchingEvents.forEach { + it.delete() + } + val now = Clock.System.now() + val segmentsToCreateEventsFor = segments.filter { segment -> + val existingEventsForSegment = segmentsWithEvents[segment] ?: emptyList() + existingEventsForSegment.isEmpty() && segment.endTime > now + } + followUp = followUp.edit { content = listOfNotNull( "found ${segments.size} segments", notMatchingEvents.takeIf { it.isNotEmpty() }?.let { "deleted ${it.size} events ✅" }, - "created ${createdEvents.size}/${segmentsToCreateEventsFor.size} events ✅", - (segmentsToCreateEventsFor.size - createdEvents.size).takeIf { it > 0 }?.let { - "failed creating $it events ❌" + segmentsWithEvents.takeIf { it.isNotEmpty() }?.let { + "creating ${it.size} events ... (this may take about ${((it.size - 5) / 5).minutes}" }, - ) - .joinToString("\n") - .also { - this@TwitchExtension.logger.infoF { "message: \n$it" } + ).joinToString("\n") + } + launch( + this@TwitchExtension.kord.coroutineContext + + CoroutineName("events-create-${userData.login}") + ) { + val createdEvents = segmentsToCreateEventsFor.map { segment -> + val startTime = segment.startTime.takeIf { it > now } ?: (now + 5.seconds) + val title = segment.title + (segment.category?.name?.let { " - $it" } ?: "") + guild.createScheduledEvent( + name = title, + privacyLevel = GuildScheduledEventPrivacyLevel.GuildOnly, + scheduledStartTime = startTime, + entityType = ScheduledEntityType.External, + ) { + description = """ + automatically created by ${event.interaction.user.mention} at ${now.toMessageFormat()} + id: ${segment.id} + """.trimIndent() + scheduledEndTime = segment.endTime + entityMetadata = GuildScheduledEventEntityMetadata( + location = "https://twitch.tv/${userData.login}".optional() + ) + }.also { event -> + this@TwitchExtension.logger.infoF { "created event ${event.id} for segment $segment" } } + } + this@TwitchExtension.logger.infoF { "done creating events" } + followUp.edit { + content = listOfNotNull( + "found ${segments.size} segments", + notMatchingEvents.takeIf { it.isNotEmpty() }?.let { + "deleted ${it.size} events ✅" + }, + "created ${createdEvents.size}/${segmentsToCreateEventsFor.size} events ✅", + (segmentsToCreateEventsFor.size - createdEvents.size).takeIf { it > 0 }?.let { + "failed creating $it events ❌" + }, + ) + .joinToString("\n") + .also { + this@TwitchExtension.logger.infoF { "message: \n$it" } + } + } + this@TwitchExtension.logger.infoF { "followup edited" } } - this@TwitchExtension.logger.infoF { "followup edited" } } - } } - } - - ephemeralSubCommand(::TwitchScheduleDeleteArgs) { - name = "delete" - description = "delete all events for a twitch user" - - requireBotPermissions( - Permission.ManageEvents, - ) - check { - with(configurationExtension) { requiresBotControl() } - } - - action { - withLogContext(event, guild) { guild -> - val token = httpClient.getToken() - val userData = httpClient.getUsers( - logins = listOf(arguments.twitchUserName), - token = token, - )[arguments.twitchUserName] - ?: relayError("cannot get user data for ${arguments.twitchUserName}") - - val existingEvents = guild.scheduledEvents - .filter { event -> event.entityType == ScheduledEntityType.External } - .filter { event -> - event.location?.contains("https://twitch.tv/${userData.login}") ?: false + ephemeralSubCommand(::TwitchScheduleDeleteArgs) { + name = "delete" + description = "delete all events for a twitch user" + requireBotPermissions( + Permission.ManageEvents, + ) + check { + with(configurationExtension) { requiresBotControl() } + } + action { + withLogContext(event, guild) { guild -> + val token = httpClient.getToken() + val userData = httpClient.getUsers( + logins = listOf(arguments.twitchUserName), + token = token, + )[arguments.twitchUserName] + ?: relayError("cannot get user data for ${arguments.twitchUserName}") + val existingEvents = guild.scheduledEvents + .filter { event -> event.entityType == ScheduledEntityType.External } + .filter { event -> + event.location?.contains("https://twitch.tv/${userData.login}") ?: false + } + .toList() + val followUp = respond { + content = """ + deleting ${existingEvents.size} events ... + """.trimIndent() + } + existingEvents.forEach { it.delete() } + followUp.edit { + content = """ + deleted ${existingEvents.size} events ✅ + """.trimIndent() } - .toList() - val followUp = respond { - content = """ - deleting ${existingEvents.size} events ... - """.trimIndent() - } - - existingEvents.forEach { it.delete() } - - followUp.edit { - content = """ - deleted ${existingEvents.size} events ✅ - """.trimIndent() } } } - } - - ephemeralSubCommand(::TwitchScheduleListArgs) { - name = "list" - description = "list streamer schedule" - - requireBotPermissions( - Permission.ManageEvents, - ) - action { - withLogContext(event, guild) { guild -> - val token = httpClient.getToken() - val userData = httpClient.getUsers( - logins = listOf(arguments.twitchUserName), - token = token, - )[arguments.twitchUserName] - ?: relayError("cannot get user data for ${arguments.twitchUserName}") - - val segments = httpClient.getSchedule( - token = token, - broadcasterId = userData.id, - ) - .filter { arguments.includeCancelled || (it.canceledUntil == null && it.vacationCancelledUntil == null) } - .take(arguments.amount) - .toList().distinct() - - segments.forEach { - this@TwitchExtension.logger.debugF { it } - } - - if (segments.isNotEmpty()) { - segments.joinToString("\n") { segment -> - val title = segment.title.let { - if (segment.canceledUntil != null || segment.vacationCancelledUntil != null) { - "~~$it~~" - } else { - it + ephemeralSubCommand(::TwitchScheduleListArgs) { + name = "list" + description = "list streamer schedule" + requireBotPermissions( + Permission.ManageEvents, + ) + action { + withLogContext(event, guild) { guild -> + val token = httpClient.getToken() + val userData = httpClient.getUsers( + logins = listOf(arguments.twitchUserName), + token = token, + )[arguments.twitchUserName] + ?: relayError("cannot get user data for ${arguments.twitchUserName}") + val segments = httpClient.getSchedule( + token = token, + broadcasterId = userData.id, + ) + .filter { arguments.includeCancelled || (it.canceledUntil == null && it.vacationCancelledUntil == null) } + .take(arguments.amount) + .toList().distinct() + segments.forEach { + this@TwitchExtension.logger.debugF { it } + } + if (segments.isNotEmpty()) { + segments.joinToString("\n") { segment -> + val title = segment.title.let { + if (segment.canceledUntil != null || segment.vacationCancelledUntil != null) { + "~~$it~~" + } else { + it + } } + "${segment.startTime.toMessageFormat()}-${segment.endTime.toMessageFormat()} ${title}" + + (segment.category?.name?.let { " - $it" } ?: "") + }.linesChunkedByMaxLength(2000) + .forEach { + respond { content = it } + } + } else { + respond { + content = "no schedule segments found" } - "${segment.startTime.toMessageFormat()}-${segment.endTime.toMessageFormat()} ${title}" + - (segment.category?.name?.let { " - $it" } ?: "") - }.linesChunkedByMaxLength(2000) - .forEach { - respond { content = it } - } - } else { - respond { - content = "no schedule segments found" } } } } } } - */ } private suspend fun add( @@ -980,7 +951,7 @@ class TwitchExtension() : Extension(), Klogging { } val twitchUrl = "[twitch.tv/${userData.displayName}](https://twitch.tv/${userData.login})" val message = if (vod != null) { - val timestamp = RelativeTime.format(vod.createdAt.epochSeconds) + val timestamp = TimestampType.RelativeTime.format(vod.createdAt.epochSeconds) val cleanedVodTitle = vod.title .replace("\\|\\|+".toRegex(), "|") val vodUrl = "[${cleanedVodTitle}](${vod.url})" diff --git a/versions.properties b/versions.properties index 0d052ce..ceb08a2 100644 --- a/versions.properties +++ b/versions.properties @@ -7,9 +7,9 @@ #### suppress inspection "SpellCheckingInspection" for whole file #### suppress inspection "UnusedProperty" for whole file -plugin.com.github.johnrengelman.shadow=8.1.1 +plugin.dev.kordex.gradle.kordex=1.4.2 -plugin.com.google.devtools.ksp=2.0.20-1.0.24 +plugin.com.github.johnrengelman.shadow=8.1.1 version.br.com.colman..dice-helper=1.0.0 @@ -22,20 +22,6 @@ version.io.klogging..klogging-jvm=0.7.2 version.io.klogging..slf4j-klogging=0.7.2 ## # available=0.8.0-SNAPSHOT -version.junit.jupiter=5.10.2 -## # available=5.10.3-SNAPSHOT -## # available=5.10.3 -## # available=5.10.4-SNAPSHOT -## # available=5.11.0-SNAPSHOT -## # available=5.11.0-M1 -## # available=5.11.0-M2 -## # available=5.11.0-RC1 -## # available=5.11.0 -## # available=5.11.1-SNAPSHOT -## # available=5.12.0-SNAPSHOT - -version.kord.extensions=1.9.0-SNAPSHOT - version.kord.x.emoji=0.5.0 version.kotlin=2.0.20