Skip to content

Instantly share code, notes, and snippets.

@Vincent-Stragier
Created February 3, 2022 00:01
Show Gist options
  • Save Vincent-Stragier/2b561f2e1f58a4cc429486db784eeff5 to your computer and use it in GitHub Desktop.
Save Vincent-Stragier/2b561f2e1f58a4cc429486db784eeff5 to your computer and use it in GitHub Desktop.
Generate a simple icalendar using Python 3 and the icalendar module
from datetime import datetime, timedelta
import os
from icalendar import Calendar, Event, vText, Alarm
from icalendar.cal import Component
def component_wrapper(component: Component, *arg, **karg) -> Component:
use_vtext = karg.get('use_vtext', True)
# We can only add Components
for value in arg:
if isinstance(value, Component):
component.add_component(value)
else:
raise ValueError(
f'{value} is of type {type(value)}, '
'but only Component can be passed.'
)
for key, value in karg.items():
# Allow to use experimental variables ('X-...-')
key = key.replace('_', '-')
if isinstance(value, str) and use_vtext:
value = vText(value)
if isinstance(value, dict):
component.add(key, **value)
else:
component.add(key, value)
return component
def calendar_wrapper(*arg, **karg) -> Calendar:
return component_wrapper(Calendar(), *arg, **karg)
def alarm_wrapper(*arg, **karg) -> Alarm:
return component_wrapper(Alarm(), *arg, **karg)
def event_wrapper(*arg, **karg) -> Event:
return component_wrapper(Event(), *arg, **karg)
def event_to_ics(
filename: str,
summary: str,
start_date: datetime,
end_date: datetime,
description: str,
location: str,
alarm_description: str,
alarm_trigger: str,
alarm_duration: str,
alarm_repeat: str,
calendar_class: str = 'PRIVATE',
sequence: str = '0',
product_id: str = '-//IR VS//ICAL_GENERATOR//BE'
):
event = event_wrapper(
alarm_wrapper(
action='DISPLAY',
repeat=alarm_repeat,
trigger=alarm_trigger,
duration=alarm_duration,
description=alarm_description,
),
summary=summary,
dtstart=start_date,
dtend=end_date,
description=description,
location=location,
sequence=sequence
)
calendar = calendar_wrapper(
event,
version='2.0',
prodid={'value': product_id},
CLASS=calendar_class,
)
open(filename, 'wb').write(calendar.to_ical())
if __name__ == '__main__':
minutes_before_alarm = 60
minutes_duration_alarm = 15
# datetime(2022, 2, 1, 23, 19)
start_date = datetime.now() + timedelta(minutes=62)
end_date = start_date + timedelta(minutes=15)
formated_date_time = start_date.strftime("%d-%m-%Y - %H:%M:%S")
ical_root = os.path.dirname(__file__)
rdv_id = 'ABCabc123'
filename = os.path.join(ical_root, f'{rdv_id}.ics')
rdv_url = f'https://example.com/{rdv_id}'
patient_firstname = 'Firstname'
patient_lastname = 'Lastname'
patient = f'{patient_lastname} {patient_firstname}'
doctor_name = 'John Doe'
doctor_gender_emoji = '👩🏼‍⚕️'
# Emojis will probably bug on UNIX
# 👨‍⚕️ (male), 🧑‍⚕️ (neutral)
room = 'Cabinet Privé'
summary = f'{doctor_gender_emoji}- Dr {doctor_name} - {room}'
location = 'Lost Avenue, 1234 Heaven'
description = f"""Madame, Monsieur,\n
Nous avons bien enregistré le rendez-vous suivant :
{formated_date_time}\n
{patient}
Détail de la consultation :
Dr {doctor_name}
{room}\n
{location}\n
Info et annulation : {rdv_url}\n
Merci d'avoir utilisé nos services.
"""
# More info about icalendar can be found in the RFC5545
# And on https://github.com/collective/icalendar
event_to_ics(
filename,
summary,
start_date,
end_date,
description,
location,
summary,
f'-PT{minutes_before_alarm}M',
f'PT{minutes_duration_alarm}M',
alarm_repeat='4',
sequence='0'
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment