Last active
February 12, 2025 18:01
-
-
Save minhqnd/63480067e7f492d5c15cb25ce3b1a253 to your computer and use it in GitHub Desktop.
Convert FAP FPT Calendar to ics
This file contains hidden or 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 json | |
| import uuid | |
| from datetime import datetime, timezone | |
| def create_event(data): | |
| """Format each event for the iCalendar file with Apple-specific attributes.""" | |
| event_template = """BEGIN:VEVENT | |
| TRANSP:OPAQUE | |
| DTSTART;TZID=Asia/Ho_Chi_Minh:{start_time} | |
| DTEND;TZID=Asia/Ho_Chi_Minh:{end_time} | |
| UID:{uid} | |
| DTSTAMP:{timestamp} | |
| LOCATION:{location} | |
| DESCRIPTION:{description} | |
| STATUS:CONFIRMED | |
| SEQUENCE:1 | |
| SUMMARY:{summary} | |
| LAST-MODIFIED:{timestamp} | |
| CREATED:{timestamp} | |
| X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC | |
| X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-APPLE-MAPKIT-HANDLE={mapkit_handle};X-APPLE-RADIUS=141.9449615478516;X-TITLE={location}:geo:{geo} | |
| END:VEVENT""" | |
| date = datetime.strptime(data['date'], '%m/%d/%Y %I:%M:%S %p') | |
| start_time, end_time = data['slotTime'][1:-1].split('-') | |
| start_datetime = datetime.strptime(f"{date.date()} {start_time}", '%Y-%m-%d %H:%M') | |
| end_datetime = datetime.strptime(f"{date.date()} {end_time}", '%Y-%m-%d %H:%M') | |
| mapkit_handle = "CAESpwMIrk0QmaPutrGyraLOARoSCawDe6ddAzVAEaeB1UeWYVpAIpwBCgdWaWV0bmFtEgJWThoFSGFub2kqClRoYWNoIFRoYXQyClRoYWNoIFRoYXRSFFRoYW5nIExvbmcgQm91bGV2YXJkYhRUaGFuZyBMb25nIEJvdWxldmFyZIoBQUVkdWNhdGlvbiBhbmQgVHJhaW5pbmcgQXJlYSDigJMgSG9hIExhYyBIaWdoLVRlY2ggUGFyayBUaGFjaCBUaGF0KhpUcsaw4budbmcgxJDhuqFpIEjhu41jIEZQVDJkVGhhbmcgTG9uZyBCb3VsZXZhcmQKRWR1Y2F0aW9uIGFuZCBUcmFpbmluZyBBcmVhIOKAkyBIb2EgTGFjIEhpZ2gtVGVjaCBQYXJrClRoYWNoIFRoYXQKSGFub2kKVmlldG5hbTgvUAFaXgooCJmj7raxsq2izgESEgmsA3unXQM1QBGngdVHlmFaQBiuTZADAZgDAaIfMQiZo+62sbKtos4BGiQKGlRyxrDhu51uZyDEkOG6oWkgSOG7jWMgRlBUEAAqAnZpQAA=" # Thay bằng mã thật nếu có | |
| geo = "21.013148,105.524797" | |
| event_data = { | |
| "start_time": start_datetime.strftime('%Y%m%dT%H%M%S'), | |
| "end_time": end_datetime.strftime('%Y%m%dT%H%M%S'), | |
| "uid": str(uuid.uuid4()).upper(), | |
| "timestamp": datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%SZ'), | |
| "location": data['roomNo'], | |
| "description": f"{data['lecturer']} - {data['groupName']} - Session: {data['sessionNo']}", | |
| "summary": data['subjectCode'], | |
| "mapkit_handle": mapkit_handle, | |
| "geo": geo, | |
| "alarm_uid": str(uuid.uuid4()).upper() | |
| } | |
| return event_template.format(**event_data) | |
| def create_calendar(json_file, output_file="calendar.ics"): | |
| """Generate an iCalendar file with Apple-specific attributes.""" | |
| with open(json_file, 'r', encoding='utf-8') as f: | |
| json_data = json.load(f) | |
| calendar_header = """BEGIN:VCALENDAR | |
| METHOD:PUBLISH | |
| VERSION:2.0 | |
| X-WR-CALNAME:MySchedule | |
| PRODID:-//Apple Inc.//macOS 12.7.4//EN | |
| X-APPLE-CALENDAR-COLOR:#711A76 | |
| X-WR-TIMEZONE:Asia/Ho_Chi_Minh | |
| CALSCALE:GREGORIAN | |
| BEGIN:VTIMEZONE | |
| TZID:Asia/Ho_Chi_Minh | |
| BEGIN:STANDARD | |
| TZOFFSETFROM:+0800 | |
| DTSTART:19750613T000000 | |
| TZNAME:GMT+7 | |
| TZOFFSETTO:+0700 | |
| RDATE:19750613T000000 | |
| END:STANDARD | |
| END:VTIMEZONE""" | |
| calendar_footer = "END:VCALENDAR" | |
| events = [create_event(item) for item in json_data['data']] | |
| with open(output_file, 'w', encoding='utf-8') as f: | |
| f.write(calendar_header + "\n") | |
| f.write("\n".join(events) + "\n") | |
| f.write(calendar_footer) | |
| print(f"Calendar saved as {output_file}") | |
| # Replace 'cal.txt' with your actual JSON file | |
| create_calendar("cal.txt") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment