Commit dbab66c5 by Adam

Merge pull request #6564 from edx/merge-release

Merge release
parents 75a26a7e ba102b4a
"""
Script for fixing the item not found errors in a course
"""
from django.core.management.base import BaseCommand, CommandError
from opaque_keys.edx.keys import CourseKey
from xmodule.modulestore.django import modulestore
from xmodule.modulestore import ModuleStoreEnum
# To run from command line: ./manage.py cms fix_not_found course-v1:org+course+run
class Command(BaseCommand):
"""Fix a course's item not found errors"""
help = "Fix a course's ItemNotFound errors"
def handle(self, *args, **options):
"Execute the command"
if len(args) != 1:
raise CommandError("requires 1 argument: <course_id>")
course_key = CourseKey.from_string(args[0])
# for now only support on split mongo
# pylint: disable=protected-access
owning_store = modulestore()._get_modulestore_for_courseid(course_key)
if hasattr(owning_store, 'fix_not_found'):
owning_store.fix_not_found(course_key, ModuleStoreEnum.UserID.mgmt_command)
else:
raise CommandError("The owning modulestore does not support this command.")
...@@ -119,7 +119,7 @@ class SplitMigrator(object): ...@@ -119,7 +119,7 @@ class SplitMigrator(object):
# clean up orphans in published version: in old mongo, parents pointed to the union of their published and draft # clean up orphans in published version: in old mongo, parents pointed to the union of their published and draft
# children which meant some pointers were to non-existent locations in 'direct' # children which meant some pointers were to non-existent locations in 'direct'
self.split_modulestore.internal_clean_children(course_version_locator) self.split_modulestore.fix_not_found(course_version_locator, user_id)
def _add_draft_modules_to_course(self, published_course_usage_key, source_course_key, user_id, **kwargs): def _add_draft_modules_to_course(self, published_course_usage_key, source_course_key, user_id, **kwargs):
""" """
......
...@@ -2418,22 +2418,26 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase): ...@@ -2418,22 +2418,26 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase):
# update the index entry if appropriate # update the index entry if appropriate
self._update_head(dest_course_key, index_entry, dest_course_key.branch, new_structure['_id']) self._update_head(dest_course_key, index_entry, dest_course_key.branch, new_structure['_id'])
def internal_clean_children(self, course_locator): def fix_not_found(self, course_locator, user_id):
""" """
Only intended for rather low level methods to use. Goes through the children attrs of Only intended for rather low level methods to use. Goes through the children attrs of
each block removing any whose block_id is not a member of the course. Does not generate each block removing any whose block_id is not a member of the course.
a new version of the course but overwrites the existing one.
:param course_locator: the course to clean :param course_locator: the course to clean
""" """
original_structure = self._lookup_course(course_locator).structure original_structure = self._lookup_course(course_locator).structure
for block in original_structure['blocks'].itervalues(): index_entry = self._get_index_if_valid(course_locator)
new_structure = self.version_structure(course_locator, original_structure, user_id)
for block in new_structure['blocks'].itervalues():
if 'fields' in block and 'children' in block['fields']: if 'fields' in block and 'children' in block['fields']:
block['fields']["children"] = [ block['fields']["children"] = [
block_id for block_id in block['fields']["children"] block_id for block_id in block['fields']["children"]
if block_id in original_structure['blocks'] if block_id in new_structure['blocks']
] ]
self.update_structure(course_locator, original_structure) self.update_structure(course_locator, new_structure)
if index_entry is not None:
# update the index entry if appropriate
self._update_head(course_locator, index_entry, course_locator.branch, new_structure['_id'])
def convert_references_to_keys(self, course_key, xblock_class, jsonfields, blocks): def convert_references_to_keys(self, course_key, xblock_class, jsonfields, blocks):
""" """
......
...@@ -251,6 +251,16 @@ class DraftVersioningModuleStore(SplitMongoModuleStore, ModuleStoreDraftAndPubli ...@@ -251,6 +251,16 @@ class DraftVersioningModuleStore(SplitMongoModuleStore, ModuleStoreDraftAndPubli
course_key = self._map_revision_to_branch(course_key) course_key = self._map_revision_to_branch(course_key)
return super(DraftVersioningModuleStore, self).get_orphans(course_key, **kwargs) return super(DraftVersioningModuleStore, self).get_orphans(course_key, **kwargs)
def fix_not_found(self, course_key, user_id):
"""
Fix any children which point to non-existent blocks in the course's published and draft branches
"""
for branch in [ModuleStoreEnum.RevisionOption.published_only, ModuleStoreEnum.RevisionOption.draft_only]:
super(DraftVersioningModuleStore, self).fix_not_found(
self._map_revision_to_branch(course_key, branch),
user_id
)
def has_changes(self, xblock): def has_changes(self, xblock):
""" """
Checks if the given block has unpublished changes Checks if the given block has unpublished changes
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment