Skip to content

Instantly share code, notes, and snippets.

@fcojperez
Last active March 1, 2024 17:57
Show Gist options
  • Save fcojperez/459bdf0ed3efc9d41d9d203a60329886 to your computer and use it in GitHub Desktop.
Save fcojperez/459bdf0ed3efc9d41d9d203a60329886 to your computer and use it in GitHub Desktop.
CNCF Events Converter to ICS
"""
A script to parse cncf.io api events into ICS format
Developer: fcojperez@gmail.com
license: MIT
"""
import requests
from icalendar import Calendar, Event
from datetime import datetime
from datetime import timedelta
from tzlocal import get_localzone
import pytz
import json
CNCF_BOOK_CLUB_CHAPTER = 596
CNCF_API_PAGE_SIZE = 5
CNFC_EVENTS_API= f'https://community.cncf.io/api/event_slim/?chapter={CNCF_BOOK_CLUB_CHAPTER}&page_size={CNCF_API_PAGE_SIZE}&status=Live&include_cohosted_events=true&visible_on_parent_chapter_only=true&order=start_date&fields=title,start_date,event_type_title,cropped_picture_url,cropped_banner_url,url,cohost_registration_url,description,description_short&page=1'
CNCF_EVENTS_LOCAL_JSON = 'cncf_events.json'
CNCF_EVNTS_ICS = 'cncf_events.ics'
def fetch_json(url, save_path=None):
try:
json_data = []
response = requests.get(url)
response.raise_for_status()
j = response.json()
json_data.extend(j['results'])
while j['links']['next'] is not None:
response = requests.get(j['links']['next'])
response.raise_for_status()
j = response.json()
json_data.extend(j['results'])
if save_path:
with open(save_path, 'w') as f:
json.dump(json_data, f, indent=4)
print(f"JSON data saved to '{save_path}'")
print(f"Results: {len(json_data)} events")
return json_data
except requests.exceptions.RequestException as e:
print("Error fetching JSON:", e)
return None
except Exception as e:
print("Error saving JSON:", e)
return None
def filtering_events(data, fltr=None):
if fltr:
filtered_data = [x for x in data if fltr in x['description_short']]
if filtered_data:
return filtered_data
else:
raise Exception(f"Sorry not event found out with filter: {fltr}")
else:
return data
def create_ics(json_data):
cal = Calendar()
local_timezone = get_localzone()
for item in json_data:
event = Event()
url = item.get('url', '')
event.add('summary', item.get('title', ''))
event.add('description', f"{item.get('description_short', '')}\n\nVirtual event URL: {url}")
event.add('url', url) # Add URL property
start_time = datetime.strptime(item.get('start_date', '')[:19], '%Y-%m-%dT%H:%M:%S')
start_time_local = pytz.utc.localize(start_time).astimezone(local_timezone)
end_time_local = start_time_local + timedelta(hours=1)
event.add('dtstart', start_time_local)
event.add('dtend', end_time_local)
cal.add_component(event)
return cal.to_ical()
def save_ics(ics_data, filename):
try:
with open(filename, 'wb') as f:
f.write(ics_data)
print(f"iCalendar file saved as '{filename}'")
except Exception as e:
print("Error saving iCalendar file:", e)
if __name__ == "__main__":
filter = input("Enter a string to filter events (e.g., Book Club): ")
json_data_raw = fetch_json(CNFC_EVENTS_API,CNCF_EVENTS_LOCAL_JSON)
json_data = filtering_events(json_data_raw, fltr=filter)
if json_data:
ics_data = create_ics(json_data)
save_ics(ics_data, CNCF_EVNTS_ICS)
appdirs==1.4.4
certifi==2024.2.2
charset-normalizer==3.3.2
icalendar==5.0.11
idna==3.6
jedi==0.19.1
parso==0.8.3
prompt-toolkit==3.0.43
Pygments==2.17.2
python-dateutil==2.9.0
pytz==2024.1
requests==2.31.0
six==1.16.0
tzlocal==5.2
urllib3==2.2.1
wcwidth==0.2.13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment