Fix issue with meetings that start on day1 and end on day2

Consider the following meetings (both at the same venue)
Meeting1:  Monday at 2330 for 1 hour
Meeting2: Tuesday at 0000 for 1 hour

It's clear that these meetings conflict.  The current conflicts() check
will return no conflict becuase we explictly check the start day.

Also there is a special case where day1 is Sunday so handle that case.

Fix this by converting the day into a date and including that in the conflicts
check.

Change-Id: I06f1f2ab644bf2f6aeb0e62258884a5ff85b6706
This commit is contained in:
Tony Breeds 2015-06-12 12:49:01 +10:00
parent 2d86450f7e
commit afc3819c80
3 changed files with 104 additions and 6 deletions

View File

@ -19,6 +19,17 @@ import yaml
from yaml2ical.recurrence import supported_recurrences
DATES = {
'Monday': datetime.datetime(1900, 1, 1).date(),
'Tuesday': datetime.datetime(1900, 1, 2).date(),
'Wednesday': datetime.datetime(1900, 1, 3).date(),
'Thursday': datetime.datetime(1900, 1, 4).date(),
'Friday': datetime.datetime(1900, 1, 5).date(),
'Saturday': datetime.datetime(1900, 1, 6).date(),
'Sunday': datetime.datetime(1900, 1, 7).date(),
}
ONE_WEEK = datetime.timedelta(weeks=1)
class Schedule(object):
"""A meeting schedule."""
@ -31,7 +42,8 @@ class Schedule(object):
try:
self.utc = sched_yaml['time']
self.time = datetime.datetime.strptime(sched_yaml['time'], '%H%M')
self.day = sched_yaml['day']
# Sanitize the Day
self.day = sched_yaml['day'].lower().capitalize()
self.irc = sched_yaml['irc']
self.freq = sched_yaml['frequency']
self.recurrence = supported_recurrences[sched_yaml['frequency']]
@ -40,14 +52,27 @@ class Schedule(object):
"attribute '{0}'".format(e.args[0]))
raise
if self.day not in DATES.keys():
raise ValueError("'%s' is not a valid day of the week")
# NOTE(tonyb): We need to do this datetime shenanigans is so we can
# deal with meetings that start on day1 and end on day2.
self.meeting_start = datetime.datetime.combine(DATES[self.day],
self.time.time())
self.meeting_end = (self.meeting_start + datetime.timedelta(hours=1))
if self.day == 'Sunday' and self.meeting_end.strftime("%a") == 'Mon':
self.meeting_start = self.meeting_start - ONE_WEEK
self.meeting_end = self.meeting_end - ONE_WEEK
def conflicts(self, other):
"""Checks for conflicting schedules."""
alternating = set(['biweekly-odd', 'biweekly-even'])
return (
((self.day == other.day) and
(abs(self.time - other.time) < datetime.timedelta(hours=1)) and
(self.irc == other.irc)) and
(set([self.freq, other.freq]) != alternating))
# NOTE(tonyb): .meeting_start also includes the day of the week. So no
# need to check .day explictly
return ((self.irc == other.irc) and
((self.meeting_start < other.meeting_end) and
(other.meeting_start < self.meeting_end)) and
(set([self.freq, other.freq]) != alternating))
class Meeting(object):

View File

@ -14,6 +14,18 @@
"""Sample meeting data to use for testing."""
BAD_MEETING_DAY = """
project: OpenStack Subteam Meeting
schedule:
- time: '1200'
day: go_bang
irc: openstack-meeting
frequency: weekly
chair: Joe Developer
description: >
Weekly meeting for Subteam project.
"""
WEEKLY_MEETING = """
project: OpenStack Subteam Meeting
schedule:
@ -101,3 +113,51 @@ description: >
agenda: |
* Top bugs this week
"""
MEETING_SUNDAY_LATE = """
project: OpenStack Subteam 8 Meeting
schedule:
- time: '2330'
day: Sunday
irc: openstack-meeting
frequency: weekly
chair: Shannon Stacker
description: >
Weekly late meeting for Subteam 8 project.
"""
MEETING_MONDAY_EARLY = """
project: OpenStack Subteam Meeting
schedule:
- time: '0000'
day: Monday
irc: openstack-meeting
frequency: weekly
chair: Joe Developer
description: >
Weekly long meeting for Subteam project.
"""
MEETING_MONDAY_LATE = """
project: OpenStack Subteam 8 Meeting
schedule:
- time: '2330'
day: Monday
irc: openstack-meeting
frequency: weekly
chair: Shannon Stacker
description: >
Weekly late meeting for Subteam 8 project.
"""
MEETING_TUESDAY_EARLY = """
project: OpenStack Subteam Meeting
schedule:
- time: '0000'
day: Tuesday
irc: openstack-meeting
frequency: weekly
chair: Joe Developer
description: >
Weekly long meeting for Subteam project.
"""

View File

@ -18,6 +18,11 @@ from yaml2ical.tests import sample_data
class MeetingTestCase(unittest.TestCase):
def test_bad_meeting_day(self):
self.assertRaises(ValueError,
meeting.load_meetings,
sample_data.BAD_MEETING_DAY)
def test_load_yaml_file(self):
m = meeting.load_meetings(sample_data.WEEKLY_MEETING)[0]
self.assertEqual('OpenStack Subteam Meeting', m.project)
@ -62,3 +67,11 @@ class MeetingTestCase(unittest.TestCase):
self.should_not_conflict(
sample_data.BIWEEKLY_ODD_MEETING,
sample_data.BIWEEKLY_EVEN_MEETING)
def test_late_early_conflicts(self):
self.should_be_conflicting(
sample_data.MEETING_SUNDAY_LATE,
sample_data.MEETING_MONDAY_EARLY)
self.should_be_conflicting(
sample_data.MEETING_MONDAY_LATE,
sample_data.MEETING_TUESDAY_EARLY)