From c88deeebe1aa91c45c422d2915fdb42b9ffcbc4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Camblor?= Date: Fri, 30 Aug 2024 18:24:51 +0200 Subject: [PATCH] #74 introduced FullEvent.lineupSpeakers aimed at being able to list speakers even when we don't have any schedule yet --- cloud/functions/src/crawlers/bdxio/crawler.ts | 3 +- .../crawlers/camping-des-speakers/crawler.ts | 3 +- .../src/crawlers/codeurs-en-seine/crawler.ts | 3 +- .../src/crawlers/devoxx-scala/crawler.ts | 5 ++- .../functions/src/crawlers/devoxx/crawler.ts | 5 ++- .../src/crawlers/jugsummercamp/crawler.ts | 3 +- .../src/crawlers/la-product-conf/crawler.ts | 3 +- .../src/crawlers/openplanner/crawler.ts | 5 ++- .../src/crawlers/single-file/crawler.ts | 41 +++++++++--------- .../functions/src/crawlers/web2day/crawler.ts | 3 +- cloud/functions/src/models/Event.ts | 42 ++++++++++++++++++- shared/event-lineup.firestore.d.ts | 20 +++++++++ 12 files changed, 103 insertions(+), 33 deletions(-) create mode 100644 shared/event-lineup.firestore.d.ts diff --git a/cloud/functions/src/crawlers/bdxio/crawler.ts b/cloud/functions/src/crawlers/bdxio/crawler.ts index a9dda9f0..a82408eb 100644 --- a/cloud/functions/src/crawlers/bdxio/crawler.ts +++ b/cloud/functions/src/crawlers/bdxio/crawler.ts @@ -1,5 +1,5 @@ import {z} from "zod"; -import {FullEvent} from "../../models/Event"; +import {detailedTalksToSpeakersLineup, FullEvent} from "../../models/Event"; import { BreakTimeSlot, DailySchedule, DetailedTalk, Room, ScheduleTimeSlot, @@ -360,6 +360,7 @@ export const BDXIO_CRAWLER: CrawlerKind = { conferenceDescriptor: confDescriptor, daySchedules: dailySchedules, talks: detailedTalks, + lineupSpeakers: detailedTalksToSpeakersLineup(detailedTalks), }; return fullEvent; diff --git a/cloud/functions/src/crawlers/camping-des-speakers/crawler.ts b/cloud/functions/src/crawlers/camping-des-speakers/crawler.ts index 35f62634..31d11488 100644 --- a/cloud/functions/src/crawlers/camping-des-speakers/crawler.ts +++ b/cloud/functions/src/crawlers/camping-des-speakers/crawler.ts @@ -1,5 +1,5 @@ import {z} from "zod"; -import {FullEvent} from "../../models/Event"; +import {detailedTalksToSpeakersLineup, FullEvent} from "../../models/Event"; import { BreakTimeSlot, DailySchedule, DetailedTalk, ScheduleTimeSlot, @@ -268,6 +268,7 @@ export const CAMPING_DES_SPEAKERS_CRAWLER: CrawlerKind = { const event: FullEvent = { id: eventId, info: eventInfo, daySchedules, - talks: eventTalks, conferenceDescriptor: eventDescriptor + talks: eventTalks, conferenceDescriptor: eventDescriptor, + lineupSpeakers: detailedTalksToSpeakersLineup(eventTalks), } return event } diff --git a/cloud/functions/src/crawlers/jugsummercamp/crawler.ts b/cloud/functions/src/crawlers/jugsummercamp/crawler.ts index 75e9676f..9df40a7f 100644 --- a/cloud/functions/src/crawlers/jugsummercamp/crawler.ts +++ b/cloud/functions/src/crawlers/jugsummercamp/crawler.ts @@ -1,5 +1,5 @@ import {z} from "zod"; -import {FullEvent} from "../../models/Event"; +import {detailedTalksToSpeakersLineup, FullEvent} from "../../models/Event"; import { BreakTimeSlot, DailySchedule, DetailedTalk, ScheduleTimeSlot, @@ -258,6 +258,7 @@ export const JUG_SUMMERCAMP_CRAWLER: CrawlerKind = conferenceDescriptor: confDescriptor, daySchedules: dailySchedules, talks: detailedTalks, + lineupSpeakers: detailedTalksToSpeakersLineup(detailedTalks), }; return fullEvent; diff --git a/cloud/functions/src/crawlers/la-product-conf/crawler.ts b/cloud/functions/src/crawlers/la-product-conf/crawler.ts index 9141947e..d40b20f4 100644 --- a/cloud/functions/src/crawlers/la-product-conf/crawler.ts +++ b/cloud/functions/src/crawlers/la-product-conf/crawler.ts @@ -1,5 +1,5 @@ import {z} from "zod"; -import {FullEvent} from "../../models/Event"; +import {detailedTalksToSpeakersLineup, FullEvent} from "../../models/Event"; import {ISODatetime, ISOLocalDate} from "../../../../../shared/type-utils"; import {Temporal} from "@js-temporal/polyfill"; import { @@ -286,6 +286,7 @@ export const LA_PRODUCT_CONF_CRAWLER: CrawlerKind timeslot.start.startsWith(day.localDate)) })) + const talks = descriptor.talks.map(detailedTalk => ({ + start: detailedTalk.start, + end: detailedTalk.end, + summary: detailedTalk.summary, + description: detailedTalk.summary, + tags: detailedTalk.tags, + assets: detailedTalk.assets, + speakers: detailedTalk.speakers, + id: detailedTalk.id, + title: detailedTalk.title, + isOverflow: detailedTalk.isOverflow, + + format: findItemById(descriptor.talkFormats, detailedTalk.formatId, "format"), + language: findItemById(descriptor.supportedTalkLanguages, detailedTalk.langId, "language").id, + track: findItemById(descriptor.talkTracks, detailedTalk.trackId, "track"), + room: findItemById(descriptor.rooms, detailedTalk.roomId, "room"), + })) + const event: FullEvent = { id: eventId, info: eventInfo, daySchedules: dailySchedules, - talks: descriptor.talks.map(detailedTalk => ({ - start: detailedTalk.start, - end: detailedTalk.end, - summary: detailedTalk.summary, - description: detailedTalk.summary, - tags: detailedTalk.tags, - assets: detailedTalk.assets, - speakers: detailedTalk.speakers, - id: detailedTalk.id, - title: detailedTalk.title, - isOverflow: detailedTalk.isOverflow, - - format: findItemById(descriptor.talkFormats, detailedTalk.formatId, "format"), - language: findItemById(descriptor.supportedTalkLanguages, detailedTalk.langId, "language").id, - track: findItemById(descriptor.talkTracks, detailedTalk.trackId, "track"), - room: findItemById(descriptor.rooms, detailedTalk.roomId, "room"), - })), + talks, conferenceDescriptor: { ...eventInfo, headingTitle: descriptor.headingTitle, @@ -150,7 +152,8 @@ export const SINGLE_FILE_CRAWLER: CrawlerKind = { conferenceDescriptor: confDescriptor, daySchedules: dailySchedules, talks: detailedTalks, + lineupSpeakers: detailedTalksToSpeakersLineup(detailedTalks), }; return fullEvent; diff --git a/cloud/functions/src/models/Event.ts b/cloud/functions/src/models/Event.ts index dd0f9da8..459ff060 100644 --- a/cloud/functions/src/models/Event.ts +++ b/cloud/functions/src/models/Event.ts @@ -1,7 +1,13 @@ import { ListableEvent } from "../../../../shared/event-list.firestore"; -import {BreakTimeSlot, DailySchedule, DetailedTalk, Talk} from "../../../../shared/daily-schedule.firestore"; +import { + BreakTimeSlot, + DailySchedule, + DetailedTalk, +} from "../../../../shared/daily-schedule.firestore"; import {ConferenceDescriptor} from "../../../../shared/conference-descriptor.firestore"; import {Replace} from "../../../../shared/type-utils"; +import {LineupSpeaker} from "../../../../shared/event-lineup.firestore"; +import {match, P} from "ts-pattern"; export type BreakTimeslotWithPotentiallyUnknownIcon = Replace }> -export interface FullEvent { +export type FullEvent = { id: string, conferenceDescriptor: Omit, info: Omit, daySchedules: DailySchedule[], talks: DetailedTalk[], + lineupSpeakers: LineupSpeaker[], } +export function detailedTalksToSpeakersLineup(talks: DetailedTalk[]): LineupSpeaker[] { + return talks.reduce((speakers, talk) => { + talk.speakers.forEach(speaker => { + const lineupSpeaker = match(speakers.find(lineupSpeaker => lineupSpeaker.id === speaker.id)) + .with(P.not(P.nullish), lineupSpeaker => lineupSpeaker) + .otherwise(() => { + const newLineupSpeaker: LineupSpeaker = { + ...speaker, + talks: [] + } + speakers.push(newLineupSpeaker); + return newLineupSpeaker; + }) + + lineupSpeaker.talks.push({ + id: talk.id, + title: talk.title, + format: talk.format, + language: talk.language, + track: talk.track, + tags: talk.tags, + allocation: { + room: talk.room, + start: talk.start, + end: talk.end, + }, + }) + }) + return speakers; + }, [] as LineupSpeaker[]) +} diff --git a/shared/event-lineup.firestore.d.ts b/shared/event-lineup.firestore.d.ts new file mode 100644 index 00000000..9447214f --- /dev/null +++ b/shared/event-lineup.firestore.d.ts @@ -0,0 +1,20 @@ +import {Room, Speaker, TalkAsset, TalkFormat, Track} from "./daily-schedule.firestore"; +import type {ISODatetime} from "./type-utils"; + +export type LineupTalk = { + id: string, + title: string, + format: TalkFormat, + language: string, + track: Track, + tags: string[], + allocation: { + room: Room, + start: ISODatetime, + end: ISODatetime, + }|undefined, +} + +export type LineupSpeaker = Speaker & { + talks: LineupTalk[], +}