yaml2ical/src/meeting.py

100 lines
3.4 KiB
Python

import pprint
import pytz
import icalendar
import datetime
import time
import os
import yaml
import logging
weekdays = {
'Monday' : 0
, 'Tuesday' : 1
, 'Wednesday' : 2
, 'Thursday' : 3
, 'Friday' : 4
, 'Saturday' : 5
, 'Sunday' : 6
}
class Meeting:
"""An OpenStack meeting."""
def __init__(self, yaml, filename):
self.filename = filename
# create yaml object from yaml file. use it initialize following fields.
self.project = yaml['project']
self.chair = yaml['chair']
self.description = yaml['description']
self.agenda = yaml['agenda'] # this is a list of list of topics
# create schedule objects
self.schedules = [Schedule(s) for s in yaml['schedule']]
def write_ical(self):
cal = icalendar.Calendar()
# add properties to ensure compliance
cal.add('prodid', '-//OpenStack//Gerrit-Powered Meeting Agendas//EN')
cal.add('version', '2.0')
i = 1
for s in self.schedules:
# one Event per iCal file
event = icalendar.Event()
# I think the summary field needs to be unique per event in an ical file (at least, for it to work with Google Calendar)
event.add('summary', self.project + ' ' + str(i))
# add ical description (meeting description, irc, agenda, chair, etc.)
ical_descript = "Project: %s\nChair: %s\nIRC: %s\nAgenda:\n%s\n\nDescription: %s" % (self.project, self.chair, s.irc, yaml.dump(self.agenda, default_flow_style=False), self.description)
event.add('description', ical_descript)
# get starting date
d = datetime.datetime.utcnow()
next_meeting = next_weekday(d, weekdays[s.day]) # 0 = Monday, 1=Tuesday, 2=Wednesday...
next_meeting_dt = datetime.datetime(next_meeting.year, next_meeting.month, next_meeting.day, s.time.hour, s.time.minute, tzinfo=pytz.utc)
event.add('dtstart', next_meeting_dt)
# add recurrence rule
event.add('rrule', {'freq': s.freq})
# add meeting length
# TODO: figure out what to do for meeting length. doesn't seem to be specified for any of the openstack meetings
event.add('duration', datetime.timedelta(hours=1))
# add event to calendar
cal.add_component(event)
i += 1
# write ical files to disk
ical_dir = '../icals'
ical_filename = self.filename[:-4] + 'ics'
if not os.path.exists(ical_dir):
os.makedirs(ical_dir)
os.chdir(ical_dir)
with open(ical_filename, 'wb') as ics:
ics.write(cal.to_ical())
logging.info('\'%s\' processed. Contains %d events.' % (ical_filename, len(cal.subcomponents)))
class Schedule:
"""A meeting schedule."""
def __init__(self, sched_yaml):
self.time = datetime.datetime.strptime(sched_yaml['time'], '%H%M')
self.day = sched_yaml['day']
self.irc = sched_yaml['irc']
self.freq = sched_yaml['frequency']
# https://stackoverflow.com/questions/6558535/python-find-the-date-for-the-first-monday-after-a-given-a-date
def next_weekday(d, weekday):
days_ahead = weekday - d.weekday()
if days_ahead <= 0: # Target day already happened this week
days_ahead += 7
return d + datetime.timedelta(days_ahead)