Created
July 6, 2024 09:39
-
-
Save yorickvP/eeb569c3733b7a67031d3f8047ed1079 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import xml.etree.ElementTree as ET | |
from datetime import datetime, timedelta | |
import uuid | |
from slugify import slugify | |
import re | |
MY_NAMESPACE = uuid.UUID('ca6c8e77-59a4-4e51-919c-25e38457f0ee') | |
def generate_deterministic_uuid(*args): | |
# Convert all arguments to strings and join them | |
name = ':'.join(map(str, args)) | |
# Generate a UUID using uuid5 | |
return uuid.uuid5(MY_NAMESPACE, name) | |
def parse_schedule(file_path): | |
events = [] | |
with open(file_path, 'r') as file: | |
for line in file: | |
date_time = line[0:13] | |
# regex split on 2 or more spaces | |
parts = re.split(r' {2,}', line.strip()) | |
print(parts) | |
if len(parts) >= 3: | |
date_time, room, title = parts[:3] | |
description = parts[3] if len(parts) > 3 else "" | |
events.append((dt_to_dttz(date_time), room, title, description)) | |
else: | |
print(f"Invalid line: {line}") | |
return events | |
def dt_to_dttz(date_time) -> datetime: | |
# Parse the date and time | |
year = date_time[:4] | |
month = date_time[4:6] | |
day = date_time[6:8] | |
hour = date_time[9:11] | |
minute = date_time[11:13] | |
if hour == "90": | |
hour = "09" | |
return datetime(int(year), int(month), int(day), int(hour), int(minute)) | |
def create_frab_xml(events): | |
schedule = ET.Element("schedule") | |
ET.SubElement(schedule, "version").text = "0.1" | |
conference = ET.SubElement(schedule, "conference") | |
start_date = min(events, key=lambda x: x[0])[0] | |
start_date = start_date.replace(hour=0, minute=0, second=0, microsecond=0) | |
ET.SubElement(conference, "acronym").text = "vierdaagsef-2024" | |
ET.SubElement(conference, "title").text = "Vierdaagsefeesten" | |
ET.SubElement(conference, "start").text = start_date.strftime("%Y-%m-%d") | |
ET.SubElement(conference, "end").text = max(events, key=lambda x: x[0])[0].strftime("%Y-%m-%d") | |
ET.SubElement(conference, "days").text = "7" | |
ET.SubElement(conference, "timeslot_duration").text = "00:15" | |
rooms = set([event[1] for event in events]) | |
xdays = [] | |
for d in range(1, 8): | |
day = ET.SubElement(schedule, "day") | |
date = (start_date + timedelta(days=d-1)).strftime("%Y-%m-%d") | |
day.set("date", date) | |
day.set("index", str(d)) | |
day.set("start", f"{date}T09:00:00+02:00") | |
day.set("end", f"{date}T23:59:00+02:00") | |
for r in rooms: | |
room = ET.SubElement(day, "room") | |
room.set("name", r) | |
xdays.append(day) | |
for i, (start, room, title, description) in enumerate(events, 1): | |
day_id = (start - start_date).days + 1 | |
xday = xdays[day_id - 1] | |
xroom = xday.find(f"room[@name='{room}']") | |
event = ET.SubElement(xroom, "event") | |
event.set("id", str(i)) | |
guid = generate_deterministic_uuid(start, room, title) | |
event.set("guid", str(guid)) | |
date_string = start.strftime("%Y-%m-%dT%H:%M:00+02:00") | |
ET.SubElement(event, "date").text = date_string | |
end = start + timedelta(hours=2) | |
ET.SubElement(event, "start").text = start.strftime("%H:%M") | |
ET.SubElement(event, "duration").text = "02:00" | |
ET.SubElement(event, "room").text = room | |
ET.SubElement(event, "title").text = title | |
ET.SubElement(event, "description").text = description | |
ET.SubElement(event, "abstract").text = description | |
ET.SubElement(event, "type").text = "performance" | |
ET.SubElement(event, "track").text = "valkhof" | |
ET.SubElement(event, "language").text = "en" | |
ET.SubElement(event, "slug").text = f"vierdaagsef-2024-{str(i)}-{slugify(title, to_lower=True)}" | |
ET.SubElement(event, "subtitle") # xs:string | |
xrec = ET.SubElement(event, "recording") | |
ET.SubElement(xrec, "license") | |
ET.SubElement(xrec, "optout").text = "false" | |
ET.SubElement(event, "persons") | |
ET.SubElement(event, "links") | |
ET.SubElement(event, "attachments") # attachments | |
ET.SubElement(event, "url").text = "https://example.com" # httpURI | |
ET.SubElement(event, "feedback_url").text = "https://example.com" # httpURI | |
return ET.ElementTree(schedule) | |
# Usage | |
input_file = "festival_schedule.txt" # Replace with your input file path | |
output_file = "festival_schedule.xml" # Replace with your desired output file path | |
events = parse_schedule(input_file) | |
xml_tree = create_frab_xml(events) | |
xml_tree.write(output_file, encoding="UTF-8", xml_declaration=True) | |
print(f"Frab XML file has been created: {output_file}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment