def start_flow(pctx, flow_identifier): request = pctx.request now_datetime = get_now_or_fake_time(request) fctx = FlowContext(pctx.repo, pctx.course, flow_identifier, participation=pctx.participation) current_access_rule = fctx.get_current_access_rule( None, pctx.role, pctx.participation, now_datetime) may_view = flow_permission.view in current_access_rule.permissions have_in_progress_session = (FlowSession.objects .filter( participation=pctx.participation, flow_id=fctx.flow_identifier, in_progress=True, participation__isnull=False, )).count() > 0 past_sessions = (FlowSession.objects .filter( participation=pctx.participation, flow_id=fctx.flow_identifier, participation__isnull=False) .order_by("start_time")) past_session_count = past_sessions.count() if current_access_rule.allowed_session_count is not None: allowed_another_session = ( past_session_count < current_access_rule.allowed_session_count) else: allowed_another_session = True if request.method == "POST": from course.content import set_up_flow_session_page_data resume_match = None for post_key in request.POST: resume_match = RESUME_RE.match(post_key) if resume_match is not None: break if resume_match is not None: resume_session_id = int(resume_match.group(1)) resume_session = get_object_or_404(FlowSession, pk=resume_session_id) if resume_session.participation != pctx.participation: raise PermissionDenied("not your session") if not may_view: raise PermissionDenied("may not resume session without " "'view' permission") if resume_session.participation is None: raise PermissionDenied("can't resume anonymous session") if resume_session.flow_id != fctx.flow_identifier: raise SuspiciousOperation("flow id mismatch on resume") if not (flow_permission.view_past in current_access_rule.permissions or resume_session.in_progress): raise PermissionDenied("not allowed to resume session") request.session["flow_session_id"] = resume_session_id return redirect("course.flow.view_flow_page", pctx.course.identifier, flow_identifier, 0) elif ("start_no_credit" in request.POST or "start_credit" in request.POST): if not may_view: raise PermissionDenied("may not start session without " "'view' permission") if not allowed_another_session: raise PermissionDenied("new session would exceed " "allowed session count limit exceed") if have_in_progress_session: raise PermissionDenied("cannot start flow when other flow " "session is already in progress") session = FlowSession() session.course = fctx.course session.participation = pctx.participation session.active_git_commit_sha = fctx.flow_commit_sha.decode() session.flow_id = flow_identifier session.in_progress = True session.for_credit = "start_credit" in request.POST session.access_rules_id = current_access_rule.id session.save() request.session["flow_session_id"] = session.id page_count = set_up_flow_session_page_data(fctx.repo, session, pctx.course.identifier, fctx.flow_desc, fctx.flow_commit_sha) session.page_count = page_count session.save() return redirect("course.flow.view_flow_page", pctx.course.identifier, flow_identifier, 0) else: raise SuspiciousOperation("unrecognized POST action") else: may_start_credit = ( may_view and not have_in_progress_session and allowed_another_session and flow_permission.start_credit in current_access_rule.permissions) may_start_no_credit = ( may_view and not have_in_progress_session and allowed_another_session and (flow_permission.start_no_credit in current_access_rule.permissions)) may_review = ( may_view and flow_permission.view_past in current_access_rule.permissions) if hasattr(fctx.flow_desc, "grade_aggregation_strategy"): from course.models import GRADE_AGGREGATION_STRATEGY_CHOICES grade_aggregation_strategy_text = ( dict(GRADE_AGGREGATION_STRATEGY_CHOICES) [fctx.flow_desc.grade_aggregation_strategy]) else: grade_aggregation_strategy_text = None # {{{ fish out relevant rules from course.utils import ( get_flow_access_rules, get_relevant_rules) rules = get_flow_access_rules(fctx.course, pctx.participation, flow_identifier, fctx.flow_desc) # }}} return render_course_page(pctx, "course/flow-start.html", { "flow_desc": fctx.flow_desc, "grade_aggregation_strategy": grade_aggregation_strategy_text, "flow_identifier": flow_identifier, "rules": get_relevant_rules(rules, pctx.role, now_datetime), "now": now_datetime, "may_start_credit": may_start_credit, "may_start_no_credit": may_start_no_credit, "may_review": may_review, "past_sessions": past_sessions, }, allow_instant_flow_requests=False)
def start_flow(request, course_identifier, flow_identifier): fctx = FlowContext(request, course_identifier, flow_identifier) from course.models import flow_permission if flow_permission.view not in fctx.permissions: raise PermissionDenied() have_in_progress_session = (FlowSession.objects .filter( participation=fctx.participation, flow_id=fctx.flow_identifier, in_progress=True, participation__isnull=False, )).count() > 0 past_sessions = (FlowSession.objects .filter( participation=fctx.participation, flow_id=fctx.flow_identifier, participation__isnull=False) .order_by("start_time")) past_session_count = past_sessions.count() if hasattr(fctx.stipulations, "allowed_session_count"): allowed_another_session = ( past_session_count < fctx.stipulations.allowed_session_count) else: allowed_another_session = True if request.method == "POST": from course.content import set_up_flow_session_page_data resume_match = None for post_key in request.POST: resume_match = RESUME_RE.match(post_key) if resume_match is not None: break if resume_match is not None: resume_session_id = int(resume_match.group(1)) resume_session = get_object_or_404(FlowSession, pk=resume_session_id) if resume_session.participation != fctx.participation: raise PermissionDenied("not your session") if resume_session.participation is None: raise PermissionDenied("can't resume anonymous session") if resume_session.flow_id != fctx.flow_identifier: raise SuspiciousOperation("flow id mismatch on resume") if not (flow_permission.view_past in fctx.permissions or resume_session.in_progress): raise PermissionDenied("not allowed to resume session") request.session["flow_session_id"] = resume_session_id return redirect("course.flow.view_flow_page", course_identifier, flow_identifier, 0) elif ("start_no_credit" in request.POST or "start_credit" in request.POST): if not allowed_another_session: raise PermissionDenied("new session would exceed " "allowed session count limit exceed") if have_in_progress_session: raise PermissionDenied("cannot start flow when other flow " "is already in progress") session = FlowSession() session.course = fctx.course session.participation = fctx.participation session.active_git_commit_sha = fctx.flow_commit_sha.decode() session.flow_id = flow_identifier session.in_progress = True session.for_credit = "start_credit" in request.POST session.save() request.session["flow_session_id"] = session.id page_count = set_up_flow_session_page_data(fctx.repo, session, course_identifier, fctx.flow_desc, fctx.flow_commit_sha) session.page_count = page_count session.save() return redirect("course.flow.view_flow_page", course_identifier, flow_identifier, 0) else: raise SuspiciousOperation("unrecognized POST action") else: may_start_credit = ( not have_in_progress_session and allowed_another_session and flow_permission.start_credit in fctx.permissions) may_start_no_credit = ( not have_in_progress_session and allowed_another_session and flow_permission.start_no_credit in fctx.permissions) may_review = ( flow_permission.view_past in fctx.permissions) if hasattr(fctx.flow_desc, "grade_aggregation_strategy"): from course.models import GRADE_AGGREGATION_STRATEGY_CHOICES grade_aggregation_strategy_text = ( dict(GRADE_AGGREGATION_STRATEGY_CHOICES) [fctx.flow_desc.grade_aggregation_strategy]) else: grade_aggregation_strategy_text = None return render(request, "course/flow-start.html", { "participation": fctx.participation, "course_desc": fctx.course_desc, "course": fctx.course, "flow_desc": fctx.flow_desc, "role": fctx.role, "participation_role": participation_role, "grade_aggregation_strategy": grade_aggregation_strategy_text, "flow_identifier": flow_identifier, "may_start_credit": may_start_credit, "may_start_no_credit": may_start_no_credit, "may_review": may_review, "past_sessions": past_sessions, "stipulations": fctx.stipulations, })