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