Skip to content
Snippets Groups Projects
Commit f3fb82f8 authored by Don Mitchell's avatar Don Mitchell
Browse files

Merge pull request #3750 from edx/dhm/opaque-delete-course

Ensure all cms commands accept either deprecated or new syntax for keys
parents 77b895cb 84da71d9
No related merge requests found
......@@ -2,6 +2,8 @@ from django.core.management.base import BaseCommand, CommandError
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.xml_importer import check_module_metadata_editability
from xmodule.modulestore.keys import CourseKey
from opaque_keys import InvalidKeyError
from xmodule.modulestore.locations import SlashSeparatedCourseKey
class Command(BaseCommand):
......@@ -11,7 +13,10 @@ class Command(BaseCommand):
if len(args) != 1:
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()
......
......@@ -7,6 +7,8 @@ from xmodule.modulestore.django import modulestore
from xmodule.contentstore.django import contentstore
from student.roles import CourseInstructorRole, CourseStaffRole
from xmodule.modulestore.keys import CourseKey
from opaque_keys import InvalidKeyError
from xmodule.modulestore.locations import SlashSeparatedCourseKey
#
......@@ -16,13 +18,22 @@ class Command(BaseCommand):
"""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):
"Execute the command"
if len(args) != 2:
raise CommandError("clone requires 2 arguments: <source-course_id> <dest-course_id>")
source_course_id = CourseKey.from_string(args[0])
dest_course_id = CourseKey.from_string(args[1])
source_course_id = self.course_key_from_arg(args[0])
dest_course_id = self.course_key_from_arg(args[1])
mstore = modulestore('direct')
cstore = contentstore()
......
......@@ -5,6 +5,8 @@ from django.core.management.base import BaseCommand, CommandError
from .prompt import query_yes_no
from contentstore.utils import delete_course_and_groups
from xmodule.modulestore.keys import CourseKey
from opaque_keys import InvalidKeyError
from xmodule.modulestore.locations import SlashSeparatedCourseKey
class Command(BaseCommand):
......@@ -14,7 +16,10 @@ class Command(BaseCommand):
if len(args) != 1 and len(args) != 2:
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
if len(args) == 2:
......@@ -23,6 +28,6 @@ class Command(BaseCommand):
if commit:
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"):
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.
course_key = CourseKey.from_string(options['course'])
except InvalidKeyError:
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)
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
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.keys import CourseKey
from .prompt import query_yes_no
from opaque_keys import InvalidKeyError
from xmodule.modulestore.locations import SlashSeparatedCourseKey
class Command(BaseCommand):
......@@ -13,7 +15,12 @@ class Command(BaseCommand):
raise CommandError("empty_asset_trashcan requires one or no arguments: |<course_id>|")
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:
course_ids = [course.id for course in modulestore('direct').get_courses()]
......
......@@ -8,7 +8,8 @@ from xmodule.modulestore.xml_exporter import export_to_xml
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.keys import CourseKey
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):
......@@ -22,12 +23,16 @@ class Command(BaseCommand):
if len(args) != 2:
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]
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)
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
from xmodule.modulestore.xml_exporter import export_to_xml
from xmodule.modulestore.django import modulestore
from xmodule.contentstore.django import contentstore
from xmodule.course_module import CourseDescriptor
class Command(BaseCommand):
......
......@@ -7,6 +7,9 @@ from django.contrib.auth.models import User
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.split_migrator import SplitMigrator
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):
......@@ -28,20 +31,23 @@ class Command(BaseCommand):
"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):
"""
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 len(args) < 2:
raise CommandError(
"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:
user = user_from_str(args[1])
......@@ -54,10 +60,10 @@ class Command(BaseCommand):
except IndexError:
org = offering = None
return location, user, org, offering
return course_key, user, org, offering
def handle(self, *args, **options):
location, user, org, offering = self.parse_args(*args)
course_key, user, org, offering = self.parse_args(*args)
migrator = SplitMigrator(
draft_modulestore=modulestore('default'),
......@@ -66,4 +72,4 @@ class Command(BaseCommand):
loc_mapper=loc_mapper(),
)
migrator.migrate_mongo_course(location, user, org, offering)
migrator.migrate_mongo_course(course_key, user, org, offering)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment