const PRETALX_URL = `https://pretalx.lebib.org/` const EVENT_ID = `camp-interhack-2026-2025` const TALKS_EXPIRATION = 60*60*1000; const API_ROOT = new URL("api/", PRETALX_URL); // Database management let cached_talks = null; export async function getFreshTalks(){ if(!cached_talks || (Date.now() - cached_talks.updatedAt.getTime()) > TALKS_EXPIRATION){ let talk_list = [] for await(let talk_json of requestAllTalks()){ if(talk_json.state != "confirmed"){ continue } let talk = new Talk(talk_json); talk_list.push(talk) } talk_list.sort((a,b) => a.startTime.getTime() - b.startTime.getTime()) // { // let mock_i = 2 // talk_list[mock_i].slot.start = new Date(Date.now() - 120*1000).toJSON() // talk_list[mock_i].slot.end = (new Date(Date.now() + 3600000 + ( Math.random()*10000))).toJSON() // console.log("mock event", talk_list[mock_i]) // } let talks_by_room_id = {} for(let talk of talk_list) { if(!talks_by_room_id[talk.slot.room_id]){ talks_by_room_id[talk.slot.room_id] = [] } talks_by_room_id[talk.slot.room_id].push(talk) } cached_talks = { updatedAt: new Date(), talks: talk_list, talks_by_room: talks_by_room_id } } return cached_talks } export async function getUpcomingTalksForRoom(room_id){ let db = await getFreshTalks() return (db.talks_by_room[room_id] || []).filter(it => it.endTime.getTime() > Date.now()) } class Talk { constructor(srcObj){ Object.assign(this, srcObj) } get startTime(){ return new Date(this.slot.start) } get endTime(){ return new Date(this.slot.end) } get displayUrl(){ return new URL(`${encodeURIComponent(EVENT_ID)}/talk/${encodeURIComponent(this.code)}`, PRETALX_URL).toString() } get isActive(){ return this.startTime.getTime() <= Date.now() && this.endTime.getTime() >= Date.now() } } // Lower level tools const requestAllRooms = makePaginatedGenerator(new URL(`events/${encodeURIComponent(EVENT_ID)}/rooms/`, API_ROOT)) const requestAllTalks = makePaginatedGenerator(new URL(`events/${encodeURIComponent(EVENT_ID)}/talks/`, API_ROOT)) function makePaginatedGenerator(baseUrl){ return async function*(){ let buffer = [] let next_url = baseUrl while(buffer.length > 0 || next_url != null){ let item = buffer.shift() if(item){ yield item } else { let res = await fetch(next_url) if(!res.ok){ throw new Error(`Server responded with error ${res.status} ${res.statusText}`) } let response = await res.json() next_url = response.next buffer.push(...response.results) } } } }