Add DTSTAMP and UID values to meeting instances

The iCalendar spec expects a meeting vEvent to include a datetime stamp
and a unique ID for each instance. This adds these values to the
generated output.

Minor cleanup also included since I was touching code around them and
noticed little nits.

Change-Id: I4753571850665a2f28a6799b84ead4c31a275cc7
Signed-off-by: Sean McGinnis <sean.mcginnis@gmail.com>
This commit is contained in:
Sean McGinnis 2019-06-27 10:22:14 -05:00
parent 1b6acfd138
commit a63d1c5e12
No known key found for this signature in database
GPG Key ID: CE7EE4BFAF8D70C8
4 changed files with 44 additions and 4 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@
# Packages
*.egg
*.eggs
*.egg-info
dist
build

View File

@ -7,6 +7,7 @@ install_command = pip install -U {opts} {packages}
deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands = python setup.py testr --slowest --testr-args='{posargs}'
usedevelop = true
[testenv:pep8]
basepython = python3

View File

@ -11,10 +11,11 @@
# under the License.
import datetime
import icalendar
import logging
import os
import os.path
import icalendar
import pytz
@ -108,9 +109,19 @@ class Yaml2IcalCalendar(icalendar.Calendar):
for skip_date in sch.skip_dates:
event.add('exdate', skip_date.date)
# NOTE(tonyb): If this is a skipped meeting add a
# non-recurring event with an obvisous summary.
# non-recurring event with an obvious summary.
self.add_schedule(meeting, sch, exdate=skip_date)
# Add update timestamp and unique ID for the event.
# Note: we need a way to uniquely identify the meeting, even if its
# details are modified. We don't really have much to go on to do
# that, so best effort just use the project name and date.
event.add('dtstamp', meeting.last_update)
start_date = exdate.date if exdate else next_meeting_date
event.add('uid', '%s-%s' % (
meeting.project.replace(' ', '').lower(),
datetime.datetime.strftime(start_date, '%Y%m%d')))
# add event to calendar
self.add_component(event)

View File

@ -15,6 +15,7 @@ from io import StringIO
import os
import os.path
import pytz
import subprocess
import yaml
@ -201,10 +202,16 @@ class Meeting(object):
s = Schedule(self, sch)
self.schedules.append(s)
# Set a default last update time
self.last_update = datetime.datetime.utcnow()
@classmethod
def fromfile(cls, yaml_file):
f = open(yaml_file, 'r')
return cls(f)
with open(yaml_file, 'r') as f:
meeting = cls(f)
meeting.last_update = _get_update_time(yaml_file)
return meeting
@classmethod
def fromstring(cls, yaml_string):
@ -212,6 +219,26 @@ class Meeting(object):
return cls(s)
def _get_update_time(src_file):
"""Attempts to figure out the last time the file was updated.
If the file is under source control, this will try to find the last time it
was updated. If that is not possible, it will fallback to using the last
time the local file was modified.
"""
try:
last_updated = subprocess.check_output(
[
'git', 'log', '-n1', '--format=%ad',
'--date=format:%Y-%m-%d %H:%M:%S',
'--', src_file,
]
).decode('utf-8').strip()
return datetime.datetime.strptime(last_updated, '%Y-%m-%d %H:%M:%S')
except (subprocess.CalledProcessError, ValueError):
return datetime.datetime.fromtimestamp(os.path.getmtime(src_file))
def load_meetings(yaml_source):
"""Build YAML object and load meeting data