Commit 84da71d9 by Don Mitchell

Ensure all cms commands accept either deprecated or new syntax for keys

LMS-2712
parent 77b895cb
...@@ -2,6 +2,8 @@ from django.core.management.base import BaseCommand, CommandError ...@@ -2,6 +2,8 @@ from django.core.management.base import BaseCommand, CommandError
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.xml_importer import check_module_metadata_editability from xmodule.modulestore.xml_importer import check_module_metadata_editability
from xmodule.modulestore.keys import CourseKey from xmodule.modulestore.keys import CourseKey
from opaque_keys import InvalidKeyError
from xmodule.modulestore.locations import SlashSeparatedCourseKey
class Command(BaseCommand): class Command(BaseCommand):
...@@ -11,7 +13,10 @@ class Command(BaseCommand): ...@@ -11,7 +13,10 @@ class Command(BaseCommand):
if len(args) != 1: if len(args) != 1:
raise CommandError("check_course requires one argument: <course_id>") raise CommandError("check_course requires one argument: <course_id>")
course_key = CourseKey.from_string(args[0]) try:
course_key = CourseKey.from_string(args[0])
except InvalidKeyError:
course_key = SlashSeparatedCourseKey.from_deprecated_string(args[0])
store = modulestore() store = modulestore()
......
...@@ -7,6 +7,8 @@ from xmodule.modulestore.django import modulestore ...@@ -7,6 +7,8 @@ from xmodule.modulestore.django import modulestore
from xmodule.contentstore.django import contentstore from xmodule.contentstore.django import contentstore
from student.roles import CourseInstructorRole, CourseStaffRole from student.roles import CourseInstructorRole, CourseStaffRole
from xmodule.modulestore.keys import CourseKey from xmodule.modulestore.keys import CourseKey
from opaque_keys import InvalidKeyError
from xmodule.modulestore.locations import SlashSeparatedCourseKey
# #
...@@ -16,13 +18,22 @@ class Command(BaseCommand): ...@@ -16,13 +18,22 @@ class Command(BaseCommand):
"""Clone a MongoDB-backed course to another location""" """Clone a MongoDB-backed course to another location"""
help = 'Clone a MongoDB backed course to another location' help = 'Clone a MongoDB backed course to another location'
def course_key_from_arg(self, arg):
"""
Convert the command line arg into a course key
"""
try:
return CourseKey.from_string(arg)
except InvalidKeyError:
return SlashSeparatedCourseKey.from_deprecated_string(arg)
def handle(self, *args, **options): def handle(self, *args, **options):
"Execute the command" "Execute the command"
if len(args) != 2: if len(args) != 2:
raise CommandError("clone requires 2 arguments: <source-course_id> <dest-course_id>") raise CommandError("clone requires 2 arguments: <source-course_id> <dest-course_id>")
source_course_id = CourseKey.from_string(args[0]) source_course_id = self.course_key_from_arg(args[0])
dest_course_id = CourseKey.from_string(args[1]) dest_course_id = self.course_key_from_arg(args[1])
mstore = modulestore('direct') mstore = modulestore('direct')
cstore = contentstore() cstore = contentstore()
......
...@@ -5,6 +5,8 @@ from django.core.management.base import BaseCommand, CommandError ...@@ -5,6 +5,8 @@ from django.core.management.base import BaseCommand, CommandError
from .prompt import query_yes_no from .prompt import query_yes_no
from contentstore.utils import delete_course_and_groups from contentstore.utils import delete_course_and_groups
from xmodule.modulestore.keys import CourseKey from xmodule.modulestore.keys import CourseKey
from opaque_keys import InvalidKeyError
from xmodule.modulestore.locations import SlashSeparatedCourseKey
class Command(BaseCommand): class Command(BaseCommand):
...@@ -14,7 +16,10 @@ class Command(BaseCommand): ...@@ -14,7 +16,10 @@ class Command(BaseCommand):
if len(args) != 1 and len(args) != 2: if len(args) != 1 and len(args) != 2:
raise CommandError("delete_course requires one or more arguments: <course_id> |commit|") raise CommandError("delete_course requires one or more arguments: <course_id> |commit|")
course_id = CourseKey.from_string(args[0]) try:
course_key = CourseKey.from_string(args[0])
except InvalidKeyError:
course_key = SlashSeparatedCourseKey.from_deprecated_string(args[0])
commit = False commit = False
if len(args) == 2: if len(args) == 2:
...@@ -23,6 +28,6 @@ class Command(BaseCommand): ...@@ -23,6 +28,6 @@ class Command(BaseCommand):
if commit: if commit:
print('Actually going to delete the course from DB....') print('Actually going to delete the course from DB....')
if query_yes_no("Deleting course {0}. Confirm?".format(course_id), default="no"): if query_yes_no("Deleting course {0}. Confirm?".format(course_key), default="no"):
if query_yes_no("Are you sure. This action cannot be undone!", default="no"): if query_yes_no("Are you sure. This action cannot be undone!", default="no"):
delete_course_and_groups(course_id, commit) delete_course_and_groups(course_key, commit)
...@@ -71,7 +71,7 @@ command again, adding --insert or --delete to edit the list. ...@@ -71,7 +71,7 @@ command again, adding --insert or --delete to edit the list.
course_key = CourseKey.from_string(options['course']) course_key = CourseKey.from_string(options['course'])
except InvalidKeyError: except InvalidKeyError:
course_key = SlashSeparatedCourseKey.from_deprecated_string(options['course']) course_key = SlashSeparatedCourseKey.from_deprecated_string(options['course'])
print u'Warning: you are using a deprecated format. Please use {} in the future'.format(course_key)
course = get_course_by_id(course_key) course = get_course_by_id(course_key)
print 'Warning: this command directly edits the list of course tabs in mongo.' print 'Warning: this command directly edits the list of course tabs in mongo.'
......
...@@ -3,6 +3,8 @@ from xmodule.contentstore.utils import empty_asset_trashcan ...@@ -3,6 +3,8 @@ from xmodule.contentstore.utils import empty_asset_trashcan
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.keys import CourseKey from xmodule.modulestore.keys import CourseKey
from .prompt import query_yes_no from .prompt import query_yes_no
from opaque_keys import InvalidKeyError
from xmodule.modulestore.locations import SlashSeparatedCourseKey
class Command(BaseCommand): class Command(BaseCommand):
...@@ -13,7 +15,12 @@ class Command(BaseCommand): ...@@ -13,7 +15,12 @@ class Command(BaseCommand):
raise CommandError("empty_asset_trashcan requires one or no arguments: |<course_id>|") raise CommandError("empty_asset_trashcan requires one or no arguments: |<course_id>|")
if len(args) == 1: if len(args) == 1:
course_ids = [CourseKey.from_string(args[0])] try:
course_key = CourseKey.from_string(args[0])
except InvalidKeyError:
course_key = SlashSeparatedCourseKey.from_deprecated_string(args[0])
course_ids = [course_key]
else: else:
course_ids = [course.id for course in modulestore('direct').get_courses()] course_ids = [course.id for course in modulestore('direct').get_courses()]
......
...@@ -8,7 +8,8 @@ from xmodule.modulestore.xml_exporter import export_to_xml ...@@ -8,7 +8,8 @@ from xmodule.modulestore.xml_exporter import export_to_xml
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.keys import CourseKey from xmodule.modulestore.keys import CourseKey
from xmodule.contentstore.django import contentstore from xmodule.contentstore.django import contentstore
from xmodule.course_module import CourseDescriptor from opaque_keys import InvalidKeyError
from xmodule.modulestore.locations import SlashSeparatedCourseKey
class Command(BaseCommand): class Command(BaseCommand):
...@@ -22,12 +23,16 @@ class Command(BaseCommand): ...@@ -22,12 +23,16 @@ class Command(BaseCommand):
if len(args) != 2: if len(args) != 2:
raise CommandError("export requires two arguments: <course id> <output path>") raise CommandError("export requires two arguments: <course id> <output path>")
course_id = CourseKey.from_string(args[0]) try:
course_key = CourseKey.from_string(args[0])
except InvalidKeyError:
course_key = SlashSeparatedCourseKey.from_deprecated_string(args[0])
output_path = args[1] output_path = args[1]
print("Exporting course id = {0} to {1}".format(course_id, output_path)) print("Exporting course id = {0} to {1}".format(course_key, output_path))
root_dir = os.path.dirname(output_path) root_dir = os.path.dirname(output_path)
course_dir = os.path.splitext(os.path.basename(output_path))[0] course_dir = os.path.splitext(os.path.basename(output_path))[0]
export_to_xml(modulestore('direct'), contentstore(), course_id, root_dir, course_dir, modulestore()) export_to_xml(modulestore('direct'), contentstore(), course_key, root_dir, course_dir, modulestore())
...@@ -5,7 +5,6 @@ from django.core.management.base import BaseCommand, CommandError ...@@ -5,7 +5,6 @@ from django.core.management.base import BaseCommand, CommandError
from xmodule.modulestore.xml_exporter import export_to_xml from xmodule.modulestore.xml_exporter import export_to_xml
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.contentstore.django import contentstore from xmodule.contentstore.django import contentstore
from xmodule.course_module import CourseDescriptor
class Command(BaseCommand): class Command(BaseCommand):
......
...@@ -7,6 +7,9 @@ from django.contrib.auth.models import User ...@@ -7,6 +7,9 @@ from django.contrib.auth.models import User
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.split_migrator import SplitMigrator from xmodule.modulestore.split_migrator import SplitMigrator
from xmodule.modulestore.django import loc_mapper from xmodule.modulestore.django import loc_mapper
from xmodule.modulestore.keys import CourseKey
from opaque_keys import InvalidKeyError
from xmodule.modulestore.locations import SlashSeparatedCourseKey
def user_from_str(identifier): def user_from_str(identifier):
...@@ -28,20 +31,23 @@ class Command(BaseCommand): ...@@ -28,20 +31,23 @@ class Command(BaseCommand):
"Migrate a course from old-Mongo to split-Mongo" "Migrate a course from old-Mongo to split-Mongo"
help = "Migrate a course from old-Mongo to split-Mongo" help = "Migrate a course from old-Mongo to split-Mongo"
args = "location email <new org> <new offering>" args = "course_key email <new org> <new offering>"
def parse_args(self, *args): def parse_args(self, *args):
""" """
Return a 4-tuple of (location, user, org, offering). Return a 4-tuple of (course_key, user, org, offering).
If the user didn't specify an org & offering, those will be None. If the user didn't specify an org & offering, those will be None.
""" """
if len(args) < 2: if len(args) < 2:
raise CommandError( raise CommandError(
"migrate_to_split requires at least two arguments: " "migrate_to_split requires at least two arguments: "
"a location and a user identifier (email or ID)" "a course_key and a user identifier (email or ID)"
) )
location = args[0] try:
course_key = CourseKey.from_string(args[0])
except InvalidKeyError:
course_key = SlashSeparatedCourseKey.from_deprecated_string(args[0])
try: try:
user = user_from_str(args[1]) user = user_from_str(args[1])
...@@ -54,10 +60,10 @@ class Command(BaseCommand): ...@@ -54,10 +60,10 @@ class Command(BaseCommand):
except IndexError: except IndexError:
org = offering = None org = offering = None
return location, user, org, offering return course_key, user, org, offering
def handle(self, *args, **options): def handle(self, *args, **options):
location, user, org, offering = self.parse_args(*args) course_key, user, org, offering = self.parse_args(*args)
migrator = SplitMigrator( migrator = SplitMigrator(
draft_modulestore=modulestore('default'), draft_modulestore=modulestore('default'),
...@@ -66,4 +72,4 @@ class Command(BaseCommand): ...@@ -66,4 +72,4 @@ class Command(BaseCommand):
loc_mapper=loc_mapper(), loc_mapper=loc_mapper(),
) )
migrator.migrate_mongo_course(location, user, org, offering) migrator.migrate_mongo_course(course_key, user, org, offering)
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