Beispiel #1
0
    def update_from_json(cls, descriptor, jsondict, filter_tabs=True):
        """
        Decode the json into CourseMetadata and save any changed attrs to the db.

        Ensures none of the fields are in the blacklist.
        """
        dirty = False

        # Copy the filtered list to avoid permanently changing the class attribute.
        filtered_list = list(cls.FILTERED_LIST)
        # Don't filter on the tab attribute if filter_tabs is False.
        if not filter_tabs:
            filtered_list.remove("tabs")

        for key, val in jsondict.iteritems():
            # should it be an error if one of the filtered list items is in the payload?
            if key in filtered_list:
                continue

            if key == "unsetKeys":
                dirty = True
                for unset in val:
                    descriptor.fields[unset].delete_from(descriptor)

            if hasattr(descriptor, key) and getattr(descriptor, key) != val:
                dirty = True
                value = descriptor.fields[key].from_json(val)
                setattr(descriptor, key, value)

        if dirty:
            get_modulestore(descriptor.location).update_metadata(
                descriptor.location, own_metadata(descriptor))

        return cls.fetch(descriptor)
    def update_grader_from_json(course_location, grader):
        """
        Create or update the grader of the given type (string key) for the given course. Returns the modified
        grader which is a full model on the client but not on the server (just a dict)
        """
        course_old_location = loc_mapper().translate_locator_to_location(
            course_location)
        descriptor = get_modulestore(course_old_location).get_item(
            course_old_location)

        # parse removes the id; so, grab it before parse
        index = int(grader.get('id', len(descriptor.raw_grader)))
        grader = CourseGradingModel.parse_grader(grader)

        if index < len(descriptor.raw_grader):
            descriptor.raw_grader[index] = grader
        else:
            descriptor.raw_grader.append(grader)

        get_modulestore(course_old_location).update_item(
            course_old_location,
            descriptor.get_explicitly_set_fields_by_scope(Scope.content))

        return CourseGradingModel.jsonize_grader(index,
                                                 descriptor.raw_grader[index])
Beispiel #3
0
    def update_grader_from_json(course_location, grader):
        """
        Create or update the grader of the given type (string key) for the given course. Returns the modified
        grader which is a full model on the client but not on the server (just a dict)
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        # # ??? it would be good if these had the course_location in them so that they stand alone sufficiently
        # # but that would require not using CourseDescriptor's field directly. Opinions?

        # parse removes the id; so, grab it before parse
        index = int(grader.get('id', len(descriptor.raw_grader)))
        grader = CourseGradingModel.parse_grader(grader)

        if index < len(descriptor.raw_grader):
            descriptor.raw_grader[index] = grader
        else:
            descriptor.raw_grader.append(grader)

        # Save the data that we've just changed to the underlying
        # MongoKeyValueStore before we update the mongo datastore.
        descriptor.save()
        get_modulestore(course_location).update_item(
            course_location, descriptor._model_data._kvs._data)

        return CourseGradingModel.jsonize_grader(index,
                                                 descriptor.raw_grader[index])
    def update_from_json(course_locator, jsondict):
        """
        Decode the json into CourseGradingModel and save any changes. Returns the modified model.
        Probably not the usual path for updates as it's too coarse grained.
        """
        course_old_location = loc_mapper().translate_locator_to_location(
            course_locator)
        descriptor = get_modulestore(course_old_location).get_item(
            course_old_location)

        graders_parsed = [
            CourseGradingModel.parse_grader(jsonele)
            for jsonele in jsondict['graders']
        ]

        descriptor.raw_grader = graders_parsed
        descriptor.grade_cutoffs = jsondict['grade_cutoffs']

        get_modulestore(course_old_location).update_item(
            course_old_location,
            descriptor.get_explicitly_set_fields_by_scope(Scope.content))

        CourseGradingModel.update_grace_period_from_json(
            course_locator, jsondict['grace_period'])

        return CourseGradingModel.fetch(course_locator)
Beispiel #5
0
def component_handler(request, usage_key_string, handler, suffix=''):
    """
    Dispatch an AJAX action to an xblock

    Args:
        usage_id: The usage-id of the block to dispatch to
        handler (str): The handler to execute
        suffix (str): The remainder of the url to be passed to the handler

    Returns:
        :class:`django.http.HttpResponse`: The response from the handler, converted to a
            django response
    """

    usage_key = UsageKey.from_string(usage_key_string)

    descriptor = get_modulestore(usage_key).get_item(usage_key)
    # Let the module handle the AJAX
    req = django_to_webob_request(request)

    try:
        resp = descriptor.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.info("XBlock %s attempted to access missing handler %r", descriptor, handler, exc_info=True)
        raise Http404

    # unintentional update to handle any side effects of handle call; so, request user didn't author
    # the change
    get_modulestore(usage_key).update_item(descriptor, None)

    return webob_to_django_response(resp)
Beispiel #6
0
    def test_update_section_grader_type(self):
        # Get the descriptor and the section_grader_type and assert they are the default values
        descriptor = get_modulestore(self.course.location).get_item(
            self.course.location)
        section_grader_type = CourseGradingModel.get_section_grader_type(
            self.course_locator)

        self.assertEqual('notgraded', section_grader_type['graderType'])
        self.assertEqual(None, descriptor.format)
        self.assertEqual(False, descriptor.graded)

        # Change the default grader type to Homework, which should also mark the section as graded
        CourseGradingModel.update_section_grader_type(self.course, 'Homework',
                                                      self.user)
        descriptor = get_modulestore(self.course.location).get_item(
            self.course.location)
        section_grader_type = CourseGradingModel.get_section_grader_type(
            self.course_locator)

        self.assertEqual('Homework', section_grader_type['graderType'])
        self.assertEqual('Homework', descriptor.format)
        self.assertEqual(True, descriptor.graded)

        # Change the grader type back to notgraded, which should also unmark the section as graded
        CourseGradingModel.update_section_grader_type(self.course, 'notgraded',
                                                      self.user)
        descriptor = get_modulestore(self.course.location).get_item(
            self.course.location)
        section_grader_type = CourseGradingModel.get_section_grader_type(
            self.course_locator)

        self.assertEqual('notgraded', section_grader_type['graderType'])
        self.assertEqual(None, descriptor.format)
        self.assertEqual(False, descriptor.graded)
Beispiel #7
0
def module_info(request, module_location):
    location = Location(module_location)

    # check that logged in user has permissions to this item
    if not has_access(request.user, location):
        raise PermissionDenied()

    real_method = get_request_method(request)

    rewrite_static_links = request.GET.get('rewrite_url_links',
                                           'True') in ['True', 'true']
    logging.debug('rewrite_static_links = {0} {1}'.format(
        request.GET.get('rewrite_url_links', 'False'), rewrite_static_links))

    # check that logged in user has permissions to this item
    if not has_access(request.user, location):
        raise PermissionDenied()

    if real_method == 'GET':
        return HttpResponse(json.dumps(
            get_module_info(get_modulestore(location),
                            location,
                            rewrite_static_links=rewrite_static_links)),
                            mimetype="application/json")
    elif real_method == 'POST' or real_method == 'PUT':
        return HttpResponse(json.dumps(
            set_module_info(get_modulestore(location), location,
                            request.POST)),
                            mimetype="application/json")
    else:
        return HttpResponseBadRequest()
Beispiel #8
0
    def test_course_export_success(self):
        """
        Test successful course export response.
        """
        # Build out local bare repo, and set course git url to it
        repo_dir = os.path.abspath(git_export_utils.GIT_REPO_EXPORT_DIR)
        os.mkdir(repo_dir)
        self.addCleanup(shutil.rmtree, repo_dir)

        bare_repo_dir = '{0}/test_repo.git'.format(
            os.path.abspath(git_export_utils.GIT_REPO_EXPORT_DIR))
        os.mkdir(bare_repo_dir)
        self.addCleanup(shutil.rmtree, bare_repo_dir)

        subprocess.check_output([
            'git',
            '--bare',
            'init',
        ], cwd=bare_repo_dir)

        self.populate_course()
        self.course_module.giturl = 'file://{}'.format(bare_repo_dir)
        get_modulestore(self.course_module.location).update_item(
            self.course_module)

        response = self.client.get('{}?action=push'.format(self.test_url))
        self.assertIn('Export Succeeded', response.content)
Beispiel #9
0
    def update_grader_from_json(course_location, grader):
        """
        Create or update the grader of the given type (string key) for the given course. Returns the modified
        grader which is a full model on the client but not on the server (just a dict)
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        # # ??? it would be good if these had the course_location in them so that they stand alone sufficiently
        # # but that would require not using CourseDescriptor's field directly. Opinions?

        # parse removes the id; so, grab it before parse
        index = int(grader.get('id', len(descriptor.raw_grader)))
        grader = CourseGradingModel.parse_grader(grader)

        if index < len(descriptor.raw_grader):
            descriptor.raw_grader[index] = grader
        else:
            descriptor.raw_grader.append(grader)

        # Save the data that we've just changed to the underlying
        # MongoKeyValueStore before we update the mongo datastore.
        descriptor.save()
        get_modulestore(course_location).update_item(course_location, descriptor._model_data._kvs._data)

        return CourseGradingModel.jsonize_grader(index, descriptor.raw_grader[index])
Beispiel #10
0
    def update_grace_period_from_json(course_location, graceperiodjson):
        """
        Update the course's default grace period. Incoming dict is {hours: h, minutes: m} possibly as a
        grace_period entry in an enclosing dict. It is also safe to call this method with a value of
        None for graceperiodjson.
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        # Before a graceperiod has ever been created, it will be None (once it has been
        # created, it cannot be set back to None).
        if graceperiodjson is not None:
            if 'grace_period' in graceperiodjson:
                graceperiodjson = graceperiodjson['grace_period']

            # lms requires these to be in a fixed order
            grace_timedelta = timedelta(**graceperiodjson)

            descriptor = get_modulestore(course_location).get_item(course_location)
            descriptor.lms.graceperiod = grace_timedelta

            # Save the data that we've just changed to the underlying
            # MongoKeyValueStore before we update the mongo datastore.
            descriptor.save()
            get_modulestore(course_location).update_metadata(course_location, descriptor._model_data._kvs._metadata)
Beispiel #11
0
def module_info(request, module_location):
    "Get or set information for a module in the modulestore"
    location = Location(module_location)

    # check that logged in user has permissions to this item
    if not has_access(request.user, location):
        raise PermissionDenied()

    rewrite_static_links = request.GET.get('rewrite_url_links', 'True') in ['True', 'true']
    logging.debug('rewrite_static_links = {0} {1}'.format(
        request.GET.get('rewrite_url_links', False),
        rewrite_static_links)
    )

    # check that logged in user has permissions to this item
    if not has_access(request.user, location):
        raise PermissionDenied()

    if request.method == 'GET':
        rsp = get_module_info(
            get_modulestore(location),
            location,
            rewrite_static_links=rewrite_static_links
        )
    elif request.method in ("POST", "PUT"):
        rsp = set_module_info(
            get_modulestore(location),
            location, request.POST
        )
    return JsonResponse(rsp)
    def update_from_json(cls, descriptor, jsondict, filter_tabs=True, user=None):
        """
        Decode the json into CourseMetadata and save any changed attrs to the db.

        Ensures none of the fields are in the blacklist.
        """
        dirty = False

        # Copy the filtered list to avoid permanently changing the class attribute.
        filtered_list = list(cls.FILTERED_LIST)
        # Don't filter on the tab attribute if filter_tabs is False.
        if not filter_tabs:
            filtered_list.remove("tabs")

        for key, val in jsondict.iteritems():
            # should it be an error if one of the filtered list items is in the payload?
            if key in filtered_list:
                continue

            if key == "unsetKeys":
                dirty = True
                for unset in val:
                    descriptor.fields[unset].delete_from(descriptor)

            if hasattr(descriptor, key) and getattr(descriptor, key) != val:
                dirty = True
                value = descriptor.fields[key].from_json(val)
                setattr(descriptor, key, value)

        if dirty:
            get_modulestore(descriptor.location).update_item(descriptor, user.id if user else None)

        return cls.fetch(descriptor)
Beispiel #13
0
def component_handler(request, usage_key_string, handler, suffix=''):
    """
    Dispatch an AJAX action to an xblock

    Args:
        usage_id: The usage-id of the block to dispatch to
        handler (str): The handler to execute
        suffix (str): The remainder of the url to be passed to the handler

    Returns:
        :class:`django.http.HttpResponse`: The response from the handler, converted to a
            django response
    """

    usage_key = UsageKey.from_string(usage_key_string)

    descriptor = get_modulestore(usage_key).get_item(usage_key)
    # Let the module handle the AJAX
    req = django_to_webob_request(request)

    try:
        resp = descriptor.handle(handler, req, suffix)

    except NoSuchHandlerError:
        log.info("XBlock %s attempted to access missing handler %r", descriptor, handler, exc_info=True)
        raise Http404

    # unintentional update to handle any side effects of handle call; so, request user didn't author
    # the change
    get_modulestore(usage_key).update_item(descriptor, None)

    return webob_to_django_response(resp)
def module_info(request, module_location):
    "Get or set information for a module in the modulestore"
    location = Location(module_location)

    # check that logged in user has permissions to this item
    if not has_access(request.user, location):
        raise PermissionDenied()

    rewrite_static_links = request.GET.get('rewrite_url_links', 'True') in ['True', 'true']
    logging.debug('rewrite_static_links = {0} {1}'.format(
        request.GET.get('rewrite_url_links', False),
        rewrite_static_links)
    )

    # check that logged in user has permissions to this item
    if not has_access(request.user, location):
        raise PermissionDenied()

    if request.method == 'GET':
        rsp = get_module_info(
            get_modulestore(location),
            location,
            rewrite_static_links=rewrite_static_links
        )
    elif request.method in ("POST", "PUT"):
        rsp = set_module_info(
            get_modulestore(location),
            location, request.POST
        )
    return JsonResponse(rsp)
Beispiel #15
0
    def update_grace_period_from_json(course_location, graceperiodjson):
        """
        Update the course's default grace period. Incoming dict is {hours: h, minutes: m} possibly as a
        grace_period entry in an enclosing dict. It is also safe to call this method with a value of
        None for graceperiodjson.
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        # Before a graceperiod has ever been created, it will be None (once it has been
        # created, it cannot be set back to None).
        if graceperiodjson is not None:
            if 'grace_period' in graceperiodjson:
                graceperiodjson = graceperiodjson['grace_period']

            # lms requires these to be in a fixed order
            grace_timedelta = timedelta(**graceperiodjson)

            descriptor = get_modulestore(course_location).get_item(
                course_location)
            descriptor.lms.graceperiod = grace_timedelta

            # Save the data that we've just changed to the underlying
            # MongoKeyValueStore before we update the mongo datastore.
            descriptor.save()
            get_modulestore(course_location).update_metadata(
                course_location, descriptor._model_data._kvs._metadata)
    def test_update_section_grader_type(self):
        # Get the descriptor and the section_grader_type and assert they are the default values
        descriptor = get_modulestore(self.course.location).get_item(self.course.location)
        section_grader_type = CourseGradingModel.get_section_grader_type(self.course.location)

        self.assertEqual('Not Graded', section_grader_type['graderType'])
        self.assertEqual(None, descriptor.format)
        self.assertEqual(False, descriptor.graded)

        # Change the default grader type to Homework, which should also mark the section as graded
        CourseGradingModel.update_section_grader_type(self.course.location, {'graderType': 'Homework'})
        descriptor = get_modulestore(self.course.location).get_item(self.course.location)
        section_grader_type = CourseGradingModel.get_section_grader_type(self.course.location)

        self.assertEqual('Homework', section_grader_type['graderType'])
        self.assertEqual('Homework', descriptor.format)
        self.assertEqual(True, descriptor.graded)

        # Change the grader type back to Not Graded, which should also unmark the section as graded
        CourseGradingModel.update_section_grader_type(self.course.location, {'graderType': 'Not Graded'})
        descriptor = get_modulestore(self.course.location).get_item(self.course.location)
        section_grader_type = CourseGradingModel.get_section_grader_type(self.course.location)

        self.assertEqual('Not Graded', section_grader_type['graderType'])
        self.assertEqual(None, descriptor.format)
        self.assertEqual(False, descriptor.graded)
Beispiel #17
0
    def update_from_json(jsondict):
        """
        Decode the json into CourseGradingModel and save any changes. Returns the modified model.
        Probably not the usual path for updates as it's too coarse grained.
        """
        course_location = Location(jsondict['course_location'])
        descriptor = get_modulestore(course_location).get_item(course_location)
        graders_parsed = [
            CourseGradingModel.parse_grader(jsonele)
            for jsonele in jsondict['graders']
        ]

        descriptor.raw_grader = graders_parsed
        descriptor.grade_cutoffs = jsondict['grade_cutoffs']

        # Save the data that we've just changed to the underlying
        # MongoKeyValueStore before we update the mongo datastore.
        descriptor.save()
        get_modulestore(course_location).update_item(
            course_location, descriptor.xblock_kvs._data)

        CourseGradingModel.update_grace_period_from_json(
            course_location, jsondict['grace_period'])

        return CourseGradingModel.fetch(course_location)
    def test_course_export_failures(self):
        """
        Test failed course export response.
        """
        self.course_module.giturl = 'foobar'
        get_modulestore(self.course_module.location).update_item(self.course_module)

        response = self.client.get('{}?action=push'.format(self.test_url))
        self.assertIn('Export Failed:', response.content)
    def test_exception_translation(self):
        """
        Regression test for making sure errors are properly stringified
        """
        self.course_module.giturl = 'foobar'
        get_modulestore(self.course_module.location).update_item(self.course_module)

        response = self.client.get('{}?action=push'.format(self.test_url))
        self.assertNotIn('django.utils.functional.__proxy__', response.content)
Beispiel #20
0
    def test_course_export_failures(self):
        """
        Test failed course export response.
        """
        self.course_module.giturl = 'foobar'
        get_modulestore(self.course_module.location).update_item(
            self.course_module)

        response = self.client.get('{}?action=push'.format(self.test_url))
        self.assertIn('Export Failed:', response.content)
Beispiel #21
0
    def delete_grace_period(course_location):
        """
        Delete the course's default grace period.
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        del descriptor.lms.graceperiod
        get_modulestore(course_location).update_metadata(course_location, descriptor._model_data._kvs._metadata)
Beispiel #22
0
    def update_section_grader_type(descriptor, grader_type, user):
        if grader_type is not None and grader_type != u'notgraded':
            descriptor.format = grader_type
            descriptor.graded = True
        else:
            del descriptor.format
            del descriptor.graded

        get_modulestore(descriptor.location).update_item(descriptor, user.id)
        return {'graderType': grader_type}
Beispiel #23
0
    def delete_grace_period(course_location):
        """
        Delete the course's default grace period.
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        del descriptor.lms.graceperiod
        get_modulestore(course_location).update_metadata(course_location, descriptor._model_data._kvs._metadata)
Beispiel #24
0
    def delete_grace_period(course_location, user):
        """
        Delete the course's grace period.
        """
        course_old_location = loc_mapper().translate_locator_to_location(course_location)
        descriptor = get_modulestore(course_old_location).get_item(course_old_location)

        del descriptor.graceperiod

        get_modulestore(course_old_location).update_item(descriptor, user.id)
Beispiel #25
0
    def test_exception_translation(self):
        """
        Regression test for making sure errors are properly stringified
        """
        self.course_module.giturl = 'foobar'
        get_modulestore(self.course_module.location).update_item(
            self.course_module)

        response = self.client.get('{}?action=push'.format(self.test_url))
        self.assertNotIn('django.utils.functional.__proxy__', response.content)
Beispiel #26
0
    def delete_cutoffs(course_location, cutoffs):
        """
        Resets the cutoffs to the defaults
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        descriptor.grade_cutoffs = descriptor.defaut_grading_policy["GRADE_CUTOFFS"]
        get_modulestore(course_location).update_item(course_location, descriptor._model_data._kvs._data)

        return descriptor.grade_cutoffs
    def update_section_grader_type(descriptor, grader_type):
        if grader_type is not None and grader_type != u'notgraded':
            descriptor.format = grader_type
            descriptor.graded = True
        else:
            del descriptor.format
            del descriptor.graded

        get_modulestore(descriptor.location).update_metadata(
            descriptor.location,
            descriptor.get_explicitly_set_fields_by_scope(Scope.settings))
        return {'graderType': grader_type}
def set_course_list(request):
    try:
        course_id = request.POST.getlist("data[]");
        for i in range(len(course_id)):
            course = modulestore().get_item(Location(course_id[i]))
            course.display_sort_number=(i+1)*'1'
            course.save()
            get_modulestore(Location(course_id[i])).update_metadata(Location(course_id[i]), course._field_data._kvs._metadata)

        return JsonResponse({"info":"success"})
    except:
        return JsonResponse({"info":"fail"})
Beispiel #29
0
    def delete_grace_period(course_location):
        """
        Delete the course's grace period.
        """
        course_old_location = loc_mapper().translate_locator_to_location(course_location)
        descriptor = get_modulestore(course_old_location).get_item(course_old_location)

        del descriptor.graceperiod

        get_modulestore(course_old_location).update_metadata(
            course_old_location, descriptor.get_explicitly_set_fields_by_scope(Scope.settings)
        )
Beispiel #30
0
    def update_section_grader_type(descriptor, grader_type):
        if grader_type is not None and grader_type != u"Not Graded":
            descriptor.format = grader_type
            descriptor.graded = True
        else:
            del descriptor.format
            del descriptor.graded

        get_modulestore(descriptor.location).update_metadata(
            descriptor.location, descriptor.get_explicitly_set_fields_by_scope(Scope.settings)
        )
        return {'graderType': grader_type}
Beispiel #31
0
    def update_cutoffs_from_json(course_location, cutoffs, user):
        """
        Create or update the grade cutoffs for the given course. Returns sent in cutoffs (ie., no extra
        db fetch).
        """
        course_old_location = loc_mapper().translate_locator_to_location(course_location)
        descriptor = get_modulestore(course_old_location).get_item(course_old_location)
        descriptor.grade_cutoffs = cutoffs

        get_modulestore(course_old_location).update_item(descriptor, user.id)

        return cutoffs
Beispiel #32
0
    def delete_cutoffs(course_location, cutoffs):
        """
        Resets the cutoffs to the defaults
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        descriptor.grade_cutoffs = descriptor.defaut_grading_policy['GRADE_CUTOFFS']
        get_modulestore(course_location).update_item(course_location, descriptor._model_data._kvs._data)

        return descriptor.grade_cutoffs
Beispiel #33
0
    def update_section_grader_type(location, jsondict):
        if not isinstance(location, Location):
            location = Location(location)

        descriptor = get_modulestore(location).get_item(location)
        if "graderType" in jsondict and jsondict["graderType"] != u"Not Graded":
            descriptor.lms.format = jsondict.get("graderType")
            descriptor.lms.graded = True
        else:
            del descriptor.lms.format
            del descriptor.lms.graded

        get_modulestore(location).update_metadata(location, descriptor._model_data._kvs._metadata)
Beispiel #34
0
    def update_cutoffs_from_json(course_location, cutoffs):
        """
        Create or update the grade cutoffs for the given course. Returns sent in cutoffs (ie., no extra
        db fetch).
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        descriptor.grade_cutoffs = cutoffs
        get_modulestore(course_location).update_item(course_location, descriptor._model_data._kvs._data)

        return cutoffs
Beispiel #35
0
    def update_section_grader_type(location, jsondict):
        if not isinstance(location, Location):
            location = Location(location)

        descriptor = get_modulestore(location).get_item(location)
        if 'graderType' in jsondict and jsondict['graderType'] != u"Not Graded":
            descriptor.lms.format = jsondict.get('graderType')
            descriptor.lms.graded = True
        else:
            del descriptor.lms.format
            del descriptor.lms.graded

        get_modulestore(location).update_metadata(location, descriptor._model_data._kvs._metadata)
Beispiel #36
0
    def update_cutoffs_from_json(course_location, cutoffs):
        """
        Create or update the grade cutoffs for the given course. Returns sent in cutoffs (ie., no extra
        db fetch).
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        descriptor.grade_cutoffs = cutoffs
        get_modulestore(course_location).update_item(course_location, descriptor._model_data._kvs._data)

        return cutoffs
    def delete_grace_period(course_location):
        """
        Delete the course's grace period.
        """
        course_old_location = loc_mapper().translate_locator_to_location(
            course_location)
        descriptor = get_modulestore(course_old_location).get_item(
            course_old_location)

        del descriptor.graceperiod

        get_modulestore(course_old_location).update_metadata(
            course_old_location,
            descriptor.get_explicitly_set_fields_by_scope(Scope.settings))
Beispiel #38
0
    def delete_grader(course_location, index):
        """
        Delete the grader of the given type from the given course.
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        index = int(index)
        if index < len(descriptor.raw_grader):
            del descriptor.raw_grader[index]
            # force propagation to definition
            descriptor.raw_grader = descriptor.raw_grader
            get_modulestore(course_location).update_item(course_location, descriptor._model_data._kvs._data)
Beispiel #39
0
    def delete_grader(course_location, index):
        """
        Delete the grader of the given type from the given course.
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        index = int(index)
        if index < len(descriptor.raw_grader):
            del descriptor.raw_grader[index]
            # force propagation to definition
            descriptor.raw_grader = descriptor.raw_grader
            get_modulestore(course_location).update_item(course_location, descriptor._model_data._kvs._data)
Beispiel #40
0
    def delete_grace_period(course_location):
        """
        Delete the course's default grace period.
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        del descriptor.lms.graceperiod

        # Save the data that we've just changed to the underlying
        # MongoKeyValueStore before we update the mongo datastore.
        descriptor.save()
        get_modulestore(course_location).update_metadata(course_location, descriptor._model_data._kvs._metadata)
Beispiel #41
0
    def update_cutoffs_from_json(course_location, cutoffs):
        """
        Create or update the grade cutoffs for the given course. Returns sent in cutoffs (ie., no extra
        db fetch).
        """
        course_old_location = loc_mapper().translate_locator_to_location(course_location)
        descriptor = get_modulestore(course_old_location).get_item(course_old_location)
        descriptor.grade_cutoffs = cutoffs

        get_modulestore(course_old_location).update_item(
            course_old_location, descriptor.get_explicitly_set_fields_by_scope(Scope.content)
        )

        return cutoffs
Beispiel #42
0
    def delete_grader(course_location, index, user):
        """
        Delete the grader of the given type from the given course.
        """
        course_old_location = loc_mapper().translate_locator_to_location(course_location)
        descriptor = get_modulestore(course_old_location).get_item(course_old_location)

        index = int(index)
        if index < len(descriptor.raw_grader):
            del descriptor.raw_grader[index]
            # force propagation to definition
            descriptor.raw_grader = descriptor.raw_grader

        get_modulestore(course_old_location).update_item(descriptor, user.id)
Beispiel #43
0
    def delete_grace_period(course_location):
        """
        Delete the course's default grace period.
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        del descriptor.lms.graceperiod

        # Save the data that we've just changed to the underlying
        # MongoKeyValueStore before we update the mongo datastore.
        descriptor.save()
        get_modulestore(course_location).update_metadata(
            course_location, descriptor._model_data._kvs._metadata)
Beispiel #44
0
    def setUp(self):
        """
        These tests need a user in the DB so that the django Test Client
        can log them in.
        They inherit from the ModuleStoreTestCase class so that the mongodb collection
        will be cleared out before each test case execution and deleted
        afterwards.
        """
        uname = 'testuser'
        email = '*****@*****.**'
        password = '******'

        # Create the user so we can log them in.
        self.user = User.objects.create_user(uname, email, password)

        # Note that we do not actually need to do anything
        # for registration if we directly mark them active.
        self.user.is_active = True
        # Staff has access to view all courses
        self.user.is_staff = True
        self.user.save()

        self.client = AjaxEnabledTestClient()
        self.client.login(username=uname, password=password)

        self.course = CourseFactory.create(
            org='MITx',
            number='999',
            display_name='Robot Super Course',
        )
        self.store = get_modulestore(self.course.location)
Beispiel #45
0
def xml_only_video(step):
    # Create a new video *without* metadata. This requires a certain
    # amount of rummaging to make sure all the correct data is present
    step.given('I have clicked the new unit button')

    # Wait for the new unit to be created and to load the page
    world.wait(1)

    location = world.scenario_dict['COURSE'].location
    store = get_modulestore(location)

    parent_location = store.get_items(Location(category='vertical', revision='draft'))[0].location

    youtube_id = 'ABCDEFG'
    world.scenario_dict['YOUTUBE_ID'] = youtube_id

    # Create a new Video component, but ensure that it doesn't have
    # metadata. This allows us to test that we are correctly parsing
    # out XML
    video = world.ItemFactory.create(
        parent_location=parent_location,
        category='video',
        data='<video youtube="1.00:%s"></video>' % youtube_id
    )

    # Refresh to see the new video
    reload_the_page(step)
Beispiel #46
0
    def delete_grader(course_location, index):
        """
        Delete the grader of the given type from the given course.
        """
        course_old_location = loc_mapper().translate_locator_to_location(course_location)
        descriptor = get_modulestore(course_old_location).get_item(course_old_location)

        index = int(index)
        if index < len(descriptor.raw_grader):
            del descriptor.raw_grader[index]
            # force propagation to definition
            descriptor.raw_grader = descriptor.raw_grader

        get_modulestore(course_old_location).update_item(
            course_old_location, descriptor.get_explicitly_set_fields_by_scope(Scope.content)
        )
Beispiel #47
0
    def fetch_grader(course_location, index):
        """
        Fetch the course's nth grader
        Returns an empty dict if there's no such grader.
        """
        if not isinstance(course_location, Location):
            course_location = Location(course_location)

        descriptor = get_modulestore(course_location).get_item(course_location)
        # # ??? it would be good if these had the course_location in them so that they stand alone sufficiently
        # # but that would require not using CourseDescriptor's field directly. Opinions?

        index = int(index)
        if len(descriptor.raw_grader) > index:
            return CourseGradingModel.jsonize_grader(index, descriptor.raw_grader[index])

        # return empty model
        else:
            return {"id": index,
                    "type": "",
                    "min_count": 0,
                    "drop_count": 0,
                    "short_label": None,
                    "weight": 0
                    }
Beispiel #48
0
    def test_get_checklists(self):
        """ Tests the get checklists method. """
        checklists_url = reverse("checklists", kwargs={
            'org': self.course.location.org,
            'course': self.course.location.course,
            'name': self.course.location.name,
        })
        response = self.client.get(checklists_url)
        self.assertContains(response, "Getting Started With Studio")
        # Verify expansion of action URL happened.
        self.assertContains(response, '/mitX/333/team/Checklists_Course')
        # Verify persisted checklist does NOT have expanded URL.
        checklist_0 = self.get_persisted_checklists()[0]
        self.assertEqual('ManageUsers', get_action_url(checklist_0, 0))
        payload = response.content

        # Now delete the checklists from the course and verify they get repopulated (for courses
        # created before checklists were introduced).
        self.course.checklists = None
        # Save the changed `checklists` to the underlying KeyValueStore before updating the modulestore
        self.course.save()
        modulestore = get_modulestore(self.course.location)
        modulestore.update_metadata(self.course.location, own_metadata(self.course))
        self.assertEqual(self.get_persisted_checklists(), None)
        response = self.client.get(checklists_url)
        self.assertEqual(payload, response.content)
 def setUp(self):
     CourseTestCase.setUp(self)
     # add in the full class too
     import_from_xml(get_modulestore(
         self.course_location), 'common/test/data/', ['full'])
     self.fullcourse_location = Location(
         ['i4x', 'edX', 'full', 'course', '6.002_Spring_2012', None])
 def test_initial_grader(self):
     descriptor = get_modulestore(self.course.location).get_item(self.course.location)
     test_grader = CourseGradingModel(descriptor)
     # ??? How much should this test bake in expectations about defaults and thus fail if defaults change?
     self.assertEqual(self.course.location, test_grader.course_location, "Course locations")
     self.assertIsNotNone(test_grader.graders, "No graders")
     self.assertIsNotNone(test_grader.grade_cutoffs, "No cutoffs")
Beispiel #51
0
def textbooks_detail_handler(request,
                             tid,
                             tag=None,
                             package_id=None,
                             branch=None,
                             version_guid=None,
                             block=None):
    """
    JSON API endpoint for manipulating a textbook via its internal ID.
    Used by the Backbone application.

    GET
        json: return JSON representation of textbook
    POST or PUT
        json: update textbook based on provided information
    DELETE
        json: remove textbook
    """
    __, course = _get_locator_and_course(package_id, branch, version_guid,
                                         block, request.user)
    store = get_modulestore(course.location)
    matching_id = [
        tb for tb in course.pdf_textbooks
        if unicode(tb.get("id")) == unicode(tid)
    ]
    if matching_id:
        textbook = matching_id[0]
    else:
        textbook = None

    if request.method == 'GET':
        if not textbook:
            return JsonResponse(status=404)
        return JsonResponse(textbook)
    elif request.method in ('POST', 'PUT'):  # can be either and sometimes
        # django is rewriting one to the other
        try:
            new_textbook = validate_textbook_json(request.body)
        except TextbookValidationError as err:
            return JsonResponse({"error": err.message}, status=400)
        new_textbook["id"] = tid
        if textbook:
            i = course.pdf_textbooks.index(textbook)
            new_textbooks = course.pdf_textbooks[0:i]
            new_textbooks.append(new_textbook)
            new_textbooks.extend(course.pdf_textbooks[i + 1:])
            course.pdf_textbooks = new_textbooks
        else:
            course.pdf_textbooks.append(new_textbook)
        store.update_item(course, request.user.id)
        return JsonResponse(new_textbook, status=201)
    elif request.method == 'DELETE':
        if not textbook:
            return JsonResponse(status=404)
        i = course.pdf_textbooks.index(textbook)
        new_textbooks = course.pdf_textbooks[0:i]
        new_textbooks.extend(course.pdf_textbooks[i + 1:])
        course.pdf_textbooks = new_textbooks
        store.update_item(course, request.user.id)
        return JsonResponse()
 def get_section_grader_type(location):
     old_location = loc_mapper().translate_locator_to_location(location)
     descriptor = get_modulestore(old_location).get_item(old_location)
     return {
         "graderType": descriptor.format if descriptor.format is not None else 'notgraded',
         "location": unicode(location),
     }
Beispiel #53
0
def course_audit_api(request, course_id, operation):
    re_json = {"success": False}

    request_method = request.method
    if request_method != "POST":
        return JsonResponse(re_json)
    # get course location and module infomation
    try:
        course_location_info = course_id.split('.')
        locator = BlockUsageLocator(package_id=course_id, branch='draft', version_guid=None, block_id=course_location_info[-1])
        course_location = loc_mapper().translate_locator_to_location(locator)
        course_module = get_modulestore(course_location).get_item(course_location)

        instructors = CourseInstructorRole(locator).users_with_role()
        if len(instructors) <= 0:
            return JsonResponse(re_json)

        user = instructors[0]

        meta_json = {}
        if operation == "pass":
            meta_json["course_audit"] = 1
        elif operation == "offline":
            meta_json["course_audit"] = 0
        else:
            return JsonResponse(re_json)

        re_json["success"] = True
        CourseMetadata.update_from_json(course_module, meta_json, True, user)
        return JsonResponse(re_json)
    except:
        return JsonResponse(re_json)
    def fetch_grader(course_location, index):
        """
        Fetch the course's nth grader
        Returns an empty dict if there's no such grader.
        """
        course_old_location = loc_mapper().translate_locator_to_location(
            course_location)
        descriptor = get_modulestore(course_old_location).get_item(
            course_old_location)

        index = int(index)
        if len(descriptor.raw_grader) > index:
            return CourseGradingModel.jsonize_grader(
                index, descriptor.raw_grader[index])

        # return empty model
        else:
            return {
                "id": index,
                "type": "",
                "min_count": 0,
                "drop_count": 0,
                "short_label": None,
                "weight": 0
            }
Beispiel #55
0
def xml_only_video(step):
    # Create a new video *without* metadata. This requires a certain
    # amount of rummaging to make sure all the correct data is present
    step.given('I have clicked the new unit button')

    # Wait for the new unit to be created and to load the page
    world.wait(1)

    course = world.scenario_dict['COURSE']
    store = get_modulestore(course.location)

    parent_location = store.get_items(course.id,
                                      category='vertical',
                                      revision='draft')[0].location

    youtube_id = 'ABCDEFG'
    world.scenario_dict['YOUTUBE_ID'] = youtube_id

    # Create a new Video component, but ensure that it doesn't have
    # metadata. This allows us to test that we are correctly parsing
    # out XML
    world.ItemFactory.create(
        parent_location=parent_location,
        category='video',
        data='<video youtube="1.00:%s"></video>' % youtube_id,
        modulestore=store,
    )
Beispiel #56
0
def create_textbook(request, org, course, name):
    """
    JSON API endpoint for creating a textbook. Used by the Backbone application.
    """
    location = get_location_and_verify_access(request, org, course, name)
    store = get_modulestore(location)
    course_module = store.get_item(location, depth=0)

    try:
        textbook = validate_textbook_json(request.body)
    except TextbookValidationError as err:
        return JsonResponse({"error": err.message}, status=400)
    if not textbook.get("id"):
        tids = set(t["id"] for t in course_module.pdf_textbooks if "id" in t)
        textbook["id"] = assign_textbook_id(textbook, tids)
    existing = course_module.pdf_textbooks
    existing.append(textbook)
    course_module.pdf_textbooks = existing
    if not any(tab['type'] == 'pdf_textbooks' for tab in course_module.tabs):
        tabs = course_module.tabs
        tabs.append({"type": "pdf_textbooks"})
        course_module.tabs = tabs
    # Save the data that we've just changed to the underlying
    # MongoKeyValueStore before we update the mongo datastore.
    course_module.save()
    store.update_metadata(course_module.location, own_metadata(course_module))
    resp = JsonResponse(textbook, status=201)
    resp["Location"] = reverse("textbook_by_id", kwargs={
        'org': org,
        'course': course,
        'name': name,
        'tid': textbook["id"],
    })
    return resp