Exemple #1
0
def get_current_repo_file(request, course_identifier, path):
    course = get_object_or_404(Course, identifier=course_identifier)
    role, participation = get_role_and_participation(request, course)

    from course.views import check_course_state
    check_course_state(course, role)

    from course.content import get_course_commit_sha
    commit_sha = get_course_commit_sha(course, participation)

    role, participation = get_role_and_participation(request, course)

    repo = get_course_repo(course)

    from course.content import is_repo_file_public
    if not is_repo_file_public(repo, commit_sha, path):
        raise PermissionDenied()

    from course.content import get_repo_blob_data_cached

    try:
        data = get_repo_blob_data_cached(repo, path, commit_sha.encode())
    except ObjectDoesNotExist:
        raise http.Http404()

    from mimetypes import guess_type
    content_type, _ = guess_type(path)

    return http.HttpResponse(data, content_type=content_type)
Exemple #2
0
    def __init__(self, repo, course, flow_id,
            participation=None, flow_session=None):
        """*participation* and *flow_session* are not stored and only used
        to figure out versioning of the flow content.
        """

        self.repo = repo
        self.course = course
        self.flow_id = flow_id

        from django.core.exceptions import ObjectDoesNotExist

        self.course_commit_sha = get_course_commit_sha(
                self.course, participation)

        try:
            self.flow_desc = get_flow_desc(self.repo, self.course,
                    flow_id, self.course_commit_sha)
        except ObjectDoesNotExist:
            raise http.Http404()

        if flow_session is not None:
            from course.content import adjust_flow_session_page_data
            adjust_flow_session_page_data(repo, flow_session,
                    course.identifier, self.flow_desc)
Exemple #3
0
    def __init__(self,
                 repo,
                 course,
                 flow_id,
                 participation=None,
                 flow_session=None):
        """*participation* and *flow_session* are not stored and only used
        to figure out versioning of the flow content.
        """

        self.repo = repo
        self.course = course
        self.flow_id = flow_id

        from django.core.exceptions import ObjectDoesNotExist

        self.course_commit_sha = get_course_commit_sha(self.course,
                                                       participation)

        try:
            self.flow_desc = get_flow_desc(self.repo, self.course, flow_id,
                                           self.course_commit_sha)
        except ObjectDoesNotExist:
            raise http.Http404()

        if flow_session is not None:
            from course.content import adjust_flow_session_page_data
            adjust_flow_session_page_data(repo, flow_session,
                                          course.identifier, self.flow_desc)
Exemple #4
0
    def __init__(self, request, course_identifier):
        # type: (http.HttpRequest, Text) -> None

        self.request = request
        self.course_identifier = course_identifier
        self._permissions_cache = None  # type: Optional[FrozenSet[Tuple[Text, Optional[Text]]]]  # noqa
        self._role_identifiers_cache = None  # type: Optional[List[Text]]
        self.old_language = None

        # using this to prevent nested using as context manager
        self._is_in_context_manager = False

        from course.models import Course  # noqa
        self.course = get_object_or_404(Course, identifier=course_identifier)

        from course.enrollment import get_participation_for_request
        self.participation = get_participation_for_request(
            request, self.course)

        from course.views import check_course_state
        check_course_state(self.course, self.participation)

        self.course_commit_sha = get_course_commit_sha(self.course,
                                                       self.participation)

        self.repo = get_course_repo(self.course)

        # logic duplicated in course.content.get_course_commit_sha
        sha = self.course.active_git_commit_sha.encode()

        if self.participation is not None:
            if self.participation.preview_git_commit_sha:
                preview_sha = self.participation.preview_git_commit_sha.encode(
                )

                with get_course_repo(self.course) as repo:
                    from relate.utils import SubdirRepoWrapper
                    if isinstance(repo, SubdirRepoWrapper):
                        true_repo = repo.repo
                    else:
                        true_repo = cast(dulwich.repo.Repo, repo)

                    try:
                        true_repo[preview_sha]
                    except KeyError:
                        from django.contrib import messages
                        messages.add_message(
                            request, messages.ERROR,
                            _("Preview revision '%s' does not exist--"
                              "showing active course content instead.") %
                            preview_sha.decode())

                        preview_sha = None
                    finally:
                        true_repo.close()

                if preview_sha is not None:
                    sha = preview_sha

        self.course_commit_sha = sha
Exemple #5
0
def get_current_repo_file(request, course_identifier, path):
    course = get_object_or_404(Course, identifier=course_identifier)
    role, participation = get_role_and_participation(
            request, course)

    from course.views import check_course_state
    check_course_state(course, role)

    from course.content import get_course_commit_sha
    commit_sha = get_course_commit_sha(course, participation)

    role, participation = get_role_and_participation(request, course)

    repo = get_course_repo(course)

    from course.content import is_repo_file_public
    if not is_repo_file_public(repo, commit_sha, path):
        raise PermissionDenied()

    from course.content import get_repo_blob_data_cached

    try:
        data = get_repo_blob_data_cached(
                repo, path, commit_sha.encode())
    except ObjectDoesNotExist:
        raise http.Http404()

    from mimetypes import guess_type
    content_type, _ = guess_type(path)

    return http.HttpResponse(data, content_type=content_type)
Exemple #6
0
    def __init__(self, request, course_identifier):
        # type: (http.HttpRequest, Text) -> None

        self.request = request
        self.course_identifier = course_identifier
        self._permissions_cache = None  # type: Optional[FrozenSet[Tuple[Text, Optional[Text]]]]  # noqa
        self._role_identifiers_cache = None  # type: Optional[List[Text]]
        self.old_language = None

        # using this to prevent nested using as context manager
        self._is_in_context_manager = False

        from course.models import Course  # noqa
        self.course = get_object_or_404(Course, identifier=course_identifier)

        from course.enrollment import get_participation_for_request
        self.participation = get_participation_for_request(
                request, self.course)

        from course.views import check_course_state
        check_course_state(self.course, self.participation)

        self.course_commit_sha = get_course_commit_sha(
                self.course, self.participation)

        self.repo = get_course_repo(self.course)

        # logic duplicated in course.content.get_course_commit_sha
        sha = self.course.active_git_commit_sha.encode()

        if self.participation is not None:
            if self.participation.preview_git_commit_sha:
                preview_sha = self.participation.preview_git_commit_sha.encode()

                with get_course_repo(self.course) as repo:
                    from relate.utils import SubdirRepoWrapper
                    if isinstance(repo, SubdirRepoWrapper):
                        true_repo = repo.repo
                    else:
                        true_repo = cast(dulwich.repo.Repo, repo)

                    try:
                        true_repo[preview_sha]
                    except KeyError:
                        from django.contrib import messages
                        messages.add_message(request, messages.ERROR,
                                _("Preview revision '%s' does not exist--"
                                "showing active course content instead.")
                                % preview_sha.decode())

                        preview_sha = None
                    finally:
                        true_repo.close()

                if preview_sha is not None:
                    sha = preview_sha

        self.course_commit_sha = sha
Exemple #7
0
def get_current_repo_file(request, course_identifier, path):
    course = get_object_or_404(Course, identifier=course_identifier)
    role, participation = get_role_and_participation(request, course)

    from course.content import get_course_commit_sha
    commit_sha = get_course_commit_sha(course, participation)

    return get_repo_file_backend(request, course, role, participation,
                                 commit_sha, path)
Exemple #8
0
def get_current_repo_file(request, course_identifier, path):
    course = get_object_or_404(Course, identifier=course_identifier)
    role, participation = get_role_and_participation(
            request, course)

    from course.content import get_course_commit_sha
    commit_sha = get_course_commit_sha(course, participation)

    return get_repo_file_backend(
            request, course, role, participation, commit_sha, path)
Exemple #9
0
def get_current_repo_file(request, course_identifier, path):
    # type: (http.HttpRequest, str, str) -> http.HttpResponse

    course = get_object_or_404(Course, identifier=course_identifier)
    participation = get_participation_for_request(request, course)

    from course.content import get_course_commit_sha
    commit_sha = get_course_commit_sha(course, participation)

    return get_repo_file_backend(
            request, course, participation, commit_sha, path)
Exemple #10
0
def current_repo_file_etag_func(request, course_identifier, path):
    course = get_object_or_404(Course, identifier=course_identifier)
    role, participation = get_role_and_participation(request, course)

    from course.views import check_course_state
    check_course_state(course, role)

    from course.content import get_course_commit_sha
    commit_sha = get_course_commit_sha(course, participation)

    return ":".join([course_identifier, commit_sha, path])
Exemple #11
0
def current_repo_file_etag_func(request, course_identifier, path):
    # type: (http.HttpRequest, str, str) -> str
    course = get_object_or_404(Course, identifier=course_identifier)
    participation = get_participation_for_request(request, course)

    check_course_state(course, participation)

    from course.content import get_course_commit_sha
    commit_sha = get_course_commit_sha(course, participation)

    return ":".join([course_identifier, commit_sha.decode(), path])
Exemple #12
0
def get_current_repo_file(request, course_identifier, path):
    # type: (http.HttpRequest, str, str) -> http.HttpResponse

    course = get_object_or_404(Course, identifier=course_identifier)
    participation = get_participation_for_request(request, course)

    from course.content import get_course_commit_sha
    commit_sha = get_course_commit_sha(course, participation)

    return get_repo_file_backend(request, course, participation, commit_sha,
                                 path)
Exemple #13
0
def current_repo_file_etag_func(request, course_identifier, path):
    # type: (http.HttpRequest, str, str) -> str
    course = get_object_or_404(Course, identifier=course_identifier)
    participation = get_participation_for_request(request, course)

    check_course_state(course, participation)

    from course.content import get_course_commit_sha
    commit_sha = get_course_commit_sha(course, participation)

    return ":".join([course_identifier, commit_sha.decode(), path])
Exemple #14
0
def current_repo_file_etag_func(request, course_identifier, path):
    course = get_object_or_404(Course, identifier=course_identifier)
    role, participation = get_role_and_participation(
            request, course)

    from course.views import check_course_state
    check_course_state(course, role)

    from course.content import get_course_commit_sha
    commit_sha = get_course_commit_sha(course, participation)

    return ":".join([course_identifier, commit_sha.decode(), path])
def set_course_metadata(apps, schema_editor):
    Course = apps.get_model("course", "Course")  # noqa
    for course in Course.objects.all():
        from course.content import get_course_repo, get_course_desc, get_course_commit_sha

        repo = get_course_repo(course)
        course_desc = get_course_desc(repo, course, get_course_commit_sha(course, participation=None))

        course.name = course_desc.name
        course.number = course_desc.number
        course.time_period = course_desc.run

        repo.close()
        course.save()
Exemple #16
0
    def clean(self):
        super(FlowRuleException, self).clean()

        if (self.kind == flow_rule_kind.grading
                and self.expiration is not None):
            raise ValidationError(_("grading rules may not expire"))

        from course.validation import (
                ValidationError as ContentValidationError,
                validate_session_start_rule,
                validate_session_access_rule,
                validate_session_grading_rule,
                ValidationContext)
        from course.content import (get_course_repo,
                get_course_commit_sha,
                get_flow_desc)

        from relate.utils import dict_to_struct
        rule = dict_to_struct(self.rule)

        repo = get_course_repo(self.participation.course)
        commit_sha = get_course_commit_sha(
                self.participation.course, self.participation)
        ctx = ValidationContext(
                repo=repo,
                commit_sha=commit_sha)

        flow_desc = get_flow_desc(repo,
                self.participation.course,
                self.flow_id, commit_sha)

        tags = None
        if hasattr(flow_desc, "rules"):
            tags = getattr(flow_desc.rules, "tags", None)

        try:
            if self.kind == flow_rule_kind.start:
                validate_session_start_rule(ctx, unicode(self), rule, tags)
            elif self.kind == flow_rule_kind.access:
                validate_session_access_rule(ctx, unicode(self), rule, tags)
            elif self.kind == flow_rule_kind.grading:
                validate_session_grading_rule(ctx, unicode(self), rule, tags)
            else:
                # the rule refers to FlowRuleException rule
                raise ValidationError(_("invalid rule kind: ")+self.kind)

        except ContentValidationError as e:
            # the rule refers to FlowRuleException rule
            raise ValidationError(_("invalid existing_session_rules: ")+str(e))
Exemple #17
0
    def __init__(self, request, course_identifier):
        self.request = request
        self.course_identifier = course_identifier

        self.course = get_object_or_404(Course, identifier=course_identifier)
        self.role, self.participation = get_role_and_participation(
            request, self.course)

        from course.views import check_course_state
        check_course_state(self.course, self.role)

        self.course_commit_sha = get_course_commit_sha(self.course,
                                                       self.participation)

        self.repo = get_course_repo(self.course)
Exemple #18
0
    def __init__(self, request, course_identifier):
        self.request = request
        self.course_identifier = course_identifier

        self.course = get_object_or_404(Course, identifier=course_identifier)
        self.role, self.participation = get_role_and_participation(
                request, self.course)

        from course.views import check_course_state
        check_course_state(self.course, self.role)

        self.course_commit_sha = get_course_commit_sha(
                self.course, self.participation)

        self.repo = get_course_repo(self.course)
Exemple #19
0
    def __init__(self, request, course_identifier):
        self.request = request
        self.course_identifier = course_identifier

        from course.models import Course
        self.course = get_object_or_404(Course, identifier=course_identifier)

        from course.views import get_role_and_participation
        self.role, self.participation = get_role_and_participation(
                request, self.course)

        from course.views import check_course_state
        check_course_state(self.course, self.role)

        self.course_commit_sha = get_course_commit_sha(
                self.course, self.participation)

        self.repo = get_course_repo(self.course)

        # logic duplicated in course.content.get_course_commit_sha
        sha = self.course.active_git_commit_sha.encode()

        if (self.participation is not None
                and self.participation.preview_git_commit_sha):
            preview_sha = self.participation.preview_git_commit_sha.encode()

            repo = get_course_repo(self.course)

            from course.content import SubdirRepoWrapper
            if isinstance(repo, SubdirRepoWrapper):
                repo = repo.repo

            try:
                repo[preview_sha]
            except KeyError:
                from django.contrib import messages
                messages.add_message(request, messages.ERROR,
                        _("Preview revision '%s' does not exist--"
                        "showing active course content instead.")
                        % preview_sha.decode())

                preview_sha = None

            if preview_sha is not None:
                sha = preview_sha

        self.course_commit_sha = sha
Exemple #20
0
def set_course_metadata(apps, schema_editor):
    Course = apps.get_model("course", "Course")  # noqa
    for course in Course.objects.all():
        from course.content import (
                get_course_repo, get_course_desc,
                get_course_commit_sha)

        repo = get_course_repo(course)
        course_desc = get_course_desc(
                repo, course,
                get_course_commit_sha(course, participation=None))

        course.name = course_desc.name
        course.number = course_desc.number
        course.time_period = course_desc.run

        repo.close()
        course.save()
Exemple #21
0
def start_flow(repo, course, participation, flow_id, flow_desc, access_rules_tag, now_datetime):
    from course.content import get_course_commit_sha

    course_commit_sha = get_course_commit_sha(course, participation)

    session = FlowSession(
        course=course,
        participation=participation,
        active_git_commit_sha=course_commit_sha.decode(),
        flow_id=flow_id,
        in_progress=True,
        expiration_mode=flow_session_expiration_mode.end,
        access_rules_tag=access_rules_tag,
    )

    session.save()

    # Create flow grading opportunity. This makes the flow
    # show up in the grade book.

    from course.utils import get_flow_rules
    from course.models import get_flow_grading_opportunity

    for grading_rule in get_flow_rules(
        flow_desc, flow_rule_kind.grading, participation, flow_id, now_datetime, consider_exceptions=False
    ):
        identifier = getattr(grading_rule, "grade_identifier", None)
        if identifier is not None:
            get_flow_grading_opportunity(
                course,
                flow_id,
                flow_desc,
                FlowSessionGradingRule(
                    grade_identifier=identifier,
                    grade_aggregation_strategy=getattr(grading_rule, "grade_aggregation_strategy"),
                ),
            )

    # will implicitly modify and save the session if there are changes
    from course.content import adjust_flow_session_page_data

    adjust_flow_session_page_data(repo, session, course.identifier, flow_desc, course_commit_sha)

    return session
Exemple #22
0
    def __init__(self, repo, course, flow_identifier,
            participation=None, flow_session=None):
        """*participation* and *flow_session* are not stored and only used
        to figure out versioning of the flow content.
        """

        self.repo = repo
        self.course = course
        self.flow_identifier = flow_identifier

        from course.content import get_flow_commit_sha
        from django.core.exceptions import ObjectDoesNotExist

        # Fetch 'current' version of the flow to compute permissions
        # and versioning rules.
        # Fall back to 'old' version if current git version does not
        # contain this flow any more.

        self.course_commit_sha = get_course_commit_sha(
                self.course, participation)

        try:
            current_flow_desc_sha = self.course_commit_sha
            self.current_flow_desc = get_flow_desc(self.repo, self.course,
                    flow_identifier, current_flow_desc_sha)
        except ObjectDoesNotExist:
            if flow_session is None:
                raise http.Http404()

            current_flow_desc_sha = flow_session.active_git_commit_sha.encode()
            self.current_flow_desc = get_flow_desc(self.repo, self.course,
                    flow_identifier, current_flow_desc_sha)

        self.flow_commit_sha = get_flow_commit_sha(
                self.course, participation,
                self.current_flow_desc, flow_session)

        if self.flow_commit_sha == current_flow_desc_sha:
            self.flow_desc = self.current_flow_desc
        else:
            self.flow_desc = get_flow_desc(self.repo, self.course,
                flow_identifier, self.flow_commit_sha)
Exemple #23
0
    def __init__(self, repo, course, flow_id, participation=None):
        # type: (Repo_ish, Course, Text, Optional[Participation]) -> None
        """*participation* and *flow_session* are not stored and only used
        to figure out versioning of the flow content.
        """

        self.repo = repo
        self.course = course
        self.flow_id = flow_id

        from django.core.exceptions import ObjectDoesNotExist

        self.course_commit_sha = get_course_commit_sha(self.course,
                                                       participation)

        try:
            self.flow_desc = get_flow_desc(self.repo, self.course, flow_id,
                                           self.course_commit_sha)
        except ObjectDoesNotExist:
            raise http.Http404()
Exemple #24
0
    def clean(self):
        if (self.kind == flow_rule_kind.grading
                and self.expiration is not None):
            raise ValidationError("grading rules may not expire")

        from course.validation import (ValidationError as
                                       ContentValidationError,
                                       validate_session_start_rule,
                                       validate_session_access_rule,
                                       validate_session_grading_rule,
                                       ValidationContext)
        from course.content import (get_course_repo, get_course_commit_sha,
                                    get_flow_desc)

        from relate.utils import dict_to_struct
        rule = dict_to_struct(self.rule)

        repo = get_course_repo(self.participation.course)
        commit_sha = get_course_commit_sha(self.participation.course,
                                           self.participation)
        ctx = ValidationContext(repo=repo, commit_sha=commit_sha)

        flow_desc = get_flow_desc(repo, self.participation.course,
                                  self.flow_id, commit_sha)

        tags = None
        if hasattr(flow_desc, "rules"):
            tags = getattr(flow_desc.rules, "tags", None)

        try:
            if self.kind == flow_rule_kind.start:
                validate_session_start_rule(ctx, unicode(self), rule, tags)
            elif self.kind == flow_rule_kind.access:
                validate_session_access_rule(ctx, unicode(self), rule, tags)
            elif self.kind == flow_rule_kind.grading:
                validate_session_grading_rule(ctx, unicode(self), rule, tags)
            else:
                raise ValidationError("invalid rule kind: " + self.kind)

        except ContentValidationError as e:
            raise ValidationError("invalid existing_session_rules: " + str(e))
Exemple #25
0
    def __init__(self, repo, course, flow_id, participation=None):
        # type: (Repo_ish, Course, Text, Optional[Participation]) -> None

        """*participation* and *flow_session* are not stored and only used
        to figure out versioning of the flow content.
        """

        self.repo = repo
        self.course = course
        self.flow_id = flow_id

        from django.core.exceptions import ObjectDoesNotExist

        self.course_commit_sha = get_course_commit_sha(
                self.course, participation)

        try:
            self.flow_desc = get_flow_desc(self.repo, self.course,
                    flow_id, self.course_commit_sha)
        except ObjectDoesNotExist:
            raise http.Http404()
Exemple #26
0
    def __init__(self, request, course_identifier):
        # type: (http.HttpRequest, Text) -> None

        self.request = request
        self.course_identifier = course_identifier
        self._permissions_cache = None  # type: Optional[FrozenSet[Tuple[Text, Optional[Text]]]]  # noqa
        self._role_identifiers_cache = None  # type: Optional[List[Text]]
        self.old_language = None

        # using this to prevent nested using as context manager
        self._is_in_context_manager = False

        from course.models import Course  # noqa
        self.course = get_object_or_404(Course, identifier=course_identifier)

        from course.enrollment import get_participation_for_request
        self.participation = get_participation_for_request(
            request, self.course)

        from course.views import check_course_state
        check_course_state(self.course, self.participation)

        self.repo = get_course_repo(self.course)

        try:
            sha = get_course_commit_sha(
                self.course,
                self.participation,
                repo=self.repo,
                raise_on_nonexistent_preview_commit=True)
        except CourseCommitSHADoesNotExist as e:
            from django.contrib import messages
            messages.add_message(request, messages.ERROR, str(e))

            sha = self.course.active_git_commit_sha.encode()

        self.course_commit_sha = sha
Exemple #27
0
    def __init__(self, request, course_identifier):
        # type: (http.HttpRequest, Text) -> None

        self.request = request
        self.course_identifier = course_identifier
        self._permissions_cache = None  # type: Optional[FrozenSet[Tuple[Text, Optional[Text]]]]  # noqa
        self._role_identifiers_cache = None  # type: Optional[List[Text]]
        self.old_language = None

        # using this to prevent nested using as context manager
        self._is_in_context_manager = False

        from course.models import Course  # noqa
        self.course = get_object_or_404(Course, identifier=course_identifier)

        from course.enrollment import get_participation_for_request
        self.participation = get_participation_for_request(
                request, self.course)

        from course.views import check_course_state
        check_course_state(self.course, self.participation)

        self.repo = get_course_repo(self.course)

        try:
            sha = get_course_commit_sha(
                self.course, self.participation,
                repo=self.repo,
                raise_on_nonexistent_preview_commit=True)
        except CourseCommitSHADoesNotExist as e:
            from django.contrib import messages
            messages.add_message(request, messages.ERROR, str(e))

            sha = self.course.active_git_commit_sha.encode()

        self.course_commit_sha = sha
Exemple #28
0
def _get_current_access_rule(participation, flow_id):
    course = participation.course

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

    repo = get_course_repo(course)

    course_commit_sha = get_course_commit_sha(course, participation)

    try:
        flow_desc = get_flow_desc(repo, course,
                flow_id.encode(), course_commit_sha)
    except ObjectDoesNotExist:
        return None
    else:
        from course.utils import get_current_flow_access_rule
        from django.utils.timezone import now

        return get_current_flow_access_rule(course, participation,
                participation.role, flow_id, flow_desc,
                now(), rule_id=None, use_exceptions=False)
Exemple #29
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 #30
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()