Rewrite config to use Konf (2): Localization

This commit is contained in:
kageru 2019-10-18 19:34:41 +02:00
parent e31d46ceb5
commit 17c7120796
Signed by: kageru
GPG Key ID: 8282A2BEA4ADA3D2
12 changed files with 47 additions and 61 deletions

View File

@ -5,6 +5,7 @@ import moe.kageru.kagebot.Log
import moe.kageru.kagebot.MessageUtil
import moe.kageru.kagebot.Util.applyIf
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.config.LocalizationSpec
import moe.kageru.kagebot.config.RawCommand
import moe.kageru.kagebot.features.MessageFeature
import org.javacord.api.entity.message.MessageAuthor
@ -41,8 +42,8 @@ class Command(cmd: RawCommand) {
fun execute(message: MessageCreateEvent): Boolean {
if (permissions?.isAllowed(message) == false) {
if (Config.localization.permissionDenied.isNotBlank()) {
message.channel.sendMessage(Config.localization.permissionDenied)
if (Config.localization[LocalizationSpec.permissionDenied].isNotBlank()) {
message.channel.sendMessage(Config.localization[LocalizationSpec.permissionDenied])
}
Log.info("Denying command ${this.trigger} to user ${message.messageAuthor.discriminatedName} (ID: ${message.messageAuthor.id})")
return false
@ -62,9 +63,10 @@ class Command(cmd: RawCommand) {
fun matches(msg: String) = this.matchType.matches(msg, this)
private fun respond(author: MessageAuthor, response: String) = response.applyIf(response.contains(AUTHOR_PLACEHOLDER)) {
it.replace(AUTHOR_PLACEHOLDER, MessageUtil.mention(author))
}
private fun respond(author: MessageAuthor, response: String) =
response.applyIf(response.contains(AUTHOR_PLACEHOLDER)) {
it.replace(AUTHOR_PLACEHOLDER, MessageUtil.mention(author))
}
}
enum class MatchType {

View File

@ -3,6 +3,7 @@ package moe.kageru.kagebot.command
import moe.kageru.kagebot.Log
import moe.kageru.kagebot.MessageUtil.sendEmbed
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.config.LocalizationSpec
import moe.kageru.kagebot.config.RawMessageActions
import org.javacord.api.event.message.MessageCreateEvent
@ -24,7 +25,7 @@ class MessageActions(rawActions: RawMessageActions) {
message.deleteMessage()
message.messageAuthor.asUser().ifPresent { user ->
user.sendEmbed {
addField("__Blacklisted__", Config.localization.messageDeleted)
addField("__Blacklisted__", Config.localization[LocalizationSpec.messageDeleted])
addField("Original:", "${message.readableMessageContent}")
}
}

View File

@ -6,6 +6,7 @@ import moe.kageru.kagebot.Util
import moe.kageru.kagebot.Util.applyIf
import moe.kageru.kagebot.Util.failed
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.config.LocalizationSpec
import moe.kageru.kagebot.config.RawRedirect
import org.javacord.api.entity.channel.TextChannel
import org.javacord.api.event.message.MessageCreateEvent
@ -21,7 +22,7 @@ internal class MessageRedirect(rawRedirect: RawRedirect) {
.applyIf(command.matchType == MatchType.PREFIX) { content ->
content.removePrefix(command.trigger).trim()
}
addField(Config.localization.redirectedMessage, redirectedText)
addField(Config.localization[LocalizationSpec.redirectedMessage], redirectedText)
Log.info("Redirected message: $redirectedText")
}
// No inlined if/else because the types are different.

View File

@ -7,10 +7,11 @@ import moe.kageru.kagebot.features.Features
import org.javacord.api.entity.server.Server
object Config {
val specs = Config { addSpec(SystemSpec) }.from.toml
lateinit var config: Config
val systemSpec = Config { addSpec(SystemSpec) }.from.toml
val localeSpec = Config { addSpec(LocalizationSpec) }.from.toml
lateinit var system: Config
lateinit var localization: Config
lateinit var server: Server
lateinit var commands: List<Command>
lateinit var features: Features
lateinit var localization: Localization
}

View File

@ -11,21 +11,16 @@ object ConfigParser {
fun initialLoad(file: String) {
val rawConfig = RawConfig.read(file)
val config = Config.specs.file(RawConfig.getFile(file))
Config.config = config
val configFile = RawConfig.getFile(file)
val config = Config.systemSpec.file(configFile)
Config.system = config
Config.server = Globals.api.getServerById(config[serverId])
.orElseThrow { IllegalArgumentException("Invalid server configured.") }
reloadLocalization(rawConfig)
Config.localization = Config.localeSpec.file(configFile)
reloadFeatures(rawConfig)
reloadCommands(rawConfig)
}
fun reloadLocalization(rawConfig: RawConfig) {
Config.localization = rawConfig.localization?.let(::Localization)
?: throw IllegalArgumentException("No [localization] block in config.")
}
fun reloadCommands(rawConfig: RawConfig) {
Config.commands = rawConfig.commands?.map(::Command)?.toMutableList()
?: throw IllegalArgumentException("No commands found in config.")
@ -36,22 +31,3 @@ object ConfigParser {
?: Features(RawFeatures(null, null))
}
}
class Localization(
val permissionDenied: String,
val redirectedMessage: String,
val messageDeleted: String,
val timeout: String
) {
constructor(rawLocalization: RawLocalization) : this(
permissionDenied = rawLocalization.permissionDenied
?: throw IllegalArgumentException("No [localization.permissionDenied] defined"),
redirectedMessage = rawLocalization.redirectedMessage
?: throw IllegalArgumentException("No [localization.redirectMessage] defined"),
messageDeleted = rawLocalization.messageDeleted
?: throw IllegalArgumentException("No [localization.messageDeleted] defined"),
timeout = rawLocalization.timeout
?: throw IllegalArgumentException("No [localization.timeout] defined")
)
}

View File

@ -3,12 +3,11 @@ package moe.kageru.kagebot.config
import com.google.gson.annotations.SerializedName
import com.moandjiezana.toml.Toml
import com.uchuhimo.konf.ConfigSpec
import moe.kageru.kagebot.config.Config.config
import moe.kageru.kagebot.config.Config.system
import java.awt.Color
import java.io.File
class RawConfig(
val localization: RawLocalization?,
@SerializedName("command")
val commands: List<RawCommand>?,
@SerializedName("feature")
@ -38,12 +37,12 @@ class RawConfig(
object SystemSpec : ConfigSpec() {
private val rawColor by optional("#1793d0", name = "color")
val serverId by required<String>()
val color by kotlin.lazy { Color.decode(config[rawColor])!! }
val color by kotlin.lazy { Color.decode(system[rawColor])!! }
}
class RawLocalization(
val permissionDenied: String?,
val redirectedMessage: String?,
val messageDeleted: String?,
val timeout: String?
)
object LocalizationSpec : ConfigSpec() {
val permissionDenied by optional("You do not have the permission to use this command.")
val redirectedMessage by optional("says")
val messageDeleted by optional("Your message was deleted.")
val timeout by optional("You have been timed out for @@ minutes.")
}

View File

@ -2,6 +2,7 @@ package moe.kageru.kagebot.features
import moe.kageru.kagebot.Log
import moe.kageru.kagebot.MessageUtil.sendEmbed
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.config.ConfigParser
import moe.kageru.kagebot.config.RawConfig
import org.javacord.api.entity.channel.TextChannel
@ -22,7 +23,7 @@ class SetConfigFeature : MessageFeature {
return
}
try {
ConfigParser.reloadLocalization(rawConfig)
Config.localization = Config.localeSpec.string(newConfig)
ConfigParser.reloadFeatures(rawConfig)
ConfigParser.reloadCommands(rawConfig)
ConfigParser.configFile.writeText(newConfig)

View File

@ -6,6 +6,7 @@ import moe.kageru.kagebot.Util.findRole
import moe.kageru.kagebot.Util.findUser
import moe.kageru.kagebot.Util.ifNotEmpty
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.config.LocalizationSpec
import moe.kageru.kagebot.config.RawTimeoutFeature
import moe.kageru.kagebot.persistence.Dao
import org.javacord.api.entity.permission.Role
@ -41,7 +42,10 @@ class TimeoutFeature(raw: RawTimeoutFeature) : MessageFeature {
val releaseTime = Instant.now().plus(Duration.ofMinutes(timeout.duration)).epochSecond
Dao.saveTimeout(releaseTime, listOf(user.id) + oldRoles)
user.sendEmbed {
addField("Timeout", Config.localization.timeout.replace("@@", timeout.duration.toString()))
addField(
"Timeout",
Config.localization[LocalizationSpec.timeout].replace("@@", timeout.duration.toString())
)
timeout.reason?.let {
addField("Reason", it)
}

View File

@ -6,6 +6,7 @@ import io.kotlintest.specs.ShouldSpec
import io.mockk.every
import io.mockk.mockk
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.config.LocalizationSpec
import moe.kageru.kagebot.config.SystemSpec
import moe.kageru.kagebot.features.SetConfigFeature
import java.awt.Color
@ -14,9 +15,8 @@ import java.awt.Color
class ConfigTest : ShouldSpec({
TestUtil.prepareTestEnvironment()
"should properly parse test config" {
Config.config[SystemSpec.serverId] shouldNotBe null
Config.system[SystemSpec.serverId] shouldNotBe null
SystemSpec.color shouldBe Color.decode("#1793d0")
Config.localization shouldNotBe null
Config.features shouldNotBe null
Config.commands.size shouldBe 3
}
@ -38,6 +38,6 @@ class ConfigTest : ShouldSpec({
every { url.openStream().readAllBytes() } returns testConfig.toByteArray()
})
SetConfigFeature().handle(message)
Config.localization.permissionDenied shouldBe denied
Config.localization[LocalizationSpec.permissionDenied] shouldBe denied
}
})

View File

@ -116,7 +116,7 @@ object TestUtil {
return (embed.delegate as EmbedBuilderDelegateImpl).toJsonNode().toString()
}
fun <R> withCommands(config: String, test: (() -> R)) {
fun withCommands(config: String, test: (() -> Unit)) {
val oldCmds = Config.commands
val rawConfig = RawConfig.readFromString(config)
ConfigParser.reloadCommands(rawConfig)
@ -124,10 +124,9 @@ object TestUtil {
Config.commands = oldCmds
}
fun <R> withLocalization(config: String, test: (() -> R)) {
fun withLocalization(config: String, test: (() -> Unit)) {
val oldLoc = Config.localization
val rawConfig = RawConfig.readFromString(config)
ConfigParser.reloadLocalization(rawConfig)
Config.localization = Config.localeSpec.string(config)
test()
Config.localization = oldLoc
}

View File

@ -5,7 +5,6 @@ import io.kotlintest.shouldBe
import io.kotlintest.specs.StringSpec
import io.mockk.every
import io.mockk.mockk
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.Globals
import moe.kageru.kagebot.Kagebot.process
import moe.kageru.kagebot.TestUtil
@ -17,6 +16,9 @@ import moe.kageru.kagebot.TestUtil.testMessageSuccess
import moe.kageru.kagebot.TestUtil.withCommands
import moe.kageru.kagebot.TestUtil.withLocalization
import moe.kageru.kagebot.Util
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.config.Config.localization
import moe.kageru.kagebot.config.LocalizationSpec
import org.javacord.api.entity.message.embed.EmbedBuilder
import org.javacord.api.entity.permission.Role
import org.javacord.api.entity.user.User
@ -146,7 +148,7 @@ class CommandTest : StringSpec({
val replies = mutableListOf<String>()
val mockMessage = mockMessage("!restricted", replies = replies)
mockMessage.process()
replies shouldBe mutableListOf(Config.localization.permissionDenied)
replies shouldBe mutableListOf(localization[LocalizationSpec.permissionDenied])
withLocalization(
"""
[localization]
@ -231,7 +233,7 @@ class CommandTest : StringSpec({
every { get().getRoles(any()) } returns emptyList()
}
mockMessage.process()
calls shouldBe mutableListOf(Config.localization.permissionDenied, "access granted")
calls shouldBe mutableListOf(localization[LocalizationSpec.permissionDenied], "access granted")
}
}
"should refuse DM only message in server channel" {
@ -246,7 +248,7 @@ class CommandTest : StringSpec({
) {
val calls = mutableListOf<String>()
mockMessage("!dm", replies = calls).process()
calls shouldBe listOf(Config.localization.permissionDenied)
calls shouldBe listOf(localization[LocalizationSpec.permissionDenied])
}
}
/*

View File

@ -3,12 +3,12 @@ package moe.kageru.kagebot.features
import io.kotlintest.specs.StringSpec
import io.mockk.every
import io.mockk.mockk
import moe.kageru.kagebot.config.Config
import moe.kageru.kagebot.Kagebot.process
import moe.kageru.kagebot.TestUtil
import moe.kageru.kagebot.TestUtil.mockMessage
import moe.kageru.kagebot.TestUtil.withCommands
import moe.kageru.kagebot.TestUtil.withReplyContents
import moe.kageru.kagebot.config.Config
import org.javacord.api.entity.message.embed.EmbedBuilder
import java.util.*