Exemple #1
0
    def __init__(self, request, course_identifier, flow_identifier,
            ordinal, flow_session):
        FlowContext.__init__(self, request, course_identifier, flow_identifier,
                flow_session=flow_session)

        from course.models import FlowPageData
        page_data = self.page_data = get_object_or_404(
                FlowPageData, flow_session=flow_session, ordinal=ordinal)

        from course.content import get_flow_page_desc
        self.page_desc = get_flow_page_desc(
                flow_session, self.flow_desc, page_data.group_id, page_data.page_id)

        self.page = instantiate_flow_page_with_ctx(self, page_data)

        from course.page import PageContext
        self.page_context = PageContext(
                course=self.course, repo=self.repo, commit_sha=self.flow_commit_sha)

        # {{{ dig for previous answers

        from course.flow import get_flow_session_graded_answers_qset
        previous_answer_visits = (
                get_flow_session_graded_answers_qset(flow_session)
                .filter(page_data=page_data)
                .order_by("-visit_time"))

        self.prev_answer_visit = None
        for prev_visit in previous_answer_visits[:1]:
            self.prev_answer_visit = prev_visit
Exemple #2
0
def instantiate_flow_page_with_ctx(fctx, page_data):
    from course.content import get_flow_page_desc
    page_desc = get_flow_page_desc(fctx.flow_id, fctx.flow_desc,
                                   page_data.group_id, page_data.page_id)

    from course.content import instantiate_flow_page
    return instantiate_flow_page(
        "course '%s', flow '%s', page '%s/%s'" %
        (fctx.course.identifier, fctx.flow_id, page_data.group_id,
         page_data.page_id), fctx.repo, page_desc, fctx.course_commit_sha)
Exemple #3
0
def instantiate_flow_page_with_ctx(fctx, page_data):
    from course.content import get_flow_page_desc
    page_desc = get_flow_page_desc(
            fctx.flow_session, fctx.flow_desc, page_data.group_id, page_data.page_id)

    from course.content import instantiate_flow_page
    return instantiate_flow_page(
            "course '%s', flow '%s', page '%s/%s'"
            % (fctx.course_identifier, fctx.flow_identifier,
                page_data.group_id, page_data.page_id),
            fctx.repo, page_desc, fctx.flow_commit_sha)
Exemple #4
0
    def __init__(self,
                 repo,
                 course,
                 flow_id,
                 ordinal,
                 participation,
                 flow_session,
                 request=None):
        FlowContext.__init__(self,
                             repo,
                             course,
                             flow_id,
                             participation,
                             flow_session=flow_session)

        from course.content import adjust_flow_session_page_data
        adjust_flow_session_page_data(repo, flow_session, course.identifier,
                                      self.flow_desc)

        if ordinal >= flow_session.page_count:
            raise PageOrdinalOutOfRange()

        from course.models import FlowPageData
        page_data = self.page_data = get_object_or_404(
            FlowPageData, flow_session=flow_session, ordinal=ordinal)

        from course.content import get_flow_page_desc
        try:
            self.page_desc = get_flow_page_desc(flow_session, self.flow_desc,
                                                page_data.group_id,
                                                page_data.page_id)
        except ObjectDoesNotExist:
            self.page_desc = None
            self.page = None
            self.page_context = None
        else:
            self.page = instantiate_flow_page_with_ctx(self, page_data)

            page_uri = None
            if request is not None:
                from django.core.urlresolvers import reverse
                page_uri = request.build_absolute_uri(
                    reverse("relate-view_flow_page",
                            args=(course.identifier, flow_session.id,
                                  ordinal)))

            from course.page import PageContext
            self.page_context = PageContext(course=self.course,
                                            repo=self.repo,
                                            commit_sha=self.course_commit_sha,
                                            flow_session=flow_session,
                                            page_uri=page_uri)

        self._prev_answer_visit = False
Exemple #5
0
def instantiate_flow_page_with_ctx(fctx, page_data):
    # type: (FlowContext, FlowPageData) -> PageBase

    from course.content import get_flow_page_desc
    page_desc = get_flow_page_desc(
            fctx.flow_id, fctx.flow_desc,
            page_data.group_id, page_data.page_id)

    from course.content import instantiate_flow_page
    return instantiate_flow_page(
            "course '%s', flow '%s', page '%s/%s'"
            % (fctx.course.identifier, fctx.flow_id,
                page_data.group_id, page_data.page_id),
            fctx.repo, page_desc, fctx.course_commit_sha)
Exemple #6
0
    def __init__(
            self,
            repo,  # type: Repo_ish
            course,  # type: Course
            flow_id,  # type: Text
            page_ordinal,  # type: int
            participation,  # type: Optional[Participation]
            flow_session,  # type: FlowSession
            request=None,  # type: Optional[http.HttpRequest]
    ):
        # type: (...) -> None
        super(FlowPageContext, self).__init__(repo, course, flow_id,
                                              participation)

        if page_ordinal >= flow_session.page_count:
            raise PageOrdinalOutOfRange()

        from course.models import FlowPageData  # noqa
        page_data = self.page_data = get_object_or_404(
            FlowPageData, flow_session=flow_session, page_ordinal=page_ordinal)

        from course.content import get_flow_page_desc
        try:
            self.page_desc = get_flow_page_desc(
                flow_session.flow_id, self.flow_desc, page_data.group_id,
                page_data.page_id)  # type: Optional[FlowPageDesc]
        except ObjectDoesNotExist:
            self.page_desc = None
            self.page = None  # type: Optional[PageBase]
            self.page_context = None  # type: Optional[PageContext]
        else:
            self.page = instantiate_flow_page_with_ctx(self, page_data)

            page_uri = None
            if request is not None:
                from django.urls import reverse
                page_uri = request.build_absolute_uri(
                    reverse("relate-view_flow_page",
                            args=(course.identifier, flow_session.id,
                                  page_ordinal)))

            self.page_context = PageContext(course=self.course,
                                            repo=self.repo,
                                            commit_sha=self.course_commit_sha,
                                            flow_session=flow_session,
                                            page_uri=page_uri)

        self._prev_answer_visit = False
Exemple #7
0
    def __init__(
            self,
            repo,  # type: Repo_ish
            course,  # type: Course
            flow_id,  # type: Text
            page_ordinal,  # type: int
            participation,  # type: Optional[Participation]
            flow_session,  # type: FlowSession
            request=None,  # type: Optional[http.HttpRequest]
            ):
        # type: (...) -> None
        super(FlowPageContext, self).__init__(repo, course, flow_id, participation)

        if page_ordinal >= flow_session.page_count:
            raise PageOrdinalOutOfRange()

        from course.models import FlowPageData  # noqa
        page_data = self.page_data = get_object_or_404(
                FlowPageData, flow_session=flow_session, page_ordinal=page_ordinal)

        from course.content import get_flow_page_desc
        try:
            self.page_desc = get_flow_page_desc(
                    flow_session.flow_id, self.flow_desc, page_data.group_id,
                    page_data.page_id)  # type: Optional[FlowPageDesc]
        except ObjectDoesNotExist:
            self.page_desc = None
            self.page = None  # type: Optional[PageBase]
            self.page_context = None  # type: Optional[PageContext]
        else:
            self.page = instantiate_flow_page_with_ctx(self, page_data)

            page_uri = None
            if request is not None:
                from django.urls import reverse
                page_uri = request.build_absolute_uri(
                    reverse(
                        "relate-view_flow_page",
                        args=(course.identifier, flow_session.id, page_ordinal)))

            self.page_context = PageContext(
                    course=self.course, repo=self.repo,
                    commit_sha=self.course_commit_sha,
                    flow_session=flow_session,
                    page_uri=page_uri)

        self._prev_answer_visit = False
Exemple #8
0
    def __init__(self, repo, course, flow_id, ordinal,
             participation, flow_session, request=None):
        FlowContext.__init__(self, repo, course, flow_id,
                participation, flow_session=flow_session)

        from course.content import adjust_flow_session_page_data
        adjust_flow_session_page_data(repo, flow_session,
                course.identifier, self.flow_desc)

        if ordinal >= flow_session.page_count:
            raise PageOrdinalOutOfRange()

        from course.models import FlowPageData
        page_data = self.page_data = get_object_or_404(
                FlowPageData, flow_session=flow_session, ordinal=ordinal)

        from course.content import get_flow_page_desc
        try:
            self.page_desc = get_flow_page_desc(
                    flow_session, self.flow_desc, page_data.group_id,
                    page_data.page_id)
        except ObjectDoesNotExist:
            self.page_desc = None
            self.page = None
            self.page_context = None
        else:
            self.page = instantiate_flow_page_with_ctx(self, page_data)

            page_uri = None
            if request is not None:
                from django.core.urlresolvers import reverse
                page_uri = request.build_absolute_uri(
                        reverse("relate-view_flow_page",
                            args=(course.identifier, flow_session.id, ordinal)))

            from course.page import PageContext
            self.page_context = PageContext(
                    course=self.course, repo=self.repo,
                    commit_sha=self.course_commit_sha,
                    flow_session=flow_session,
                    page_uri=page_uri)

        self._prev_answer_visit = False
Exemple #9
0
    def get_page(self, group_id, page_id, commit_sha):
        key = (group_id, page_id, commit_sha)
        try:
            return self.page_cache[key]
        except KeyError:

            from course.content import get_flow_page_desc, instantiate_flow_page
            page_desc = get_flow_page_desc(
                    self.flow_id,
                    self.get_flow_desc_from_cache(commit_sha),
                    group_id, page_id)

            page = instantiate_flow_page(
                    location="flow '%s', group, '%s', page '%s'"
                    % (self.flow_id, group_id, page_id),
                    repo=self.repo, page_desc=page_desc,
                    commit_sha=commit_sha)

            self.page_cache[key] = page
            return page
Exemple #10
0
    def get_page(self, group_id, page_id, commit_sha):
        key = (group_id, page_id, commit_sha)
        try:
            return self.page_cache[key]
        except KeyError:

            from course.content import get_flow_page_desc, instantiate_flow_page
            page_desc = get_flow_page_desc(
                    self.flow_id,
                    self.get_flow_desc_from_cache(commit_sha),
                    group_id, page_id)

            page = instantiate_flow_page(
                    location="flow '%s', group, '%s', page '%s'"
                    % (self.flow_id, group_id, page_id),
                    repo=self.repo, page_desc=page_desc,
                    commit_sha=commit_sha)

            self.page_cache[key] = page
            return page
Exemple #11
0
    def __init__(self, repo, course, flow_id, ordinal, participation,
                 flow_session):
        FlowContext.__init__(self,
                             repo,
                             course,
                             flow_id,
                             participation,
                             flow_session=flow_session)

        from course.content import adjust_flow_session_page_data
        adjust_flow_session_page_data(repo, flow_session, course.identifier,
                                      self.flow_desc, self.course_commit_sha)

        if ordinal >= flow_session.page_count:
            raise PageOrdinalOutOfRange()

        from course.models import FlowPageData
        page_data = self.page_data = get_object_or_404(
            FlowPageData, flow_session=flow_session, ordinal=ordinal)

        from course.content import get_flow_page_desc
        try:
            self.page_desc = get_flow_page_desc(flow_session, self.flow_desc,
                                                page_data.group_id,
                                                page_data.page_id)
        except ObjectDoesNotExist:
            self.page_desc = None
            self.page = None
            self.page_context = None
        else:
            self.page = instantiate_flow_page_with_ctx(self, page_data)

            from course.page import PageContext
            self.page_context = PageContext(course=self.course,
                                            repo=self.repo,
                                            commit_sha=self.course_commit_sha,
                                            flow_session=flow_session)

        self._prev_answer_visit = False
Exemple #12
0
def grade_page_visit(visit, visit_grade_model=FlowPageVisitGrade,
        grade_data=None, graded_at_git_commit_sha=None):
    if not visit.is_graded_answer:
        raise RuntimeError("cannot grade ungraded answer")

    flow_session = visit.flow_session
    course = flow_session.course
    page_data = visit.page_data

    from course.content import (
            get_course_repo,
            get_course_commit_sha,
            get_flow_commit_sha,
            get_flow_desc,
            get_flow_page_desc,
            instantiate_flow_page)

    repo = get_course_repo(course)

    course_commit_sha = get_course_commit_sha(
            course, flow_session.participation)

    flow_desc_pre = get_flow_desc(repo, course,
            flow_session.flow_id, course_commit_sha)

    flow_commit_sha = get_flow_commit_sha(
            course, flow_session.participation, flow_desc_pre,
            visit.flow_session)

    flow_desc = get_flow_desc(repo, course,
            flow_session.flow_id, flow_commit_sha)

    page_desc = get_flow_page_desc(
            flow_session.flow_id,
            flow_desc,
            page_data.group_id, page_data.page_id)

    page = instantiate_flow_page(
            location="flow '%s', group, '%s', page '%s'"
            % (flow_session.flow_id, page_data.group_id, page_data.page_id),
            repo=repo, page_desc=page_desc,
            commit_sha=flow_commit_sha)

    from course.page import PageContext
    grading_page_context = PageContext(
            course=course,
            repo=repo,
            commit_sha=flow_commit_sha)

    answer_feedback = page.grade(
            grading_page_context, visit.page_data.data,
            visit.answer, grade_data=grade_data)

    grade = visit_grade_model()
    grade.visit = visit
    grade.grade_data = grade_data
    grade.max_points = page.max_points(visit.page_data)
    grade.graded_at_git_commit_sha = graded_at_git_commit_sha

    if answer_feedback is not None:
        grade.correctness = answer_feedback.correctness
        grade.feedback = answer_feedback.as_json()

    grade.save()
Exemple #13
0
def grade_page_visit(visit, visit_grade_model=FlowPageVisitGrade, grade_data=None, graded_at_git_commit_sha=None):
    if not visit.is_submitted_answer:
        raise RuntimeError(_("cannot grade ungraded answer"))

    flow_session = visit.flow_session
    course = flow_session.course
    page_data = visit.page_data

    most_recent_grade = visit.get_most_recent_grade()
    if most_recent_grade is not None and grade_data is None:
        grade_data = most_recent_grade.grade_data

    from course.content import (
        get_course_repo,
        get_course_commit_sha,
        get_flow_desc,
        get_flow_page_desc,
        instantiate_flow_page,
    )

    repo = get_course_repo(course)

    course_commit_sha = get_course_commit_sha(course, flow_session.participation)

    flow_desc = get_flow_desc(repo, course, flow_session.flow_id, course_commit_sha)

    page_desc = get_flow_page_desc(flow_session.flow_id, flow_desc, page_data.group_id, page_data.page_id)

    page = instantiate_flow_page(
        location="flow '%s', group, '%s', page '%s'" % (flow_session.flow_id, page_data.group_id, page_data.page_id),
        repo=repo,
        page_desc=page_desc,
        commit_sha=course_commit_sha,
    )

    assert page.expects_answer()
    if not page.is_answer_gradable():
        return

    from course.page import PageContext

    grading_page_context = PageContext(
        course=course, repo=repo, commit_sha=course_commit_sha, flow_session=flow_session
    )

    answer_feedback = page.grade(grading_page_context, visit.page_data.data, visit.answer, grade_data=grade_data)

    grade = visit_grade_model()
    grade.visit = visit
    grade.grade_data = grade_data
    grade.max_points = page.max_points(visit.page_data)
    grade.graded_at_git_commit_sha = graded_at_git_commit_sha

    bulk_feedback_json = None
    if answer_feedback is not None:
        grade.correctness = answer_feedback.correctness
        grade.feedback, bulk_feedback_json = answer_feedback.as_json()

    grade.save()

    update_bulk_feedback(page_data, grade, bulk_feedback_json)
Exemple #14
0
def convert_flow_page_visit(stderr, fpv):
    course = fpv.flow_session.course

    from course.content import (get_course_repo, get_flow_desc,
                                get_flow_page_desc, instantiate_flow_page)
    repo = get_course_repo(course)
    flow_id = fpv.flow_session.flow_id
    commit_sha = course.active_git_commit_sha.encode()
    try:
        flow_desc = get_flow_desc(repo,
                                  course,
                                  flow_id,
                                  commit_sha,
                                  tolerate_tabs=True)
    except ObjectDoesNotExist:
        stderr.write("warning: no flow yaml file found for '%s' in '%s'" %
                     (flow_id, course.identifier))
        return

    try:
        page_desc = get_flow_page_desc(fpv.flow_session.flow_id, flow_desc,
                                       fpv.page_data.group_id,
                                       fpv.page_data.page_id)
    except ObjectDoesNotExist:
        stderr.write(
            f"warning: flow page visit {fpv.id}: no page yaml desc "
            "found for "
            f"'{flow_id}:{fpv.page_data.group_id}/{fpv.page_data.page_id}' "
            f"in '{course.identifier}'")
        return

    page = instantiate_flow_page(
        location="flow '%s', group, '%s', page '%s'" %
        (flow_id, fpv.page_data.group_id, fpv.page_data.page_id),
        repo=repo,
        page_desc=page_desc,
        commit_sha=commit_sha)

    from course.page.base import PageContext
    pctx = PageContext(course=course,
                       repo=repo,
                       commit_sha=commit_sha,
                       flow_session=fpv.flow_session,
                       page_uri=None)

    from course.page.upload import FileUploadQuestion
    from course.page.code import CodeQuestion

    if isinstance(page, FileUploadQuestion):
        content, mime_type = page.get_content_from_answer_data(fpv.answer)

        from django.core.files.base import ContentFile
        answer_data = page.file_to_answer_data(pctx, ContentFile(content),
                                               mime_type)
        fpv.answer = answer_data
        fpv.save()

        return True

    elif isinstance(page, CodeQuestion):
        code = page.get_code_from_answer_data(fpv.answer)
        answer_data = page.code_to_answer_data(pctx, code)
        fpv.answer = answer_data
        fpv.save()

        return True
    else:
        return False

    assert False