-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpretalx.py
More file actions
184 lines (147 loc) · 5.15 KB
/
pretalx.py
File metadata and controls
184 lines (147 loc) · 5.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
from datetime import datetime
from typing import Any
from pydantic import BaseModel, Field, field_validator, model_validator
from src.misc import SubmissionState
class PretalxAnswer(BaseModel):
question_text: str
answer_text: str
answer_file: str | None = None
submission_id: str | None = None
speaker_id: str | None = None
@model_validator(mode="before")
@classmethod
def extract(cls, values) -> dict:
values["question_text"] = values["question"]["question"]["en"]
values["answer_text"] = values["answer"]
values["answer_file"] = values["answer_file"]
values["submission_id"] = values["submission"]
values["speaker_id"] = values["person"]
return values
class PretalxSlot(BaseModel):
room: str | None = None
start: datetime | None = None
end: datetime | None = None
@field_validator("room", mode="before")
@classmethod
def handle_localized(cls, v) -> str | None:
if isinstance(v, dict):
return v["name"].get("en")
return v
class PretalxSpeaker(BaseModel):
"""
Model for Pretalx speaker data
"""
code: str
name: str
biography: str | None = None
avatar_url: str | None = None
submissions: list[str]
answers: list[PretalxAnswer]
class PretalxSubmission(BaseModel):
"""
Model for Pretalx submission data
"""
code: str
title: str
speakers: list[str] # We only want the code, not the full info
submission_type: str
track: str | None = None
state: SubmissionState
abstract: str = ""
duration: str = ""
resources: list[dict[str, str | None]] | None = None
answers: list[PretalxAnswer]
slots: list[PretalxSlot] = Field(default_factory=list, exclude=True)
slot_count: int = Field(..., exclude=True)
# Extracted from slot data
room: str | None = None
start: datetime | None = None
end: datetime | None = None
@field_validator("submission_type", "track", mode="before")
@classmethod
def handle_localized(cls, v) -> str | None:
if isinstance(v, dict):
return v["name"].get("en")
return v
@field_validator("duration", mode="before")
@classmethod
def duration_to_string(cls, v) -> str:
if isinstance(v, int):
return str(v)
return v
@field_validator("resources", mode="before")
@classmethod
def handle_resources(cls, v) -> list[dict[str, str]] | None:
return v or None
@model_validator(mode="before")
@classmethod
def process_values(cls, values) -> dict:
# Transform resource information
if raw_resources := values.get("resources"):
resources = [
{"description": res["description"], "resource": res["resource"]}
for res in raw_resources
]
values["resources"] = resources
# Set slot information
if values.get("slots"):
first_slot = PretalxSlot.model_validate(values["slots"][0])
values["room"] = first_slot.room
values["start"] = first_slot.start
last_slot = PretalxSlot.model_validate(values["slots"][-1])
values["end"] = last_slot.end
return values
@property
def is_publishable(self) -> bool:
return self.state in (SubmissionState.accepted, SubmissionState.confirmed)
class PretalxScheduleBreak(BaseModel):
"""
Model for Pretalx schedule break data
"""
room: str
start: datetime
end: datetime
description: dict[str, str] | str
@field_validator("description", mode="before")
@classmethod
def handle_localized(cls, v) -> str | Any:
if isinstance(v, dict):
return v.get("en")
return v
@model_validator(mode="before")
@classmethod
def set_slot_info(cls, values) -> dict:
slot = PretalxSlot.model_validate(values)
values["room"] = slot.room
values["start"] = slot.start
values["end"] = slot.end
return values
class PretalxSchedule(BaseModel):
"""
Model for Pretalx schedule data
"""
slots: list[PretalxSubmission]
breaks: list[PretalxScheduleBreak]
@model_validator(mode="before")
@classmethod
def process_values(cls, values) -> dict:
submission_slots = []
break_slots = []
for slot_dict in values["slots"]:
# extract nested slot fields into slot
slot_object = PretalxSlot.model_validate(slot_dict)
slot_dict["slot"] = slot_object
slot_dict["room"] = slot_object.room
slot_dict["start"] = slot_object.start
slot_dict["end"] = slot_object.end
if slot_dict.get("submission") is None:
break_slots.append(slot_dict)
else:
# merge submission fields into slot
slot_dict.update(slot_dict.get("submission", {}))
# remove resource IDs (not expandable with API, not required for schedule)
slot_dict.pop("resources", None)
submission_slots.append(slot_dict)
values["slots"] = submission_slots
values["breaks"] = break_slots
return values