Skip to content
flow.py 42.7 KiB
Newer Older
                or (
                    (flow_permission.see_answer_after_completion
                        in permissions)
                    and not flow_session.in_progress))

        if show_correctness or show_answer:
    elif fpctx.page.expects_answer() and not answer_was_graded:
        # Don't show answer yet
        pass
    else:
        show_answer = (
                flow_permission.see_answer in permissions
                or (
                    (flow_permission.see_answer_after_completion
                        in permissions)
                    and not flow_session.in_progress))

    title = fpctx.page.title(page_context, page_data.data)
    body = fpctx.page.body(page_context, page_data.data)

    if show_answer:
        correct_answer = fpctx.page.correct_answer(
                page_context, page_data.data,
                answer_data, grade_data)
    else:
        correct_answer = None

Andreas Klöckner's avatar
Andreas Klöckner committed
    # {{{ render flow page

        form_html = fpctx.page.form_to_html(
                pctx.request, page_context, form, answer_data)
Andreas Klöckner's avatar
Andreas Klöckner committed

    args = {
        "flow_identifier": fpctx.flow_identifier,
        "flow_desc": fpctx.flow_desc,
        "ordinal": fpctx.ordinal,
        "page_data": fpctx.page_data,
        "percentage": int(100*(fpctx.ordinal+1) / flow_session.page_count),
        "flow_session": flow_session,
Andreas Klöckner's avatar
Andreas Klöckner committed
        "title": title, "body": body,
        "form": form,
Andreas Klöckner's avatar
Andreas Klöckner committed
        "form_html": form_html,
        "correct_answer": correct_answer,

Andreas Klöckner's avatar
Andreas Klöckner committed
        "show_correctness": show_correctness,
        "may_change_answer": may_change_answer,
        "may_change_graded_answer": (
            (flow_permission.change_answer
                        in permissions)
        "will_receive_feedback": will_receive_feedback(permissions),
Andreas Klöckner's avatar
Andreas Klöckner committed
        "show_answer": show_answer,
    }

    if fpctx.page.expects_answer():
        args["max_points"] = fpctx.page.max_points(fpctx.page_data)

    return render_course_page(
            pctx, "course/flow-page.html", args,
            allow_instant_flow_requests=False)

@transaction.atomic
@course_view
def finish_flow_session_view(pctx, flow_identifier):
    request = pctx.request

    flow_session = find_current_flow_session(
            request, pctx.course, flow_identifier)

    if flow_session is None:
        messages.add_message(request, messages.WARNING,
                "No session record found for this flow. "
                "Redirected to flow start page.")

        return redirect("course.flow.start_flow",
                pctx.course.identifier,
    fctx = FlowContext(pctx.repo, pctx.course, flow_identifier,
            participation=pctx.participation,
            flow_session=flow_session)

    current_access_rule = fctx.get_current_access_rule(
            flow_session, pctx.role, pctx.participation,
            get_now_or_fake_time(request))

    answer_visits = assemble_answer_visits(flow_session)

    from course.content import markup_to_html
    completion_text = markup_to_html(
            fctx.course, fctx.repo, fctx.flow_commit_sha,
            fctx.flow_desc.completion_text)

    (answered_count, unanswered_count) = count_answered(
            fctx, flow_session, answer_visits)
    is_graded_flow = bool(answered_count + unanswered_count)
    if flow_permission.view not in current_access_rule.permissions:
        raise PermissionDenied()

    def render_finish_response(template, **kwargs):
        render_args = {
            "flow_identifier": fctx.flow_identifier,
            "flow_desc": fctx.flow_desc,
        }
        render_args.update(kwargs)
        return render_course_page(
                pctx, template, render_args,
                allow_instant_flow_requests=False)

    if request.method == "POST":
        if "submit" not in request.POST:
            raise SuspiciousOperation("odd POST parameters")

        if not flow_session.in_progress:
            raise PermissionDenied("Can't end a session that's already ended")

        # Actually end the flow session
        get_flow_session_id_map(request)[flow_identifier] = None
        grade_info = finish_flow_session(fctx, flow_session, current_access_rule)
            return render_finish_response(
                    "course/flow-completion-grade.html",
                    completion_text=completion_text,
                    grade_info=grade_info)

        else:
            return render_finish_response(
                    "course/flow-completion.html",
                    last_page_nr=None,
                    completion_text=completion_text)

            and fctx.flow_commit_sha == fctx.course_commit_sha):
        # Not serious--no questions in flow, and no new version available.
        # No need to end the flow visit.

        return render_finish_response(
                "course/flow-completion.html",
                last_page_nr=flow_session.page_count-1,
                completion_text=completion_text)

    elif not flow_session.in_progress:
        # Just reviewing: re-show grades.
        grade_info = gather_grade_info(flow_session, answer_visits)
        return render_finish_response(
                "course/flow-completion-grade.html",
                completion_text=completion_text,
                grade_info=grade_info)

    else:
        # confirm ending flow
        return render_finish_response(
                "course/flow-confirm-completion.html",
                last_page_nr=flow_session.page_count-1,
                answered_count=answered_count,
                unanswered_count=unanswered_count,
                total_count=answered_count+unanswered_count)

# {{{ view: regrade flow

class RegradeFlowForm(StyledForm):
    def __init__(self, flow_ids, *args, **kwargs):
        super(RegradeFlowForm, self).__init__(*args, **kwargs)

        self.fields["flow_id"] = forms.ChoiceField(
                choices=[(fid, fid) for fid in flow_ids],
                initial=participation_role.student,
                required=True)
        self.fields["access_rules_id"] = forms.CharField(
                required=False,
                help_text="If non-empty, limit the regrading to sessions started "
                "under this access rules ID.")
        self.fields["regraded_session_in_progress"] = forms.ChoiceField(
                choices=(
                    ("any", "Regrade in-progress and not-in-progress sessions"),
                    ("yes", "Regrade in-progress sessions only"),
                    ("no", "Regrade not-in-progress sessions only"),
                    ))

        self.helper.add_input(
                Submit("regrade", "Regrade", css_class="col-lg-offset-2"))


@transaction.atomic
def _regrade_sessions(repo, course, sessions):
    count = 0

    from course.flow import regrade_session
    for session in sessions:
        regrade_session(repo, course, session)
        count += 1

    return count


@course_view
def regrade_not_for_credit_flows_view(pctx):
    if pctx.role != participation_role.instructor:
        raise PermissionDenied("must be instructor to regrade flows")

    from course.content import list_flow_ids
    flow_ids = list_flow_ids(pctx.repo, pctx.course_commit_sha)

    request = pctx.request
    if request.method == "POST":
        form = RegradeFlowForm(flow_ids, request.POST, request.FILES)
        if form.is_valid():
            sessions = (FlowSession.objects
                    .filter(
                        course=pctx.course,
                        flow_id=form.cleaned_data["flow_id"],
                        for_credit=False))
            if form.cleaned_data["access_rules_id"]:
                sessions = sessions.filter(
                        access_rules_id=form.cleaned_data["access_rules_id"])

            inprog_value = {
                    "any": None,
                    "yes": True,
                    "no": False,
                    }[form.cleaned_data["regraded_session_in_progress"]]

            if inprog_value is not None:
                sessions = sessions.filter(
                        in_progress=inprog_value)

            count = _regrade_sessions(pctx.repo, pctx.course, sessions)

            messages.add_message(request, messages.SUCCESS,
                    "%d sessions regraded." % count)
    else:
        form = RegradeFlowForm(flow_ids)

    return render_course_page(pctx, "course/generic-course-form.html", {
        "form": form,
        "form_text":
        "<p>This regrading process only considers not-for-credit flow "
        "sessions. If you would like to regrade for-credit flows, "
        "use the corresponding functionality in the grade book.</p>",
        "form_description": "Regrade not-for-credit Flow Sessions",
    })

# }}}

# vim: foldmethod=marker