4 Commits 086fc21406 ... 5caf616723

Author SHA1 Message Date
  Justin Tracey 5caf616723 improve documentation 3 years ago
  Justin Tracey 5c522173fd add support for date ranges in constraints 3 years ago
  Justin Tracey 74c6aedd1c fix behavior of combining end date and max weeks 3 years ago
  Justin Tracey 06d7b5d3df add link for upcoming events to email 3 years ago
1 changed files with 42 additions and 24 deletions
  1. 42 24
      vice-speaker-rotator.py

+ 42 - 24
vice-speaker-rotator.py

@@ -3,6 +3,15 @@ from datetime import date,timedelta
 import sys, argparse
 from argparse import RawTextHelpFormatter
 
+# text appended to the end of generated emails
+email_body = """
+Full speaker schedule:
+https://cs.uwaterloo.ca/twiki/view/CrySP/SpeakerSchedule
+
+Other upcoming events:
+https://cs.uwaterloo.ca/twiki/view/CrySP/UpcomingEvents
+"""
+
 def str_to_date(string_date):
     return date(*[int(s) for s in string_date.split('-')])
 
@@ -29,7 +38,7 @@ class CryspCalendar:
         if end:
             last_meeting = str_to_date(end)
         if weeks:
-            last_meeting = max(first_meeting + timedelta(weeks=weeks),
+            last_meeting = min(first_meeting + timedelta(weeks=weeks),
                                last_meeting)
         ret = []
         next_meeting = first_meeting
@@ -46,8 +55,16 @@ class CryspCalendar:
             date_strs = constraint[1:]
             dates     = []
             for date_str in date_strs:
-                dates.append(str_to_date(date_str))
-                constraint_dict[name] = dates
+                if '--' in date_str:
+                    #date_range = list(map(str_to_date, date_str.split('--')))
+                    date_range = date_str.split('--')
+                    date_range = [str_to_date(date_range[0]),
+                                  str_to_date(date_range[1])]
+                    [dates.append(d) for d in self.dates \
+                     if date_range[0] <= d <= date_range[1]]
+                else:
+                    dates.append(str_to_date(date_str))
+            constraint_dict[name] = dates
         return constraint_dict
 
     def parse_practice_talks(self, practice, half=False):
@@ -160,7 +177,7 @@ class CryspCalendar:
             else:
                 emailstr += note
             emailstr += '\n'
-        emailstr += '\nhttps://cs.uwaterloo.ca/twiki/view/CrySP/SpeakerSchedule\n'
+        emailstr += email_body
         return emailstr
 
 def parse_constraintsfile(filename):
@@ -172,21 +189,22 @@ def parse_constraintsfile(filename):
         return tweaks['c'], tweaks['p'], tweaks['h'], tweaks['n']
 
 def make_parser():
-    parser = argparse.ArgumentParser(description =
-        'Print a speaker schedule for the CrySP weekly meetings.',
+    parser = argparse.ArgumentParser(description ='''\
+Print a speaker schedule for the CrySP weekly meetings.
+All dates are ISO formatted (yyyy-mm-dd). Constraints in the constraints file
+can also be ranges of ISO formatted dates (yyyy-mm-dd--yyyy-mm-dd).''',
         formatter_class=RawTextHelpFormatter)
     parser.add_argument('-s', '--start',
                         metavar = 'DATE', required = True,
                         help =
-                        'date of the first meeting in ISO format\n' +\
-                        '(yyyy-mm-dd)')
+                        'date of the first meeting')
     parser.add_argument('-e', '--end', metavar = 'DATE',
                         help =
-                        'last date to schedule a meeting on or before\n' +\
+                        'last date to schedule a meeting on or before\n' \
                         '(if -w also specified, uses whatever is shortest)')
     parser.add_argument('-w', '--weeks', type=int,
                         help =
-                        'number of weeks to schedule for\n' +\
+                        'number of weeks to schedule for\n' \
                         '(if -e also specified, uses whatever is shortest)')
 
     group = parser.add_mutually_exclusive_group()
@@ -197,24 +215,24 @@ def make_parser():
     group.add_argument('-f', '--namesfile',
                        metavar = 'FILE',
                        help =
-                       'path of a file that contains a comma-seperated\n' +\
+                       'path of a file that contains a comma-seperated\n' \
                        ' list of names to schedule in their speaking order')
 
     parser.add_argument('-c', '--constraintsfile',
                         metavar = 'FILE',
                         help =
-                        'Provide constraints, practice talks, and notes\n' +\
-                        'via supplied csv file. The CSV can contain the\n' +\
-                        'following lines:\n' +\
-                        'constraints - dates where someone cannot speak:\n' +\
-                        '"c,[name],[date1],[date2],[...]"\n' +\
-                        'notes - goes in the notes column for that date:\n' +\
-                        '"n,[date],[note]"\n' +\
-                        'practice talks - dates where something other than\n' +\
-                        'the usual CrySP meeting talks is happening:\n' +\
-                        '"p,[name],[date],[note (e.g., "practice talk")]"\n' +\
-                        'half-slot - a rare case where someone/thing needs\n' +\
-                        'only one of the speaker slots on this date:\n' +\
+                        'Provide constraints, practice talks, and notes\n' \
+                        'via supplied CSV file. The CSV can contain the\n' \
+                        'following lines:\n' \
+                        'constraints - dates where someone cannot speak:\n' \
+                        '"c,[name],[date/range1],[date/range2],[...]"\n' \
+                        'notes - goes in the notes column for that date:\n' \
+                        '"n,[date],[note]"\n' \
+                        'practice talks - dates where something other than\n' \
+                        'the usual CrySP meeting talks is happening:\n' \
+                        '"p,[name],[date],[note (e.g., "practice talk")]"\n' \
+                        'half-slot - a rare case where someone/thing needs\n' \
+                        'only one of the speaker slots on this date:\n' \
                         '"h,[name],[date],[note]"\n')
 
     parser.add_argument('-r', '--no-repeat',
@@ -225,7 +243,7 @@ def make_parser():
                         nargs = '?', const = 2, default = False,
                         metavar = 'WEEKS',
                         help =
-                        'print an email for notifying who is speaking\n' +\
+                        'print an email for notifying who is speaking\n' \
                         'the next two (or specified) weeks')
     return parser