Skip to content

Commit 314c619

Browse files
Read schedule from Pretalx
Resolves #62
1 parent 1c6a1f0 commit 314c619

File tree

5 files changed

+83
-79
lines changed

5 files changed

+83
-79
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ Populate environment variables:
1717
- `MATRIX_BASE_URL`: Homeserver base URL
1818
- `MATRIX_RATE_LIMIT`: Rate limit in hertz
1919
- `ISSUE_8895_COOLDOWN`: Seconds to wait before room creation ([matrix-org/synapse#8895])
20-
- [OSEM]:
21-
- `OSEM_RATE_LIMIT`: Rate limit in hertz
20+
- [Pretalx]:
21+
- `PRETALX_RATE_LIMIT`: Rate limit in hertz
2222
- [Sentry]:
2323
- `SENTRY_DSN` (Optional): Data Source Name of Sentry project. If unset, error reporting is not enabled.
2424

@@ -38,7 +38,7 @@ yarn start
3838
[this Stack Exchange question]: https://webapps.stackexchange.com/q/131056/19769
3939
[matrix-org/synapse#8895]: https://github.com/matrix-org/synapse/issues/8895
4040
[Node.js]: https://nodejs.org/
41-
[OSEM]: https://osem.seagl.org/
41+
[Pretalx]: https://pretalx.seagl.org/
4242
[SeaGL]: https://seagl.org/
4343
[SeaGL Matrix space]: https://seagl.org/meet
4444
[Sentry]: https://sentry.io/

src/lib/Osem.ts

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/lib/Plan.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ export namespace Plan {
2727
export type Rooms = Record<string, Room>;
2828

2929
export interface Sessions {
30-
conference: string;
3130
demo?: string;
31+
event: string;
3232
ignore?: string[];
3333
intro?: string;
3434
openEarly: number;

src/lib/Pretalx.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import Bottleneck from "bottleneck";
2+
import { DateTime } from "luxon";
3+
import { env, fetch as unlimited } from "./utilities.js";
4+
5+
const origin = "https://pretalx.seagl.org";
6+
const minTime = 1000 / Number(env("PRETALX_RATE_LIMIT"));
7+
8+
const limiter = new Bottleneck({ maxConcurrent: 1, minTime });
9+
const fetch = limiter.wrap(unlimited);
10+
11+
// Reference: https://docs.pretalx.org/api/fundamentals/#pagination
12+
interface PaginatedResponse<T = {}> {
13+
next: string | null;
14+
results: T[];
15+
}
16+
17+
export interface Talk {
18+
beginning: DateTime;
19+
end: DateTime;
20+
id: string;
21+
roomId: string;
22+
roomName: string;
23+
title: string;
24+
url: string;
25+
}
26+
27+
// Reference: https://docs.pretalx.org/api/resources/talks/
28+
type TalksResponse = PaginatedResponse<{
29+
code: string;
30+
slot?: {
31+
end: string;
32+
room: { en: string };
33+
room_id: number;
34+
start: string;
35+
};
36+
title: string;
37+
}>;
38+
39+
export const getTalks = async (event: string): Promise<Talk[]> => {
40+
const talks: Talk[] = [];
41+
42+
const url = `${origin}/api/events/${event}/talks/?limit=100&state=confirmed`;
43+
for await (const page of pages<TalksResponse>(url))
44+
for (const { code, slot, title } of page)
45+
if (slot)
46+
talks.push({
47+
beginning: DateTime.fromISO(slot.start),
48+
end: DateTime.fromISO(slot.end),
49+
id: code,
50+
roomId: slot.room_id.toString(),
51+
roomName: slot.room.en,
52+
title,
53+
url: `${origin}/${event}/talk/${code}/`,
54+
});
55+
56+
return talks;
57+
};
58+
59+
async function* pages<Response extends PaginatedResponse>(
60+
url: string,
61+
): AsyncGenerator<Response["results"]> {
62+
let next: string | null = url;
63+
do {
64+
const response = (await (await fetch(next)).json()) as Response;
65+
next = response.next;
66+
yield response.results;
67+
} while (next);
68+
}

src/modules/Reconciler.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ import {
2323
StateEventInput,
2424
} from "../lib/matrix.js";
2525
import Module from "../lib/Module.js";
26-
import * as OSEM from "../lib/Osem.js";
2726
import type { Plan, SessionGroupId } from "../lib/Plan.js";
27+
import * as Pretalx from "../lib/Pretalx.js";
2828
import type { Scheduled } from "../lib/scheduling.js";
29-
import { expect, maxDelay, optional, populate, unimplemented } from "../lib/utilities.js";
29+
import { expect, maxDelay, populate, unimplemented } from "../lib/utilities.js";
3030
import type Patch from "../Patch.js";
3131

3232
const md = new MarkdownIt();
@@ -42,7 +42,7 @@ interface ListedSpace extends Space {
4242
local: string;
4343
}
4444

45-
interface Session extends OSEM.Event {
45+
interface Session extends Pretalx.Talk {
4646
day: number;
4747
open: DateTime;
4848
}
@@ -704,11 +704,10 @@ export default class extends Module {
704704
) {
705705
const ignore = new Set(plan.ignore ?? []);
706706

707-
this.debug("📅 Get sessions", { conference: plan.conference });
708-
const osemRooms = await OSEM.getRooms(plan.conference);
709-
const osemEvents = await OSEM.getEvents(plan.conference);
710-
const startOfDay = DateTime.min(...osemEvents.map((e) => e.beginning)).startOf("day");
711-
const sessions = osemEvents
707+
this.debug("📅 Get sessions", { event: plan.event });
708+
const talks = await Pretalx.getTalks(plan.event);
709+
const startOfDay = DateTime.min(...talks.map((e) => e.beginning)).startOf("day");
710+
const sessions = talks
712711
.filter((e) => !ignore.has(e.id))
713712
.map((event) => ({
714713
...event,
@@ -730,21 +729,20 @@ export default class extends Module {
730729
for (const [index, session] of sessions.entries()) {
731730
const suffix = plan.suffixes?.[session.id] ?? `session-${session.id}`;
732731
const redirect = plan.redirects?.[session.id];
733-
const venueRoom = osemRooms[session.room]?.name;
734-
const values = { room: venueRoom, title: session.title, url: session.url };
732+
const values = { room: session.roomName, title: session.title, url: session.url };
735733
const intro = populate(values, plan.intro);
736734
const topic = populate(values, plan.topic);
737-
const widget = redirect ? undefined : plan.widgets?.[session.room]?.[session.day];
735+
const widget = redirect ? undefined : plan.widgets?.[session.roomId]?.[session.day];
738736

739737
const local = `${plan.prefix}${suffix}`;
740738
const room = await this.reconcileRoom(inheritedUsers, local, sortKey(index), {
741739
name: [
742740
session.beginning.toFormat("EEE HH:mm"),
743-
...optional(venueRoom?.replace(/Room (?=\d+)/, "R")),
741+
session.roomName.replace(/Room (?=\d+)/, "R"),
744742
"·",
745743
session.title,
746744
].join(" "),
747-
tag: `osem-event-${session.id}`,
745+
tag: `pretalx-talk-${session.id}`,
748746
...(intro ? { intro } : {}),
749747
...(redirect ? { redirect } : {}),
750748
...(topic ? { topic } : {}),

0 commit comments

Comments
 (0)