Skip to content

Commit

Permalink
feat(backend): create service for /planning
Browse files Browse the repository at this point in the history
  • Loading branch information
GerardPaligot committed May 8, 2024
1 parent 15fe346 commit b35a13a
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
package org.gdglille.devfest.backend.events

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import org.gdglille.devfest.backend.NotAcceptableException
import org.gdglille.devfest.backend.NotFoundException
import org.gdglille.devfest.backend.categories.CategoryDao
import org.gdglille.devfest.backend.categories.CategoryDb
import org.gdglille.devfest.backend.formats.FormatDao
import org.gdglille.devfest.backend.formats.FormatDb
import org.gdglille.devfest.backend.internals.date.FormatterPattern
import org.gdglille.devfest.backend.internals.date.format
import org.gdglille.devfest.backend.partners.PartnerDao
import org.gdglille.devfest.backend.partners.Sponsorship
import org.gdglille.devfest.backend.partners.convertToModel
import org.gdglille.devfest.backend.qanda.QAndADao
import org.gdglille.devfest.backend.schedulers.ScheduleDb
import org.gdglille.devfest.backend.schedulers.ScheduleItemDao
import org.gdglille.devfest.backend.schedulers.convertToModel
import org.gdglille.devfest.backend.schedulers.convertToPlanningEventModel
import org.gdglille.devfest.backend.schedulers.convertToPlanningTalkModel
import org.gdglille.devfest.backend.sessions.EventSessionDb
import org.gdglille.devfest.backend.sessions.SessionDao
import org.gdglille.devfest.backend.sessions.SessionDb
import org.gdglille.devfest.backend.sessions.TalkDb
import org.gdglille.devfest.backend.sessions.convertToModel
import org.gdglille.devfest.backend.sessions.convertToModelInfo
import org.gdglille.devfest.backend.speakers.SpeakerDao
import org.gdglille.devfest.backend.speakers.SpeakerDb
import org.gdglille.devfest.backend.third.parties.geocode.GeocodeApi
import org.gdglille.devfest.backend.third.parties.geocode.convertToDb
import org.gdglille.devfest.models.Agenda
import org.gdglille.devfest.models.CreatedEvent
import org.gdglille.devfest.models.Event
import org.gdglille.devfest.models.EventList
import org.gdglille.devfest.models.EventPartners
import org.gdglille.devfest.models.PlanningItem
import org.gdglille.devfest.models.inputs.CoCInput
import org.gdglille.devfest.models.inputs.CreatingEventInput
import org.gdglille.devfest.models.inputs.EventInput
Expand Down Expand Up @@ -146,4 +158,69 @@ class EventRepository(
}.awaitAll().associate { it }.toSortedMap()
return@coroutineScope Agenda(talks = schedules)
}

suspend fun planning(eventDb: EventDb): Map<String, Map<String, List<PlanningItem>>> = coroutineScope {
val sessions = sessionDao.getAll(eventDb.slugId)
val speakers = speakerDao.getAll(eventDb.slugId)
val categories = categoryDao.getAll(eventDb.slugId)
val formats = formatDao.getAll(eventDb.slugId)
return@coroutineScope scheduleItemDao.getAll(eventDb.slugId)
.groupBy { LocalDateTime.parse(it.startTime).format(FormatterPattern.YearMonthDay) }
.entries.map { schedulesByDay ->
schedulesByDay(schedulesByDay, sessions, speakers, categories, formats, eventDb)
}
.awaitAll()
.sortedBy { it.first }
.associate { it }
.toMap()
}

@Suppress("LongParameterList")
private fun CoroutineScope.schedulesByDay(
schedulesByDay: Map.Entry<String, List<ScheduleDb>>,
sessions: List<SessionDb>,
speakers: List<SpeakerDb>,
categories: List<CategoryDb>,
formats: List<FormatDb>,
eventDb: EventDb
) = async {
return@async schedulesByDay.key to schedulesByDay.value
.groupBy { LocalDateTime.parse(it.startTime).format(FormatterPattern.HoursMinutes) }
.entries.map { schedulesBySlot ->
schedulesBySlot.key to schedulesBySlot.value
.map { schedule ->
schedulesBySlot(schedule, sessions, speakers, categories, formats, eventDb)
}
.awaitAll()
.sortedBy { it.order }
}
.sortedBy { it.first }
.associate { it }
.toMap()
}

@Suppress("LongParameterList")
private fun CoroutineScope.schedulesBySlot(
schedule: ScheduleDb,
sessions: List<SessionDb>,
speakers: List<SpeakerDb>,
categories: List<CategoryDb>,
formats: List<FormatDb>,
eventDb: EventDb
) = async {
val session = sessions.find { it.id == schedule.talkId }
?: throw NotFoundException("Session ${schedule.id} not found")
when (session) {
is EventSessionDb -> schedule.convertToPlanningEventModel(session.convertToModelInfo())

is TalkDb -> {
val speakersTalk = speakers.filter { session.speakerIds.contains(it.id) }
val category = categories.find { it.id == session.category }
val format = formats.find { it.id == session.format }
schedule.convertToPlanningTalkModel(
session.convertToModel(speakersTalk, category, format, eventDb)
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,25 @@ fun Route.registerEventRoutes(
val input = call.receiveValidated<FeaturesActivatedInput>()
call.respond(HttpStatusCode.OK, repository.updateFeatures(eventId, apiKey, input))
}
get("/events/{eventId}/planning") {
val eventId = call.parameters["eventId"]!!
val event = eventDao.get(eventId) ?: throw NotFoundException("Event $eventId Not Found")
val zoneId = ZoneId.of("Europe/Paris")
val lastModified = ZonedDateTime.of(
LocalDateTime.ofInstant(Instant.ofEpochMilli(event.agendaUpdatedAt), zoneId),
zoneId
)
val etag = lastModified.hashCode().toString()
val version = EntityTagVersion(etag)
val result = version.check(call.request.headers)
if (result == VersionCheckResult.NOT_MODIFIED) {
call.respond(HttpStatusCode.NotModified)
} else {
call.response.lastModified(lastModified)
call.response.etag(etag)
call.respond(HttpStatusCode.OK, repository.planning(event))
}
}
get("/events/{eventId}/agenda") {
val eventId = call.parameters["eventId"]!!
val event = eventDao.get(eventId) ?: throw NotFoundException("Event $eventId Not Found")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,35 @@
package org.gdglille.devfest.backend.schedulers

import org.gdglille.devfest.backend.NotAcceptableException
import org.gdglille.devfest.backend.internals.date.FormatterPattern
import org.gdglille.devfest.backend.internals.date.format
import org.gdglille.devfest.models.Info
import org.gdglille.devfest.models.PlanningItem
import org.gdglille.devfest.models.ScheduleItem
import org.gdglille.devfest.models.ScheduleItemV3
import org.gdglille.devfest.models.ScheduleItemV4
import org.gdglille.devfest.models.Talk
import org.gdglille.devfest.models.inputs.ScheduleInput
import java.time.LocalDateTime

fun ScheduleDb.convertToPlanningTalkModel(talk: Talk) = PlanningItem.TalkItem(
id = this.id,
order = order ?: 0,
startTime = this.startTime,
endTime = this.endTime,
room = this.room,
talk = talk
)

fun ScheduleDb.convertToPlanningEventModel(info: Info) = PlanningItem.EventItem(
id = this.id,
order = order ?: 0,
startTime = this.startTime,
endTime = this.endTime,
room = this.room,
info = info
)

fun ScheduleDb.convertToModel(talk: Talk?) = ScheduleItem(
id = this.id,
order = order ?: 0,
Expand Down Expand Up @@ -36,7 +57,7 @@ fun ScheduleDb.convertToModelV4() = ScheduleItemV4(
startTime = this.startTime,
endTime = this.endTime,
room = this.room,
sessionId = talkId
sessionId = talkId ?: throw NotAcceptableException("Talk id can't be null with version 4")
)

fun ScheduleInput.convertToDb(endTime: String, talkId: String? = null) = ScheduleDb(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import org.gdglille.devfest.backend.events.openFeedbackUrl
import org.gdglille.devfest.backend.formats.FormatDb
import org.gdglille.devfest.backend.speakers.SpeakerDb
import org.gdglille.devfest.backend.speakers.convertToModel
import org.gdglille.devfest.models.Info
import org.gdglille.devfest.models.Session
import org.gdglille.devfest.models.Talk
import org.gdglille.devfest.models.TalkV3
Expand Down Expand Up @@ -39,6 +40,12 @@ fun EventSessionDb.convertToModelEventSession(): Session = Session.Event(
description = description
)

fun EventSessionDb.convertToModelInfo(): Info = Info(
id = id,
title = title,
description = description
)

fun TalkDb.convertToModel(
speakers: List<SpeakerDb>,
category: CategoryDb?,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.gdglille.devfest.models

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
sealed class PlanningItem {
abstract val id: String
abstract val order: Int

@Serializable
@SerialName("talk-session")
data class TalkItem(
override val id: String,
override val order: Int,
val startTime: String,
val endTime: String,
val room: String,
val talk: Talk
) : PlanningItem()

@Serializable
@SerialName("event-session")
data class EventItem(
override val id: String,
override val order: Int,
val startTime: String,
val endTime: String,
val room: String,
val info: Info
) : PlanningItem()
}

@Serializable
data class Info(
val id: String,
val title: String,
val description: String?
)
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,5 @@ data class ScheduleItemV4(
val endTime: String,
val room: String,
@SerialName("session_id")
val sessionId: String?
val sessionId: String
)

0 comments on commit b35a13a

Please sign in to comment.