Skip to content

Commit

Permalink
Continued work on new translations system
Browse files Browse the repository at this point in the history
  • Loading branch information
gdude2002 committed Sep 10, 2024
1 parent 2d1e28e commit 7c48b82
Show file tree
Hide file tree
Showing 15 changed files with 258 additions and 147 deletions.
28 changes: 22 additions & 6 deletions buildSrc/src/main/kotlin/Translations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.gradle.api.tasks.Sync
import org.gradle.configurationcache.extensions.capitalized
import org.gradle.kotlin.dsl.*
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
import java.nio.file.Files
import java.util.Properties
import kotlin.collections.filterNotNull

Expand Down Expand Up @@ -45,7 +46,12 @@ fun Project.getTranslations(classesPackage: String, bundle: String = project.nam
getTranslations(project.name, classesPackage, bundle)
}

fun Project.getTranslations(name: String, classesPackage: String, bundle: String = name) {
fun Project.getTranslations(
name: String,
classesPackage: String,
bundle: String = name,
translationsClass: String = "Translations",
) {
val outputDir = project.layout.buildDirectory.dir("translations")
val gitDir = project.layout.buildDirectory.dir("translationsGit")

Expand Down Expand Up @@ -98,17 +104,27 @@ fun Project.getTranslations(name: String, classesPackage: String, bundle: String
doLast {
val props = Properties()

val bundleName = if (bundle == name || "." in bundle) {
bundle
} else {
"$name.$bundle"
}

props.load(
gitDir.get()
.file("$name/$bundle.properties")
.asFile
.inputStream()
Files.newBufferedReader(
gitDir.get()
.file("$name/${bundleName.split(".").last()}.properties")
.asFile.toPath(),

Charsets.UTF_8
)
)

val keys = props.toList()
.map { (left, _) -> left.toString() }

createTranslationsClass("$classesPackage.generated", keys).writeTo(classOutputDir.get().asFile)
createTranslationsClass("$classesPackage.generated", keys, props, bundleName, translationsClass)
.writeTo(classOutputDir.get().asFile)
}
}

Expand Down
65 changes: 51 additions & 14 deletions buildSrc/src/main/kotlin/TranslationsClassBuilder.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import com.hanggrian.kotlinpoet.TypeSpecBuilder
import com.hanggrian.kotlinpoet.addObject
import com.hanggrian.kotlinpoet.buildFileSpec
import com.hanggrian.kotlinpoet.buildObjectTypeSpec
import com.hanggrian.kotlinpoet.buildPropertySpec
import com.squareup.kotlinpoet.ClassName
import org.gradle.configurationcache.extensions.capitalized
import java.util.Properties

/*
* Copyrighted (Kord Extensions, 2024). Licensed under the EUPL-1.2
Expand All @@ -14,19 +14,46 @@ import org.gradle.configurationcache.extensions.capitalized
* Any redistribution must include the specific provision above.
*/

fun key(name: String, value: String) = buildPropertySpec(name, ClassName("dev.kordex.core.i18n.types", "Key")) {
setInitializer("Key(%S)", value)
}
fun bundle(bundleName: String) =
buildPropertySpec("bundle", ClassName("dev.kordex.core.i18n.types", "Bundle")) {
setInitializer("Bundle(%S)", bundleName)
}

fun key(name: String, value: String, property: String, translationsClassName: String) =
buildPropertySpec(name.replace("-", "_"), ClassName("dev.kordex.core.i18n.types", "Key")) {
setInitializer("Key(%S)\n.withBundle(%L.bundle)", value, translationsClassName)

fun createTranslationsClass(classPackage: String, keys: List<String>) =
buildFileSpec(classPackage, "Translations") {
types.addObject("Translations") {
addKeys(keys)
property.lines().forEach {
kdoc.addStatement(
"%L",
it.trim().replace("*/", "")
)
}
}

fun TypeSpecBuilder.addKeys(keys: List<String>, parent: String? = null) {

fun createTranslationsClass(
classPackage: String,
keys: List<String>,
props: Properties,
bundleName: String,
translationsClassName: String,
) = buildFileSpec(classPackage, translationsClassName) {
types.addObject(translationsClassName) {
properties.add(
bundle(bundleName)
)

addKeys(keys, props, translationsClassName)
}
}

fun TypeSpecBuilder.addKeys(
keys: List<String>,
props: Properties,
translationsClassName: String,
parent: String? = null,
) {
val paritioned = keys.partition()

paritioned.forEach { (k, v) ->
Expand All @@ -36,12 +63,22 @@ fun TypeSpecBuilder.addKeys(keys: List<String>, parent: String? = null) {
k
}

if (v.isEmpty()) {
properties.add(key(k.toVarName(), keyName))
} else {
if (v.isEmpty() || props[keyName] != null) {
properties.add(
key(k.toVarName(), keyName, props.getProperty(keyName), translationsClassName)
)
}

if (v.isNotEmpty()) {
// Object
types.addObject(k.capitalized()) {
addKeys(v, keyName)
val objName = k
.replace("-", " ")
.split(" ")
.map { it.capitalized() }
.joinToString("")

types.addObject(objName) {
addKeys(v, props, translationsClassName, keyName)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion kord-extensions/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ plugins {
`ksp-module`
}

getTranslations("core", "dev.kordex.core.i18n", "strings")
getTranslations("core", "dev.kordex.core.i18n", "kordex.strings", "CoreTranslations")

metadata {
name = "KordEx Core"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@

package dev.kordex.core.builders.about

public sealed class CopyrightType(public val key: String) {
public object Framework : CopyrightType("extensions.about.copyright.type.frameworks")
public object Library : CopyrightType("extensions.about.copyright.type.libraries")
public object PluginModule : CopyrightType("extensions.about.copyright.type.plugins-modules")
public object Tool : CopyrightType("extensions.about.copyright.type.tools")
import dev.kordex.core.i18n.generated.CoreTranslations
import dev.kordex.core.i18n.types.Key

public sealed class CopyrightType(public val key: Key) {
public object Framework : CopyrightType(CoreTranslations.Extensions.About.Copyright.Type.frameworks)
public object Library : CopyrightType(CoreTranslations.Extensions.About.Copyright.Type.libraries)
public object PluginModule : CopyrightType(CoreTranslations.Extensions.About.Copyright.Type.plugins_modules)
public object Tool : CopyrightType(CoreTranslations.Extensions.About.Copyright.Type.tools)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package dev.kordex.core.commands

import dev.kordex.core.commands.converters.Converter
import dev.kordex.core.i18n.TranslationsProvider
import dev.kordex.core.i18n.types.Key

/**
* Data class representing a single argument.
Expand All @@ -19,8 +20,8 @@ import dev.kordex.core.i18n.TranslationsProvider
* @param converter Argument converter to use for this argument.
*/
public data class Argument<T : Any?>(
val displayName: String,
val description: String,
val displayName: Key,
val description: Key,
val converter: Converter<T, *, *, *>,
) {
init {
Expand All @@ -29,8 +30,5 @@ public data class Argument<T : Any?>(
}

internal fun Argument<*>.getDefaultTranslatedDisplayName(provider: TranslationsProvider, command: Command): String =
provider.translate(
key = displayName,
bundleName = command.resolvedBundle ?: converter.bundle,
locale = provider.defaultLocale
)
displayName.withBundle(command.resolvedBundle ?: converter.bundle)
.translateLocale(provider.defaultLocale)
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import dev.kordex.core.builders.ExtensibleBotBuilder
import dev.kordex.core.commands.events.CommandEvent
import dev.kordex.core.extensions.Extension
import dev.kordex.core.i18n.TranslationsProvider
import dev.kordex.core.i18n.types.Bundle
import dev.kordex.core.i18n.types.Key
import dev.kordex.core.koin.KordExKoinComponent
import dev.kordex.core.sentry.SentryAdapter
import dev.kordex.core.types.Lockable
Expand All @@ -44,19 +46,19 @@ public abstract class Command(public val extension: Extension) : Lockable, KordE
/**
* The name of this command, for invocation and help commands.
*/
public open lateinit var name: String
public open lateinit var name: Key

/** Set this to `true` to lock command execution with a Mutex. **/
public override var locking: Boolean = false

/** Translation bundle to use, if not the one provided by the extension. **/
public var bundle: String? = null
public var bundle: Bundle? = null

/**
* @suppress Bundle getter that exists because the extension bundle may have changed by the time the command is
* registered.
*/
public val resolvedBundle: String?
public val resolvedBundle: Bundle?
get() = bundle ?: extension.bundle

override var mutex: Mutex? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import dev.kordex.core.commands.events.*
import dev.kordex.core.extensions.Extension
import dev.kordex.core.extensions.impl.SENTRY_EXTENSION_NAME
import dev.kordex.core.i18n.EMPTY_VALUE_STRING
import dev.kordex.core.i18n.generated.Translations
import dev.kordex.core.i18n.types.Key
import dev.kordex.core.sentry.BreadcrumbType
import dev.kordex.core.types.FailureReason
import dev.kordex.core.utils.MutableStringKeyedMap
Expand Down Expand Up @@ -63,7 +65,7 @@ public open class ChatCommand<T : Arguments>(
*
* This is intended to be made use of by help commands.
*/
public open var description: String = "commands.defaultDescription"
public open var description: Key = Translations.Commands.defaultDescription

/**
* Whether this command is enabled and can be invoked.
Expand Down Expand Up @@ -105,7 +107,7 @@ public open class ChatCommand<T : Arguments>(
* If this is set, the [aliases] list is ignored. This is also slightly more efficient during the first
* translation pass, as only one key will ever need to be translated.
*/
public open var aliasKey: String? = null
public open var aliasKey: Key? = null

/**
* @suppress
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import dev.kordex.core.commands.Arguments
import dev.kordex.core.commands.CommandContext
import dev.kordex.core.commands.converters.builders.ConverterBuilder
import dev.kordex.core.commands.converters.builders.ValidationContext
import dev.kordex.core.i18n.types.Bundle
import dev.kordex.core.i18n.types.Key
import dev.kordex.core.koin.KordExKoinComponent
import dev.kordex.parser.StringParser
import org.koin.core.component.inject
Expand Down Expand Up @@ -70,14 +72,14 @@ public abstract class Converter<InputType : Any?, OutputType : Any?, NamedInputT
* Translation key pointing to a short string describing the type of data this converter handles. Should be very
* short.
*/
public abstract val signatureTypeString: String
public abstract val signatureTypeString: Key

/**
* String referring to the translation bundle name required to resolve translations for this converter.
*
* For more information, see the i18n page of the documentation.
*/
public open val bundle: String? = null
public open val bundle: Bundle? = null

/**
* If the [signatureTypeString] isn't sufficient, you can optionally provide a translation key pointing to a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import dev.kord.core.Kord
import dev.kord.core.event.Event
import dev.kord.gateway.Intent
import dev.kordex.core.ExtensibleBot
import dev.kordex.core.annotations.tooling.Translatable
import dev.kordex.core.annotations.tooling.TranslatableType
import dev.kordex.core.checks.types.ChatCommandCheck
import dev.kordex.core.checks.types.MessageCommandCheck
import dev.kordex.core.checks.types.SlashCommandCheck
Expand All @@ -28,6 +26,7 @@ import dev.kordex.core.commands.chat.ChatCommand
import dev.kordex.core.commands.chat.ChatCommandRegistry
import dev.kordex.core.events.EventHandler
import dev.kordex.core.events.ExtensionStateEvent
import dev.kordex.core.i18n.types.Bundle
import dev.kordex.core.koin.KordExKoinComponent
import io.github.oshai.kotlinlogging.KotlinLogging
import org.koin.core.component.inject
Expand Down Expand Up @@ -146,8 +145,7 @@ public abstract class Extension : KordExKoinComponent {
public val userCommandChecks: MutableList<UserCommandCheck> = mutableListOf()

/** String representing the bundle to get translations from for command names/descriptions. **/
@Translatable(TranslatableType.BUNDLE)
public open val bundle: String? = null
public open val bundle: Bundle? = null

/** Set of intents required by this extension's event handlers and commands. **/
public open val intents: MutableSet<Intent> = mutableSetOf()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import dev.kordex.core.extensions.Extension
import dev.kordex.core.extensions.chatGroupCommand
import dev.kordex.core.extensions.ephemeralSlashCommand
import dev.kordex.core.extensions.publicSlashCommand
import dev.kordex.core.i18n.TranslationsProvider
import dev.kordex.core.i18n.generated.Translations
import dev.kordex.core.i18n.key
import dev.kordex.core.pagination.builders.PaginatorBuilder
import org.koin.core.component.inject
import java.util.Locale
Expand All @@ -29,7 +30,6 @@ import java.util.Locale
public class AboutExtension : Extension() {
override val name: String = "kordex.about"

private val translations: TranslationsProvider by inject()
private val settings: ExtensibleBotBuilder by inject()

override suspend fun setup() {
Expand Down Expand Up @@ -177,23 +177,17 @@ public class AboutExtension : Extension() {
color = DISCORD_BLURPLE
title = "Copyright Information"

description = buildString {
appendLine(
translations.translate(
"extensions.about.copyright.intro",
locale,
replacements = arrayOf(
"[Kord Extensions](https://kordex.dev)",
"EUPL",
"1.2"
)
)
description = Translations.Extensions.About.Copyright.intro
.withLocale(locale)
.translate(
"[Kord Extensions](https://kordex.dev)",
"EUPL",
"1.2"
)
}
}

copyright
.groupBy { translations.translate(it.type.key, locale) }
.groupBy { it.type.key.withLocale(locale).translate() }
.toSortedMap { left, right -> left.compareTo(right) }
.forEach { (type, items) ->
items
Expand Down
Loading

0 comments on commit 7c48b82

Please sign in to comment.