From 3359d4afddbbac459c68168dc64f01a7e807583f Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Tue, 15 Mar 2016 11:10:01 -0500 Subject: [PATCH] Support referring to ends of events in datespecs --- course/content.py | 62 ++++++++++++++++++++++++++--------------------- course/models.py | 2 +- doc/content.rst | 14 ++++++++--- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/course/content.py b/course/content.py index ca2197eb..7ecbb5d1 100644 --- a/course/content.py +++ b/course/content.py @@ -793,6 +793,8 @@ def extract_title_from_markup(markup_text): DATE_RE = re.compile(r"^([0-9]+)\-([01][0-9])\-([0-3][0-9])$") TRAILING_NUMERAL_RE = re.compile(r"^(.*)\s+([0-9]+)$") +END_PREFIX = "end:" + class InvalidDatespec(ValueError): def __init__(self, datespec): @@ -935,36 +937,26 @@ def parse_date_spec(course, datespec, vctx=None, location=None): datetime.datetime.combine(result, datetime.time.min)) return apply_postprocs(result) + is_end = datespec.startswith(END_PREFIX) + if is_end: + datespec = datespec[END_PREFIX:] + match = TRAILING_NUMERAL_RE.match(datespec) if match: - if vctx is not None: - from course.validation import validate_identifier - validate_identifier(vctx, "%s: event kind" % location, - match.group(1)) + # event with numeral - if course is None: - return now() + event_kind = match.group(1) + ordinal = int(match.group(2)) - from course.models import Event - try: - return apply_postprocs( - Event.objects.get( - course=course, - kind=match.group(1), - ordinal=int(match.group(2))).time) + else: + # event without numeral - except ObjectDoesNotExist: - if vctx is not None: - vctx.add_warning( - location, - _("unrecognized date/time specification: '%s' " - "(interpreted as 'now')") - % orig_datespec) - return now() + event_kind = match.group(1) + ordinal = int(match.group(2)) if vctx is not None: from course.validation import validate_identifier - validate_identifier(vctx, "%s: event kind" % location, datespec) + validate_identifier(vctx, "%s: event kind" % location, event_kind) if course is None: return now() @@ -972,11 +964,10 @@ def parse_date_spec(course, datespec, vctx=None, location=None): from course.models import Event try: - return apply_postprocs( - Event.objects.get( - course=course, - kind=datespec, - ordinal=None).time) + event_obj = Event.objects.get( + course=course, + kind=event_kind, + ordinal=ordinal) except ObjectDoesNotExist: if vctx is not None: @@ -987,6 +978,23 @@ def parse_date_spec(course, datespec, vctx=None, location=None): % orig_datespec) return now() + if is_end: + if event_obj.end_time is not None: + result = event_obj.end_time + else: + result = event_obj.time + if vctx is not None: + vctx.add_warning( + location, + _("event '%s' has no end time, using start time instead") + % orig_datespec) + + else: + result = event_obj.time + + return apply_postprocs(result) + + # }}} diff --git a/course/models.py b/course/models.py index 39b62990..4f179a61 100644 --- a/course/models.py +++ b/course/models.py @@ -1403,7 +1403,7 @@ class InstantMessage(models.Model): # }}} -# {{{ exam tickets +# {{{ exams class Exam(models.Model): course = models.ForeignKey(Course, diff --git a/doc/content.rst b/doc/content.rst index b75c76fd..8c5ae9d2 100644 --- a/doc/content.rst +++ b/doc/content.rst @@ -542,11 +542,17 @@ Specifying dates in RELATE In various places around its :ref:`YAML documents <yaml-files>`, RELATE allows dates to be specified. The following formats are supported: -* ``symbolic_name ordinal`` (e.g. ``lecture 13``) to refer to :ref:`calendear - events <events>` with an ordinal. +* ``symbolic_name ordinal`` (e.g. ``lecture 13``) to refer to the start time of + :ref:`calendar events <events>` with an ordinal. -* ``symbolic_name`` (e.g. ``final_exam``) to refer to :ref:`calendear events <events>` - *without* an ordinal. +* ``symbolic_name`` (e.g. ``final_exam``) to refer to the start time of + :ref:`calendear events <events>` *without* an ordinal. + +* ``end:symbolic_name ordinal`` (e.g. ``end:lecture 13``) to refer to the end time + of :ref:`calendar events <events>` with an ordinal. + +* ``end:symbolic_name`` (e.g. ``end:final_exam``) to refer to the end time of + :ref:`calendar events <events>` *without* an ordinal. * ISO-formatted dates (``2014-10-13``) -- GitLab