Skip to content

Commit

Permalink
Got ahead of myself
Browse files Browse the repository at this point in the history
Recreated some of the V2 endpoints that the legacy website still needs.

Definitely could do a better job at fixing this code, but for now I'm looking just to make sure it works functionally the same and I care less about making this respect new patterns since its deprecated anyways
  • Loading branch information
NovaFox161 committed Dec 9, 2024
1 parent 2a4ce80 commit 1212dba
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.dreamexposure.discal.core.`object`.new.model.discal.v2

import com.fasterxml.jackson.annotation.JsonProperty
import discord4j.common.util.Snowflake
import org.dreamexposure.discal.core.`object`.new.Calendar
import java.time.ZoneId

@Deprecated("Prefer to use V3 APIs, this is for compatibility for the old site old")
data class CalendarV2Model(
@JsonProperty("guild_id")
val guildId: Snowflake,
@JsonProperty("calendar_id")
val calendarId: String,
@JsonProperty("calendar_address")
val calendarAddress: String,
@JsonProperty("calendar_number")
val calendarNumber: Int,
val host: String,
@JsonProperty("host_link")
val hostLink: String,
val external: Boolean,
val name: String,
val description: String,
val timezone: ZoneId,
val link: String,
) {
constructor(calendar: Calendar): this(
guildId = calendar.metadata.guildId,
calendarId = calendar.metadata.id,
calendarAddress = calendar.metadata.address,
calendarNumber = calendar.metadata.number,
host = calendar.metadata.host.name,
hostLink = calendar.hostLink,
external = calendar.metadata.external,
name = calendar.name,
description = calendar.description,
timezone = calendar.timezone,
link = calendar.link,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.dreamexposure.discal.core.`object`.new.model.discal.v2

import com.fasterxml.jackson.annotation.JsonProperty
import discord4j.common.util.Snowflake
import org.dreamexposure.discal.core.`object`.event.Recurrence
import org.dreamexposure.discal.core.`object`.new.Calendar
import org.dreamexposure.discal.core.`object`.new.Event

@Deprecated("Prefer to use V3 API implementation. This exists to maintain compatibility for the legacy website")
data class EventV2Model(
@JsonProperty("guild_id")
val guildId: Snowflake,
val calendar: CalendarV2Model,
@JsonProperty("event_id")
val eventId: String,
@JsonProperty("epoch_start")
val epochStart: Long,
@JsonProperty("epoch_end")
val epochEnd: Long,
val name: String,
val description: String,
val location: String,
@JsonProperty("is_parent")
val isParent: Boolean,
val color: String,
val recur: Boolean,
val recurrence: Recurrence,
val rrule: String,
val image: String,
) {
constructor(event: Event, calendar: Calendar): this(
guildId = event.guildId,
calendar = CalendarV2Model(calendar),
eventId = event.id,
epochStart = event.start.toEpochMilli(),
epochEnd = event.end.toEpochMilli(),
name = event.name,
description = event.description,
location = event.location,
isParent = !event.id.contains("_"),
color = event.color.name,
recur = event.recur,
recurrence = event.recurrence,
rrule = event.recurrence.toRRule(),
image = event.image,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.dreamexposure.discal.server.endpoints.v2.calendar

import com.fasterxml.jackson.databind.ObjectMapper
import discord4j.common.util.Snowflake
import kotlinx.coroutines.reactor.mono
import kotlinx.serialization.encodeToString
import org.dreamexposure.discal.core.annotations.SecurityRequirement
import org.dreamexposure.discal.core.business.CalendarService
import org.dreamexposure.discal.core.logger.LOGGER
import org.dreamexposure.discal.core.`object`.new.model.discal.v2.CalendarV2Model
import org.dreamexposure.discal.core.utils.GlobalVal
import org.dreamexposure.discal.server.utils.Authentication
import org.dreamexposure.discal.server.utils.responseMessage
import org.json.JSONException
import org.json.JSONObject
import org.springframework.http.server.reactive.ServerHttpResponse
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ServerWebExchange
import reactor.core.publisher.Mono

@RestController
@RequestMapping("/v2/calendar")
class GetCalendarEndpoint(
private val authentication: Authentication,
private val calendarService: CalendarService,
private val objectMapper: ObjectMapper,
) {
@PostMapping("/get", produces = ["application/json"])
@SecurityRequirement(disableSecurity = true, scopes = [])
fun getCalendar(swe: ServerWebExchange, response: ServerHttpResponse, @RequestBody rBody: String): Mono<String> {
return authentication.authenticate(swe).flatMap { authState ->
if (!authState.success) {
response.rawStatusCode = authState.status
return@flatMap Mono.just(GlobalVal.JSON_FORMAT.encodeToString(authState))
}

//Handle request
val body = JSONObject(rBody)
val guildId = Snowflake.of(body.getString("guild_id"))
val calNumber = body.getInt("calendar_number")

return@flatMap mono {calendarService.getCalendar(guildId, calNumber) }
.map(::CalendarV2Model)
.map { objectMapper.writeValueAsString(it) }
.switchIfEmpty(responseMessage("Calendar not found")
.doOnNext { response.rawStatusCode = GlobalVal.STATUS_NOT_FOUND }
)
}.onErrorResume(JSONException::class.java) {
LOGGER.trace("[API-v2] JSON error. Bad request?", it)

response.rawStatusCode = GlobalVal.STATUS_BAD_REQUEST
return@onErrorResume responseMessage("Bad Request")
}.onErrorResume {
LOGGER.error(GlobalVal.DEFAULT, "[API-v2] get calendar error", it)

response.rawStatusCode = GlobalVal.STATUS_INTERNAL_ERROR
return@onErrorResume responseMessage("Internal Server Error")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.dreamexposure.discal.server.endpoints.v2.calendar

import com.fasterxml.jackson.databind.ObjectMapper
import discord4j.common.util.Snowflake
import kotlinx.coroutines.reactor.mono
import org.dreamexposure.discal.core.logger.LOGGER
import org.dreamexposure.discal.core.annotations.SecurityRequirement
import org.dreamexposure.discal.core.business.CalendarService
import org.dreamexposure.discal.core.utils.GlobalVal
import org.dreamexposure.discal.server.utils.Authentication
import org.dreamexposure.discal.server.utils.responseMessage
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import org.springframework.http.server.reactive.ServerHttpResponse
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ServerWebExchange
import reactor.core.publisher.Mono
import java.time.Instant
import kotlinx.serialization.encodeToString
import org.dreamexposure.discal.core.`object`.new.model.discal.v2.EventV2Model


@RestController
@RequestMapping("/v2/events/list")
class ListEventMonthEndpoint(
private val authentication: Authentication,
private val calendarService: CalendarService,
private val objectMapper: ObjectMapper,
) {
@PostMapping("/month", produces = ["application/json"])
@SecurityRequirement(disableSecurity = true, scopes = [])
fun listByMonth(swe: ServerWebExchange, response: ServerHttpResponse, @RequestBody rBody: String): Mono<String> {
return authentication.authenticate(swe).flatMap { authState ->
if (!authState.success) {
response.rawStatusCode = authState.status
return@flatMap Mono.just(GlobalVal.JSON_FORMAT.encodeToString(authState))
}

//Handle request
val body = JSONObject(rBody)
val guildId = Snowflake.of(body.getString("guild_id"))
val calendarNumber = body.getInt("calendar_number")
val start = Instant.ofEpochMilli(body.getLong("epoch_start"))
val daysInMonth = body.getInt("days_in_month")


mono { calendarService.getCalendar(guildId, calendarNumber) }.flatMap { calendar ->
mono { calendarService.getEventsInMonth(guildId, calendarNumber, start, daysInMonth) }.map { events ->
events.map { objectMapper.writeValueAsString(EventV2Model(it, calendar)) }
}
}.map(::JSONArray)
.map { JSONObject().put("events", it).put("message", "Success").toString() }
.doOnNext { response.rawStatusCode = GlobalVal.STATUS_SUCCESS }
.switchIfEmpty(responseMessage("Calendar not found")
.doOnNext { response.rawStatusCode = GlobalVal.STATUS_NOT_FOUND }
)
}.onErrorResume(JSONException::class.java) {
LOGGER.trace("[API-v2] JSON error. Bad request?", it)

response.rawStatusCode = GlobalVal.STATUS_BAD_REQUEST
return@onErrorResume responseMessage("Bad Request")
}.onErrorResume {
LOGGER.error(GlobalVal.DEFAULT, "[API-v2] list events by month error", it)

response.rawStatusCode = GlobalVal.STATUS_INTERNAL_ERROR
return@onErrorResume responseMessage("Internal Server Error")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.dreamexposure.discal.server.endpoints.v2.event.list

import com.fasterxml.jackson.databind.ObjectMapper
import discord4j.common.util.Snowflake
import kotlinx.coroutines.reactor.mono
import kotlinx.serialization.encodeToString
import org.dreamexposure.discal.core.annotations.SecurityRequirement
import org.dreamexposure.discal.core.business.CalendarService
import org.dreamexposure.discal.core.logger.LOGGER
import org.dreamexposure.discal.core.`object`.new.model.discal.v2.EventV2Model
import org.dreamexposure.discal.core.utils.GlobalVal
import org.dreamexposure.discal.server.utils.Authentication
import org.dreamexposure.discal.server.utils.responseMessage
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import org.springframework.http.server.reactive.ServerHttpResponse
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.server.ServerWebExchange
import reactor.core.publisher.Mono
import java.time.Instant

@RestController
@RequestMapping("/v2/events/list")
class ListEventRangeEndpoint(
private val authentication: Authentication,
private val calendarService: CalendarService,
private val objectMapper: ObjectMapper,
) {
@PostMapping("/range", produces = ["application/json"])
@SecurityRequirement(disableSecurity = true, scopes = [])
fun listByRange(swe: ServerWebExchange, response: ServerHttpResponse, @RequestBody rBody: String): Mono<String> {
return authentication.authenticate(swe).flatMap { authState ->
if (!authState.success) {
response.rawStatusCode = authState.status
return@flatMap Mono.just(GlobalVal.JSON_FORMAT.encodeToString(authState))
}

//Handle request
val body = JSONObject(rBody)
val guildId = Snowflake.of(body.getString("guild_id"))
val calendarNumber = body.getInt("calendar_number")
val start = Instant.ofEpochMilli(body.getLong("epoch_start"))
val end = Instant.ofEpochMilli(body.getLong("epoch_end"))

mono { calendarService.getCalendar(guildId, calendarNumber) }.flatMap { calendar ->
mono { calendarService.getEventsInTimeRange(guildId, calendarNumber, start, end) }.map { events ->
events.map { objectMapper.writeValueAsString(EventV2Model(it, calendar)) }
}
}.map(::JSONArray)
.map { JSONObject().put("events", it).put("message", "Success").toString() }
.doOnNext { response.rawStatusCode = GlobalVal.STATUS_SUCCESS }
.switchIfEmpty(responseMessage("Calendar not found")
.doOnNext { response.rawStatusCode = GlobalVal.STATUS_NOT_FOUND }
)
}.onErrorResume(JSONException::class.java) {
LOGGER.trace("[API-v2] JSON error. Bad request?", it)

response.rawStatusCode = GlobalVal.STATUS_BAD_REQUEST
return@onErrorResume responseMessage("Bad Request")
}.onErrorResume {
LOGGER.error(GlobalVal.DEFAULT, "[API-v2] list events by range error", it)

response.rawStatusCode = GlobalVal.STATUS_INTERNAL_ERROR
return@onErrorResume responseMessage("Internal Server Error")
}
}
}

0 comments on commit 1212dba

Please sign in to comment.