def parse_date_spec(course, datespec, vctx=None, location=None): if datespec is None: return None orig_datespec = datespec def localize_if_needed(d): if d.tzinfo is None: from relate.utils import localize_datetime return localize_datetime(d) else: return d if isinstance(datespec, datetime.datetime): return localize_if_needed(datespec) if isinstance(datespec, datetime.date): return localize_if_needed( datetime.datetime.combine(datespec, datetime.time.min)) datespec = datespec.strip() # {{{ parse postprocessors postprocs = [] while True: parsed_one = False for pp_class in DATESPEC_POSTPROCESSORS: datespec, postproc = pp_class.parse(datespec) if postproc is not None: parsed_one = True postprocs.insert(0, postproc) break datespec = datespec.strip() if not parsed_one: break # }}} def apply_postprocs(dtime): for postproc in postprocs: dtime = postproc.apply(dtime) return dtime match = DATE_RE.match(datespec) if match: result = datetime.date( int(match.group(1)), int(match.group(2)), int(match.group(3))) result = localize_if_needed( datetime.datetime.combine(result, datetime.time.min)) return apply_postprocs(result) 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)) if course is None: return now() from course.models import Event try: return apply_postprocs( Event.objects.get( course=course, kind=match.group(1), ordinal=int(match.group(2))).time) except ObjectDoesNotExist: if vctx is not None: vctx.add_warning( location, _("unrecognized date/time specification: '%s' " "(interpreted as 'now')") % orig_datespec) return now() if vctx is not None: from course.validation import validate_identifier validate_identifier(vctx, "%s: event kind" % location, datespec) if course is None: return now() from course.models import Event try: return apply_postprocs( Event.objects.get( course=course, kind=datespec, ordinal=None).time) except ObjectDoesNotExist: if vctx is not None: vctx.add_warning( location, _("unrecognized date/time specification: '%s' " "(interpreted as 'now')") % orig_datespec) return now()
def parse_date_spec( course, # type: Optional[Course] datespec, # type: Union[Text, datetime.date, datetime.datetime] vctx=None, # type: Optional[ValidationContext] location=None, # type: Optional[Text] ): # type: (...) -> datetime.datetime if datespec is None: return None orig_datespec = datespec def localize_if_needed(d): # type: (datetime.datetime) -> datetime.datetime if d.tzinfo is None: from relate.utils import localize_datetime return localize_datetime(d) else: return d if isinstance(datespec, datetime.datetime): return localize_if_needed(datespec) if isinstance(datespec, datetime.date): return localize_if_needed( datetime.datetime.combine(datespec, datetime.time.min)) try: from typing import Text except ImportError: Text = None # noqa datespec_str = cast(Text, datespec).strip() # type: ignore # {{{ parse postprocessors postprocs = [] # type: List[DatespecPostprocessor] while True: parsed_one = False for pp_class in DATESPEC_POSTPROCESSORS: datespec_str, postproc = pp_class.parse(datespec_str) if postproc is not None: parsed_one = True postprocs.insert(0, cast(DatespecPostprocessor, postproc)) break datespec_str = datespec_str.strip() if not parsed_one: break # }}} def apply_postprocs(dtime): # type: (datetime.datetime) -> datetime.datetime for postproc in postprocs: dtime = postproc.apply(dtime) return dtime match = DATE_RE.match(datespec_str) if match: res_date = datetime.date( int(match.group(1)), int(match.group(2)), int(match.group(3))) result = localize_if_needed( datetime.datetime.combine(res_date, datetime.time.min)) return apply_postprocs(result) is_end = datespec_str.startswith(END_PREFIX) if is_end: datespec_str = datespec_str[len(END_PREFIX):] match = TRAILING_NUMERAL_RE.match(datespec_str) if match: # event with numeral event_kind = match.group(1) ordinal = int(match.group(2)) # type: Optional[int] else: # event without numeral event_kind = datespec_str ordinal = None if vctx is not None: from course.validation import validate_identifier validate_identifier(vctx, "%s: event kind" % location, event_kind) if course is None: return now() from course.models import Event try: event_obj = Event.objects.get( course=course, kind=event_kind, ordinal=ordinal) except ObjectDoesNotExist: if vctx is not None: vctx.add_warning( location, _("unrecognized date/time specification: '%s' " "(interpreted as 'now')") % 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)
def parse_date_spec(course, datespec, vctx=None, location=None): if datespec is None: return None orig_datespec = datespec def localize_if_needed(d): if d.tzinfo is None: from relate.utils import localize_datetime return localize_datetime(d) else: return d if isinstance(datespec, datetime.datetime): return localize_if_needed(datespec) if isinstance(datespec, datetime.date): return localize_if_needed( datetime.datetime.combine(datespec, datetime.time.min)) datespec = datespec.strip() # {{{ parse postprocessors postprocs = [] while True: parsed_one = False for pp_class in DATESPEC_POSTPROCESSORS: datespec, postproc = pp_class.parse(datespec) if postproc is not None: parsed_one = True postprocs.insert(0, postproc) break datespec = datespec.strip() if not parsed_one: break # }}} def apply_postprocs(dtime): for postproc in postprocs: dtime = postproc.apply(dtime) return dtime match = DATE_RE.match(datespec) if match: result = datetime.date(int(match.group(1)), int(match.group(2)), int(match.group(3))) result = localize_if_needed( datetime.datetime.combine(result, datetime.time.min)) return apply_postprocs(result) 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)) if course is None: return now() from course.models import Event try: return apply_postprocs( Event.objects.get(course=course, kind=match.group(1), ordinal=int(match.group(2))).time) except ObjectDoesNotExist: if vctx is not None: vctx.add_warning( location, _("unrecognized date/time specification: '%s' " "(interpreted as 'now')") % orig_datespec) return now() if vctx is not None: from course.validation import validate_identifier validate_identifier(vctx, "%s: event kind" % location, datespec) if course is None: return now() from course.models import Event try: return apply_postprocs( Event.objects.get(course=course, kind=datespec, ordinal=None).time) except ObjectDoesNotExist: if vctx is not None: vctx.add_warning( location, _("unrecognized date/time specification: '%s' " "(interpreted as 'now')") % orig_datespec) return now()
def parse_date_spec( course, # type: Optional[Course] datespec, # type: Union[Text, datetime.date, datetime.datetime] vctx=None, # type: Optional[ValidationContext] location=None, # type: Optional[Text] ): # type: (...) -> datetime.datetime if datespec is None: return None orig_datespec = datespec def localize_if_needed(d): # type: (datetime.datetime) -> datetime.datetime if d.tzinfo is None: from relate.utils import localize_datetime return localize_datetime(d) else: return d if isinstance(datespec, datetime.datetime): return localize_if_needed(datespec) if isinstance(datespec, datetime.date): return localize_if_needed( datetime.datetime.combine(datespec, datetime.time.min)) try: from typing import Text except ImportError: Text = None # noqa datespec_str = cast(Text, datespec).strip() # type: ignore # {{{ parse postprocessors postprocs = [] # type: List[DatespecPostprocessor] while True: parsed_one = False for pp_class in DATESPEC_POSTPROCESSORS: datespec_str, postproc = pp_class.parse(datespec_str) if postproc is not None: parsed_one = True postprocs.insert(0, cast(DatespecPostprocessor, postproc)) break datespec_str = datespec_str.strip() if not parsed_one: break # }}} def apply_postprocs(dtime): # type: (datetime.datetime) -> datetime.datetime for postproc in postprocs: dtime = postproc.apply(dtime) return dtime match = DATE_RE.match(datespec_str) if match: res_date = datetime.date(int(match.group(1)), int(match.group(2)), int(match.group(3))) result = localize_if_needed( datetime.datetime.combine(res_date, datetime.time.min)) return apply_postprocs(result) is_end = datespec_str.startswith(END_PREFIX) if is_end: datespec_str = datespec_str[len(END_PREFIX):] match = TRAILING_NUMERAL_RE.match(datespec_str) if match: # event with numeral event_kind = match.group(1) ordinal = int(match.group(2)) # type: Optional[int] else: # event without numeral event_kind = datespec_str ordinal = None if vctx is not None: from course.validation import validate_identifier validate_identifier(vctx, "%s: event kind" % location, event_kind) if course is None: return now() from course.models import Event try: event_obj = Event.objects.get(course=course, kind=event_kind, ordinal=ordinal) except ObjectDoesNotExist: if vctx is not None: vctx.add_warning( location, _("unrecognized date/time specification: '%s' " "(interpreted as 'now')") % 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)