101 lines
No EOL
3 KiB
JavaScript
101 lines
No EOL
3 KiB
JavaScript
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)
|
|
}
|
|
}
|
|
}
|
|
} |