diff --git a/docker-compose.yml b/docker-compose.yml index 362d678..17f1557 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,7 +8,7 @@ services: - "/etc/timezone:/etc/timezone:ro" - "/etc/localtime:/etc/localtime:ro" - ./logs:/user/app/logs - .env_file: + env_file: - .env ports: - - 127.0.0.1:8045:80 \ No newline at end of file + - 127.0.0.1:8045:80 diff --git a/src/main/kotlin/de/nycode/bankobot/BankoBot.kt b/src/main/kotlin/de/nycode/bankobot/BankoBot.kt index dd95ea3..0f9dba0 100644 --- a/src/main/kotlin/de/nycode/bankobot/BankoBot.kt +++ b/src/main/kotlin/de/nycode/bankobot/BankoBot.kt @@ -56,6 +56,7 @@ import dev.kord.x.commands.model.prefix.or import dev.kord.x.commands.model.processor.BaseEventHandler import io.ktor.client.* import io.ktor.client.engine.cio.* +import io.ktor.client.features.* import io.ktor.client.features.json.* import io.ktor.client.features.json.serializer.* import io.ktor.util.* @@ -63,6 +64,8 @@ import kapt.kotlin.generated.configure import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job +import kotlinx.coroutines.coroutineScope +import mu.KotlinLogging import org.bson.UuidRepresentation import org.litote.kmongo.coroutine.CoroutineCollection import org.litote.kmongo.coroutine.CoroutineDatabase @@ -70,16 +73,21 @@ import org.litote.kmongo.coroutine.coroutine import org.litote.kmongo.reactivestreams.KMongo import org.litote.kmongo.serialization.registerSerializer import kotlin.coroutines.CoroutineContext +import kotlin.time.ExperimentalTime +import kotlin.time.seconds object BankoBot : CoroutineScope { private var initialized = false override val coroutineContext: CoroutineContext = Dispatchers.IO + Job() - lateinit var availableDocs: List + var availableDocs: List? = null private set - @OptIn(KtorExperimentalAPI::class) + private val logger = KotlinLogging.logger { } + + @Suppress("MagicNumber") + @OptIn(KtorExperimentalAPI::class, ExperimentalTime::class) val httpClient = HttpClient(CIO) { install(JsonFeature) { val json = kotlinx.serialization.json.Json { @@ -88,6 +96,10 @@ object BankoBot : CoroutineScope { } serializer = KotlinxSerializer(json) } + install(HttpTimeout) { + requestTimeoutMillis = 10.seconds.toLongMilliseconds() + connectTimeoutMillis = 10.seconds.toLongMilliseconds() + } } val repositories = Repositories() @@ -107,15 +119,27 @@ object BankoBot : CoroutineScope { suspend operator fun invoke() { require(!initialized) { "Cannot initialize bot twice" } initialized = true + loadJavadocs() initializeDatabase() kord = Kord(Config.DISCORD_TOKEN) - availableDocs = DocDex.allJavadocs().map { it.names }.flatten() initializeKord() } + private suspend fun loadJavadocs(): Unit = coroutineScope { + runCatching { + availableDocs = DocDex.allJavadocs().map { it.names }.flatten() + } + .onSuccess { + logger.info("Successfully loaded available javadocs! (${availableDocs?.size})") + } + .onFailure { + logger.error("Unable to load available javadocs!") + } + } + @Suppress("MagicNumber") private suspend fun initializeDatabase() { registerSerializer(SnowflakeSerializer) diff --git a/src/main/kotlin/de/nycode/bankobot/commands/general/DCommand.kt b/src/main/kotlin/de/nycode/bankobot/commands/general/DCommand.kt new file mode 100644 index 0000000..3e88782 --- /dev/null +++ b/src/main/kotlin/de/nycode/bankobot/commands/general/DCommand.kt @@ -0,0 +1,52 @@ +/* + * MIT License + * + * Copyright (c) 2021 BankoBot Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +package de.nycode.bankobot.commands.general + +import de.nycode.bankobot.command.command +import de.nycode.bankobot.command.description +import de.nycode.bankobot.commands.GeneralModule +import dev.kord.core.behavior.channel.MessageChannelBehavior +import dev.kord.core.behavior.channel.createEmbed +import dev.kord.x.commands.annotation.AutoWired +import dev.kord.x.commands.annotation.ModuleName +import dev.kord.x.commands.model.command.invoke + +@ModuleName(GeneralModule) +@AutoWired +fun dCommand() = command("dddd") { + alias("d", "dd", "ddd") + description("They don't know :pepeLaugh:") + + invoke { + channel.specificCommand() + } +} + +private suspend fun MessageChannelBehavior.specificCommand() { + createEmbed { + title = "Imagine using xd in 2k21... oh wait" + } +} diff --git a/src/main/kotlin/de/nycode/bankobot/commands/general/DocsCommand.kt b/src/main/kotlin/de/nycode/bankobot/commands/general/DocsCommand.kt index 7d95ccd..bb17236 100644 --- a/src/main/kotlin/de/nycode/bankobot/commands/general/DocsCommand.kt +++ b/src/main/kotlin/de/nycode/bankobot/commands/general/DocsCommand.kt @@ -54,7 +54,13 @@ import dev.kord.x.commands.model.command.invoke const val DocsModule = "Documentation" private fun Argument.docsFilter() = filter { doc -> - if (doc in BankoBot.availableDocs) { + + if (BankoBot.availableDocs == null) { + return@filter FilterResult + .Fail("Die verfügbaren Docs konnten leider nicht geladen werden! Versuche es später erneut!") + } + + if (BankoBot.availableDocs?.contains(doc) == true) { FilterResult.Pass } else { FilterResult.Fail("Dieses Doc is unbekannt. (Siehe `xd list-docs`)") @@ -91,10 +97,20 @@ fun allDocsCommand() = command("alldocs") { alias("all-docs", "list-docs", "listdocs", "availabledocs", "available-docs") invoke { - respondEmbed(Embeds.info( - "Verfügbare Dokumentationen!", - BankoBot.availableDocs.format() - )) + + val embed = if (BankoBot.availableDocs == null) { + Embeds.error( + "Keine Docs verfügbar!", + "Die Docs konnten leider nicht geladen werden! Versuche es später erneut!" + ) + } else { + Embeds.info( + "Verfügbare Dokumentationen!", + BankoBot.availableDocs?.format() + ) + } + + respondEmbed(embed) } } @@ -102,7 +118,7 @@ fun allDocsCommand() = command("alldocs") { @ModuleName(DocsModule) fun docsCommand() = command("docs") { description("Zeigt Javadoc in Discord an") - alias("doc", "d") + alias("doc") invoke( JavaDocArgument, diff --git a/src/main/kotlin/de/nycode/bankobot/docdex/DocDex.kt b/src/main/kotlin/de/nycode/bankobot/docdex/DocDex.kt index 0d13f5c..025d77b 100644 --- a/src/main/kotlin/de/nycode/bankobot/docdex/DocDex.kt +++ b/src/main/kotlin/de/nycode/bankobot/docdex/DocDex.kt @@ -30,12 +30,15 @@ import de.nycode.bankobot.config.Config import io.ktor.client.request.* import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlin.time.ExperimentalTime object DocDex { /** * Retrieves a list of all available javadocs. */ + @OptIn(ExperimentalTime::class) + @Suppress("MagicNumber") suspend fun allJavadocs(): List = BankoBot.httpClient.get(Config.DOCDEX_URL) { url { path("javadocs")