Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
HugoGresse committed Sep 5, 2024
1 parent 3a1670d commit 60d62ce
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 16 deletions.
62 changes: 60 additions & 2 deletions functions/src/api/dao/eventDao.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import firebase from 'firebase-admin'
import { Event } from '../../types'
import firebase, { firestore } from 'firebase-admin'
import { Category, Event, Format, Track } from '../../types'
import FieldValue = firestore.FieldValue
import { randomColor } from '../other/randomColor'

export class EventDao {
public static async getEvent(firebaseApp: firebase.app.App, eventId: string): Promise<Event> {
Expand All @@ -12,4 +14,60 @@ export class EventDao {
}
return data as Event
}

public static async createCategory(
firebaseApp: firebase.app.App,
eventId: string,
category: Category
): Promise<any> {
const db = firebaseApp.firestore()

db.collection(`events`)
.doc(eventId)
.update({
categories: FieldValue.arrayUnion({
id: category.id,
name: category.name,
color: category.color || randomColor(),
}),
})
.catch((error) => {
console.error('error creating category', error)
throw new Error('Error creating category ' + error)
})
}

public static async createTrack(firebaseApp: firebase.app.App, eventId: string, track: Track): Promise<any> {
const db = firebaseApp.firestore()

db.collection(`events`)
.doc(eventId)
.update({
tracks: FieldValue.arrayUnion({
id: track.id,
name: track.name,
}),
})
.catch((error) => {
console.error('error creating track', error)
throw new Error('Error creating track ' + error)
})
}
public static async createFormat(firebaseApp: firebase.app.App, eventId: string, format: Format): Promise<any> {
const db = firebaseApp.firestore()

db.collection(`events`)
.doc(eventId)
.update({
formats: FieldValue.arrayUnion({
id: format,
name: format.name,
durationMinutes: format.durationMinutes,
}),
})
.catch((error) => {
console.error('error creating format', error)
throw new Error('Error creating format ' + error)
})
}
}
50 changes: 48 additions & 2 deletions functions/src/api/dao/sessionDao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,40 @@ import { Session } from '../../types'
const { FieldValue } = firebase.firestore

export class SessionDao {
public static async doesSessionExist(
firebaseApp: firebase.app.App,
eventId: string,
sessionId: string
): Promise<boolean | Session> {
const db = firebaseApp.firestore()

// 1. Check if the session exist
const snapshot = await db.collection(`events/${eventId}/sessions`).doc(sessionId).get()
const existingSessionData = snapshot.data()
if (!existingSessionData) {
return false
}
return existingSessionData as Session
}

public static async createSession(
firebaseApp: firebase.app.App,
eventId: string,
session: Partial<Session> & {
id: string
}
): Promise<any> {
const db = firebaseApp.firestore()

await db
.collection(`events/${eventId}/sessions`)
.doc(session.id)
.set({
...session,
updatedAt: FieldValue.serverTimestamp(),
})
}

public static async updateSession(
firebaseApp: firebase.app.App,
eventId: string,
Expand All @@ -12,8 +46,7 @@ export class SessionDao {
const db = firebaseApp.firestore()

// 1. Check if the session exist
const snapshot = await db.collection(`events/${eventId}/sessions`).doc(partialSession.id).get()
const existingSessionData = snapshot.data()
const existingSessionData = await SessionDao.doesSessionExist(firebaseApp, eventId, partialSession.id)
if (!existingSessionData) {
throw new Error('Session not found')
}
Expand All @@ -31,4 +64,17 @@ export class SessionDao {
const snapshot2 = await db.collection(`events/${eventId}/sessions`).doc(partialSession.id).get()
return snapshot2.data() as Session
}

public static async updateOrCreateSession(
firebaseApp: firebase.app.App,
eventId: string,
session: Partial<Session> & { id: string }
): Promise<any> {
const existingSessionData = await SessionDao.doesSessionExist(firebaseApp, eventId, session.id)
if (!existingSessionData) {
await SessionDao.createSession(firebaseApp, eventId, session)
} else {
await SessionDao.updateSession(firebaseApp, eventId, session)
}
}
}
78 changes: 78 additions & 0 deletions functions/src/api/dao/speakerDao.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Speaker } from '../../types'
import firebase from 'firebase-admin'

const { FieldValue } = firebase.firestore

export class SpeakerDao {
public static async doesSpeakerExist(
firebaseApp: firebase.app.App,
eventId: string,
speakerId: string
): Promise<boolean | Speaker> {
const db = firebaseApp.firestore()

// 1. Check if the session exist
const snapshot = await db.collection(`events/${eventId}/speakers`).doc(speakerId).get()
const existingSessionData = snapshot.data()
if (!existingSessionData) {
return false
}
return existingSessionData as Speaker
}

public static async createSpeaker(
firebaseApp: firebase.app.App,
eventId: string,
speaker: Partial<Speaker> & {
id: string
}
): Promise<any> {
const db = firebaseApp.firestore()

await db
.collection(`events/${eventId}/speakers`)
.doc(speaker.id)
.set({
...speaker,
updatedAt: FieldValue.serverTimestamp(),
})
return speaker
}

public static async updateSpeaker(
firebaseApp: firebase.app.App,
eventId: string,
speaker: Partial<Speaker> & {
id: string
}
): Promise<any> {
const db = firebaseApp.firestore()

// 1. Check if the session exist
const existingSpeakerData = await SpeakerDao.doesSpeakerExist(firebaseApp, eventId, speaker.id)
if (!existingSpeakerData) {
throw new Error('Speaker not found')
}

await db
.collection(`events/${eventId}/speakers`)
.doc(speaker.id)
.set({
...speaker,
updatedAt: FieldValue.serverTimestamp(),
})
}

public static async updateOrCreateSpeaker(
firebaseApp: firebase.app.App,
eventId: string,
speaker: Partial<Speaker> & { id: string }
): Promise<any> {
const existingSpeakerData = await SpeakerDao.doesSpeakerExist(firebaseApp, eventId, speaker.id)
if (!existingSpeakerData) {
await SpeakerDao.createSpeaker(firebaseApp, eventId, speaker)
} else {
await SpeakerDao.updateSpeaker(firebaseApp, eventId, speaker)
}
}
}
4 changes: 2 additions & 2 deletions functions/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { faqRoutes } from './routes/faq/faq'
import { helloRoute } from './routes/hello/hello'
import { sessionsRoutes } from './routes/sessions/sessions'
import { transcriptionRoutes } from './routes/transcription/transcription'
import { overwriteSpeakerSponsors } from './routes/overwriteSpeakerSponsors/overwriteSpeakerSponsors'
import { overwriteSpeakerSessions } from './routes/overwriteSpeakerSponsors/overwriteSpeakerSessions'

type Firebase = firebaseApp.App

Expand Down Expand Up @@ -53,7 +53,7 @@ fastify.register(sessionsRoutes)
fastify.register(faqRoutes)
fastify.register(transcriptionRoutes)
fastify.register(filesRoutes)
fastify.register(overwriteSpeakerSponsors)
fastify.register(overwriteSpeakerSessions)
fastify.register(helloRoute)

fastify.setErrorHandler(fastifyErrorHandler)
Expand Down
18 changes: 18 additions & 0 deletions functions/src/api/other/randomColor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const randomColor = (mode: 'colorful' | 'random' = 'colorful') => {
if (mode === 'colorful') {
// Generate random values for the red, green, and blue components
const red = Math.floor(Math.random() * 256)
const green = Math.floor(Math.random() * 256)
const blue = Math.floor(Math.random() * 256)

// Convert the values to hexadecimal format
const redHex = red.toString(16).padStart(2, '0')
const greenHex = green.toString(16).padStart(2, '0')
const blueHex = blue.toString(16).padStart(2, '0')

// Concatenate the hexadecimal values to form a color in the "#RRGGBB" format
return `#${redHex}${greenHex}${blueHex}`
}

return '#' + Math.floor(Math.random() * 16777215).toString(16)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { FastifyInstance } from 'fastify'
import { FormatRegistry, Static, Type } from '@sinclair/typebox'
import { DateTime } from 'luxon'
import { verifyOverwriteData } from './verifyOverwriteData'
import { EventDao } from '../../dao/eventDao'
import { SessionDao } from '../../dao/sessionDao'
import { SpeakerDao } from '../../dao/speakerDao'

const MAX_STRING_LENGTH = 10000

Expand Down Expand Up @@ -63,7 +66,7 @@ export const OverwriteSpeakerType = Type.Object({
maxLength: MAX_STRING_LENGTH,
}),
icon: Type.String(),
link: Type.Optional(Type.String({ format: 'uri' })),
link: Type.String({ format: 'uri' }),
})
)
),
Expand Down Expand Up @@ -142,6 +145,7 @@ export const OverwriteSpeakerType = Type.Object({
maxLength: MAX_STRING_LENGTH,
})
),
categoryColor: Type.Optional(Type.String()),
showInFeedback: Type.Optional(Type.Boolean()),
hideTrackTitle: Type.Optional(Type.Boolean()),
note: Type.Optional(Type.String()),
Expand All @@ -157,14 +161,15 @@ interface IQuerystring {
reUploadAssets?: boolean
}

export const overwriteSpeakerSponsors = (fastify: FastifyInstance, options: any, done: () => any) => {
export const overwriteSpeakerSessions = (fastify: FastifyInstance, options: any, done: () => any) => {
fastify.post<{ Querystring: IQuerystring; Body: OverwriteSpeakerSessionsType; Reply: string }>(
'/v1/:eventId/overwriteSpeakerSponsors',
{
schema: {
tags: ['speakers', 'sessions'],
summary:
'Overwrite sessions and speakers: if any data exist before, each filed given in the body will rewrite the corresponding data. Tracks, formats and categories will only be created if none exist before. If track, format or category does exist, the ID will be matched again the trackName or the trackId, same for categories and formats.',
'Overwrite sessions and speakers: if any data exist before, each filed given in the body will rewrite the corresponding data. ' +
'Tracks, formats and categories will only be created if none exist before and if you provide an id. If track, format or category does exist, the ID will be matched again the trackName or the trackId, same for categories and formats.',
body: OverwriteSpeakerType,
querystring: {
type: 'object',
Expand Down Expand Up @@ -192,7 +197,66 @@ export const overwriteSpeakerSponsors = (fastify: FastifyInstance, options: any,
const { eventId } = request.params as { eventId: string }
const {} = request.query

verifyOverwriteData(request.body)
const existingEvent = await EventDao.getEvent(fastify.firebase, eventId)
console.log(`overwriteSpeakerSessions for event ${eventId} ${existingEvent.name}`)

const { tracksToCreate, categoriesToCreate, formatsToCreate } = verifyOverwriteData(
request.body,
existingEvent
)

console.log(
`Creating tracks: ${tracksToCreate.length}, categories: ${categoriesToCreate.length}, formats: ${formatsToCreate.length}`
)
for (const track of tracksToCreate) {
try {
await EventDao.createTrack(fastify.firebase, eventId, track)
} catch (error) {
console.error('error creating track', error)
reply.status(400).send((error as object).toString())
return
}
}
for (const category of categoriesToCreate) {
try {
await EventDao.createCategory(fastify.firebase, eventId, category)
} catch (error) {
console.error('error creating category', error)
reply.status(400).send((error as object).toString())
return
}
}
for (const format of formatsToCreate) {
try {
await EventDao.createFormat(fastify.firebase, eventId, format)
} catch (error) {
console.error('error creating format', error)
reply.status(400).send((error as object).toString())
return
}
}

// Sessions
for (const session of request.body.sessions) {
try {
await SessionDao.updateOrCreateSession(fastify.firebase, eventId, session)
} catch (error) {
console.error('error creating session', error)
reply.status(400).send((error as object).toString())
return
}
}

// Speakers
for (const speaker of request.body.speakers) {
try {
await SpeakerDao.updateOrCreateSpeaker(fastify.firebase, eventId, speaker)
} catch (error) {
console.error('error creating speaker', error)
reply.status(400).send((error as object).toString())
return
}
}

reply.status(201).send(eventId)
}
Expand Down
Loading

0 comments on commit 60d62ce

Please sign in to comment.