コード例 #1
0
 def create_module(descriptor):
     '''creates an XModule instance given a descriptor'''
     # TODO: We need the request to pass into here. If we could forego that, our arguments
     # would be simpler
     with manual_transaction():
         field_data_cache = FieldDataCache([descriptor], course.id, student)
     return get_module_for_descriptor(student, request, descriptor, field_data_cache, course.id)
コード例 #2
0
ファイル: courses.py プロジェクト: xiandiancloud/edx-platform
def get_course_info_section(request, course, section_key):
    """
    This returns the snippet of html to be rendered on the course info page,
    given the key for the section.

    Valid keys:
    - handouts
    - guest_handouts
    - updates
    - guest_updates
    """
    usage_key = course.id.make_usage_key('course_info', section_key)

    # Use an empty cache
    field_data_cache = FieldDataCache([], course.id, request.user)
    info_module = get_module(request.user,
                             request,
                             usage_key,
                             field_data_cache,
                             log_if_not_found=False,
                             wrap_xmodule_display=False,
                             static_asset_path=course.static_asset_path)

    html = ''

    if info_module is not None:
        try:
            html = info_module.render(STUDENT_VIEW).content
        except Exception:  # pylint: disable=broad-except
            html = render_to_string('courseware/error-message.html', None)
            log.exception(
                u"Error rendering course={course}, section_key={section_key}".
                format(course=course, section_key=section_key))

    return html
コード例 #3
0
ファイル: courses.py プロジェクト: praveen-pal/edx-platform
def get_course_info_section(request, course, section_key):
    """
    This returns the snippet of html to be rendered on the course info page,
    given the key for the section.

    Valid keys:
    - handouts
    - guest_handouts
    - updates
    - guest_updates
    """


    loc = Location(course.location.tag, course.location.org, course.location.course, 'course_info', section_key)

    # Use an empty cache
    field_data_cache = FieldDataCache([], course.id, request.user)
    info_module = get_module(
        request.user,
        request,
        loc,
        field_data_cache,
        course.id,
        wrap_xmodule_display=False,
        static_asset_path=course.static_asset_path
    )

    html = ''

    if info_module is not None:
        html = info_module.runtime.render(info_module, None, 'student_view').content

    return html
コード例 #4
0
 def setUp(self):
     super(TestInvalidScopes, self).setUp()
     self.user = UserFactory.create(username='******')
     self.field_data_cache = FieldDataCache(
         [mock_descriptor([mock_field(Scope.user_state, 'a_field')])],
         course_id, self.user)
     self.kvs = DjangoKeyValueStore(self.field_data_cache)
コード例 #5
0
ファイル: courses.py プロジェクト: mmoralesf/edx-fullstack
def get_course_info_section_module(request, course, section_key):
    """
    This returns the course info module for a given section_key.

    Valid keys:
    - handouts
    - guest_handouts
    - updates
    - guest_updates
    """
    usage_key = course.id.make_usage_key('course_info', section_key)

    # Use an empty cache
    field_data_cache = FieldDataCache([], course.id, request.user)

    return get_module(
        request.user,
        request,
        usage_key,
        field_data_cache,
        log_if_not_found=False,
        wrap_xmodule_display=False,
        static_asset_path=course.static_asset_path,
        course=course
    )
コード例 #6
0
def edxnotes_visibility(request, course_id):
    """
    Handle ajax call from "Show notes" checkbox.
    """
    course_key = CourseKey.from_string(course_id)
    course = get_course_with_access(request.user, "load", course_key)
    field_data_cache = FieldDataCache([course], course_key, request.user)
    course_module = get_module_for_descriptor(request.user,
                                              request,
                                              course,
                                              field_data_cache,
                                              course_key,
                                              course=course)

    if not is_feature_enabled(course, request.user):
        raise Http404

    try:
        visibility = json.loads(request.body)["visibility"]
        course_module.edxnotes_visibility = visibility
        course_module.save()
        return JsonResponse(status=200)
    except (ValueError, KeyError):
        log.warning(
            "Could not decode request body as JSON and find a boolean visibility field: '%s'",
            request.body)
        return JsonResponseBadRequest()
コード例 #7
0
ファイル: courses.py プロジェクト: smarnach/edx-platform
 def inner_get_module(descriptor):
     """
     Delegate to get_module_for_descriptor.
     """
     field_data_cache = FieldDataCache([descriptor], course.id,
                                       request.user)
     return get_module_for_descriptor(request.user, request, descriptor,
                                      field_data_cache, course.id)
コード例 #8
0
def get_course_child_content(request, user, course_key, child_descriptor):
    """
    Returns course child content
    """
    field_data_cache = FieldDataCache([child_descriptor], course_key, user)
    child_content = module_render.get_module_for_descriptor(
        user, request, child_descriptor, field_data_cache, course_key)
    return child_content
コード例 #9
0
def get_course_content(request, user, course_key, course_descriptor):  # pylint: disable=W0613
    """
    Returns course content
    """
    field_data_cache = FieldDataCache([course_descriptor], course_key, user)
    course_content = module_render.get_module_for_descriptor(
        user, request, course_descriptor, field_data_cache, course_key)
    return course_content
コード例 #10
0
 def _get_course_module(self):
     """
     Returns the course module.
     """
     field_data_cache = FieldDataCache([self.course], self.course.id,
                                       self.user)
     return get_module_for_descriptor(self.user, MagicMock(), self.course,
                                      field_data_cache, self.course.id)
コード例 #11
0
 def setUp(self):
     self.user = UserFactory.create(username='******')
     self.assertEqual(
         self.user.id,
         1)  # check our assumption hard-coded in the key functions above.
     self.field_data_cache = FieldDataCache([mock_descriptor()], course_id,
                                            self.user)
     self.kvs = DjangoKeyValueStore(self.field_data_cache)
コード例 #12
0
def get_module_for_student(student, course, location):
    """Return the module for the (student, location) using a DummyRequest."""
    request = DummyRequest()
    request.user = student

    descriptor = modulestore().get_instance(course.id, location, depth=0)
    field_data_cache = FieldDataCache([descriptor], course.id, student)
    return get_module(student, request, location, field_data_cache, course.id)
コード例 #13
0
 def inner_get_module(descriptor):
     """
     Delegate to get_module_for_descriptor (imported here to avoid circular reference)
     """
     from courseware.module_render import get_module_for_descriptor
     field_data_cache = FieldDataCache([descriptor], course.id,
                                       request.user)
     return get_module_for_descriptor(request.user, request, descriptor,
                                      field_data_cache, course.id)
コード例 #14
0
def get_module_for_student(student, usage_key, request=None):
    """Return the module for the (student, location) using a DummyRequest."""
    if request is None:
        request = DummyRequest()
        request.user = student

    descriptor = modulestore().get_item(usage_key, depth=0)
    field_data_cache = FieldDataCache([descriptor], usage_key.course_key,
                                      student)
    return get_module(student, request, usage_key, field_data_cache)
コード例 #15
0
 def setUp(self):
     field_storage = self.factory.create()
     if hasattr(field_storage, 'student'):
         self.user = field_storage.student
     else:
         self.user = UserFactory.create()
     self.mock_descriptor = mock_descriptor([
         mock_field(self.scope, 'existing_field'),
         mock_field(self.scope, 'other_existing_field')])
     self.field_data_cache = FieldDataCache([self.mock_descriptor], course_id, self.user)
     self.kvs = DjangoKeyValueStore(self.field_data_cache)
コード例 #16
0
ファイル: grades.py プロジェクト: dbaiying/ANALYSE-v1
 def inner_get_module(descriptor):
     """
     Delegate to get_module_for_descriptor
     """
     field_data_cache = FieldDataCache([descriptor], course.id, user)
     return get_module_for_descriptor(user,
                                      _get_mock_request(user),
                                      descriptor,
                                      field_data_cache,
                                      course.id,
                                      course=course)
コード例 #17
0
 def setUp(self):
     student_module = StudentModuleFactory(
         state=json.dumps({
             'a_field': 'a_value',
             'b_field': 'b_value'
         }))
     self.user = student_module.student
     self.field_data_cache = FieldDataCache(
         [mock_descriptor([mock_field(Scope.user_state, 'a_field')])],
         course_id, self.user)
     self.kvs = DjangoKeyValueStore(self.field_data_cache)
コード例 #18
0
 def test_rebinding_same_user(self, block_type):
     request = self.request_factory.get('')
     request.user = self.mock_user
     course = CourseFactory()
     descriptor = ItemFactory(category=block_type, parent=course)
     field_data_cache = FieldDataCache([self.toy_course, descriptor],
                                       self.toy_course.id, self.mock_user)
     render.get_module_for_descriptor(self.mock_user, request, descriptor,
                                      field_data_cache, self.toy_course.id)
     render.get_module_for_descriptor(self.mock_user, request, descriptor,
                                      field_data_cache, self.toy_course.id)
コード例 #19
0
    def test_changing_position_works(self):
        # Make a mock FieldDataCache for this course, so we can get the course module
        mock_field_data_cache = FieldDataCache([self.course], self.course.id,
                                               self.student)
        course = get_module_for_descriptor(self.student,
                                           MagicMock(name='request'),
                                           self.course, mock_field_data_cache,
                                           self.course.id)

        # Now that we have the course, change the position and save, nothing should explode!
        course.position = 2
        course.save()
コード例 #20
0
    def setUp(self):
        super(TestMissingStudentModule, self).setUp()

        self.user = UserFactory.create(username='******')
        self.assertEqual(
            self.user.id,
            1)  # check our assumption hard-coded in the key functions above.

        # The descriptor has no fields, so FDC shouldn't send any queries
        with self.assertNumQueries(0):
            self.field_data_cache = FieldDataCache([mock_descriptor()],
                                                   course_id, self.user)
        self.kvs = DjangoKeyValueStore(self.field_data_cache)
コード例 #21
0
            def create_module(descriptor):
                '''creates an XModule instance given a descriptor'''
                with manual_transaction():
                    field_data_cache = FieldDataCache([descriptor], course.id,
                                                      student)

                # don't need tracking/xqueue but we have to pass something
                return get_module_for_descriptor_internal(
                    student, descriptor,
                    field_data_cache,
                    course.id,
                    track_function=noop_track_function,  # dummy
                    xqueue_callback_url_prefix='',  # dummy
                    request_token='')  # dummy
コード例 #22
0
 def setUp(self):
     student_module = StudentModuleFactory(
         state=json.dumps({
             'a_field': 'a_value',
             'b_field': 'b_value'
         }))
     self.user = student_module.student
     self.assertEqual(
         self.user.id,
         1)  # check our assumption hard-coded in the key functions above.
     self.field_data_cache = FieldDataCache(
         [mock_descriptor([mock_field(Scope.user_state, 'a_field')])],
         course_id, self.user)
     self.kvs = DjangoKeyValueStore(self.field_data_cache)
コード例 #23
0
def mobi_course_action(request, course_id, action):
    try:
        course_id_bak = course_id.replace('.', '/')
        if action in ["updates", "handouts", "structure"]:
            user = request.user
            if not user:
                user = AnonymousUser()

            course = get_course_with_access(user, course_id_bak, 'load')
            registered = registered_for_course(course, user)

            if action == "updates" and registered:
                # course_updates = get_course_info_section(request, course, action)
                loc = Location(course.location.tag, course.location.org,
                               course.location.course, 'course_info', action)
                field_data_cache = FieldDataCache([], course.id, request.user)
                course_module = get_module(
                    user,
                    request,
                    loc,
                    field_data_cache,
                    course.id,
                    wrap_xmodule_display=False,
                    static_asset_path=course.static_asset_path)
                return JsonResponse({
                    'updates': [
                        item for item in course_module.items
                        if item["status"] != "deleted"
                    ]
                })
            elif action == "handouts" and registered:
                course_handouts = get_course_info_section(
                    request, course, action)
                return JsonResponse({"handouts": course_handouts})
            elif action == "structure":
                url_name = request.get_host(
                ) + '/m/courses/' + course_id_bak + '/courseware'
                return JsonResponse(
                    _course_json(course=course,
                                 course_id=course.location.course_id,
                                 url_name=url_name))
            else:
                raise Exception
        else:
            course = get_course_with_access(request.user, course_id_bak,
                                            'see_exists')
            return JsonResponse(mobi_course_info(request, course))
    except:
        return JsonResponse({"success": False, "errmsg": "access denied!"})
コード例 #24
0
 def setUp(self):
     field_storage = self.factory.create()
     if hasattr(field_storage, 'student'):
         self.user = field_storage.student
     else:
         self.user = UserFactory.create()
     self.mock_descriptor = mock_descriptor([
         mock_field(self.scope, 'existing_field'),
         mock_field(self.scope, 'other_existing_field')
     ])
     # Each field is stored as a separate row in the table,
     # but we can query them in a single query
     with self.assertNumQueries(1):
         self.field_data_cache = FieldDataCache([self.mock_descriptor],
                                                course_id, self.user)
     self.kvs = DjangoKeyValueStore(self.field_data_cache)
コード例 #25
0
ファイル: runtime.py プロジェクト: xiaojunxi2008/edx-platform
    def _init_field_data_for_block(self, block):
        """
        Initialize the FieldData implementation for the specified XBlock
        """
        if self.user is None:
            # No user is specified, so we want to throw an error if anything attempts to read/write user-specific fields
            student_data_store = None
        elif self.user.is_anonymous:
            # The user is anonymous. Future work will support saving their state
            # in a cache or the django session but for now just use a highly
            # ephemeral dict.
            student_data_store = KvsFieldData(kvs=DictKeyValueStore())
        elif self.system.student_data_mode == XBlockRuntimeSystem.STUDENT_DATA_EPHEMERAL:
            # We're in an environment like Studio where we want to let the
            # author test blocks out but not permanently save their state.
            # This in-memory dict will typically only persist for one
            # request-response cycle, so we need to soon replace it with a store
            # that puts the state into a cache or the django session.
            student_data_store = KvsFieldData(kvs=DictKeyValueStore())
        else:
            # Use database-backed field data (i.e. store user_state in StudentModule)
            context_key = block.scope_ids.usage_id.context_key
            if context_key not in self.django_field_data_caches:
                field_data_cache = FieldDataCache(
                    [block],
                    course_id=context_key,
                    user=self.user,
                    asides=None,
                    read_only=False,
                )
                self.django_field_data_caches[context_key] = field_data_cache
            else:
                field_data_cache = self.django_field_data_caches[context_key]
                field_data_cache.add_descriptors_to_cache([block])
            student_data_store = KvsFieldData(
                kvs=DjangoKeyValueStore(field_data_cache))

        return SplitFieldData({
            Scope.content: self.system.authored_data_store,
            Scope.settings: self.system.authored_data_store,
            Scope.parent: self.system.authored_data_store,
            Scope.children: self.system.authored_data_store,
            Scope.user_state_summary: student_data_store,
            Scope.user_state: student_data_store,
            Scope.user_info: student_data_store,
            Scope.preferences: student_data_store,
        })
コード例 #26
0
    def test_event_publishing(self, block_type, mock_track_function):
        request = self.request_factory.get('')
        request.user = self.mock_user
        course = CourseFactory()
        descriptor = ItemFactory(category=block_type, parent=course)
        field_data_cache = FieldDataCache([course, descriptor], course.id,
                                          self.mock_user)  # pylint: disable=no-member
        block = render.get_module(self.mock_user, request, descriptor.location,
                                  field_data_cache)

        event_type = 'event_type'
        event = {'event': 'data'}

        block.runtime.publish(block, event_type, event)

        mock_track_function.assert_called_once_with(request)

        mock_track_function.return_value.assert_called_once_with(
            event_type, event)
コード例 #27
0
    def setUp(self):
        super(TestStudentModuleStorage, self).setUp()
        student_module = StudentModuleFactory(
            state=json.dumps({
                'a_field': 'a_value',
                'b_field': 'b_value'
            }))
        self.user = student_module.student
        self.assertEqual(
            self.user.id,
            1)  # check our assumption hard-coded in the key functions above.

        # There should be only one query to load a single descriptor with a single user_state field
        with self.assertNumQueries(1):
            self.field_data_cache = FieldDataCache(
                [mock_descriptor([mock_field(Scope.user_state, 'a_field')])],
                course_id, self.user)

        self.kvs = DjangoKeyValueStore(self.field_data_cache)
コード例 #28
0
def yield_problems(request, course, student):
    """
    Return an iterator over capa_modules that this student has
    potentially answered.  (all that student has answered will definitely be in
    the list, but there may be others as well).
    """
    grading_context = course.grading_context

    descriptor_locations = (
        descriptor.location.url()
        for descriptor in grading_context['all_descriptors'])
    existing_student_modules = set(
        StudentModule.objects.filter(
            module_state_key__in=descriptor_locations).values_list(
                'module_state_key', flat=True))

    sections_to_list = []
    for _, sections in grading_context['graded_sections'].iteritems():
        for section in sections:

            section_descriptor = section['section_descriptor']

            # If the student hasn't seen a single problem in the section, skip it.
            for moduledescriptor in section['xmoduledescriptors']:
                if moduledescriptor.location.url() in existing_student_modules:
                    sections_to_list.append(section_descriptor)
                    break

    field_data_cache = FieldDataCache(sections_to_list, course.id, student)
    for section_descriptor in sections_to_list:
        section_module = get_module(student, request,
                                    section_descriptor.location,
                                    field_data_cache, course.id)
        if section_module is None:
            # student doesn't have access to this module, or something else
            # went wrong.
            # log.debug("couldn't get module for student {0} for section location {1}"
            #           .format(student.username, section_descriptor.location))
            continue

        for problem in yield_module_descendents(section_module):
            if isinstance(problem, CapaModule):
                yield problem
コード例 #29
0
ファイル: courses.py プロジェクト: tinhien11/edx-platform
def get_course_about_section(course, section_key):
    """
    This returns the snippet of html to be rendered on the course about page,
    given the key for the section.

    Valid keys:
    - overview
    - title
    - university
    - number
    - short_description
    - description
    - key_dates (includes start, end, exams, etc)
    - video
    - course_staff_short
    - course_staff_extended
    - requirements
    - syllabus
    - textbook
    - faq
    - more_info
    - ocw_links
    """

    # Many of these are stored as html files instead of some semantic
    # markup. This can change without effecting this interface when we find a
    # good format for defining so many snippets of text/html.

    # TODO: Remove number, instructors from this list
    if section_key in ['short_description', 'description', 'key_dates', 'video',
                       'course_staff_short', 'course_staff_extended',
                       'requirements', 'syllabus', 'textbook', 'faq', 'more_info',
                       'number', 'instructors', 'overview',
                       'effort', 'end_date', 'prerequisites', 'ocw_links']:

        try:

            request = get_request_for_thread()

            loc = course.location.replace(category='about', name=section_key)

            # Use an empty cache
            field_data_cache = FieldDataCache([], course.id, request.user)
            about_module = get_module(
                request.user,
                request,
                loc,
                field_data_cache,
                log_if_not_found=False,
                wrap_xmodule_display=False,
                static_asset_path=course.static_asset_path
            )

            html = ''

            if about_module is not None:
                try:
                    html = about_module.render(STUDENT_VIEW).content
                except Exception:  # pylint: disable=broad-except
                    html = render_to_string('courseware/error-message.html', None)
                    log.exception(
                        u"Error rendering course={course}, section_key={section_key}".format(
                            course=course, section_key=section_key
                        ))
            return html

        except ItemNotFoundError:
            log.warning(
                u"Missing about section {key} in course {url}".format(key=section_key, url=course.location.to_deprecated_string())
            )
            return None
    elif section_key == "title":
        return course.display_name_with_default
    elif section_key == "university":
        return course.display_org_with_default
    elif section_key == "number":
        return course.display_number_with_default

    raise KeyError("Invalid about key " + str(section_key))
コード例 #30
0
def grade(student,
          request,
          course,
          field_data_cache=None,
          keep_raw_scores=False):
    """
    This grades a student as quickly as possible. It returns the
    output from the course grader, augmented with the final letter
    grade. The keys in the output are:

    course: a CourseDescriptor

    - grade : A final letter grade.
    - percent : The final percent for the class (rounded up).
    - section_breakdown : A breakdown of each section that makes
        up the grade. (For display)
    - grade_breakdown : A breakdown of the major components that
        make up the final grade. (For display)
    - keep_raw_scores : if True, then value for key 'raw_scores' contains scores for every graded module

    More information on the format is in the docstring for CourseGrader.
    """

    grading_context = course.grading_context
    raw_scores = []

    if field_data_cache is None:
        field_data_cache = FieldDataCache(grading_context['all_descriptors'],
                                          course.id, student)

    totaled_scores = {}
    # This next complicated loop is just to collect the totaled_scores, which is
    # passed to the grader
    for section_format, sections in grading_context[
            'graded_sections'].iteritems():
        format_scores = []
        for section in sections:
            section_descriptor = section['section_descriptor']
            section_name = section_descriptor.display_name_with_default

            should_grade_section = False
            # If we haven't seen a single problem in the section, we don't have to grade it at all! We can assume 0%
            for moduledescriptor in section['xmoduledescriptors']:
                # some problems have state that is updated independently of interaction
                # with the LMS, so they need to always be scored. (E.g. foldit.)
                if moduledescriptor.always_recalculate_grades:
                    should_grade_section = True
                    break

                # Create a fake key to pull out a StudentModule object from the FieldDataCache

                key = DjangoKeyValueStore.Key(Scope.user_state, student.id,
                                              moduledescriptor.location, None)
                if field_data_cache.find(key):
                    should_grade_section = True
                    break

            if should_grade_section:
                scores = []

                def create_module(descriptor):
                    '''creates an XModule instance given a descriptor'''
                    # TODO: We need the request to pass into here. If we could forego that, our arguments
                    # would be simpler
                    return get_module_for_descriptor(student, request,
                                                     descriptor,
                                                     field_data_cache,
                                                     course.id)

                for module_descriptor in yield_dynamic_descriptor_descendents(
                        section_descriptor, create_module):

                    (correct,
                     total) = get_score(course.id, student, module_descriptor,
                                        create_module, field_data_cache)
                    if correct is None and total is None:
                        continue

                    if settings.GENERATE_PROFILE_SCORES:  # for debugging!
                        if total > 1:
                            correct = random.randrange(max(total - 2, 1),
                                                       total + 1)
                        else:
                            correct = total

                    graded = module_descriptor.graded
                    if not total > 0:
                        #We simply cannot grade a problem that is 12/0, because we might need it as a percentage
                        graded = False

                    scores.append(
                        Score(correct, total, graded,
                              module_descriptor.display_name_with_default))

                _, graded_total = graders.aggregate_scores(
                    scores, section_name)
                if keep_raw_scores:
                    raw_scores += scores
            else:
                graded_total = Score(0.0, 1.0, True, section_name)

            #Add the graded total to totaled_scores
            if graded_total.possible > 0:
                format_scores.append(graded_total)
            else:
                log.exception(
                    "Unable to grade a section with a total possible score of zero. "
                    + str(section_descriptor.location))

        totaled_scores[section_format] = format_scores

    grade_summary = course.grader.grade(
        totaled_scores,
        generate_random_scores=settings.GENERATE_PROFILE_SCORES)

    # We round the grade here, to make sure that the grade is an whole percentage and
    # doesn't get displayed differently than it gets grades
    grade_summary['percent'] = round(grade_summary['percent'] * 100 +
                                     0.05) / 100

    letter_grade = grade_for_percentage(course.grade_cutoffs,
                                        grade_summary['percent'])
    grade_summary['grade'] = letter_grade
    grade_summary[
        'totaled_scores'] = totaled_scores  # make this available, eg for instructor download & debugging
    if keep_raw_scores:
        grade_summary[
            'raw_scores'] = raw_scores  # way to get all RAW scores out to instructor
        # so grader can be double-checked
    return grade_summary