Skip to content

Instantly share code, notes, and snippets.

@mecaneer23
Created May 27, 2025 20:53
Show Gist options
  • Select an option

  • Save mecaneer23/7671fc3e7d230cdfea356b82f6360df0 to your computer and use it in GitHub Desktop.

Select an option

Save mecaneer23/7671fc3e7d230cdfea356b82f6360df0 to your computer and use it in GitHub Desktop.
Script to convert a list of events to an ICS calendar file
"""Generate an ICS calendar file for a provided schedule."""
from datetime import datetime, timedelta
from pathlib import Path
from events import full_events
full_events: list[tuple[str, str, str, str, str, str, str]]
YEAR = 2025
TIMEZONE = "-05:00" # Central Daylight Time offset
def create_ics_event( # noqa: PLR0913
uid: str,
dtstart: datetime,
dtend: datetime,
summary: str,
priority: str,
gate_open: str,
extra_info: str = "",
) -> str:
"""Create an ICS event string with the given parameters."""
return f"""BEGIN:VEVENT
UID:{uid}
DTSTAMP:{dtstart.strftime("%Y%m%dT%H%M%SZ")}
DTSTART:{dtstart.strftime("%Y%m%dT%H%M%S")}
DTEND:{dtend.strftime("%Y%m%dT%H%M%S")}
DESCRIPTION:{" " + priority + "\\n" if priority else ""}
Shift start: {dtstart.strftime("%I:%M %p") + "\\n" if dtstart else ""}
Gate open: {gate_open + "\\n"}{
"Extra information: " + extra_info if extra_info else ""
}
SUMMARY:{summary}
END:VEVENT
"""
def main() -> None:
"""Generate the ICS calendar file for the provided schedule."""
ics_content = "BEGIN:VCALENDAR\nVERSION:2.0\nCALSCALE:GREGORIAN\n"
weekdays = {
0: "Monday",
1: "Tuesday",
2: "Wednesday",
3: "Thursday",
4: "Friday",
5: "Saturday",
6: "Sunday",
}
for idx, (
date_str,
day,
title,
gate_open_time,
concert_time_str,
special_scheduling,
start_time_str,
) in enumerate(
full_events,
):
extra_info = ""
date = datetime.strptime(
f"{date_str}, {YEAR} {TIMEZONE}",
"%B %d, %Y %z",
)
if weekdays.get(date.weekday(), None) != day:
msg = (
f"Mismatch between date {date_str} and day {day}. "
f"Calculated weekday: {weekdays.get(date.weekday())}"
)
raise ValueError(msg)
start_time = datetime.strptime(
start_time_str + TIMEZONE,
"%I:%M %p%z",
).time()
start_datetime = datetime.combine(date.date(), start_time)
if concert_time_str:
concert_time = datetime.strptime(
concert_time_str + TIMEZONE,
"%I:%M %p%z",
).time()
end_datetime = datetime.combine(date.date(), concert_time)
else:
end_datetime = start_datetime + timedelta(hours=3)
extra_info = (
"No event length specified, defaulting to 3-hour duration."
)
uid = f"event-{idx}"
ics_content += create_ics_event(
uid,
start_datetime,
end_datetime,
title,
special_scheduling,
gate_open_time,
extra_info=extra_info,
)
ics_content += "END:VCALENDAR"
ics_path = "schedule.ics"
with Path(ics_path).open("w", encoding="utf-8") as f:
f.write(ics_content)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment