Skip to content

Commit

Permalink
Refactor linkCal command to kotlin coroutines
Browse files Browse the repository at this point in the history
  • Loading branch information
NovaFox161 committed Feb 28, 2024
1 parent ca715f6 commit 59b1d5b
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 122 deletions.
Original file line number Diff line number Diff line change
@@ -1,38 +1,45 @@
package org.dreamexposure.discal.client.commands.global

import discord4j.core.event.domain.interaction.ChatInputInteractionEvent
import discord4j.core.`object`.command.ApplicationCommandInteractionOption
import discord4j.core.`object`.command.ApplicationCommandInteractionOptionValue
import discord4j.core.`object`.entity.Message
import discord4j.core.event.domain.interaction.ChatInputInteractionEvent
import kotlinx.coroutines.reactor.awaitSingle
import kotlinx.coroutines.reactor.awaitSingleOrNull
import org.dreamexposure.discal.client.commands.SlashCommand
import org.dreamexposure.discal.client.message.embed.CalendarEmbed
import org.dreamexposure.discal.core.`object`.GuildSettings
import org.dreamexposure.discal.core.business.EmbedService
import org.dreamexposure.discal.core.extensions.discord4j.followup
import org.dreamexposure.discal.core.extensions.discord4j.getCalendar
import org.dreamexposure.discal.core.`object`.GuildSettings
import org.dreamexposure.discal.core.utils.getCommonMsg
import org.springframework.stereotype.Component
import reactor.core.publisher.Mono

@Component
class LinkCalendarCommand : SlashCommand {
class LinkCalendarCommand(
private val embedService: EmbedService,
) : SlashCommand {
override val name = "linkcal"
override val ephemeral = false

@Deprecated("Use new handleSuspend for K-coroutines")
override fun handle(event: ChatInputInteractionEvent, settings: GuildSettings): Mono<Message> {

override suspend fun suspendHandle(event: ChatInputInteractionEvent, settings: GuildSettings): Message {
val showOverview = event.getOption("overview")
.flatMap(ApplicationCommandInteractionOption::getValue)
.map(ApplicationCommandInteractionOptionValue::asBoolean)
.orElse(true)

val calendarNumber = event.getOption("calendar")
.flatMap(ApplicationCommandInteractionOption::getValue)
.map(ApplicationCommandInteractionOptionValue::asLong)
.map(Long::toInt)
.orElse(1)

return event.interaction.guild.flatMap { guild ->
CalendarEmbed.link(guild, settings, calendarNumber, showOverview)
.flatMap(event::followup)
}.switchIfEmpty(event.followup(getCommonMsg("error.notFound.calendar", settings)))
val calendar = event.interaction.guild.flatMap {
it.getCalendar(calendarNumber)
}.awaitSingleOrNull()
if (calendar == null) {
return event.followup(getCommonMsg("error.notFound.calendar", settings)).awaitSingle()
}

return event.followup(embedService.linkCalendarEmbed(calendarNumber, settings, showOverview)).awaitSingle()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,23 @@ package org.dreamexposure.discal.client.message.embed
import discord4j.core.`object`.entity.Guild
import discord4j.core.spec.EmbedCreateSpec
import org.dreamexposure.discal.core.entities.Calendar
import org.dreamexposure.discal.core.entities.Event
import org.dreamexposure.discal.core.enums.time.DiscordTimestampFormat
import org.dreamexposure.discal.core.enums.time.TimeFormat
import org.dreamexposure.discal.core.extensions.*
import org.dreamexposure.discal.core.extensions.discord4j.getCalendar
import org.dreamexposure.discal.core.extensions.embedDescriptionSafe
import org.dreamexposure.discal.core.extensions.embedFieldSafe
import org.dreamexposure.discal.core.extensions.embedTitleSafe
import org.dreamexposure.discal.core.extensions.toMarkdown
import org.dreamexposure.discal.core.`object`.GuildSettings
import org.dreamexposure.discal.core.`object`.calendar.PreCalendar
import org.dreamexposure.discal.core.utils.GlobalVal.discalColor
import org.dreamexposure.discal.core.utils.getCommonMsg
import reactor.core.publisher.Mono
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit

object CalendarEmbed : EmbedMaker {
fun link(guild: Guild, settings: GuildSettings, calNumber: Int, overview: Boolean): Mono<EmbedCreateSpec> {
return guild.getCalendar(calNumber).flatMap {
if (overview) overview(guild, settings, it, false)
else Mono.just(link(guild, settings, it))
}
}

@Deprecated("Use replacement in EmbedService")
fun link(guild: Guild, settings: GuildSettings, calendar: Calendar): EmbedCreateSpec {
val builder = defaultBuilder(guild, settings)
//Handle optional fields
Expand All @@ -45,99 +38,6 @@ object CalendarEmbed : EmbedMaker {
.build()
}

@Deprecated("Use replacement in EmbedService")
fun overview(guild: Guild, settings: GuildSettings, calendar: Calendar, showUpdate: Boolean): Mono<EmbedCreateSpec> {
return calendar.getUpcomingEvents(15).collectList().map { it.groupByDate() }.map { events ->
val builder = defaultBuilder(guild, settings)


//Handle optional fields
if (calendar.name.isNotBlank())
builder.title(calendar.name.toMarkdown().embedTitleSafe())
if (calendar.description.isNotBlank())
builder.description(calendar.description.toMarkdown().embedDescriptionSafe())

// Truncate dates to 23 due to discord enforcing the field limit
val truncatedEvents = mutableMapOf<ZonedDateTime, List<Event>>()
for (event in events) {
if (truncatedEvents.size < 23) {
truncatedEvents[event.key] = event.value
} else break
}

// Show events
truncatedEvents.forEach { date ->

val title = date.key.toInstant().humanReadableDate(calendar.timezone, settings.timeFormat, longDay = true)

// sort events
val sortedEvents = date.value.sortedBy { it.start }

val content = StringBuilder()

sortedEvents.forEach {
// Start event
content.append("```\n")


// determine time length
val timeDisplayLen = ("${it.start.humanReadableTime(it.timezone, settings.timeFormat)} -" +
" ${it.end.humanReadableTime(it.timezone,settings.timeFormat)} ").length

// Displaying time
if (it.isAllDay()) {
content.append(getCommonMsg("generic.time.allDay", settings).padCenter(timeDisplayLen))
.append("| ")
} else {
// Add start text
var str = if (it.start.isBefore(date.key.toInstant())) {
"${getCommonMsg("generic.time.continued", settings)} - "
} else {
"${it.start.humanReadableTime(it.timezone, settings.timeFormat)} - "
}
// Add end text
str += if (it.end.isAfter(date.key.toInstant().plus(1, ChronoUnit.DAYS))) {
getCommonMsg("generic.time.continued", settings)
} else {
"${it.end.humanReadableTime(it.timezone, settings.timeFormat)} "
}
content.append(str.padCenter(timeDisplayLen))
.append("| ")
}
// Display name or ID if not set
if (it.name.isNotBlank()) content.append(it.name)
else content.append(getMessage("calendar", "link.field.id", settings)).append(" ${it.eventId}")
content.append("\n")
if (it.location.isNotBlank()) content.append(" Location: ")
.append(it.location.embedFieldSafe())
.append("\n")

// Finish event
content.append("```\n")
}

if (content.isNotBlank())
builder.addField(title, content.toString().embedFieldSafe(), false)
}


// set footer
if (showUpdate) {
val lastUpdate = Instant.now().asDiscordTimestamp(DiscordTimestampFormat.RELATIVE_TIME)
builder.footer(getMessage("calendar", "link.footer.update", settings, lastUpdate), null)
.timestamp(Instant.now())
} else builder.footer(getMessage("calendar", "link.footer.default", settings), null)

// finish and return
builder.addField(getMessage("calendar", "link.field.timezone", settings), calendar.zoneName, true)
.addField(getMessage("calendar", "link.field.number", settings), "${calendar.calendarNumber}", true)
.url(calendar.link)
.color(discalColor)
.build()
}
}


fun time(guild: Guild, settings: GuildSettings, calNumber: Int): Mono<EmbedCreateSpec> {
return guild.getCalendar(calNumber).map { cal ->
val ldt = LocalDateTime.now(cal.timezone)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,7 @@ class EmbedService(
/////////////////////////////
////// Calendar Embeds //////
/////////////////////////////
suspend fun calendarOverviewEmbed(
calendar: Calendar,
settings: GuildSettings,
showUpdate: Boolean
): EmbedCreateSpec {
suspend fun calendarOverviewEmbed(calendar: Calendar, settings: GuildSettings, showUpdate: Boolean): EmbedCreateSpec {
val builder = defaultEmbedBuilder(settings)

// Get the events to build the overview
Expand Down Expand Up @@ -144,6 +140,31 @@ class EmbedService(
.build()
}

suspend fun linkCalendarEmbed(calendarNumber: Int, settings: GuildSettings, overview: Boolean): EmbedCreateSpec {
val calendar = discordClient.getGuildById(settings.guildID).getCalendar(calendarNumber).awaitSingle()
return if (overview) calendarOverviewEmbed(calendar, settings, showUpdate = false)
else linkCalendarEmbed(calendar, settings)
}

suspend fun linkCalendarEmbed(calendar: Calendar, settings: GuildSettings): EmbedCreateSpec {
val builder = defaultEmbedBuilder(settings)

//Handle optional fields
if (calendar.name.isNotBlank())
builder.title(calendar.name.toMarkdown().embedTitleSafe())
if (calendar.description.isNotBlank())
builder.description(calendar.description.toMarkdown().embedDescriptionSafe())

return builder.addField(getEmbedMessage("calendar", "link.field.timezone", settings), calendar.zoneName, false)
.addField(getEmbedMessage("calendar", "link.field.host", settings), calendar.calendarData.host.name, true)
.addField(getEmbedMessage("calendar", "link.field.number", settings), "${calendar.calendarNumber}", true)
.addField(getEmbedMessage("calendar", "link.field.id", settings), calendar.calendarId, false)
.url(calendar.link)
.footer(getEmbedMessage("calendar", "link.footer.default", settings), null)
.color(GlobalVal.discalColor)
.build()
}

/////////////////////////
////// RSVP Embeds //////
/////////////////////////
Expand Down

0 comments on commit 59b1d5b

Please sign in to comment.