Validation warning when no content matches configured filters
This commit is contained in:
@@ -361,6 +361,31 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
|
||||
lib_tools.update_children(self, user_id, user_perms, update_db)
|
||||
return Response()
|
||||
|
||||
def _validate_library_version(self, validation, lib_tools, version, library_key):
|
||||
latest_version = lib_tools.get_library_version(library_key)
|
||||
if latest_version is not None:
|
||||
if version is None or version != latest_version:
|
||||
validation.set_summary(
|
||||
StudioValidationMessage(
|
||||
StudioValidationMessage.WARNING,
|
||||
_(u'This component is out of date. The library has new content.'),
|
||||
action_class='library-update-btn', # TODO: change this to action_runtime_event='...' once the unit page supports that feature.
|
||||
action_label=_(u"↻ Update now")
|
||||
)
|
||||
)
|
||||
return False
|
||||
else:
|
||||
validation.set_summary(
|
||||
StudioValidationMessage(
|
||||
StudioValidationMessage.ERROR,
|
||||
_(u'Library is invalid, corrupt, or has been deleted.'),
|
||||
action_class='edit-button',
|
||||
action_label=_(u"Edit Library List")
|
||||
)
|
||||
)
|
||||
return False
|
||||
return True
|
||||
|
||||
def validate(self):
|
||||
"""
|
||||
Validates the state of this Library Content Module Instance. This
|
||||
@@ -381,30 +406,27 @@ class LibraryContentDescriptor(LibraryContentFields, MakoModuleDescriptor, XmlDe
|
||||
)
|
||||
return validation
|
||||
lib_tools = self.runtime.service(self, 'library_tools')
|
||||
has_children_matching_filter = False
|
||||
for library_key, version in self.source_libraries:
|
||||
latest_version = lib_tools.get_library_version(library_key)
|
||||
if latest_version is not None:
|
||||
if version is None or version != latest_version:
|
||||
validation.set_summary(
|
||||
StudioValidationMessage(
|
||||
StudioValidationMessage.WARNING,
|
||||
_(u'This component is out of date. The library has new content.'),
|
||||
action_class='library-update-btn', # TODO: change this to action_runtime_event='...' once the unit page supports that feature.
|
||||
action_label=_(u"↻ Update now")
|
||||
)
|
||||
)
|
||||
break
|
||||
else:
|
||||
validation.set_summary(
|
||||
StudioValidationMessage(
|
||||
StudioValidationMessage.ERROR,
|
||||
_(u'Library is invalid, corrupt, or has been deleted.'),
|
||||
action_class='edit-button',
|
||||
action_label=_(u"Edit Library List")
|
||||
)
|
||||
)
|
||||
if not self._validate_library_version(validation, lib_tools, version, library_key):
|
||||
break
|
||||
|
||||
library = lib_tools.get_library(library_key)
|
||||
children_matching_filter = lib_tools.get_filtered_children(library, self.capa_type)
|
||||
# get_filtered_children returns generator, so we're basically checking if there are at least one child
|
||||
# that satisfy filtering. Children are never equal to None, so None is returned only if generator was empty
|
||||
has_children_matching_filter |= next(children_matching_filter, None) is not None
|
||||
|
||||
if not has_children_matching_filter and validation.empty:
|
||||
validation.set_summary(
|
||||
StudioValidationMessage(
|
||||
StudioValidationMessage.WARNING,
|
||||
_(u'There are no content matching configured filters in the selected libraries.'),
|
||||
action_class='edit-button',
|
||||
action_label=_(u"Edit Library List")
|
||||
)
|
||||
)
|
||||
|
||||
return validation
|
||||
|
||||
def editor_saved(self, user, old_metadata, old_content):
|
||||
|
||||
@@ -18,7 +18,7 @@ class LibraryToolsService(object):
|
||||
def __init__(self, modulestore):
|
||||
self.store = modulestore
|
||||
|
||||
def _get_library(self, library_key):
|
||||
def get_library(self, library_key):
|
||||
"""
|
||||
Given a library key like "library-v1:ProblemX+PR0B", return the
|
||||
'library' XBlock with meta-information about the library.
|
||||
@@ -39,24 +39,39 @@ class LibraryToolsService(object):
|
||||
Get the version (an ObjectID) of the given library.
|
||||
Returns None if the library does not exist.
|
||||
"""
|
||||
library = self._get_library(lib_key)
|
||||
library = self.get_library(lib_key)
|
||||
if library:
|
||||
# We need to know the library's version so ensure it's set in library.location.library_key.version_guid
|
||||
assert library.location.library_key.version_guid is not None
|
||||
return library.location.library_key.version_guid
|
||||
return None
|
||||
|
||||
def _filter_child(self, dest_block, child_descriptor):
|
||||
def _filter_child(self, capa_type, child_descriptor):
|
||||
"""
|
||||
Filters children by CAPA problem type, if configured
|
||||
"""
|
||||
if dest_block.capa_type == ANY_CAPA_TYPE_VALUE:
|
||||
if capa_type == ANY_CAPA_TYPE_VALUE:
|
||||
return True
|
||||
|
||||
if not isinstance(child_descriptor, CapaDescriptor):
|
||||
return False
|
||||
|
||||
return dest_block.capa_type in child_descriptor.problem_types
|
||||
return capa_type in child_descriptor.problem_types
|
||||
|
||||
def get_filtered_children(self, from_block, capa_type=ANY_CAPA_TYPE_VALUE):
|
||||
"""
|
||||
Filters children of `from_block` that satisfy filter criteria
|
||||
Returns generator containing (child_key, child) for all children matching filter criteria
|
||||
"""
|
||||
children = (
|
||||
(child_key, self.store.get_item(child_key, depth=9))
|
||||
for child_key in from_block.children
|
||||
)
|
||||
return (
|
||||
(child_key, child)
|
||||
for child_key, child in children
|
||||
if self._filter_child(capa_type, child)
|
||||
)
|
||||
|
||||
def update_children(self, dest_block, user_id, user_perms=None, update_db=True):
|
||||
"""
|
||||
@@ -89,7 +104,7 @@ class LibraryToolsService(object):
|
||||
# First, load and validate the source_libraries:
|
||||
libraries = []
|
||||
for library_key, old_version in dest_block.source_libraries: # pylint: disable=unused-variable
|
||||
library = self._get_library(library_key)
|
||||
library = self.get_library(library_key)
|
||||
if library is None:
|
||||
raise ValueError("Required library not found.")
|
||||
if user_perms and not user_perms.can_read(library_key):
|
||||
@@ -109,11 +124,9 @@ class LibraryToolsService(object):
|
||||
Internal method to copy blocks from the library recursively
|
||||
"""
|
||||
new_children = []
|
||||
for child_key in from_block.children:
|
||||
child = self.store.get_item(child_key, depth=9)
|
||||
|
||||
if filter_problem_type and not self._filter_child(dest_block, child):
|
||||
continue
|
||||
target_capa_type = dest_block.capa_type if filter_problem_type else ANY_CAPA_TYPE_VALUE
|
||||
filtered_children = self.get_filtered_children(from_block, target_capa_type)
|
||||
for child_key, child in filtered_children:
|
||||
# We compute a block_id for each matching child block found in the library.
|
||||
# block_ids are unique within any branch, but are not unique per-course or globally.
|
||||
# We need our block_ids to be consistent when content in the library is updated, so
|
||||
|
||||
Reference in New Issue
Block a user