diff --git a/course/utils.py b/course/utils.py index d9af3e35e1eebedead5b0358d31b5adcc41354e8..cdcb479f87e45ee11d8d3c0a388e4f0df9ddda5e 100644 --- a/course/utils.py +++ b/course/utils.py @@ -107,6 +107,19 @@ def _eval_generic_conditions(rule, course, role, now_datetime): return True +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 + + def get_flow_rules(flow_desc, kind, participation, flow_id, now_datetime, consider_exceptions=True, default_rules_desc=[]): if (not hasattr(flow_desc, "rules") @@ -233,14 +246,13 @@ def get_session_access_rule(session, role, flow_desc, now_datetime, if not _eval_generic_conditions(rule, session.course, role, now_datetime): continue + if not _eval_generic_session_conditions(rule, session, role, now_datetime): + continue + if hasattr(rule, "if_in_facility"): if rule.if_in_facility not in facilities: continue - if hasattr(rule, "if_has_tag"): - if session.access_rules_tag != rule.if_has_tag: - continue - if hasattr(rule, "if_in_progress"): if session.in_progress != rule.if_in_progress: continue @@ -308,9 +320,8 @@ def get_session_grading_rule(session, role, flow_desc, now_datetime): 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 not _eval_generic_session_conditions(rule, session, role, now_datetime): + continue if hasattr(rule, "if_completed_before"): ds = parse_date_spec(session.course, rule.if_completed_before) diff --git a/course/validation.py b/course/validation.py index 77059100b20d12fa08abf838a669de2e0123f484..e5da23fd8669aea1c9a6e1d5a30555dc93f3a5e1 100644 --- a/course/validation.py +++ b/course/validation.py @@ -553,6 +553,7 @@ def validate_session_access_rule(vctx, location, arule, tags): allowed_attrs=[ ("if_after", datespec_types), ("if_before", datespec_types), + ("if_started_before", datespec_types), ("if_has_role", list), ("if_in_facility", str), ("if_has_tag", (six.string_types, type(None))), @@ -618,6 +619,7 @@ def validate_session_grading_rule(vctx, location, grule, tags, grade_identifier) allowed_attrs=[ ("if_has_role", list), ("if_has_tag", (six.string_types, type(None))), + ("if_started_before", datespec_types), ("if_completed_before", datespec_types), ("credit_percent", (int, float)), diff --git a/doc/flow.rst b/doc/flow.rst index cab426c9803360f2e43137ed9a3523de02f9cf73..34873c4436611ff363afbdd050e9e3f0219d35d1 100644 --- a/doc/flow.rst +++ b/doc/flow.rst @@ -389,6 +389,11 @@ Rules about accessing and interacting with a flow (Optional) A :ref:`datespec <datespec>` that determines a date/time before which this rule applies. + .. attribute:: if_started_before + + (Optional) A :ref:`datespec <datespec>`. Rule applies if the session was started before + this time. + .. attribute:: if_has_role (Optional) A list of a subset of ``[unenrolled, ta, student, instructor]``. @@ -464,6 +469,11 @@ Determining how final (overall) grades of flows are computed (Optional) A list of a subset of ``[unenrolled, ta, student, instructor]``. + .. attribute:: if_started_before + + (Optional) A :ref:`datespec <datespec>`. Rule applies if the session was started before + this time. + .. attribute:: if_has_tag (Optional) Rule applies if session has this tag (see :attr:`FlowStartRules.tag_session`),