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
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)
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)
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
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)
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
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
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
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
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
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()
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)
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