Skip to content

Commit

Permalink
Merge pull request #12 from pyconau/program
Browse files Browse the repository at this point in the history
Program
  • Loading branch information
daisylb committed Jun 28, 2023
2 parents 074780b + 304b60d commit 65a892f
Show file tree
Hide file tree
Showing 91 changed files with 1,291 additions and 0 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/update_schedule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Update schedule
on:
workflow_dispatch:
schedule:
- cron: "22 */2 * * *"
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: "3.11"
- run: |
cd scripts
pip install poetry
poetry install
poetry run python schedule_sync.py
env:
PRETALX_TOKEN: ${{ secrets.PRETALX_TOKEN }}
- run: git diff
- uses: EndBug/add-and-commit@v4
with:
add: |
public/people
src/content/sessions
src/content/people
author_name: Robot
author_email: beep-boop@local
message: "Auto-update of schedule"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ data/SpeakerPack/*
node_modules
dist/
.astro
.envrc
Binary file added public/people/37TEMH.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/3C7EAA.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/8UFZNX.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/9JGCPM.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/9SG3KG.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/A373NW.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/AHET73.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/BA8DVU.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/BALYAL.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/BHTKP3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/BUWU8Z.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/CHHWUG.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/CXEYFS.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/D8UUB3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/D9UMRR.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/E3XJKT.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/EAEYZM.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/EKSXKG.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/EXZMKL.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/FB7A7U.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/FM883L.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/GGBFN8.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/H3M7XF.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/HU3WCT.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/HYXK8D.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/people/JEXXZQ.jpg
Binary file added public/people/JJFWEP.jpg
Binary file added public/people/JRGRVG.jpg
Binary file added public/people/JYUNEP.jpg
Binary file added public/people/KCADCR.jpg
Binary file added public/people/KTZNUG.jpg
Binary file added public/people/LDFVBH.jpg
Binary file added public/people/LWZSTN.jpg
Binary file added public/people/MTGWEC.jpg
Binary file added public/people/MY7QMZ.jpg
Binary file added public/people/N9ZZWG.jpg
Binary file added public/people/PFTMME.jpg
Binary file added public/people/PGYLJB.jpg
Binary file added public/people/PZFRSS.jpg
Binary file added public/people/QVZKDG.jpg
Binary file added public/people/QWCHX7.jpg
Binary file added public/people/RDLWJ8.jpg
Binary file added public/people/RRK8EN.jpg
Binary file added public/people/RSUKRU.jpg
Binary file added public/people/RTG9TS.jpg
Binary file added public/people/RXNL8L.jpg
Binary file added public/people/TDZSSC.jpg
Binary file added public/people/TQKR8P.jpg
Binary file added public/people/UJJAJF.jpg
Binary file added public/people/VXBVLZ.jpg
Binary file added public/people/VZTVRY.jpg
Binary file added public/people/WLRBE3.jpg
Binary file added public/people/WXXHQL.jpg
Binary file added public/people/WZK8XF.jpg
Binary file added public/people/XDM3GY.jpg
Binary file added public/people/XLYVCH.jpg
Binary file added public/people/XWWMQL.jpg
Binary file added public/people/XZ9GLY.jpg
Binary file added public/people/YCFJET.jpg
Binary file added public/people/YEJTFV.jpg
Binary file added public/people/ZPQUMD.jpg
Binary file added public/people/ZY7KJB.jpg
Binary file added public/people/ZZLBQC.jpg
Binary file added public/people/placeholder.jpg
372 changes: 372 additions & 0 deletions scripts/poetry.lock

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions scripts/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[tool.poetry]
name = "pyconau-2023-website-scripts"
version = "0.1.0"
description = ""
authors = ["Daisy Leigh Brenecki <[email protected]>"]
readme = "README.md"
packages = [{include = "pyconau_2023_website_scripts"}]

[tool.poetry.dependencies]
python = "^3.11"
requests = "^2.31.0"
"ruamel.yaml" = "^0.17.32"
python-dateutil = "^2.8.2"
parse = "^1.19.1"
Markdown = "^3.4.3"
bleach = "^6.0.0"
pillow = "^9.5.0"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
254 changes: 254 additions & 0 deletions scripts/schedule_sync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
import os
import os.path
import pathlib
from datetime import timedelta
from os import environ
from pprint import pprint

import bleach
import dateutil.parser
import dateutil.tz
import requests
from markdown import Markdown
from parse import parse
from ruamel.yaml import YAML

PRETALX_TOKEN = environ["PRETALX_TOKEN"]
AEST = dateutil.tz.gettz("Australia/Melbourne")
CONTENT_DIR = pathlib.Path("../src/content")
SESSIONS_DIR = CONTENT_DIR / "sessions"
PEOPLE_DIR = CONTENT_DIR / "people"
PUBLIC_DIR = pathlib.Path("../public")
PEOPLE_IMGS_DIR = PUBLIC_DIR / "people"

TAG_IDS_TO_SKIP = {787}

yaml = YAML()
md = Markdown()


def paginate(url):
next_url = url
while next_url:
res = requests.get(
next_url,
headers={"Authorization": f"Token {PRETALX_TOKEN}"},
)
res.raise_for_status()
data = res.json()
next_url = data["next"]
yield from data["results"]


def parse_markdown(text):
html = md.convert(text)
return bleach.clean(
html,
tags=(
"a",
"abbr",
"acronym",
"b",
"blockquote",
"code",
"em",
"i",
"li",
"ol",
"strong",
"ul",
"p",
"h2",
"h3",
"s",
"del",
"ins",
),
)


rooms = {
"Backup Speakers": 0,
"Curlyboi Theatre": 1,
"Platypus Hall": 2,
"Science, Data & Analytics": 1,
"DevOops": 2,
"Education": 3,
"Snakeoil Academy (Security & Privacy)": 4,
}

tracks = {
"Our Connected Universe": "ocu",
"All Things Data!": "data",
"Education": "education",
"DjangoCon AU": "djangocon",
"Main Conference": None,
}

answers = {
"Presentation Format": 853,
"Content Warning": 2459,
"Pronouns": 2461,
"Twitter": 2455,
"Fedi": 2506,
}

format_answer = {
1062: "L", # live
1063: "P", # prerecord
}

seen_speakers = set()

yt_resp = requests.get(
"https://portal.nextdayvideo.com.au/main/C/pyconau/S/pyconau_2021.json"
)
yt_resp.raise_for_status()
youtube_slugs = {
x["conf_key"]: x["host_url"].rsplit("/", 1)[1]
for x in yt_resp.json()
if x["host_url"] is not None
}

for entry in SESSIONS_DIR.glob("*"):
entry.unlink()


for session in paginate(
"https://pretalx.com/api/events/pyconau-2023/submissions/?state=confirmed&questions=2459"
):
# Do not schedule backups
# TODO manually add backups if they are unscheduled after the event.
# if rooms[session["slot"]["room"]["en"]] == 0:
# print("not scheduling backup")
# continue
print(session["code"])

if TAG_IDS_TO_SKIP.intersection(session["tag_ids"]):
print("skipping due to tag id")
continue

speakers = [x["code"] for x in session["speakers"]]
seen_speakers.update(speakers)
with (SESSIONS_DIR / f'{session["code"]}.yml').open("w") as f:
# start = dateutil.parser.isoparse(session["slot"]["start"]).astimezone(AEST)
# end = dateutil.parser.isoparse(session["slot"]["end"]).astimezone(AEST)
# type_answer_id = format_answer[next(
# x["options"][0]["id"] for x in session["answers"] if x["question"]["id"] == answers["Presentation Format"]
# )]
cw = next(
(
x["answer"]
for x in session["answers"]
if x["question"]["id"] == answers["Content Warning"]
),
None,
)
twitter = next(
(
x["answer"]
for x in session["answers"]
if x["question"]["id"] == answers["Twitter"]
),
None,
)
fedi = next(
(
x["answer"]
for x in session["answers"]
if x["question"]["id"] == answers["Fedi"]
),
None,
)
yaml.dump(
{
"title": session["title"],
# "start": start,
# "end": end,
# "room": rooms[session["slot"]["room"]["en"]],
# "track": tracks[session["track"]["en"]],
# "type": type_answer_id,
"abstract": parse_markdown(session["abstract"]),
"description": parse_markdown(session["description"]),
"code": session["code"],
"speakers": speakers,
"cw": parse_markdown(cw) if cw is not None else None,
"youtube_slug": youtube_slugs.get(session["code"]),
},
f,
)

from io import BytesIO

from PIL import Image

with (PEOPLE_DIR / "_etags.yml").open("r") as f:
etags = yaml.load(f)

# etags none? ensure empty
if not etags:
etags = {}

for speaker in paginate(
"https://pretalx.com/api/events/pyconau-2023/speakers/?questions=2461,2455,2506"
):
if speaker["code"] not in seen_speakers:
continue
has_pic = False
try:
if speaker["avatar"] is not None:
etag = etags.get(speaker["code"], None)
print(speaker["avatar"])
avatar_resp = requests.get(
speaker["avatar"],
headers={"If-None-Match": etag} if etag is not None else {},
)
if avatar_resp.status_code == 304:
print("ETag match")
continue
avatar_resp.raise_for_status()
if "ETag" in avatar_resp.headers:
etags[speaker["code"]] = avatar_resp.headers["ETag"]
im = Image.open(BytesIO(avatar_resp.content))
im = im.convert("RGB")
im.thumbnail((128, 128))
im.save(str(PEOPLE_IMGS_DIR / f'{speaker["code"]}.jpg'))
has_pic = True
except Exception as e:
print(speaker["code"], speaker["avatar"], e)
with (PEOPLE_DIR / f'{speaker["code"]}.yml').open("w") as f:
yaml.dump(
{
"name": speaker["name"],
"pronouns": next(
(
x["answer"]
for x in speaker["answers"]
if x["question"]["id"] == answers["Pronouns"]
),
None,
),
"twitter": next(
(
x["answer"]
for x in speaker["answers"]
if x["question"]["id"] == answers["Twitter"]
),
None,
),
"fedi": next(
(
x["answer"]
for x in speaker["answers"]
if x["question"]["id"] == answers["Fedi"]
),
None,
),
"bio": parse_markdown(speaker["biography"] or ""),
"has_pic": has_pic,
},
f,
)

with (PEOPLE_DIR / "_etags.yml").open("w") as f:
yaml.dump(etags, f)
60 changes: 60 additions & 0 deletions src/components/Profile.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
import type { CollectionEntry } from "astro:content"
export type Props = {
person: CollectionEntry<"people">
bio: boolean
}
const { person, bio } = Astro.props as Props
const photo = person.data.has_pic
? `/people/${person.id}.jpg`
: "/people/placeholder.jpg"
---

<style lang="scss">
.profile {
display: flex;
flex-direction: row;

img {
width: 75px;
height: 75px;
aspect-ratio: 1;
border-radius: 1000px;
object-fit: cover;
}
.details {
display: flex;
flex-direction: column;
&:not(:first-child) {
margin-left: 1em;
}
}
b {
font-size: 4 / 3 * 1em;
}
}

.profile-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
grid-gap: 2em;
}
</style>

<div class="profile">
<img class="local-border" src={photo} />

<div class="details">
<b>{person.data.name}</b>
{
person.data.pronouns && (
<small>
{[person.data.pronouns, person.data.fedi, person.data.twitter]
.filter((x) => !!x)
.join("")}
</small>
)
}
{bio && person.data.bio && <Fragment set:html={person.data.bio} />}
</div>
</div>
Loading

0 comments on commit 65a892f

Please sign in to comment.