Skip to content

Commit e2da5f9

Browse files
Serve YouTube URLs of session recordings (#84)
* Serve YouTube URLs of session recordings * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 9f9bbf6 commit e2da5f9

File tree

9 files changed

+131
-15
lines changed

9 files changed

+131
-15
lines changed

data/examples/README.md

Lines changed: 89 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Explaining the output data
1+
# Explaining the Output Data
22

33
**Note:** Some of the fields may be `null` or empty (`""`).
44

@@ -27,19 +27,16 @@
2727
"delivery": "in-person",
2828
"resources": [
2929
{
30-
"resource": "https://example.com/notebook.ipynb",
31-
"description": "Notebook used in the talk"
32-
},
33-
{
34-
"resource": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
35-
"description": "Video of the robot in action"
30+
"resource": "https://example.com/slides.pdf",
31+
"description": "Slides for the session"
3632
}
3733
...
3834
],
3935
"room": "South Hall 2A",
40-
"start": "2024-07-10T14:00:00+02:00",
41-
"end": "2024-07-10T15:00:00+02:00",
42-
"website_url": "https://ep2024.europython.eu/session/example-talk/",
36+
"start": "2099-07-10T14:00:00+02:00",
37+
"end": "2099-07-10T15:00:00+02:00",
38+
"website_url": "https://ep2099.europython.eu/session/example-talk/",
39+
"youtube_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&pp=ygUJcmljayByb2xs",
4340
"sessions_in_parallel": [
4441
"F7G8H9",
4542
...
@@ -81,6 +78,7 @@ The fields are as follows:
8178
| `start` | `string (datetime ISO format)` \| `null` | Start time of the session |
8279
| `end` | `string (datetime ISO format)` \| `null` | End time of the session |
8380
| `website_url` | `string` | URL of the session on the conference website |
81+
| `youtube_url` | `string` \| `null` | URL of the session's video on YouTube |
8482
| `sessions_in_parallel` | `array[string]` \| `null` | List of codes of sessions happening in parallel |
8583
| `sessions_after` | `array[string]` \| `null` | List of codes of sessions happening after this session |
8684
| `sessions_before` | `array[string]` \| `null` | List of codes of sessions happening before this session |
@@ -137,3 +135,84 @@ The fields are as follows:
137135
| `twitter_url` | `string` \| `null` | URL of the speaker's Twitter profile |
138136
| `mastodon_url` | `string` \| `null` | URL of the speaker's Mastodon profile |
139137
| `website_url` | `string` | URL of the speaker's profile on the conference website |
138+
139+
&nbsp;
140+
141+
## `schedule.json`
142+
143+
<details>
144+
<summary>Example schedule data JSON</summary>
145+
146+
```json
147+
{
148+
"days": {
149+
"2099-07-08": {
150+
"events": [
151+
{
152+
"code": "LMN123",
153+
"title": "Welcome and Keynote",
154+
"speakers": [],
155+
"session_type": "Announcements",
156+
"slug": "welcome-keynote",
157+
"track": null,
158+
"level": "beginner",
159+
"rooms": [
160+
"Room A",
161+
"Room B"
162+
],
163+
"start": "2099-07-08T08:00:00+02:00",
164+
"duration": 60,
165+
"tweet": "",
166+
"website_url": "https://ep2099.europython.eu/session/welcome-keynote"
167+
},
168+
{
169+
"code": "OPQ456",
170+
"title": "Advanced Python Techniques",
171+
"speakers": [
172+
{
173+
"avatar": "https://pretalx.com/media/avatars/picture.jpg",
174+
"code": "RST789",
175+
"name": "John Doe",
176+
"slug": "john-doe",
177+
"website_url": "https://ep2099.europython.eu/speaker/john-doe"
178+
}
179+
],
180+
"session_type": "Tutorial",
181+
"slug": "advanced-python-techniques",
182+
"track": "CPython Internals",
183+
"level": "advanced",
184+
"rooms": [
185+
"Room C"
186+
],
187+
"start": "2099-07-08T10:00:00+02:00",
188+
"duration": 90,
189+
"tweet": "",
190+
"website_url": "https://ep2099.europython.eu/advanced-python-techniques"
191+
}
192+
]
193+
}
194+
}
195+
}
196+
```
197+
</details>
198+
199+
&nbsp;
200+
201+
The fields are as follows:
202+
203+
| Key | Type | Notes |
204+
|----------------|-----------------------------|------------------------------------------------------------|
205+
| `days` | `object` | Contains schedule by date |
206+
| `events` | `array[object]` | List of events for a particular day |
207+
| `code` | `string` | Unique identifier for the event |
208+
| `title` | `string` | Title of the event |
209+
| `speakers` | `array[object]` | List of speakers for the event (if applicable) |
210+
| `session_type` | `string` | Type of event (e.g. Announcements, Workshop, etc.) |
211+
| `slug` | `string` | URL-friendly version of the event title |
212+
| `track` | `string` \| `null` | Track associated with the event (e.g. Web, PyData, etc.) |
213+
| `level` | `string` | Level of the event (beginner, intermediate, advanced) |
214+
| `rooms` | `array[string]` | List of rooms the event is being held in |
215+
| `start` | `string (datetime ISO)` | Start time of the event |
216+
| `duration` | `integer` | Duration of the event in minutes |
217+
| `tweet` | `string` \| `null` | Tweet-length description of the event |
218+
| `website_url` | `string` | URL of the event on the conference website |

data/examples/europython/sessions.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"sessions_before": null,
3232
"next_session": null,
3333
"prev_session": null,
34-
"website_url": "https://ep2024.europython.eu/session/this-is-a-test-talk-from-a-test-speaker-about-a-test-topic"
34+
"website_url": "https://ep2024.europython.eu/session/this-is-a-test-talk-from-a-test-speaker-about-a-test-topic",
35+
"youtube_url": "https://youtube.com/watch?v=01234567890"
3536
},
3637
"B8CD4F": {
3738
"code": "B8CD4F",
@@ -56,6 +57,7 @@
5657
"sessions_before": null,
5758
"next_session": null,
5859
"prev_session": null,
59-
"website_url": "https://ep2024.europython.eu/session/a-talk-with-shorter-title"
60+
"website_url": "https://ep2024.europython.eu/session/a-talk-with-shorter-title",
61+
"youtube_url": "https://youtube.com/watch?v=12345679012"
6062
}
6163
}

data/examples/pretalx/youtube.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
{
3+
"submission": "A8CD3F",
4+
"youtube_link": "https://youtube.com/watch?v=01234567890",
5+
"video_id": "01234567890"
6+
},
7+
{
8+
"submission": "B8CD4F",
9+
"youtube_link": "https://youtube.com/watch?v=12345679012",
10+
"video_id": "12345679012"
11+
}
12+
]

src/download.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
# saving us later time with joining the answers.
2020
"submissions?questions=all&state=confirmed",
2121
"speakers?questions=all",
22+
"p/youtube",
2223
]
2324

2425
Config.raw_path.mkdir(parents=True, exist_ok=True)
@@ -45,7 +46,8 @@
4546

4647
pbar.close()
4748

48-
filename = resource.split("?")[0] # To get rid of "?questions"
49+
# To get the resource name without extra parameters
50+
filename = resource.split("?")[0].split("/")[-1]
4951
filename = f"{filename}_latest.json"
5052
filepath = Config.raw_path / filename
5153

src/models/europython.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ class EuroPythonSession(BaseModel):
142142
next_session: str | None = None
143143
prev_session: str | None = None
144144
slot_count: int = Field(..., exclude=True)
145+
youtube_url: str | None = None
145146

146147
@field_validator("room", mode="before")
147148
@classmethod

src/transform.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616
)
1717
pretalx_schedule = Parse.schedule(Config.raw_path / "schedule_latest.json")
1818

19+
# Parse the YouTube data
20+
youtube_data = Parse.youtube(Config.raw_path / "youtube_latest.json")
21+
1922
print("Computing timing relationships...")
2023
TimingRelationships.compute(pretalx_submissions.values())
2124

2225
print("Transforming the data...")
2326
ep_sessions = Transform.pretalx_submissions_to_europython_sessions(
24-
pretalx_submissions
27+
pretalx_submissions,
28+
youtube_data,
2529
)
2630
ep_speakers = Transform.pretalx_speakers_to_europython_speakers(pretalx_speakers)
2731
ep_schedule = Transform.pretalx_schedule_to_europython_schedule(

src/utils/parse.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,14 @@ def schedule(input_file: Path | str) -> PretalxSchedule:
6161
schedule = PretalxSchedule.model_validate(js)
6262

6363
return schedule
64+
65+
@staticmethod
66+
def youtube(input_file: Path | str) -> dict[str, str]:
67+
"""
68+
Returns the Session code to YouTube URL mapping
69+
"""
70+
with open(input_file) as fd:
71+
js = json.load(fd)
72+
youtube_data = {s["submission"]: s["youtube_link"] for s in js}
73+
74+
return youtube_data

src/utils/transform.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Transform:
1515
@staticmethod
1616
def pretalx_submissions_to_europython_sessions(
1717
submissions: dict[str, PretalxSubmission],
18+
youtube_data: dict[str, str],
1819
) -> dict[str, EuroPythonSession]:
1920
"""
2021
Transforms the given Pretalx submissions to EuroPython sessions
@@ -58,6 +59,7 @@ def pretalx_submissions_to_europython_sessions(
5859
next_session=TimingRelationships.get_next_session(submission.code),
5960
prev_session=TimingRelationships.get_prev_session(submission.code),
6061
slot_count=submission.slot_count,
62+
youtube_url=youtube_data.get(submission.code),
6163
)
6264
ep_sessions[code] = ep_session
6365

tests/test_transform_end_to_end.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88
"./data/examples/pretalx/submissions.json"
99
)
1010

11+
youtube_data = Parse.youtube("./data/examples/pretalx/youtube.json")
12+
1113

1214
def test_e2e_sessions() -> None:
1315
TimingRelationships.compute(pretalx_submissions.values())
1416

1517
ep_sessions = Transform.pretalx_submissions_to_europython_sessions(
16-
pretalx_submissions
18+
pretalx_submissions,
19+
youtube_data,
1720
)
1821
ep_sessions_dump = {
1922
k: json.loads(v.model_dump_json()) for k, v in ep_sessions.items()

0 commit comments

Comments
 (0)