Skip to content

Commit

Permalink
update local time with timezone list command
Browse files Browse the repository at this point in the history
  • Loading branch information
NikkyAI committed Jan 15, 2024
1 parent 1ee820a commit d5fb587
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 55 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ out/
build/

/data/
/config/
/logs/
/run
/colors
Expand Down
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pluginManagement {
}

plugins {
id("com.gradle.enterprise") version "3.15.1"
id("com.gradle.enterprise") version "3.16.1"
id("de.fayard.refreshVersions") version "0.60.3"
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/moe/nikky/BotInfoExtension.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.kotlindiscord.kord.extensions.extensions.Extension
import com.kotlindiscord.kord.extensions.extensions.ephemeralSlashCommand
import dev.kord.common.entity.Permission
import dev.kord.common.entity.Permissions
import dev.kord.rest.builder.message.create.embed
import dev.kord.rest.builder.message.embed
import io.klogging.Klogging
import io.ktor.http.*
import kotlinx.coroutines.flow.count
Expand Down
135 changes: 97 additions & 38 deletions src/main/kotlin/moe/nikky/LocalTimeExtension.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
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
Expand All @@ -12,18 +13,19 @@ import com.kotlindiscord.kord.extensions.storage.StorageUnit
import com.kotlindiscord.kord.extensions.utils.suggestStringMap
import dev.kord.common.entity.Snowflake
import dev.kord.core.behavior.GuildBehavior
import dev.kord.core.entity.Guild
import dev.kord.core.entity.User
import dev.kord.rest.builder.message.create.embed
import dev.kord.rest.builder.message.embed
import io.klogging.Klogging
import io.ktor.client.request.forms.*
import io.ktor.utils.io.*
import kotlinx.datetime.Clock
import kotlinx.datetime.IllegalTimeZoneException
import kotlinx.datetime.Instant
import kotlinx.datetime.TimeZone
import kotlinx.datetime.offsetAt
import kotlinx.datetime.toInstant
import kotlinx.datetime.toLocalDateTime
import kotlinx.serialization.Serializable
import kotlin.time.Duration
import kotlin.time.Duration.Companion.ZERO
import kotlin.time.Duration.Companion.seconds

Expand All @@ -48,9 +50,9 @@ class LocalTimeExtension : Extension(), Klogging {
"UTC", "GMT", "Europe/London",
"CET", "Europe/Berlin", "Europe/Paris",
"NZ", "Japan", "Asia/Tokyo",
"Asia/Manila", "Asia/Kolkata", "Asia/Jakarta",
"US/Eastern", "US/Central", "America/New_York",
"US/Pacific", "America/Sao_Paulo", "America/Chicago",
"US/Alaska", "US/Pacific", "US/Mountain",
"US/Central", "US/Eastern", "Canada/Eastern",
"America/New_York", "America/Sao_Paulo", "America/Chicago",
"America/Los_Angeles", "Europe/Moscow", "Singapore",
)
}
Expand All @@ -61,45 +63,80 @@ class LocalTimeExtension : Extension(), Klogging {
name = "timezone"
description = "list or set timezones"

action {
withLogContext(event, guild) { guild ->
logger.infoF { "received timezone id: ${arguments.timezoneId}" }
val timezone = try {
TimeZone.of(arguments.timezoneId)
} catch (e: IllegalTimeZoneException) {
respond {
content = "Possibly you meant one of the following timezones?"
embed {
SUGGEST_TIMEZONES.mapNotNull { zoneId ->
try {
TimeZone.of(zoneId)
} catch (e: IllegalTimeZoneException) {
logger.errorF { "incorrect timezone id: '$zoneId'" }
null
}
}.forEach { timezone ->
field {
val formattedTime = formatTime(Clock.System.now(), timezone)
name = timezone.id
value = "\uD83D\uDD57 `$formattedTime`"
inline = true
ephemeralSubCommand(::TimezoneArgs) {
name = "set"
description = "update your timezone"

action {
withLogContext(event, guild) { guild ->
logger.infoF { "received timezone id: ${arguments.timezoneId}" }
val timezone = try {
TimeZone.of(arguments.timezoneId)
} catch (e: IllegalTimeZoneException) {
respond {
content =
"""Possibly you meant one of the following timezones?
|for a full list of availabe zone ids run
|```
|/timezone list
|```
|""".trimMargin()
embed {
SUGGEST_TIMEZONES.mapNotNull { zoneId ->
try {
TimeZone.of(zoneId)
} catch (e: IllegalTimeZoneException) {
logger.errorF { "incorrect timezone id: '$zoneId'" }
null
}
}.forEach { timezone ->
field {
val formattedTime = formatTime(Clock.System.now(), timezone)
name = timezone.id
value = "\uD83D\uDD57 `$formattedTime`"
inline = true
}
}
}
}
return@withLogContext
}

val configStorage = guild.config(event.interaction.user.id)
configStorage.save(
TimezoneConfig(timezoneId = timezone.id)
)

respond {
val formattedTime = formatTime(Clock.System.now(), timezone)

content =
"Timezone has been set to **${timezone.id}**. Your current time should be `$formattedTime`"
}
return@withLogContext
}
}
}

val configStorage = guild.config(event.interaction.user.id)
configStorage.save(
TimezoneConfig(timezoneId = timezone.id)
)
ephemeralSubCommand() {
name = "list"
description = "sends a list of valid timezones"

respond {
val formattedTime = formatTime(Clock.System.now(), timezone)
action {
withLogContext(event, guild) { guild ->
val timezones = TimeZone.sortedList().map { (tz, offset) ->
"${offset.toString().padEnd(10, ' ')} ${tz.id}"
}

respond {
content = "a list of valid timezone ids is in the attachment"

content =
"Timezone has been set to **${timezone.id}**. Your current time should be `$formattedTime`"
addFile(
"timezones.txt",
ChannelProvider {
ByteReadChannel(timezones.joinToString("\n"))
}
)
}
}
}
}
Expand Down Expand Up @@ -150,7 +187,7 @@ class LocalTimeExtension : Extension(), Klogging {
targetUser: User,
selfUser: User,
): String {
val targetConfig = guild.config(targetUser.id).get()
val targetConfig = guild.config(targetUser.id).get()
val selfConfig = guild.config(selfUser.id).get()

if (targetConfig == null) {
Expand Down Expand Up @@ -208,6 +245,7 @@ class LocalTimeExtension : Extension(), Klogging {
}
}
}

inner class TimezoneTargetArgs : Arguments() {
val user by user {
name = "user"
Expand All @@ -223,3 +261,24 @@ data class TimezoneConfig(
) : Data {
val timezone: TimeZone by lazy { TimeZone.of(timezoneId) }
}

fun TimeZone.Companion.sortedList(): List<Pair<TimeZone, Duration>> {
val now = Clock.System.now()
return TimeZone.availableZoneIds
.map { zoneId ->
TimeZone.of(zoneId)
}
.sortedBy { tz ->
tz.offsetAt(now).totalSeconds
}.map { tz ->
val offset = tz.offsetAt(now)
val hoursOffset = -offset.totalSeconds.seconds
tz to hoursOffset
}
}

fun main() {
TimeZone.sortedList().forEach { (tz, offset) ->
println("${offset.toString().padEnd(10, ' ')} ${tz.id}")
}
}
29 changes: 14 additions & 15 deletions versions.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,20 @@

plugin.com.github.johnrengelman.shadow=8.1.1

plugin.com.google.devtools.ksp=1.9.10-1.0.13
## # available=1.9.20-Beta-1.0.13
## # available=1.9.20-Beta2-1.0.13
## # available=1.9.20-RC-1.0.13
## # available=1.9.20-RC2-1.0.13
## # available=1.9.20-1.0.13
plugin.com.google.devtools.ksp=1.9.22-1.0.16
## # available=2.0.0-Beta1-1.0.14
## # available=2.0.0-Beta1-1.0.15
## # available=2.0.0-Beta2-1.0.16

version.br.com.colman..dice-helper=1.0.0

version.io.github.xn32..json5k=0.3.0
## # available=0.4.0-SNAPSHOT

version.io.klogging..klogging-jvm=0.5.6
version.io.klogging..klogging-jvm=0.5.8
## # available=0.6.0-SNAPSHOT

version.io.klogging..slf4j-klogging=0.5.6
version.io.klogging..slf4j-klogging=0.5.8
## # available=0.6.0-SNAPSHOT

version.junit.jupiter=5.10.0
Expand All @@ -35,19 +33,20 @@ version.kord.extensions=1.6.0-SNAPSHOT

version.kord.x.emoji=0.5.0

version.kotlin=1.9.10
## # available=1.9.20-Beta
## # available=1.9.20-Beta2
## # available=1.9.20-RC
## # available=1.9.20-RC2
## # available=1.9.20
version.kotlin=1.9.22
## # available=2.0.0-Beta1
## # available=2.0.0-Beta2

version.kotlinx.coroutines=1.7.3
## # available=1.8.0-RC
## # available=1.8.0-RC2

version.kotlinx.datetime=0.4.1

version.kotlinx.serialization=1.6.0

version.ktor=2.3.5

version.org.slf4j..slf4j-api=2.0.9
version.org.slf4j..slf4j-api=2.0.11
## # available=2.1.0-alpha0
## # available=2.1.0-alpha1

0 comments on commit d5fb587

Please sign in to comment.