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 # Packages
*.egg *.egg
*.eggs
*.egg-info *.egg-info
dist dist
build build

View File

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

View File

@ -11,10 +11,11 @@
# under the License. # under the License.
import datetime import datetime
import icalendar
import logging import logging
import os import os
import os.path import os.path
import icalendar
import pytz import pytz
@ -108,9 +109,19 @@ class Yaml2IcalCalendar(icalendar.Calendar):
for skip_date in sch.skip_dates: for skip_date in sch.skip_dates:
event.add('exdate', skip_date.date) event.add('exdate', skip_date.date)
# NOTE(tonyb): If this is a skipped meeting add a # 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) 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 # add event to calendar
self.add_component(event) self.add_component(event)

View File

@ -15,6 +15,7 @@ from io import StringIO
import os import os
import os.path import os.path
import pytz import pytz
import subprocess
import yaml import yaml
@ -201,10 +202,16 @@ class Meeting(object):
s = Schedule(self, sch) s = Schedule(self, sch)
self.schedules.append(s) self.schedules.append(s)
# Set a default last update time
self.last_update = datetime.datetime.utcnow()
@classmethod @classmethod
def fromfile(cls, yaml_file): def fromfile(cls, yaml_file):
f = open(yaml_file, 'r') with open(yaml_file, 'r') as f:
return cls(f) meeting = cls(f)
meeting.last_update = _get_update_time(yaml_file)
return meeting
@classmethod @classmethod
def fromstring(cls, yaml_string): def fromstring(cls, yaml_string):
@ -212,6 +219,26 @@ class Meeting(object):
return cls(s) 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): def load_meetings(yaml_source):
"""Build YAML object and load meeting data """Build YAML object and load meeting data