Example #1
0
def create_modulestore_instance(
    engine,
    content_store,
    doc_store_config,
    options,
    i18n_service=None,
    fs_service=None,
    user_service=None,
    signal_handler=None,
):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    FUNCTION_KEYS = ['render_template']
    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = get_cache('mongo_metadata_inheritance')
    except InvalidCacheBackendError:
        metadata_inheritance_cache = get_cache('default')

    if issubclass(class_, MixedModuleStore):
        _options['create_modulestore_instance'] = create_modulestore_instance

    if issubclass(class_, BranchSettingMixin):
        _options['branch_setting_func'] = _get_modulestore_branch_setting

    if HAS_USER_SERVICE and not user_service:
        xb_user_service = DjangoXBlockUserService(get_current_user())
    else:
        xb_user_service = None

    if 'read_preference' in doc_store_config:
        doc_store_config['read_preference'] = getattr(
            ReadPreference, doc_store_config['read_preference'])

    return class_(
        contentstore=content_store,
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        xblock_mixins=getattr(settings, 'XBLOCK_MIXINS', ()),
        xblock_select=getattr(settings, 'XBLOCK_SELECT_FUNCTION', None),
        doc_store_config=doc_store_config,
        i18n_service=i18n_service or ModuleI18nService(),
        fs_service=fs_service or xblock.reference.plugins.FSService(),
        user_service=user_service or xb_user_service,
        signal_handler=signal_handler or SignalHandler(class_),
        **_options)
Example #2
0
    def handle(self, *args, **options):
        "Execute the command"
        if len(args) != 2:
            raise CommandError("clone requires two arguments: <source-course_id> <dest-course_id>")

        source_course_id = args[0]
        dest_course_id = args[1]

        mstore = modulestore('direct')
        cstore = contentstore()

        mstore.metadata_inheritance_cache_subsystem = CACHE
        mstore.request_cache = RequestCache.get_request_cache()
        org, course_num, run = dest_course_id.split("/")
        mstore.ignore_write_events_on_courses.append('{0}/{1}'.format(org, course_num))

        print("Cloning course {0} to {1}".format(source_course_id, dest_course_id))

        source_location = CourseDescriptor.id_to_location(source_course_id)
        dest_location = CourseDescriptor.id_to_location(dest_course_id)

        if clone_course(mstore, cstore, source_location, dest_location):
            # be sure to recompute metadata inheritance after all those updates
            mstore.refresh_cached_metadata_inheritance_tree(dest_location)

            print("copying User permissions...")
            _copy_course_group(source_location, dest_location)
Example #3
0
def get_template_request_context():
    """
    Returns the template processing context to use for the current request,
    or returns None if there is not a current request.
    """
    request = getattr(REQUEST_CONTEXT, "request", None)
    if not request:
        return None

    request_cache_dict = RequestCache.get_request_cache().data
    cache_key = "edxmako_request_context"
    if cache_key in request_cache_dict:
        return request_cache_dict[cache_key]

    context = RequestContext(request)
    context['is_secure'] = request.is_secure()
    context['site'] = safe_get_host(request)

    # This used to happen when a RequestContext object was initialized but was
    # moved to a different part of the logic when template engines were introduced.
    # Since we are not using template engines we do this here.
    # https://github.com/django/django/commit/37505b6397058bcc3460f23d48a7de9641cd6ef0
    for processor in get_template_context_processors():
        context.update(processor(request))

    request_cache_dict[cache_key] = context

    return context
Example #4
0
def create_modulestore_instance(engine, options):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = get_cache('mongo_metadata_inheritance')
    except InvalidCacheBackendError:
        metadata_inheritance_cache = get_cache('default')

    return class_(
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        modulestore_update_signal=Signal(
            providing_args=['modulestore', 'course_id', 'location']),
        **_options)
Example #5
0
 def check_team_member(user, content):
     """
     If the content has a commentable_id, verifies that either it is not associated with a team,
     or if it is, that the user is a member of that team.
     """
     if not content:
         return False
     try:
         commentable_id = content['commentable_id']
         request_cache_dict = RequestCache.get_request_cache().data
         cache_key = "django_comment_client.check_team_member.{}.{}".format(
             user.id, commentable_id)
         if cache_key in request_cache_dict:
             return request_cache_dict[cache_key]
         team = get_team(commentable_id)
         if team is None:
             passes_condition = True
         else:
             passes_condition = team.users.filter(id=user.id).exists()
         request_cache_dict[cache_key] = passes_condition
     except KeyError:
         # We do not expect KeyError in production-- it usually indicates an improper test mock.
         logging.warning("Did not find key commentable_id in content.")
         passes_condition = False
     return passes_condition
Example #6
0
def get_template_request_context():
    """
    Returns the template processing context to use for the current request,
    or returns None if there is not a current request.
    """
    request = getattr(REQUEST_CONTEXT, "request", None)
    if not request:
        return None

    request_cache_dict = RequestCache.get_request_cache().data
    cache_key = "edxmako_request_context"
    if cache_key in request_cache_dict:
        return request_cache_dict[cache_key]

    context = RequestContext(request)
    context['is_secure'] = request.is_secure()
    context['site'] = safe_get_host(request)

    # This used to happen when a RequestContext object was initialized but was
    # moved to a different part of the logic when template engines were introduced.
    # Since we are not using template engines we do this here.
    # https://github.com/django/django/commit/37505b6397058bcc3460f23d48a7de9641cd6ef0
    for processor in get_template_context_processors():
        context.update(processor(request))

    request_cache_dict[cache_key] = context

    return context
Example #7
0
def create_modulestore_instance(engine, options):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = get_cache('mongo_metadata_inheritance')
    except InvalidCacheBackendError:
        metadata_inheritance_cache = get_cache('default')

    return class_(
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        modulestore_update_signal=Signal(providing_args=['modulestore', 'course_id', 'location']),
        **_options
    )
Example #8
0
    def handle(self, *args, **options):
        if len(args) != 1 and len(args) != 2:
            raise CommandError("delete_course requires one or more arguments: <location> |commit|")

        course_id = args[0]

        commit = False
        if len(args) == 2:
            commit = args[1] == 'commit'

        if commit:
            print 'Actually going to delete the course from DB....'

        ms = modulestore('direct')
        cs = contentstore()

        ms.metadata_inheritance_cache_subsystem = CACHE
        ms.request_cache = RequestCache.get_request_cache()
        org, course_num, run = course_id.split("/")
        ms.ignore_write_events_on_courses.append('{0}/{1}'.format(org, course_num))

        if query_yes_no("Deleting course {0}. Confirm?".format(course_id), default="no"):
            if query_yes_no("Are you sure. This action cannot be undone!", default="no"):
                loc = CourseDescriptor.id_to_location(course_id)
                if delete_course(ms, cs, loc, commit):
                    print 'removing User permissions from course....'
                    # in the django layer, we need to remove all the user permissions groups associated with this course
                    if commit:
                        _delete_course_group(loc)
Example #9
0
def get_group_info_for_cohort(cohort, use_cached=False):
    """
    Get the ids of the group and partition to which this cohort has been linked
    as a tuple of (int, int).

    If the cohort has not been linked to any group/partition, both values in the
    tuple will be None.

    The partition group info is cached for the duration of a request. Pass
    use_cached=True to use the cached value instead of fetching from the
    database.
    """
    request_cache = RequestCache.get_request_cache()
    cache_key = u"cohorts.get_group_info_for_cohort.{}".format(cohort.id)

    if use_cached and cache_key in request_cache.data:
        return request_cache.data[cache_key]

    request_cache.data.pop(cache_key, None)

    try:
        partition_group = CourseUserGroupPartitionGroup.objects.get(course_user_group=cohort)
        return request_cache.data.setdefault(cache_key, (partition_group.group_id, partition_group.partition_id))
    except CourseUserGroupPartitionGroup.DoesNotExist:
        pass

    return request_cache.data.setdefault(cache_key, (None, None))
Example #10
0
def get_group_info_for_cohort(cohort, use_cached=False):
    """
    Get the ids of the group and partition to which this cohort has been linked
    as a tuple of (int, int).

    If the cohort has not been linked to any group/partition, both values in the
    tuple will be None.

    The partition group info is cached for the duration of a request. Pass
    use_cached=True to use the cached value instead of fetching from the
    database.
    """
    request_cache = RequestCache.get_request_cache()
    cache_key = u"cohorts.get_group_info_for_cohort.{}".format(cohort.id)

    if use_cached and cache_key in request_cache.data:
        return request_cache.data[cache_key]

    request_cache.data.pop(cache_key, None)

    try:
        partition_group = CourseUserGroupPartitionGroup.objects.get(
            course_user_group=cohort)
        return request_cache.data.setdefault(
            cache_key,
            (partition_group.group_id, partition_group.partition_id))
    except CourseUserGroupPartitionGroup.DoesNotExist:
        pass

    return request_cache.data.setdefault(cache_key, (None, None))
Example #11
0
def create_modulestore_instance(engine, doc_store_config, options, i18n_service=None):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = get_cache('mongo_metadata_inheritance')
    except InvalidCacheBackendError:
        metadata_inheritance_cache = get_cache('default')

    return class_(
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        modulestore_update_signal=Signal(providing_args=['modulestore', 'course_id', 'location']),
        xblock_mixins=getattr(settings, 'XBLOCK_MIXINS', ()),
        xblock_select=getattr(settings, 'XBLOCK_SELECT_FUNCTION', None),
        doc_store_config=doc_store_config,
        i18n_service=i18n_service or ModuleI18nService(),
        **_options
    )
Example #12
0
def create_modulestore_instance(
    engine,
    content_store,
    doc_store_config,
    options,
    i18n_service=None,
    fs_service=None,
    user_service=None,
    signal_handler=None,
):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    FUNCTION_KEYS = ["render_template"]
    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = get_cache("mongo_metadata_inheritance")
    except InvalidCacheBackendError:
        metadata_inheritance_cache = get_cache("default")

    if issubclass(class_, MixedModuleStore):
        _options["create_modulestore_instance"] = create_modulestore_instance

    if issubclass(class_, BranchSettingMixin):
        _options["branch_setting_func"] = _get_modulestore_branch_setting

    if HAS_USER_SERVICE and not user_service:
        xb_user_service = DjangoXBlockUserService(get_current_user())
    else:
        xb_user_service = None

    if "read_preference" in doc_store_config:
        doc_store_config["read_preference"] = getattr(ReadPreference, doc_store_config["read_preference"])

    return class_(
        contentstore=content_store,
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        xblock_mixins=getattr(settings, "XBLOCK_MIXINS", ()),
        xblock_select=getattr(settings, "XBLOCK_SELECT_FUNCTION", None),
        doc_store_config=doc_store_config,
        i18n_service=i18n_service or ModuleI18nService(),
        fs_service=fs_service or xblock.reference.plugins.FSService(),
        user_service=user_service or xb_user_service,
        signal_handler=signal_handler or SignalHandler(class_),
        **_options
    )
Example #13
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("check_course requires one argument: <location>")

        loc_str = args[0]

        loc = CourseDescriptor.id_to_location(loc_str)
        store = modulestore()

        # setup a request cache so we don't throttle the DB with all the metadata inheritance requests
        store.set_modulestore_configuration({
            'metadata_inheritance_cache_subsystem': CACHE,
            'request_cache': RequestCache.get_request_cache()
        })

        course = store.get_item(loc, depth=3)

        err_cnt = 0

        def _xlint_metadata(module):
            err_cnt = check_module_metadata_editability(module)
            for child in module.get_children():
                err_cnt = err_cnt + _xlint_metadata(child)
            return err_cnt

        err_cnt = err_cnt + _xlint_metadata(course)

        # we've had a bug where the xml_attributes field can we rewritten as a string rather than a dict
        def _check_xml_attributes_field(module):
            err_cnt = 0
            if hasattr(module, 'xml_attributes') and isinstance(module.xml_attributes, basestring):
                print 'module = {0} has xml_attributes as a string. It should be a dict'.format(module.location.url())
                err_cnt = err_cnt + 1
            for child in module.get_children():
                err_cnt = err_cnt + _check_xml_attributes_field(child)
            return err_cnt

        err_cnt = err_cnt + _check_xml_attributes_field(course)

        # check for dangling discussion items, this can cause errors in the forums
        def _get_discussion_items(module):
            discussion_items = []
            if module.location.category == 'discussion':
                discussion_items = discussion_items + [module.location.url()]

            for child in module.get_children():
                discussion_items = discussion_items + _get_discussion_items(child)

            return discussion_items

        discussion_items = _get_discussion_items(course)

        # now query all discussion items via get_items() and compare with the tree-traversal
        queried_discussion_items = store.get_items(['i4x', course.location.org, course.location.course,
                                                    'discussion', None, None])

        for item in queried_discussion_items:
            if item.location.url() not in discussion_items:
                print 'Found dangling discussion module = {0}'.format(item.location.url())
 def _enable_storage(self):
     """
     Enables storage backing by setting the waffle's cached value to True.
     """
     cache_key = func_call_cache_key(
         is_switch_enabled.request_cached_contained_func,
         _bs_waffle_switch_name(STORAGE_BACKING_FOR_CACHE),
     )
     RequestCache.get_request_cache().data[cache_key] = True
     log.warning(u'STORAGE_BACKING_FOR_CACHE is enabled.')
Example #15
0
def get_cohort(user, course_key, assign=True, use_cached=False):
    """Returns the user's cohort for the specified course.

    The cohort for the user is cached for the duration of a request. Pass
    use_cached=True to use the cached value instead of fetching from the
    database.

    Arguments:
        user: a Django User object.
        course_key: CourseKey
        assign (bool): if False then we don't assign a group to user
        use_cached (bool): Whether to use the cached value or fetch from database.

    Returns:
        A CourseUserGroup object if the course is cohorted and the User has a
        cohort, else None.

    Raises:
       ValueError if the CourseKey doesn't exist.
    """
    request_cache = RequestCache.get_request_cache()
    cache_key = u"cohorts.get_cohort.{}.{}".format(user.id, course_key)

    if use_cached and cache_key in request_cache.data:
        return request_cache.data[cache_key]

    request_cache.data.pop(cache_key, None)

    # First check whether the course is cohorted (users shouldn't be in a cohort
    # in non-cohorted courses, but settings can change after course starts)
    course_cohort_settings = get_course_cohort_settings(course_key)
    if not course_cohort_settings.is_cohorted:
        return request_cache.data.setdefault(cache_key, None)

    # If course is cohorted, check if the user already has a cohort.
    try:
        membership = CohortMembership.objects.get(
            course_id=course_key,
            user_id=user.id,
        )
        return request_cache.data.setdefault(cache_key, membership.course_user_group)
    except CohortMembership.DoesNotExist:
        # Didn't find the group. If we do not want to assign, return here.
        if not assign:
            # Do not cache the cohort here, because in the next call assign
            # may be True, and we will have to assign the user a cohort.
            return None

    # Otherwise assign the user a cohort.
    membership = CohortMembership.objects.create(
        user=user,
        course_user_group=get_random_cohort(course_key)
    )
    return request_cache.data.setdefault(cache_key, membership.course_user_group)
Example #16
0
def get_cohort(user, course_key, assign=True, use_cached=False):
    """Returns the user's cohort for the specified course.

    The cohort for the user is cached for the duration of a request. Pass
    use_cached=True to use the cached value instead of fetching from the
    database.

    Arguments:
        user: a Django User object.
        course_key: CourseKey
        assign (bool): if False then we don't assign a group to user
        use_cached (bool): Whether to use the cached value or fetch from database.

    Returns:
        A CourseUserGroup object if the course is cohorted and the User has a
        cohort, else None.

    Raises:
       ValueError if the CourseKey doesn't exist.
    """
    request_cache = RequestCache.get_request_cache()
    cache_key = u"cohorts.get_cohort.{}.{}".format(user.id, course_key)

    if use_cached and cache_key in request_cache.data:
        return request_cache.data[cache_key]

    request_cache.data.pop(cache_key, None)

    # First check whether the course is cohorted (users shouldn't be in a cohort
    # in non-cohorted courses, but settings can change after course starts)
    course_cohort_settings = get_course_cohort_settings(course_key)
    if not course_cohort_settings.is_cohorted:
        return request_cache.data.setdefault(cache_key, None)

    # If course is cohorted, check if the user already has a cohort.
    try:
        membership = CohortMembership.objects.get(
            course_id=course_key,
            user_id=user.id,
        )
        return request_cache.data.setdefault(cache_key,
                                             membership.course_user_group)
    except CohortMembership.DoesNotExist:
        # Didn't find the group. If we do not want to assign, return here.
        if not assign:
            # Do not cache the cohort here, because in the next call assign
            # may be True, and we will have to assign the user a cohort.
            return None

    # Otherwise assign the user a cohort.
    membership = CohortMembership.objects.create(
        user=user, course_user_group=get_random_cohort(course_key))
    return request_cache.data.setdefault(cache_key,
                                         membership.course_user_group)
Example #17
0
def has_permission(user, permission, course_id=None):
    assert isinstance(course_id, (NoneType, CourseKey))
    request_cache_dict = RequestCache.get_request_cache().data
    cache_key = "django_comment_client.permissions.has_permission.all_permissions.{}.{}".format(
        user.id, course_id)
    if cache_key in request_cache_dict:
        all_permissions = request_cache_dict[cache_key]
    else:
        all_permissions = all_permissions_for_user_in_course(user, course_id)
        request_cache_dict[cache_key] = all_permissions

    return permission in all_permissions
Example #18
0
def enable_for_current_request(setting_name):
    """
    Enables the given block_structure setting for the
    duration of the current request.
    """
    cache_key = func_call_cache_key(
        is_switch_enabled.request_cached_contained_func,
        _bs_waffle_switch_name(setting_name),
    )
    RequestCache.get_request_cache().data[cache_key] = True
    log.warning(u'BlockStructure: Config %s is enabled for current request.',
                setting_name)
Example #19
0
    def _bookmarks_cache(self, course_key, fetch=False):
        """
        Return the user's bookmarks cache for a particular course.

        Arguments:
            course_key (CourseKey): course_key of the course whose bookmarks cache should be returned.
            fetch (Bool): if the bookmarks should be fetched and cached if they already aren't.
        """
        store = modulestore()
        course_key = store.fill_in_run(course_key)
        if course_key.run is None:
            return []
        cache_key = CACHE_KEY_TEMPLATE.format(self._user.id, course_key)

        bookmarks_cache = RequestCache.get_request_cache().data.get(cache_key, None)
        if bookmarks_cache is None and fetch is True:
            bookmarks_cache = api.get_bookmarks(
                self._user, course_key=course_key, fields=DEFAULT_FIELDS
            )
            RequestCache.get_request_cache().data[cache_key] = bookmarks_cache

        return bookmarks_cache
Example #20
0
def has_permission(user, permission, course_id=None):
    assert isinstance(course_id, (NoneType, CourseKey))
    request_cache_dict = RequestCache.get_request_cache().data
    cache_key = "django_comment_client.permissions.has_permission.all_permissions.{}.{}".format(
        user.id, course_id
    )
    if cache_key in request_cache_dict:
        all_permissions = request_cache_dict[cache_key]
    else:
        all_permissions = all_permissions_for_user_in_course(user, course_id)
        request_cache_dict[cache_key] = all_permissions

    return permission in all_permissions
Example #21
0
 def __init__(self, **kwargs):
     request_cache_dict = RequestCache.get_request_cache().data
     services = kwargs.setdefault('services', {})
     services['user_tags'] = UserTagsService(self)
     services['partitions'] = LmsPartitionService(
         user=kwargs.get('user'),
         course_id=kwargs.get('course_id'),
         track_function=kwargs.get('track_function', None),
         cache=request_cache_dict)
     services['library_tools'] = LibraryToolsService(modulestore())
     services['fs'] = xblock.reference.plugins.FSService()
     services['settings'] = SettingsService()
     self.request_token = kwargs.pop('request_token', None)
     super(LmsModuleSystem, self).__init__(**kwargs)
Example #22
0
def get_team(commentable_id):
    """ Returns the team that the commentable_id belongs to if it exists. Returns None otherwise. """
    request_cache_dict = RequestCache.get_request_cache().data
    cache_key = "django_comment_client.team_commentable.{}".format(commentable_id)
    if cache_key in request_cache_dict:
        return request_cache_dict[cache_key]

    try:
        team = CourseTeam.objects.get(discussion_topic_id=commentable_id)
    except CourseTeam.DoesNotExist:
        team = None

    request_cache_dict[cache_key] = team
    return team
Example #23
0
def get_team(commentable_id):
    """ Returns the team that the commentable_id belongs to if it exists. Returns None otherwise. """
    request_cache_dict = RequestCache.get_request_cache().data
    cache_key = u"django_comment_client.team_commentable.{}".format(commentable_id)
    if cache_key in request_cache_dict:
        return request_cache_dict[cache_key]

    try:
        team = CourseTeam.objects.get(discussion_topic_id=commentable_id)
    except CourseTeam.DoesNotExist:
        team = None

    request_cache_dict[cache_key] = team
    return team
Example #24
0
 def __init__(self, **kwargs):
     request_cache_dict = RequestCache.get_request_cache().data
     services = kwargs.setdefault('services', {})
     services['user_tags'] = UserTagsService(self)
     services['partitions'] = LmsPartitionService(
         user=kwargs.get('user'),
         course_id=kwargs.get('course_id'),
         track_function=kwargs.get('track_function', None),
         cache=request_cache_dict
     )
     services['library_tools'] = LibraryToolsService(modulestore())
     services['fs'] = xblock.reference.plugins.FSService()
     services['settings'] = SettingsService()
     self.request_token = kwargs.pop('request_token', None)
     super(LmsModuleSystem, self).__init__(**kwargs)
Example #25
0
 def __init__(self, **kwargs):
     request_cache_dict = RequestCache.get_request_cache().data
     services = kwargs.setdefault('services', {})
     services['fs'] = xblock.reference.plugins.FSService()
     services['i18n'] = ModuleI18nService
     services['library_tools'] = LibraryToolsService(modulestore())
     services['partitions'] = PartitionService(
         course_id=kwargs.get('course_id'), cache=request_cache_dict)
     store = modulestore()
     services['settings'] = SettingsService()
     services['user_tags'] = UserTagsService(self)
     if badges_enabled():
         services['badging'] = BadgingService(
             course_id=kwargs.get('course_id'), modulestore=store)
     self.request_token = kwargs.pop('request_token', None)
     super(LmsModuleSystem, self).__init__(**kwargs)
Example #26
0
 def __init__(self, **kwargs):
     request_cache_dict = RequestCache.get_request_cache().data
     services = kwargs.setdefault('services', {})
     services['fs'] = xblock.reference.plugins.FSService()
     services['i18n'] = ModuleI18nService
     services['library_tools'] = LibraryToolsService(modulestore())
     services['partitions'] = PartitionService(
         course_id=kwargs.get('course_id'),
         cache=request_cache_dict
     )
     store = modulestore()
     services['settings'] = SettingsService()
     services['user_tags'] = UserTagsService(self)
     if badges_enabled():
         services['badging'] = BadgingService(course_id=kwargs.get('course_id'), modulestore=store)
     self.request_token = kwargs.pop('request_token', None)
     super(LmsModuleSystem, self).__init__(**kwargs)
Example #27
0
    def handle(self, *args, **options):
        if len(args) != 1 and len(args) != 2:
            raise CommandError(
                "delete_course requires one or more arguments: <location> |commit|"
            )

        course_id = args[0]

        commit = False
        if len(args) == 2:
            commit = args[1] == 'commit'

        if commit:
            print 'Actually going to delete the course from DB....'

        ms = modulestore('direct')
        cs = contentstore()

        ms.set_modulestore_configuration({
            'metadata_inheritance_cache_subsystem':
            CACHE,
            'request_cache':
            RequestCache.get_request_cache()
        })

        org, course_num, run = course_id.split("/")
        ms.ignore_write_events_on_courses.append('{0}/{1}'.format(
            org, course_num))

        if query_yes_no("Deleting course {0}. Confirm?".format(course_id),
                        default="no"):
            if query_yes_no("Are you sure. This action cannot be undone!",
                            default="no"):
                loc = CourseDescriptor.id_to_location(course_id)
                if delete_course(ms, cs, loc, commit):
                    print 'removing User permissions from course....'
                    # in the django layer, we need to remove all the user permissions groups associated with this course
                    if commit:
                        try:
                            _delete_course_group(loc)
                        except Exception as err:
                            print(
                                "Error in deleting course groups for {0}: {1}".
                                format(loc, err))
Example #28
0
    def _providers_for_course(cls, course):
        """
        Return a filtered list of enabled providers based
        on the course passed in. Cache this result per request to avoid
        needing to call the provider filter api hundreds of times.

        Arguments:
            course: The course XBlock
        """
        request_cache = RequestCache.get_request_cache()
        enabled_providers = request_cache.data.get(
            ENABLED_OVERRIDE_PROVIDERS_KEY, NOTSET
        )
        if enabled_providers == NOTSET:
            enabled_providers = tuple(
                (provider_class for provider_class in cls.provider_classes if provider_class.enabled_for(course))
            )
            request_cache.data[ENABLED_OVERRIDE_PROVIDERS_KEY] = enabled_providers

        return enabled_providers
Example #29
0
def create_modulestore_instance(engine, content_store, doc_store_config, options, i18n_service=None, fs_service=None):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    FUNCTION_KEYS = ['render_template']
    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = get_cache('mongo_metadata_inheritance')
    except InvalidCacheBackendError:
        metadata_inheritance_cache = get_cache('default')

    if issubclass(class_, MixedModuleStore):
        _options['create_modulestore_instance'] = create_modulestore_instance

    if issubclass(class_, BranchSettingMixin):
        _options['branch_setting_func'] = _get_modulestore_branch_setting

    return class_(
        contentstore=content_store,
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        xblock_mixins=getattr(settings, 'XBLOCK_MIXINS', ()),
        xblock_select=getattr(settings, 'XBLOCK_SELECT_FUNCTION', None),
        doc_store_config=doc_store_config,
        i18n_service=i18n_service or ModuleI18nService(),
        fs_service=fs_service or xblock.reference.plugins.FSService(),
        **_options
    )
Example #30
0
def create_modulestore_instance(engine,
                                content_store,
                                doc_store_config,
                                options,
                                i18n_service=None,
                                fs_service=None):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    FUNCTION_KEYS = ['render_template']
    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = get_cache('mongo_metadata_inheritance')
    except InvalidCacheBackendError:
        metadata_inheritance_cache = get_cache('default')

    return class_(
        contentstore=content_store,
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        xblock_mixins=getattr(settings, 'XBLOCK_MIXINS', ()),
        xblock_select=getattr(settings, 'XBLOCK_SELECT_FUNCTION', None),
        doc_store_config=doc_store_config,
        i18n_service=i18n_service or ModuleI18nService(),
        fs_service=fs_service or xblock.reference.plugins.FSService(),
        branch_setting_func=_get_modulestore_branch_setting,
        create_modulestore_instance=create_modulestore_instance,
        **_options)
    def _providers_for_block(cls, block):
        """
        Computes a list of enabled providers based on the given XBlock.
        The result is cached per request to avoid the overhead incurred
        by filtering override providers hundreds of times.

        Arguments:
            block: An XBlock
        """
        course_id = unicode(block.location.course_key)
        cache_key = ENABLED_MODULESTORE_OVERRIDE_PROVIDERS_KEY.format(course_id=course_id)

        request_cache = RequestCache.get_request_cache()
        enabled_providers = request_cache.data.get(cache_key)

        if enabled_providers is None:
            enabled_providers = [
                provider_class for provider_class in cls.provider_classes if provider_class.enabled_for(block)
            ]
            request_cache.data[cache_key] = enabled_providers

        return enabled_providers
Example #32
0
    def _providers_for_block(cls, block):
        """
        Computes a list of enabled providers based on the given XBlock.
        The result is cached per request to avoid the overhead incurred
        by filtering override providers hundreds of times.

        Arguments:
            block: An XBlock
        """
        course_id = unicode(block.location.course_key)
        cache_key = ENABLED_MODULESTORE_OVERRIDE_PROVIDERS_KEY.format(course_id=course_id)

        request_cache = RequestCache.get_request_cache()
        enabled_providers = request_cache.data.get(cache_key)

        if enabled_providers is None:
            enabled_providers = [
                provider_class for provider_class in cls.provider_classes if provider_class.enabled_for(block)
            ]
            request_cache.data[cache_key] = enabled_providers

        return enabled_providers
Example #33
0
def create_modulestore_instance(engine, content_store, doc_store_config, options, i18n_service=None):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    FUNCTION_KEYS = ["render_template"]
    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = get_cache("mongo_metadata_inheritance")
    except InvalidCacheBackendError:
        metadata_inheritance_cache = get_cache("default")

    return class_(
        contentstore=content_store,
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        xblock_mixins=getattr(settings, "XBLOCK_MIXINS", ()),
        xblock_select=getattr(settings, "XBLOCK_SELECT_FUNCTION", None),
        doc_store_config=doc_store_config,
        i18n_service=i18n_service or ModuleI18nService(),
        branch_setting_func=_get_modulestore_branch_setting,
        create_modulestore_instance=create_modulestore_instance,
        **_options
    )
Example #34
0
 def check_team_member(user, content):
     """
     If the content has a commentable_id, verifies that either it is not associated with a team,
     or if it is, that the user is a member of that team.
     """
     if not content:
         return False
     try:
         commentable_id = content['commentable_id']
         request_cache_dict = RequestCache.get_request_cache().data
         cache_key = u"django_comment_client.check_team_member.{}.{}".format(user.id, commentable_id)
         if cache_key in request_cache_dict:
             return request_cache_dict[cache_key]
         team = get_team(commentable_id)
         if team is None:
             passes_condition = True
         else:
             passes_condition = team.users.filter(id=user.id).exists()
         request_cache_dict[cache_key] = passes_condition
     except KeyError:
         # We do not expect KeyError in production-- it usually indicates an improper test mock.
         logging.warning("Did not find key commentable_id in content.")
         passes_condition = False
     return passes_condition
Example #35
0
 def _clear_cache(self):
     """
     Clears the requestcached values on the is_switch_enabled function.
     """
     cache_key = func_call_cache_key(is_switch_enabled.request_cached_contained_func, self.name)
     RequestCache.get_request_cache().data.pop(cache_key, None)
Example #36
0
def create_modulestore_instance(
    engine,
    content_store,
    doc_store_config,
    options,
    i18n_service=None,
    fs_service=None,
    user_service=None,
    signal_handler=None,
):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    FUNCTION_KEYS = ['render_template']
    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = caches['mongo_metadata_inheritance']
    except InvalidCacheBackendError:
        metadata_inheritance_cache = caches['default']

    if issubclass(class_, MixedModuleStore):
        _options['create_modulestore_instance'] = create_modulestore_instance

    if issubclass(class_, BranchSettingMixin):
        _options['branch_setting_func'] = _get_modulestore_branch_setting

    if HAS_USER_SERVICE and not user_service:
        xb_user_service = DjangoXBlockUserService(get_current_user())
    else:
        xb_user_service = None

    if 'read_preference' in doc_store_config:
        doc_store_config['read_preference'] = getattr(
            ReadPreference, doc_store_config['read_preference'])

    if XBlockDisableConfig and settings.FEATURES.get(
            'ENABLE_DISABLING_XBLOCK_TYPES', False):
        disabled_xblock_types = XBlockDisableConfig.disabled_block_types()
    else:
        disabled_xblock_types = ()

    xblock_field_data_wrappers = [
        load_function(path) for path in settings.XBLOCK_FIELD_DATA_WRAPPERS
    ]

    return class_(
        contentstore=content_store,
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        xblock_mixins=getattr(settings, 'XBLOCK_MIXINS', ()),
        xblock_select=getattr(settings, 'XBLOCK_SELECT_FUNCTION', None),
        xblock_field_data_wrappers=xblock_field_data_wrappers,
        disabled_xblock_types=disabled_xblock_types,
        doc_store_config=doc_store_config,
        i18n_service=i18n_service or ModuleI18nService(),
        fs_service=fs_service or xblock.reference.plugins.FSService(),
        user_service=user_service or xb_user_service,
        signal_handler=signal_handler or SignalHandler(class_),
        **_options)
Example #37
0
from dogapi import dog_http_api, dog_stats_api
from django.conf import settings
from xmodule.modulestore.django import modulestore
from django.dispatch import Signal
from request_cache.middleware import RequestCache

from django.core.cache import get_cache

CACHE = get_cache('mongo_metadata_inheritance')
for store_name in settings.MODULESTORE:
    store = modulestore(store_name)
    store.metadata_inheritance_cache_subsystem = CACHE
    store.request_cache = RequestCache.get_request_cache()

    modulestore_update_signal = Signal(
        providing_args=['modulestore', 'course_id', 'location'])
    store.modulestore_update_signal = modulestore_update_signal
if hasattr(settings, 'DATADOG_API'):
    dog_http_api.api_key = settings.DATADOG_API
    dog_stats_api.start(api_key=settings.DATADOG_API, statsd=True)
Example #38
0
def get_cohort(user, course_key, assign=True, use_cached=False):
    """Returns the user's cohort for the specified course.

    The cohort for the user is cached for the duration of a request. Pass
    use_cached=True to use the cached value instead of fetching from the
    database.

    Arguments:
        user: a Django User object.
        course_key: CourseKey
        assign (bool): if False then we don't assign a group to user
        use_cached (bool): Whether to use the cached value or fetch from database.

    Returns:
        A CourseUserGroup object if the course is cohorted and the User has a
        cohort, else None.

    Raises:
       ValueError if the CourseKey doesn't exist.
    """
    request_cache = RequestCache.get_request_cache()
    cache_key = u"cohorts.get_cohort.{}.{}".format(user.id, course_key)

    if use_cached and cache_key in request_cache.data:
        return request_cache.data[cache_key]

    request_cache.data.pop(cache_key, None)

    # First check whether the course is cohorted (users shouldn't be in a cohort
    # in non-cohorted courses, but settings can change after course starts)
    course_cohort_settings = get_course_cohort_settings(course_key)
    if not course_cohort_settings.is_cohorted:
        return request_cache.data.setdefault(cache_key, None)

    # If course is cohorted, check if the user already has a cohort.
    try:
        membership = CohortMembership.objects.get(
            course_id=course_key,
            user_id=user.id,
        )
        return request_cache.data.setdefault(cache_key, membership.course_user_group)
    except CohortMembership.DoesNotExist:
        # Didn't find the group. If we do not want to assign, return here.
        if not assign:
            # Do not cache the cohort here, because in the next call assign
            # may be True, and we will have to assign the user a cohort.
            return None

    # Otherwise assign the user a cohort.
    try:
        with transaction.atomic():
            membership = CohortMembership.objects.create(
                user=user,
                course_user_group=get_random_cohort(course_key)
            )
            return request_cache.data.setdefault(cache_key, membership.course_user_group)
    except IntegrityError as integrity_error:
        # An IntegrityError is raised when multiple workers attempt to
        # create the same row in one of the cohort model entries:
        # CourseCohort, CohortMembership.
        log.info(
            "HANDLING_INTEGRITY_ERROR: IntegrityError encountered for course '%s' and user '%s': %s",
            course_key, user.id, unicode(integrity_error)
        )
        return get_cohort(user, course_key, assign, use_cached)
Example #39
0
from dogapi import dog_http_api, dog_stats_api
from django.conf import settings
from xmodule.modulestore.django import modulestore
from django.dispatch import Signal
from request_cache.middleware import RequestCache

from django.core.cache import get_cache

cache = get_cache('mongo_metadata_inheritance')
for store_name in settings.MODULESTORE:
    store = modulestore(store_name)
    store.metadata_inheritance_cache_subsystem = cache
    store.request_cache = RequestCache.get_request_cache()

    modulestore_update_signal = Signal(providing_args=['modulestore', 'course_id', 'location'])
    store.modulestore_update_signal = modulestore_update_signal
if hasattr(settings, 'DATADOG_API'):
    dog_http_api.api_key = settings.DATADOG_API
    dog_stats_api.start(api_key=settings.DATADOG_API, statsd=True)
Example #40
0
def create_modulestore_instance(
        engine,
        content_store,
        doc_store_config,
        options,
        i18n_service=None,
        fs_service=None,
        user_service=None,
        signal_handler=None,
):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    FUNCTION_KEYS = ['render_template']
    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = caches['mongo_metadata_inheritance']
    except InvalidCacheBackendError:
        metadata_inheritance_cache = caches['default']

    if issubclass(class_, MixedModuleStore):
        _options['create_modulestore_instance'] = create_modulestore_instance

    if issubclass(class_, BranchSettingMixin):
        _options['branch_setting_func'] = _get_modulestore_branch_setting

    if HAS_USER_SERVICE and not user_service:
        xb_user_service = DjangoXBlockUserService(get_current_user())
    else:
        xb_user_service = None

    if 'read_preference' in doc_store_config:
        doc_store_config['read_preference'] = getattr(ReadPreference, doc_store_config['read_preference'])

    xblock_field_data_wrappers = [load_function(path) for path in settings.XBLOCK_FIELD_DATA_WRAPPERS]

    def fetch_disabled_xblock_types():
        """
        Get the disabled xblock names, using the request_cache if possible to avoid hitting
        a database every time the list is needed.
        """
        # If the import could not be loaded, return an empty list.
        if disabled_xblocks is None:
            return []

        if request_cache:
            if 'disabled_xblock_types' not in request_cache.data:
                request_cache.data['disabled_xblock_types'] = [block.name for block in disabled_xblocks()]
            return request_cache.data['disabled_xblock_types']
        else:
            disabled_xblock_types = [block.name for block in disabled_xblocks()]

        return disabled_xblock_types

    return class_(
        contentstore=content_store,
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        xblock_mixins=getattr(settings, 'XBLOCK_MIXINS', ()),
        xblock_select=getattr(settings, 'XBLOCK_SELECT_FUNCTION', None),
        xblock_field_data_wrappers=xblock_field_data_wrappers,
        disabled_xblock_types=fetch_disabled_xblock_types,
        doc_store_config=doc_store_config,
        i18n_service=i18n_service or ModuleI18nService,
        fs_service=fs_service or xblock.reference.plugins.FSService(),
        user_service=user_service or xb_user_service,
        signal_handler=signal_handler or SignalHandler(class_),
        **_options
    )
Example #41
0
from dogapi import dog_http_api, dog_stats_api
from django.conf import settings
from xmodule.modulestore.django import modulestore
from django.dispatch import Signal
from request_cache.middleware import RequestCache

from django.core.cache import get_cache

CACHE = get_cache('mongo_metadata_inheritance')
for store_name in settings.MODULESTORE:
    store = modulestore(store_name)

    store.set_modulestore_configuration({
        'metadata_inheritance_cache_subsystem': CACHE,
        'request_cache': RequestCache.get_request_cache()
    })

    modulestore_update_signal = Signal(providing_args=['modulestore', 'course_id', 'location'])
    store.modulestore_update_signal = modulestore_update_signal
if hasattr(settings, 'DATADOG_API'):
    dog_http_api.api_key = settings.DATADOG_API
    dog_stats_api.start(api_key=settings.DATADOG_API, statsd=True)
from dogapi import dog_http_api, dog_stats_api
from django.conf import settings
from xmodule.modulestore.django import modulestore
from request_cache.middleware import RequestCache

from django.core.cache import get_cache

cache = get_cache('mongo_metadata_inheritance')
for store_name in settings.MODULESTORE:
    store = modulestore(store_name)
    store.set_modulestore_configuration({
        'metadata_inheritance_cache_subsystem': cache,
        'request_cache': RequestCache.get_request_cache()
    })

if hasattr(settings, 'DATADOG_API'):
    dog_http_api.api_key = settings.DATADOG_API
    dog_stats_api.start(api_key=settings.DATADOG_API, statsd=True)
Example #43
0
def create_modulestore_instance(
        engine,
        content_store,
        doc_store_config,
        options,
        i18n_service=None,
        fs_service=None,
        user_service=None,
        signal_handler=None,
):
    """
    This will return a new instance of a modulestore given an engine and options
    """
    class_ = load_function(engine)

    _options = {}
    _options.update(options)

    FUNCTION_KEYS = ['render_template']
    for key in FUNCTION_KEYS:
        if key in _options and isinstance(_options[key], basestring):
            _options[key] = load_function(_options[key])

    if HAS_REQUEST_CACHE:
        request_cache = RequestCache.get_request_cache()
    else:
        request_cache = None

    try:
        metadata_inheritance_cache = caches['mongo_metadata_inheritance']
    except InvalidCacheBackendError:
        metadata_inheritance_cache = caches['default']

    if issubclass(class_, MixedModuleStore):
        _options['create_modulestore_instance'] = create_modulestore_instance

    if issubclass(class_, BranchSettingMixin):
        _options['branch_setting_func'] = _get_modulestore_branch_setting

    if HAS_USER_SERVICE and not user_service:
        xb_user_service = DjangoXBlockUserService(get_current_user())
    else:
        xb_user_service = None

    if 'read_preference' in doc_store_config:
        doc_store_config['read_preference'] = getattr(ReadPreference, doc_store_config['read_preference'])

    if XBlockDisableConfig and settings.FEATURES.get('ENABLE_DISABLING_XBLOCK_TYPES', False):
        disabled_xblock_types = XBlockDisableConfig.disabled_block_types()
    else:
        disabled_xblock_types = ()

    return class_(
        contentstore=content_store,
        metadata_inheritance_cache_subsystem=metadata_inheritance_cache,
        request_cache=request_cache,
        xblock_mixins=getattr(settings, 'XBLOCK_MIXINS', ()),
        xblock_select=getattr(settings, 'XBLOCK_SELECT_FUNCTION', None),
        disabled_xblock_types=disabled_xblock_types,
        doc_store_config=doc_store_config,
        i18n_service=i18n_service or ModuleI18nService(),
        fs_service=fs_service or xblock.reference.plugins.FSService(),
        user_service=user_service or xb_user_service,
        signal_handler=signal_handler or SignalHandler(class_),
        **_options
    )
Example #44
0
def get_cohort(user, course_key, assign=True, use_cached=False):
    """Returns the user's cohort for the specified course.

    The cohort for the user is cached for the duration of a request. Pass
    use_cached=True to use the cached value instead of fetching from the
    database.

    Arguments:
        user: a Django User object.
        course_key: CourseKey
        assign (bool): if False then we don't assign a group to user
        use_cached (bool): Whether to use the cached value or fetch from database.

    Returns:
        A CourseUserGroup object if the course is cohorted and the User has a
        cohort, else None.

    Raises:
       ValueError if the CourseKey doesn't exist.
    """
    request_cache = RequestCache.get_request_cache()
    cache_key = u"cohorts.get_cohort.{}.{}".format(user.id, course_key)

    if use_cached and cache_key in request_cache.data:
        return request_cache.data[cache_key]

    request_cache.data.pop(cache_key, None)

    # First check whether the course is cohorted (users shouldn't be in a cohort
    # in non-cohorted courses, but settings can change after course starts)
    course_cohort_settings = get_course_cohort_settings(course_key)
    if not course_cohort_settings.is_cohorted:
        return request_cache.data.setdefault(cache_key, None)

    # If course is cohorted, check if the user already has a cohort.
    try:
        membership = CohortMembership.objects.get(
            course_id=course_key,
            user_id=user.id,
        )
        return request_cache.data.setdefault(cache_key,
                                             membership.course_user_group)
    except CohortMembership.DoesNotExist:
        # Didn't find the group. If we do not want to assign, return here.
        if not assign:
            # Do not cache the cohort here, because in the next call assign
            # may be True, and we will have to assign the user a cohort.
            return None

    # Otherwise assign the user a cohort.
    try:
        with transaction.atomic():
            membership = CohortMembership.objects.create(
                user=user, course_user_group=get_random_cohort(course_key))
            return request_cache.data.setdefault(cache_key,
                                                 membership.course_user_group)
    except IntegrityError as integrity_error:
        # An IntegrityError is raised when multiple workers attempt to
        # create the same row in one of the cohort model entries:
        # CourseCohort, CohortMembership.
        log.info(
            "HANDLING_INTEGRITY_ERROR: IntegrityError encountered for course '%s' and user '%s': %s",
            course_key, user.id, unicode(integrity_error))
        return get_cohort(user, course_key, assign, use_cached)
Example #45
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError(
                "check_course requires one argument: <location>")

        loc_str = args[0]

        loc = CourseDescriptor.id_to_location(loc_str)
        store = modulestore()

        # setup a request cache so we don't throttle the DB with all the metadata inheritance requests
        store.set_modulestore_configuration({
            'metadata_inheritance_cache_subsystem':
            CACHE,
            'request_cache':
            RequestCache.get_request_cache()
        })

        course = store.get_item(loc, depth=3)

        err_cnt = 0

        def _xlint_metadata(module):
            err_cnt = check_module_metadata_editability(module)
            for child in module.get_children():
                err_cnt = err_cnt + _xlint_metadata(child)
            return err_cnt

        err_cnt = err_cnt + _xlint_metadata(course)

        # we've had a bug where the xml_attributes field can we rewritten as a string rather than a dict
        def _check_xml_attributes_field(module):
            err_cnt = 0
            if hasattr(module, 'xml_attributes') and isinstance(
                    module.xml_attributes, basestring):
                print 'module = {0} has xml_attributes as a string. It should be a dict'.format(
                    module.location.url())
                err_cnt = err_cnt + 1
            for child in module.get_children():
                err_cnt = err_cnt + _check_xml_attributes_field(child)
            return err_cnt

        err_cnt = err_cnt + _check_xml_attributes_field(course)

        # check for dangling discussion items, this can cause errors in the forums
        def _get_discussion_items(module):
            discussion_items = []
            if module.location.category == 'discussion':
                discussion_items = discussion_items + [module.location.url()]

            for child in module.get_children():
                discussion_items = discussion_items + _get_discussion_items(
                    child)

            return discussion_items

        discussion_items = _get_discussion_items(course)

        # now query all discussion items via get_items() and compare with the tree-traversal
        queried_discussion_items = store.get_items([
            'i4x', course.location.org, course.location.course, 'discussion',
            None, None
        ])

        for item in queried_discussion_items:
            if item.location.url() not in discussion_items:
                print 'Found dangling discussion module = {0}'.format(
                    item.location.url())