Example #1
0
def _eval_generic_conditions(
        rule,  # type: Any
        course,  # type: Course
        participation,  # type: Optional[Participation]
        now_datetime,  # type: datetime.datetime
        flow_id,  # type: Text
        login_exam_ticket,  # type: Optional[ExamTicket]
        ):
    # type: (...) -> bool

    if hasattr(rule, "if_before"):
        ds = parse_date_spec(course, rule.if_before)
        if not (now_datetime <= ds):
            return False

    if hasattr(rule, "if_after"):
        ds = parse_date_spec(course, rule.if_after)
        if not (now_datetime >= ds):
            return False

    if hasattr(rule, "if_has_role"):
        from course.enrollment import get_participation_role_identifiers
        roles = get_participation_role_identifiers(course, participation)
        if all(role not in rule.if_has_role for role in roles):
            return False

    if (hasattr(rule, "if_signed_in_with_matching_exam_ticket")
            and rule.if_signed_in_with_matching_exam_ticket):
        if login_exam_ticket is None:
            return False
        if login_exam_ticket.exam.flow_id != flow_id:
            return False

    return True
Example #2
0
def _eval_generic_conditions(
        rule,  # type: Any
        course,  # type: Course
        participation,  # type: Optional[Participation]
        now_datetime,  # type: datetime.datetime
        flow_id,  # type: Text
        login_exam_ticket,  # type: Optional[ExamTicket]
):
    # type: (...) -> bool

    if hasattr(rule, "if_before"):
        ds = parse_date_spec(course, rule.if_before)
        if not (now_datetime <= ds):
            return False

    if hasattr(rule, "if_after"):
        ds = parse_date_spec(course, rule.if_after)
        if not (now_datetime >= ds):
            return False

    if hasattr(rule, "if_has_role"):
        from course.enrollment import get_participation_role_identifiers
        roles = get_participation_role_identifiers(course, participation)
        if all(role not in rule.if_has_role for role in roles):
            return False

    if (hasattr(rule, "if_signed_in_with_matching_exam_ticket")
            and rule.if_signed_in_with_matching_exam_ticket):
        if login_exam_ticket is None:
            return False
        if login_exam_ticket.exam.flow_id != flow_id:
            return False

    return True
Example #3
0
def _eval_generic_conditions(rule, course, role, now_datetime,
        flow_id, login_exam_ticket):
    if hasattr(rule, "if_before"):
        ds = parse_date_spec(course, rule.if_before)
        if not (now_datetime <= ds):
            return False

    if hasattr(rule, "if_after"):
        ds = parse_date_spec(course, rule.if_after)
        if not (now_datetime >= ds):
            return False

    if hasattr(rule, "if_has_role"):
        if role not in rule.if_has_role:
            return False

    if (hasattr(rule, "if_signed_in_with_matching_exam_ticket")
            and rule.if_signed_in_with_matching_exam_ticket):
        if login_exam_ticket is None:
            return False
        if login_exam_ticket is None:
            return False
        if login_exam_ticket.exam.flow_id != flow_id:
            return False

    return True
Example #4
0
def get_session_grading_rule(session, role, flow_desc, now_datetime):
    flow_desc_rules = getattr(flow_desc, "rules", None)

    from relate.utils import dict_to_struct
    rules = get_flow_rules(
        flow_desc,
        flow_rule_kind.grading,
        session.participation,
        session.flow_id,
        now_datetime,
        default_rules_desc=[dict_to_struct(dict(generates_grade=False, ))])

    for rule in rules:
        if hasattr(rule, "if_has_role"):
            if role not in rule.if_has_role:
                continue

        if hasattr(rule, "if_has_tag"):
            if session.access_rules_tag != rule.if_has_tag:
                continue

        if hasattr(rule, "if_completed_before"):
            ds = parse_date_spec(session.course, rule.if_completed_before)
            if session.in_progress and now_datetime > ds:
                continue
            if not session.in_progress and session.completion_time > ds:
                continue

        due = parse_date_spec(session.course, getattr(rule, "due", None))
        if due is not None:
            assert due.tzinfo is not None

        generates_grade = getattr(rule, "generates_grade", True)

        grade_identifier = None
        grade_aggregation_strategy = None
        if flow_desc_rules is not None:
            grade_identifier = flow_desc_rules.grade_identifier
            grade_aggregation_strategy = getattr(flow_desc_rules,
                                                 "grade_aggregation_strategy",
                                                 None)

        return FlowSessionGradingRule(
            grade_identifier=grade_identifier,
            grade_aggregation_strategy=grade_aggregation_strategy,
            due=due,
            generates_grade=generates_grade,
            description=getattr(rule, "description", None),
            credit_percent=getattr(rule, "credit_percent", 100),
            use_last_activity_as_completion_time=getattr(
                rule, "use_last_activity_as_completion_time", False),
        )

    raise RuntimeError(
        _("grading rule determination was unable to find "
          "a grading rule"))
Example #5
0
def get_session_grading_rule(session, role, flow_desc, now_datetime):
    flow_desc_rules = getattr(flow_desc, "rules", None)

    from relate.utils import dict_to_struct
    rules = get_flow_rules(flow_desc, flow_rule_kind.grading,
            session.participation, session.flow_id, now_datetime,
            default_rules_desc=[
                dict_to_struct(dict(
                    generates_grade=False,
                    ))])

    for rule in rules:
        if hasattr(rule, "if_has_role"):
            if role not in rule.if_has_role:
                continue

        if hasattr(rule, "if_has_tag"):
            if session.access_rules_tag != rule.if_has_tag:
                continue

        if hasattr(rule, "if_completed_before"):
            ds = parse_date_spec(session.course, rule.if_completed_before)
            if session.in_progress and now_datetime > ds:
                continue
            if not session.in_progress and session.completion_time > ds:
                continue

        due = parse_date_spec(session.course, getattr(rule, "due", None))
        if due is not None:
            assert due.tzinfo is not None

        generates_grade = getattr(rule, "generates_grade", True)

        grade_identifier = None
        grade_aggregation_strategy = None
        if flow_desc_rules is not None:
            grade_identifier = flow_desc_rules.grade_identifier
            grade_aggregation_strategy = getattr(
                    flow_desc_rules, "grade_aggregation_strategy", None)

        return FlowSessionGradingRule(
                grade_identifier=grade_identifier,
                grade_aggregation_strategy=grade_aggregation_strategy,
                due=due,
                generates_grade=generates_grade,
                description=getattr(rule, "description", None),
                credit_percent=getattr(rule, "credit_percent", 100),
                use_last_activity_as_completion_time=getattr(
                    rule, "use_last_activity_as_completion_time", False),
                )

    raise RuntimeError(_("grading rule determination was unable to find "
            "a grading rule"))
Example #6
0
def _eval_generic_conditions(rule, course, role, now_datetime):
    if hasattr(rule, "if_before"):
        ds = parse_date_spec(course, rule.if_before)
        if not (now_datetime <= ds):
            return False

    if hasattr(rule, "if_after"):
        ds = parse_date_spec(course, rule.if_after)
        if not (now_datetime >= ds):
            return False

    if hasattr(rule, "if_has_role"):
        if role not in rule.if_has_role:
            return False

    return True
Example #7
0
def _eval_generic_conditions(rule, course, role, now_datetime):
    if hasattr(rule, "if_before"):
        ds = parse_date_spec(course, rule.if_before)
        if not (now_datetime <= ds):
            return False

    if hasattr(rule, "if_after"):
        ds = parse_date_spec(course, rule.if_after)
        if not (now_datetime >= ds):
            return False

    if hasattr(rule, "if_has_role"):
        if role not in rule.if_has_role:
            return False

    return True
Example #8
0
def _eval_generic_session_conditions(rule, session, role, now_datetime):
    if hasattr(rule, "if_has_tag"):
        if session.access_rules_tag != rule.if_has_tag:
            return False

    if hasattr(rule, "if_started_before"):
        ds = parse_date_spec(session.course, rule.if_started_before)
        if not session.start_time < ds:
            return False

    return True
Example #9
0
def get_session_grading_rule(session, role, flow_desc, now_datetime):
    rules = get_flow_rules(flow_desc, flow_rule_kind.grading,
                           session.participation, session.flow_id,
                           now_datetime)

    if not rules:
        return FlowSessionGradingRule()

    for rule in rules:
        if hasattr(rule, "if_has_role"):
            if role not in rule.if_has_role:
                continue

        if hasattr(rule, "if_has_tag"):
            if session.access_rules_tag != rule.if_has_tag:
                continue

        if hasattr(rule, "if_completed_before"):
            ds = parse_date_spec(session.course, rule.if_completed_before)
            if now_datetime > ds:
                continue
            if not session.in_progress and session.completion_time > ds:
                continue

        due = parse_date_spec(session.course, getattr(rule, "due", None))
        if due is not None:
            assert due.tzinfo is not None

        return FlowSessionGradingRule(
            grade_identifier=getattr(rule, "grade_identifier", None),
            grade_aggregation_strategy=getattr(rule,
                                               "grade_aggregation_strategy",
                                               None),
            due=due,
            description=getattr(rule, "description", None),
            credit_percent=getattr(rule, "credit_percent", 100))

    raise RuntimeError("grading rule determination was unable to find "
                       "a grading rule")
Example #10
0
def _eval_generic_session_conditions(
        rule,  # type: Any
        session,  # type: FlowSession
        now_datetime,  # type: datetime.datetime
        ):
    # type: (...) -> bool

    if hasattr(rule, "if_has_tag"):
        if session.access_rules_tag != rule.if_has_tag:
            return False

    if hasattr(rule, "if_started_before"):
        ds = parse_date_spec(session.course, rule.if_started_before)
        if not session.start_time < ds:
            return False

    return True
Example #11
0
def _eval_generic_session_conditions(
        rule,  # type: Any
        session,  # type: FlowSession
        now_datetime,  # type: datetime.datetime
        ):
    # type: (...) -> bool

    if hasattr(rule, "if_has_tag"):
        if session.access_rules_tag != rule.if_has_tag:
            return False

    if hasattr(rule, "if_started_before"):
        ds = parse_date_spec(session.course, rule.if_started_before)
        if not session.start_time < ds:
            return False

    return True
Example #12
0
 def encounter_datespec(self, location, datespec):
     from course.content import parse_date_spec
     parse_date_spec(self.course, datespec, vctx=self, location=location)
Example #13
0
def get_flow_access_rules(course, participation, flow_id, flow_desc,
        use_exceptions=True):
    rules = []

    attr_names = [
            "id",
            "roles",
            "start",
            "end",
            "allowed_session_count",
            "credit_percent",
            "permissions",
            "is_exception",
            "sticky",
            ]

    # {{{ scan for exceptions in database

    if use_exceptions:
        for exc in (
                FlowAccessException.objects
                .filter(
                    participation=participation,
                    flow_id=flow_id)
                .order_by("-creation_time")):

            attrs = {
                    "is_exception": True,
                    "id": "exception",
                    "permissions": [entry.permission for entry in exc.entries.all()],
                    }
            if exc.expiration is not None:
                attrs["end"] = exc.expiration
            attrs["sticky"] = exc.is_sticky

            if exc.stipulations is not None and isinstance(exc.stipulations, dict):
                attrs.update(exc.stipulations)

            rules.append(FlowAccessRule(**attrs))

    # }}}

    if not hasattr(flow_desc, "access_rules"):
        rules.append(
                FlowAccessRule(**{
                    "permissions": [
                        flow_permission.view,
                        flow_permission.start_no_credit],
                    "is_exception": False,
                    }))

    else:
        for rule in flow_desc.access_rules:
            attrs = dict(
                    (attr_name, getattr(rule, attr_name))
                    for attr_name in attr_names
                    if hasattr(rule, attr_name))

            if "start" in attrs:
                attrs["start"] = parse_date_spec(course, attrs["start"])
            if "end" in attrs:
                attrs["end"] = parse_date_spec(course, attrs["end"])

            rules.append(FlowAccessRule(**attrs))

    # {{{ set unavailable attrs to None

    def add_attrs_with_nones(rule):
        for attr_name in attr_names:
            if not hasattr(rule, attr_name):
                setattr(rule, attr_name, None)

    for rule in rules:
        add_attrs_with_nones(rule, )

    # }}}

    return rules
Example #14
0
def get_session_grading_rule(
        session,  # type: FlowSession
        flow_desc,  # type: FlowDesc
        now_datetime  # type: datetime.datetime
        ):
    # type: (...) -> FlowSessionGradingRule

    flow_desc_rules = getattr(flow_desc, "rules", None)

    from relate.utils import dict_to_struct
    rules = get_flow_rules(flow_desc, flow_rule_kind.grading,
            session.participation, session.flow_id, now_datetime,
            default_rules_desc=[
                dict_to_struct(dict(
                    generates_grade=False,
                    ))])

    from course.enrollment import get_participation_role_identifiers
    roles = get_participation_role_identifiers(session.course, session.participation)

    for rule in rules:
        if hasattr(rule, "if_has_role"):
            if all(role not in rule.if_has_role for role in roles):
                continue

        if not _eval_generic_session_conditions(rule, session, now_datetime):
            continue

        if not _eval_participation_tags_conditions(rule, session.participation):
            continue

        if hasattr(rule, "if_completed_before"):
            ds = parse_date_spec(session.course, rule.if_completed_before)

            use_last_activity_as_completion_time = False
            if hasattr(rule, "use_last_activity_as_completion_time"):
                use_last_activity_as_completion_time = \
                        rule.use_last_activity_as_completion_time

            if use_last_activity_as_completion_time:
                last_activity = session.last_activity()
                if last_activity is not None:
                    completion_time = last_activity
                else:
                    completion_time = now_datetime
            else:
                if session.in_progress:
                    completion_time = now_datetime
                else:
                    completion_time = session.completion_time

            if completion_time > ds:
                continue

        due = parse_date_spec(session.course, getattr(rule, "due", None))
        if due is not None:
            assert due.tzinfo is not None

        generates_grade = getattr(rule, "generates_grade", True)

        grade_identifier = None
        grade_aggregation_strategy = None
        if flow_desc_rules is not None:
            grade_identifier = flow_desc_rules.grade_identifier
            grade_aggregation_strategy = getattr(
                    flow_desc_rules, "grade_aggregation_strategy", None)

        bonus_points = getattr_with_fallback((rule, flow_desc), "bonus_points", 0)
        max_points = getattr_with_fallback((rule, flow_desc), "max_points", None)
        max_points_enforced_cap = getattr_with_fallback(
                (rule, flow_desc), "max_points_enforced_cap", None)

        grade_aggregation_strategy = cast(Text, grade_aggregation_strategy)

        return FlowSessionGradingRule(
                grade_identifier=grade_identifier,
                grade_aggregation_strategy=grade_aggregation_strategy,
                due=due,
                generates_grade=generates_grade,
                description=getattr(rule, "description", None),
                credit_percent=getattr(rule, "credit_percent", 100),
                use_last_activity_as_completion_time=getattr(
                    rule, "use_last_activity_as_completion_time", False),

                bonus_points=bonus_points,
                max_points=max_points,
                max_points_enforced_cap=max_points_enforced_cap,
                )

    raise RuntimeError(_("grading rule determination was unable to find "
            "a grading rule"))
Example #15
0
def get_flow_permissions(course, participation, role, flow_id, flow_desc,
        now_datetime):
    # {{{ interpret flow rules

    flow_rule = None

    if not hasattr(flow_desc, "access_rules"):
        flow_rule = dict_to_struct(
                {"permissions":
                    [flow_permission.view, flow_permission.start_no_credit]})
    else:
        for rule in flow_desc.access_rules:
            if hasattr(rule, "roles"):
                if role not in rule.roles:
                    continue

            if hasattr(rule, "start"):
                start_date = parse_date_spec(course, rule.start)
                if now_datetime < start_date:
                    continue

            if hasattr(rule, "end"):
                end_date = parse_date_spec(course, rule.end)
                if end_date < now_datetime:
                    continue

            flow_rule = rule
            break

    # }}}

    # {{{ scan for exceptions in database

    for exc in (
            FlowAccessException.objects
            .filter(participation=participation, flow_id=flow_id)
            .order_by("expiration")):

        if exc.expiration is not None and exc.expiration < now_datetime:
            continue

        exc_stipulations = exc.stipulations
        if not isinstance(exc_stipulations, dict):
            exc_stipulations = {}

        stipulations = {}

        if flow_rule is not None:
            stipulations.update(
                    (key, val)
                    for key, val in flow_rule.__dict__.iteritems()
                    if not key.startswith("_"))

        stipulations.update(exc_stipulations)
        stipulations = dict_to_struct(stipulations)

        return (
                [entry.permission for entry in exc.entries.all()],
                stipulations
                )

    # }}}

    if flow_rule is not None:
        return flow_rule.permissions, flow_rule

    raise ValueError("Flow access rules of flow '%s' did not resolve "
            "to access answer for '%s'" % (flow_id, participation))
Example #16
0
    def encounter_datespec(self, location, datespec):
        from course.content import parse_date_spec

        parse_date_spec(self.course, datespec, vctx=self, location=location)
Example #17
0
def view_calendar(pctx):
    from course.content import markup_to_html, parse_date_spec

    from course.views import get_now_or_fake_time
    now = get_now_or_fake_time(pctx.request)

    if not pctx.has_permission(pperm.view_calendar):
        raise PermissionDenied(_("may not view calendar"))

    events_json = []

    from course.content import get_raw_yaml_from_repo
    try:
        event_descr = get_raw_yaml_from_repo(pctx.repo,
                pctx.course.events_file, pctx.course_commit_sha)
    except ObjectDoesNotExist:
        event_descr = {}

    event_kinds_desc = event_descr.get("event_kinds", {})
    event_info_desc = event_descr.get("events", {})

    event_info_list = []

    events = sorted(
            Event.objects
            .filter(
                course=pctx.course,
                shown_in_calendar=True),
            key=lambda evt: (
                -evt.time.year, -evt.time.month, -evt.time.day,
                evt.time.hour, evt.time.minute, evt.time.second))

    for event in events:
        kind_desc = event_kinds_desc.get(event.kind)

        human_title = six.text_type(event)

        event_json = {
                "id": event.id,
                "start": event.time.isoformat(),
                "allDay": event.all_day,
                }
        if event.end_time is not None:
            event_json["end"] = event.end_time.isoformat()

        if kind_desc is not None:
            if "color" in kind_desc:
                event_json["color"] = kind_desc["color"]
            if "title" in kind_desc:
                if event.ordinal is not None:
                    human_title = kind_desc["title"].format(nr=event.ordinal)
                else:
                    human_title = kind_desc["title"]

        description = None
        show_description = True
        event_desc = event_info_desc.get(six.text_type(event))
        if event_desc is not None:
            if "description" in event_desc:
                description = markup_to_html(
                        pctx.course, pctx.repo, pctx.course_commit_sha,
                        event_desc["description"])

            if "title" in event_desc:
                human_title = event_desc["title"]

            if "color" in event_desc:
                event_json["color"] = event_desc["color"]

            if "show_description_from" in event_desc:
                ds = parse_date_spec(
                        pctx.course, event_desc["show_description_from"])
                if now < ds:
                    show_description = False

            if "show_description_until" in event_desc:
                ds = parse_date_spec(
                        pctx.course, event_desc["show_description_until"])
                if now > ds:
                    show_description = False

        event_json["title"] = human_title

        if show_description and description:
            event_json["url"] = "#event-%d" % event.id

            start_time = event.time
            end_time = event.end_time

            if event.all_day:
                start_time = start_time.date()
                if end_time is not None:
                    local_end_time = as_local_time(end_time)
                    end_midnight = datetime.time(tzinfo=local_end_time.tzinfo)
                    if local_end_time.time() == end_midnight:
                        end_time = (end_time - datetime.timedelta(days=1)).date()
                    else:
                        end_time = end_time.date()

            event_info_list.append(
                    EventInfo(
                        id=event.id,
                        human_title=human_title,
                        start_time=start_time,
                        end_time=end_time,
                        description=description
                        ))

        events_json.append(event_json)

    default_date = now.date()
    if pctx.course.end_date is not None and default_date > pctx.course.end_date:
        default_date = pctx.course.end_date

    from json import dumps
    return render_course_page(pctx, "course/calendar.html", {
        "events_json": dumps(events_json),
        "event_info_list": event_info_list,
        "default_date": default_date.isoformat(),
    })
Example #18
0
 def datespec_callback(location, datespec):
     try:
         parse_date_spec(pctx.course, datespec, return_now_on_error=False)
     except InvalidDatespec as e:
         invalid_datespecs.setdefault(e.datespec, []).append(location)
Example #19
0
    def encounter_datespec(self, location, datespec):
        # type: (Text, Text) -> None

        from course.content import parse_date_spec
        parse_date_spec(self.course, datespec, vctx=self, location=location)
Example #20
0
def get_session_grading_rule(
        session,  # type: FlowSession
        flow_desc,  # type: FlowDesc
        now_datetime  # type: datetime.datetime
        ):
    # type: (...) -> FlowSessionGradingRule

    flow_desc_rules = getattr(flow_desc, "rules", None)

    from relate.utils import dict_to_struct
    rules = get_flow_rules(flow_desc, flow_rule_kind.grading,
            session.participation, session.flow_id, now_datetime,
            default_rules_desc=[
                dict_to_struct(dict(
                    generates_grade=False,
                    ))])

    from course.enrollment import get_participation_role_identifiers
    roles = get_participation_role_identifiers(session.course, session.participation)

    for rule in rules:
        if hasattr(rule, "if_has_role"):
            if all(role not in rule.if_has_role for role in roles):
                continue

        if not _eval_generic_session_conditions(rule, session, now_datetime):
            continue

        if not _eval_participation_tags_conditions(rule, session.participation):
            continue

        if hasattr(rule, "if_completed_before"):
            ds = parse_date_spec(session.course, rule.if_completed_before)
            if session.in_progress and now_datetime > ds:
                continue
            if not session.in_progress and session.completion_time > ds:
                continue

        due = parse_date_spec(session.course, getattr(rule, "due", None))
        if due is not None:
            assert due.tzinfo is not None

        generates_grade = getattr(rule, "generates_grade", True)

        grade_identifier = None
        grade_aggregation_strategy = None
        if flow_desc_rules is not None:
            grade_identifier = flow_desc_rules.grade_identifier
            grade_aggregation_strategy = getattr(
                    flow_desc_rules, "grade_aggregation_strategy", None)

        bonus_points = getattr_with_fallback((rule, flow_desc), "bonus_points", 0)
        max_points = getattr_with_fallback((rule, flow_desc), "max_points", None)
        max_points_enforced_cap = getattr_with_fallback(
                (rule, flow_desc), "max_points_enforced_cap", None)

        return FlowSessionGradingRule(
                grade_identifier=grade_identifier,
                grade_aggregation_strategy=grade_aggregation_strategy,
                due=due,
                generates_grade=generates_grade,
                description=getattr(rule, "description", None),
                credit_percent=getattr(rule, "credit_percent", 100),
                use_last_activity_as_completion_time=getattr(
                    rule, "use_last_activity_as_completion_time", False),

                bonus_points=bonus_points,
                max_points=max_points,
                max_points_enforced_cap=max_points_enforced_cap,
                )

    raise RuntimeError(_("grading rule determination was unable to find "
            "a grading rule"))
Example #21
0
def view_calendar(pctx):
    from course.content import markup_to_html, parse_date_spec

    from course.views import get_now_or_fake_time

    now = get_now_or_fake_time(pctx.request)

    if not pctx.has_permission(pperm.view_calendar):
        raise PermissionDenied(_("may not view calendar"))

    events_json = []

    from course.content import get_raw_yaml_from_repo

    try:
        event_descr = get_raw_yaml_from_repo(pctx.repo, pctx.course.events_file, pctx.course_commit_sha)
    except ObjectDoesNotExist:
        event_descr = {}

    event_kinds_desc = event_descr.get("event_kinds", {})
    event_info_desc = event_descr.get("events", {})

    event_info_list = []

    for event in Event.objects.filter(course=pctx.course, shown_in_calendar=True).order_by("-time"):
        kind_desc = event_kinds_desc.get(event.kind)

        human_title = six.text_type(event)

        event_json = {"id": event.id, "start": event.time.isoformat(), "allDay": event.all_day}
        if event.end_time is not None:
            event_json["end"] = event.end_time.isoformat()

        if kind_desc is not None:
            if "color" in kind_desc:
                event_json["color"] = kind_desc["color"]
            if "title" in kind_desc:
                if event.ordinal is not None:
                    human_title = kind_desc["title"].format(nr=event.ordinal)
                else:
                    human_title = kind_desc["title"]

        description = None
        show_description = True
        event_desc = event_info_desc.get(six.text_type(event))
        if event_desc is not None:
            if "description" in event_desc:
                description = markup_to_html(pctx.course, pctx.repo, pctx.course_commit_sha, event_desc["description"])

            if "title" in event_desc:
                human_title = event_desc["title"]

            if "color" in event_desc:
                event_json["color"] = event_desc["color"]

            if "show_description_from" in event_desc:
                ds = parse_date_spec(pctx.course, event_desc["show_description_from"])
                if now < ds:
                    show_description = False

            if "show_description_until" in event_desc:
                ds = parse_date_spec(pctx.course, event_desc["show_description_until"])
                if now > ds:
                    show_description = False

        event_json["title"] = human_title

        if show_description and description:
            event_json["url"] = "#event-%d" % event.id

            start_time = event.time
            end_time = event.end_time

            if event.all_day:
                start_time = start_time.date()
                local_end_time = as_local_time(end_time)
                end_midnight = datetime.time(tzinfo=local_end_time.tzinfo)
                if local_end_time.time() == end_midnight:
                    end_time = (end_time - datetime.timedelta(days=1)).date()
                else:
                    end_time = end_time.date()

            event_info_list.append(
                EventInfo(
                    id=event.id,
                    human_title=human_title,
                    start_time=start_time,
                    end_time=end_time,
                    description=description,
                )
            )

        events_json.append(event_json)

    default_date = now.date()
    if pctx.course.end_date is not None and default_date > pctx.course.end_date:
        default_date = pctx.course.end_date

    from json import dumps

    return render_course_page(
        pctx,
        "course/calendar.html",
        {
            "events_json": dumps(events_json),
            "event_info_list": event_info_list,
            "default_date": default_date.isoformat(),
        },
    )
Example #22
0
 def datespec_callback(location, datespec):
     try:
         parse_date_spec(pctx.course, datespec, return_now_on_error=False)
     except InvalidDatespec as e:
         invalid_datespecs.setdefault(e.datespec, []).append(location)
Example #23
0
    def encounter_datespec(self, location, datespec):
        # type: (Text, Text) -> None

        from course.content import parse_date_spec
        parse_date_spec(self.course, datespec, vctx=self, location=location)