Skip to content

Instantly share code, notes, and snippets.

@htlin222
Created July 31, 2026 15:35
Show Gist options
  • Select an option

  • Save htlin222/94a4a6ea11c3bdfc6e0707cdce956dff to your computer and use it in GitHub Desktop.

Select an option

Save htlin222/94a4a6ea11c3bdfc6e0707cdce956dff to your computer and use it in GitHub Desktop.
Generate ICS calendar files from CSV; auto-sets timezone, event duration, reminders. Usage: python csv_to_ics.py events.csv
#!/usr/bin/env python3
import csv
import os
import sys
import pytz
from ics import Calendar, Event
from datetime import datetime, timedelta
# Adjust this to your local timezone
local_timezone = pytz.timezone("Asia/Taipei")
before_minutes = 10 # minutes 行前通知時間
event_duration = 30 # minutes 行程持續時間
# 主辦人 email,設在環境變數即可,例如 ORGANIZER_EMAIL=you@example.com python csv_to_ics.py events.csv
# 沒設就不寫入 ORGANIZER 欄位
organizer_email = os.environ.get("ORGANIZER_EMAIL", "")
def create_ics_file(
name, title, start_date, start_time, formatted_remark, url, location
):
cal = Calendar()
# Convert date and time to a datetime object in local timezone
start_datetime = local_timezone.localize(
datetime.strptime(f"{start_date} {start_time}", "%Y-%m-%d %H:%M")
)
end_datetime = start_datetime + timedelta(minutes=event_duration)
# Create an event
event = Event()
event.name = title
event.begin = start_datetime
event.end = end_datetime
event.description = formatted_remark
event.url = url
event.location = location
cal.events.add(event)
# Serialize the calendar to a string
ics_content = cal.serialize()
# Manually add an alarm to the event by manipulating the ICS string
alarm_component = f"BEGIN:VALARM\nACTION:DISPLAY\nDESCRIPTION:Reminder\nTRIGGER:-PT{before_minutes}M\nEND:VALARM"
injected = alarm_component
if organizer_email:
injected = (
f"ORGANIZER;CN=Organizer:mailto:{organizer_email}\n{alarm_component}"
)
# Save the calendar to an ICS file
ics_content_with_alarm = ics_content.replace(
"END:VEVENT", f"{injected}\nEND:VEVENT"
)
# Save the calendar to an ICS file
with open(f"行程_{name}.ics", "w") as ics_file:
ics_file.write(ics_content_with_alarm)
print(f"created 行程_{name}.ics")
# Check for the CSV file argument
if len(sys.argv) < 2:
print("Usage: python rent.py <path_to_csv_file>")
sys.exit(1)
csv_file_path = sys.argv[1]
# Read the CSV file and create ICS files
row_count = 0
with open(csv_file_path, newline="", encoding="utf-8") as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
title = f"🦎{row['姓名']},{row['備註']}"
name = row["姓名"] # for file name, no blank, e.g. my_name_is_lizard
start_date = row["日期"] # YYYY-MM-DD
start_time = row["開始時間"] # HH:MM
formatted_remark = f"姓名: {row['姓名']},\nPhone: {row['電話']},\n備註: {row['備註']}"
url = row["連結"]
location = row["地點"]
create_ics_file(
name, title, start_date, start_time, formatted_remark, url, location
)
row_count = row_count + 1
print(f"Total {row_count} ICS files created successfully.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment