Skip to content

Commit

Permalink
feat(38c3): first stub to produce engelsystem-specific schedule.xml
Browse files Browse the repository at this point in the history
  • Loading branch information
saerdnaer committed Dec 23, 2024
1 parent 41a1df6 commit 8d135c6
Show file tree
Hide file tree
Showing 6 changed files with 280 additions and 21 deletions.
222 changes: 222 additions & 0 deletions schedule_38C3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import os
from typing import List
import requests
import json
import pytz
import sys
import optparse
from datetime import datetime

from voc import (
GenericConference,
PretalxConference,
Event,
Schedule,
ScheduleEncoder,
ScheduleException,
Room,
Logger,
)

from voc.c3data import C3data
from git import Repo

# from voc.schedule import set_validator_filter
from voc.tools import (
commit_changes_if_something_relevant_changed,
git,
harmonize_event_type,
write,
ensure_folders_exist,
)

tz = pytz.timezone("Europe/Amsterdam")
local = False

parser = optparse.OptionParser()
parser.add_option("--online", action="store_true", dest="online", default=False)
parser.add_option(
"--fail", action="store_true", dest="exit_when_exception_occours", default=local
)
parser.add_option("--stats", action="store_true", dest="only_stats", default=False)
parser.add_option("--git", action="store_true", dest="git", default=False)
parser.add_option("--debug", action="store_true", dest="debug", default=local)

log = Logger(__name__)
options, args = parser.parse_args()

xc3 = "38c3"

main_cfp = GenericConference(
url="https://fahrplan.events.ccc.de/congress/2024/fahrplan/schedule/export/schedule.json",
data={
},
)
hub = GenericConference(
url="https://api.events.ccc.de/congress/2024/schedule.json",
data={
"name": "hub",
},
)

base_schedule = Schedule(
conference={
"url": "https://events.ccc.de/congress/2024/",
"acronym": "38c3",
"title": "38th Chaos Communication Congress",
"start": "2024-12-27T09:30:00+00:00",
"end": "2024-12-30T21:00:00+00:00",
"daysCount": 4,
"timeslot_duration": "00:10",
"time_zone_name": "Europe/Berlin",
},
version=str(datetime.now().strftime("%Y-%m-%d %H:%M")),
)

subconferences: List[GenericConference] = [
PretalxConference(
url="https://cfp.cccv.de/38c3-community-stages",
data={
"name": "community-stages",
},
),
PretalxConference(
url="https://cfp.cccv.de/38c3-chaos-computer-music-club",
data={
"name": "music",
},
),
# PretalxConference(
# url="https://cfp.cccv.de/38c3-lightningtalks/",
# data={
# "name": "lightningtalks",
# },
# ),
PretalxConference(
url="https://pretalx.c3voc.de/38c3-sendezentrum",
data={
},
),
PretalxConference(
url="https://pretalx.c3voc.de/38c3-haecksen-workshops-2024",
data={
},
),
PretalxConference(
url="https://fahrplan.alpaka.space/jugend-hackt-38c3-2024",
data={
},
),
]

targets = [
"filesystem",
"c3data",
# "voctoimport",
# "rc3hub"
]

id_offsets = {}

# this list/map is required to sort the events in the schedule.xml in the correct way
# other rooms/assemblies are added at the end on demand.
rooms = {}

channels = {}

output_dir = "/srv/www/" + xc3
secondary_output_dir = "./" + xc3
if len(sys.argv) == 2:
output_dir = sys.argv[1]

local = ensure_folders_exist(output_dir, secondary_output_dir)

def create_himmel_schedule(fahrplan):
himmel_schedule = fahrplan.copy("himmel")
himmel_schedule.rename_rooms({
'Saal 1': Room(name='Saal 1 Evac', guid='ba692ba3-421b-5371-8309-60acc34a3c06'),
'Saal GLITCH': Room(name='Saal GLITCH Evac', guid='7202df07-050c-552f-8318-992f94e40ef1'),
'Saal ZIGZAG': Room(name='Saal ZIGZAG Evac', guid='62251a07-13e4-5a72-bb3c-8528416ee0f3'),
})

himmel_schedule.export("himmel")

return himmel_schedule


def main():
fahrplan = main_cfp.schedule()
create_himmel_schedule(fahrplan)

everything = hub.schedule()
loaded_schedules = {}



# to get proper a state, we first have to remove all event files from the previous run
if not local or options.git:
git("rm events/* >/dev/null")
os.makedirs("events", exist_ok=True)

fahrplan.foreach_event(lambda e: e.export("events/", "-origin"))
everything.foreach_event(lambda e: e.export("events/", "-hub"))
#for schedule in loaded_schedules:
# schedule.foreach_event(lambda e: e.export("events/", "-origin"))

# remove overlapping 'Lötworkshop mit Lötchallenge'
# full_schedule.remove_event(guid='bd75d959-dad1-43b4-81fb-33dfb43c10ec')

# write all events to one big schedule.json/xml
write("\nExporting... ")
# set_validator_filter('strange')
everything.export("everything")


# expose metadata to own file
with open("meta.json", "w") as fp:
json.dump(
{
"data": {
"version": fahrplan.version(),
"source_urls": list(loaded_schedules.keys()),
"rooms": [
{
**room,
"schedule_name": room["name"],
"stream": channels.get(
room.get("guid", room["name"]), Room()
).stream,
}
for room in everything.rooms(mode="v2")
],
"conferences": subconferences,
},
},
fp,
indent=2,
cls=ScheduleEncoder,
)

print("\nDone")
print(" fahrplan version: " + fahrplan.version())
print(" hub version: " + everything.version())



if not local or options.git:
commit_changes_if_something_relevant_changed(everything)
# Attention: This method exits the script, if nothing relevant changed
# TOOD: make this fact more obvious or refactor code

if not local and "c3data" in targets:
print("\n== Updating c3data via API…")

c3data = C3data(everything)
c3data.process_changed_events(Repo("."), options)


if __name__ == "__main__":
main()
8 changes: 4 additions & 4 deletions voc/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import dateutil.parser
from datetime import datetime, timedelta

from voc.tools import str2timedelta

class EventSourceInterface:
origin_system = None
Expand Down Expand Up @@ -37,8 +38,7 @@ def __init__(self, data, start_time: datetime = None, origin: EventSourceInterfa
assert 'date' in data

self.start = start_time or dateutil.parser.parse(data["date"])
h, m = data['duration'].split(':', 2)
self.duration = timedelta(hours=int(h), minutes=int(m))
self.duration = str2timedelta(data["duration"])

if 'start' not in data:
data['start'] = self.start.strftime('%H:%M')
Expand Down Expand Up @@ -158,6 +158,6 @@ def meta(self):
def __str__(self):
return json.dumps(self._event, indent=2)

def export(self, prefix):
with open("{}{}.json".format(prefix, self._event["guid"]), "w") as fp:
def export(self, prefix, suffix=""):
with open("{}{}{}.json".format(prefix, self._event["guid"], suffix), "w") as fp:
json.dump(self._event, fp, indent=2)
2 changes: 1 addition & 1 deletion voc/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def __init__(self, url, data, options={}):
def __str__(self):
return self['name']

def schedule(self, *args):
def schedule(self, *args) -> Schedule:
if not self.schedule_url or self.schedule_url == 'TBD':
raise ScheduleException(' has no schedule url yet – ignoring')

Expand Down
8 changes: 5 additions & 3 deletions voc/git.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@

import argparse
import json
import os
from git import Repo
from voc.c3data import C3data
from voc.schedule import Schedule
from voc.event import Event
from voc.schedule import Schedule, ScheduleEncoder
from voc.tools import (
commit_changes_if_something_relevant_changed,
git,
Expand All @@ -19,7 +21,7 @@ def export_event_files(schedule: Schedule, options: argparse.Namespace, local =
# TODO: use Event.export()
def export_event(event: Event):
origin_system = None
if isinstance(event, Event):
if isinstance(event, Event) and event.origin:
origin_system = event.origin.origin_system

with open("events/{}.json".format(event["guid"]), "w") as fp:
Expand All @@ -37,7 +39,7 @@ def export_event(event: Event):
schedule.foreach_event(export_event)


def postprocessing(schedule: Schedule, options: argparse.Namespace, local = False):
def postprocessing(schedule: Schedule, options: argparse.Namespace, local = False, targets = []):
if not local or options.git:
commit_changes_if_something_relevant_changed(schedule)
# Attention: This method exits the script, if nothing relevant changed
Expand Down
20 changes: 14 additions & 6 deletions voc/schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,21 +283,28 @@ def add_rooms(self, rooms: list, context: EventSourceInterface = {}):
for x in rooms:
self.add_room(x, context)

def rename_rooms(self, replacements: Dict[str, str]):
def rename_rooms(self, replacements: Dict[str, str|Room]):

name_replacements = {}

for old_name_or_guid, new_name in replacements.items():
for old_name_or_guid, new_room in replacements.items():
new_name = new_room if isinstance(new_room, str) else new_room.name

r = self.room(name=old_name_or_guid) or self.room(guid=old_name_or_guid)
if r['name'] != new_name:
name_replacements[r['name']] = new_name
r['name'] = new_name
if r.get('guid'):
if isinstance(new_room, Room) and new_room.guid:
r['guid'] = new_room.guid
self._room_ids[new_name] = new_room.guid
elif r.get('guid'):
self._room_ids[new_name] = r['guid']

for day in self['conference']['days']:
for room_key, events in list(day['rooms'].items()):
new_name = replacements.get(room_key, room_key)
new_room = replacements.get(room_key, room_key)
new_name = new_room if isinstance(new_room, str) else new_room.name

day['rooms'][new_name] = day['rooms'].pop(room_key)
if room_key != new_name:
for event in events:
Expand Down Expand Up @@ -435,7 +442,7 @@ def calc_stats(event: Event):
self.stats.last_event = event

for person in event.get("persons", []):
if isinstance(person["id"], int) or person["id"].isnumeric():
if "id" in person and (isinstance(person["id"], int) or person["id"].isnumeric()):
if (
self.stats.person_min_id is None
or int(person["id"]) < self.stats.person_min_id
Expand Down Expand Up @@ -630,7 +637,8 @@ def _to_etree(d, node, parent=""):
node.text = str(d)
elif parent == "person":
node.text = d.get("public_name") or d.get('full_public_name') or d.get('full_name') or d.get('name')
_set_attrib(node, "id", d["id"])
if "id" in d:
_set_attrib(node, "id", d["id"])
if "guid" in d:
_set_attrib(node, "guid", d["guid"])

Expand Down
Loading

0 comments on commit 8d135c6

Please sign in to comment.