Skip to content

Commit

Permalink
I think I found a pattern I like for calendar abstraction finally
Browse files Browse the repository at this point in the history
Now just to get it all implemented
  • Loading branch information
NovaFox161 committed Nov 1, 2024
1 parent ef9a382 commit 835e8bb
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.dreamexposure.discal.core.business

import org.dreamexposure.discal.core.`object`.new.Calendar
import org.dreamexposure.discal.core.`object`.new.CalendarMetadata
import org.dreamexposure.discal.core.`object`.new.CalendarMetadata.*

interface CalendarProvider {
val host: Host

suspend fun getCalendar(metadata: CalendarMetadata): Calendar?

// TODO: Implement the rest of required CRUD functions
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,32 @@ import discord4j.common.util.Snowflake
import kotlinx.coroutines.reactor.awaitSingle
import kotlinx.coroutines.reactor.awaitSingleOrNull
import kotlinx.coroutines.reactor.mono
import org.dreamexposure.discal.CalendarCache
import org.dreamexposure.discal.CalendarMetadataCache
import org.dreamexposure.discal.core.crypto.AESEncryption
import org.dreamexposure.discal.core.database.CalendarMetadataRepository
import org.dreamexposure.discal.core.`object`.new.Calendar
import org.dreamexposure.discal.core.`object`.new.CalendarMetadata
import org.springframework.stereotype.Component

@Component
class CalendarService(
private val calendarMetadataRepository: CalendarMetadataRepository,
private val calendarMetadataCache: CalendarMetadataCache,
private val calendarProviders: List<CalendarProvider>,
private val calendarCache: CalendarCache,
private val settingsService: GuildSettingsService,
) {
/////////
/// Calendar count
/////////
suspend fun getCalendarCount(): Long = calendarMetadataRepository.countAll().awaitSingle()

suspend fun getCalendarCount(guildId: Snowflake) = calendarMetadataRepository.countAllByGuildId(guildId.asLong()).awaitSingle()

/////////
/// Calendar metadata
/////////
// TODO: Exposing CalendarMetadata directly should not be done once a higher abstraction has been implemented
suspend fun getAllCalendarMetadata(guildId: Snowflake): List<CalendarMetadata> {
var calendars = calendarMetadataCache.get(key = guildId)?.toList()
Expand Down Expand Up @@ -66,6 +76,30 @@ class CalendarService(
}
}

/////////
/// Calendar
/////////
suspend fun getCalendar(guildId: Snowflake, number: Int): Calendar? {
var calendar = calendarCache.get(guildId, number)
if (calendar != null) return calendar

// TODO: Is this how I want to handle that actually???
val metadata = getCalendarMetadata(guildId, number) ?: return null

calendar = calendarProviders
.firstOrNull { it.host == metadata.host }
?.getCalendar(metadata)
if (calendar != null) calendarCache.put(guildId, number, calendar)

return calendar
}

// TODO: Implement rest of required CRUD functions


/////////
/// Extra functions
/////////
suspend fun canAddNewCalendar(guildId: Snowflake): Boolean {
val calCount = getCalendarCount(guildId)
if (calCount == 0L) return true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.dreamexposure.discal.core.business.google

import org.dreamexposure.discal.core.business.CalendarProvider
import org.dreamexposure.discal.core.`object`.new.Calendar
import org.dreamexposure.discal.core.`object`.new.CalendarMetadata
import org.springframework.stereotype.Component
import java.time.ZoneId

@Component
class GoogleCalendarProviderService(
val googleCalendarApiWrapper: GoogleCalendarApiWrapper,
) : CalendarProvider {
override val host = CalendarMetadata.Host.GOOGLE

override suspend fun getCalendar(metadata: CalendarMetadata): Calendar? {
val googleCalendar = googleCalendarApiWrapper.getCalendar(metadata) ?: return null

return Calendar(
metadata = metadata,
name = googleCalendar.summary.orEmpty(),
description = googleCalendar.description.orEmpty(),
timezone = ZoneId.of(googleCalendar.timeZone),
hostLink = "https://calendar.google.com/calendar/embed?src=${metadata.id}"
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ class CacheConfig {
@Primary
@ConditionalOnProperty("bot.cache.redis", havingValue = "true")
fun calendarMetadataRedisCache(objectMapper: ObjectMapper, redisTemplate: ReactiveStringRedisTemplate): CalendarMetadataCache =
RedisStringCacheRepository(objectMapper, redisTemplate, "CalendarMetadata", calendarTtl)

@Bean
@Primary
@ConditionalOnProperty("bot.cache.redis", havingValue = "true")
fun calendarRedisCache(objectMapper: ObjectMapper, redisTemplate: ReactiveStringRedisTemplate): CalendarCache =
RedisStringCacheRepository(objectMapper, redisTemplate, "Calendars", calendarTtl)

@Bean
Expand Down Expand Up @@ -87,6 +93,9 @@ class CacheConfig {
@Bean
fun calendarMetadataFallbackCache(): CalendarMetadataCache = JdkCacheRepository(calendarTtl)

@Bean
fun calendarFallbackCache(): CalendarCache = JdkCacheRepository(calendarTtl)

@Bean
fun rsvpFallbackCache(): RsvpCache = JdkCacheRepository(rsvpTtl)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.dreamexposure.discal.core.`object`.new

import org.dreamexposure.discal.core.config.Config
import java.time.ZoneId

data class Calendar(
val metadata: CalendarMetadata,
val name: String,
val description: String,
val timezone: ZoneId,
val hostLink: String,
) {
// TODO: Consider moving this link formatting somewhere else?
val link: String
get() = "${Config.URL_BASE.getString()}/embed/${metadata.guildId.asString()}/calendar/${metadata.number}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ typealias GuildSettingsCache = CacheRepository<Snowflake, GuildSettings>
typealias CredentialsCache = CacheRepository<Int, Credential>
typealias OauthStateCache = CacheRepository<String, String>
typealias CalendarMetadataCache = CacheRepository<Snowflake, Array<CalendarMetadata>>
typealias CalendarCache = CacheRepository<Int, Calendar>
typealias RsvpCache = CacheRepository<String, Rsvp>
typealias StaticMessageCache = CacheRepository<Snowflake, StaticMessage>
typealias AnnouncementCache = CacheRepository<Snowflake, Array<Announcement>>
Expand Down

0 comments on commit 835e8bb

Please sign in to comment.