Merge pull request #1192 from MITx/feature/cdodge/clone-course

implement course clone and delete functionality from the command line
This commit is contained in:
Don Mitchell
2012-12-20 11:29:49 -08:00
7 changed files with 272 additions and 3 deletions

View File

@@ -55,6 +55,22 @@ def create_new_course_group(creator, location, role):
return
'''
This is to be called only by either a command line code path or through a app which has already
asserted permissions
'''
def _delete_course_group(location):
# remove all memberships
instructors = Group.objects.get(name=get_course_groupname_for_role(location, INSTRUCTOR_ROLE_NAME))
for user in instructors.user_set.all():
user.groups.remove(instructors)
user.save()
staff = Group.objects.get(name=get_course_groupname_for_role(location, STAFF_ROLE_NAME))
for user in staff.user_set.all():
user.groups.remove(staff)
user.save()
def add_user_to_course_group(caller, user, location, role):
# only admins can add/remove other users

View File

@@ -0,0 +1,31 @@
###
### Script for cloning a course
###
from django.core.management.base import BaseCommand, CommandError
from xmodule.modulestore.store_utilities import clone_course
from xmodule.modulestore.django import modulestore
from xmodule.contentstore.django import contentstore
from xmodule.modulestore import Location
from xmodule.course_module import CourseDescriptor
#
# To run from command line: rake cms:clone SOURCE_LOC=MITx/111/Foo1 DEST_LOC=MITx/135/Foo3
#
class Command(BaseCommand):
help = \
'''Clone a MongoDB backed course to another location'''
def handle(self, *args, **options):
if len(args) != 2:
raise CommandError("clone requires two arguments: <source-location> <dest-location>")
source_location_str = args[0]
dest_location_str = args[1]
print "Cloning course {0} to {1}".format(source_location_str, dest_location_str)
source_location = CourseDescriptor.id_to_location(source_location_str)
dest_location = CourseDescriptor.id_to_location(dest_location_str)
clone_course(modulestore('direct'), contentstore(), source_location, dest_location)

View File

@@ -0,0 +1,36 @@
###
### Script for cloning a course
###
from django.core.management.base import BaseCommand, CommandError
from xmodule.modulestore.store_utilities import delete_course
from xmodule.modulestore.django import modulestore
from xmodule.contentstore.django import contentstore
from xmodule.modulestore import Location
from xmodule.course_module import CourseDescriptor
from prompt import query_yes_no
from auth.authz import _delete_course_group
#
# To run from command line: rake cms:delete_course LOC=MITx/111/Foo1
#
class Command(BaseCommand):
help = \
'''Delete a MongoDB backed course'''
def handle(self, *args, **options):
if len(args) != 1:
raise CommandError("delete_course requires one arguments: <location>")
loc_str = args[0]
if query_yes_no("Deleting course {0}. Confirm?".format(loc_str), default="no"):
if query_yes_no("Are you sure. This action cannot be undone!", default="no"):
loc = CourseDescriptor.id_to_location(loc_str)
if delete_course(modulestore('direct'), contentstore(), loc) == True:
# in the django layer, we need to remove all the user permissions groups associated with this course
_delete_course_group(loc)

View File

@@ -0,0 +1,33 @@
import sys
def query_yes_no(question, default="yes"):
"""Ask a yes/no question via raw_input() and return their answer.
"question" is a string that is presented to the user.
"default" is the presumed answer if the user just hits <Enter>.
It must be "yes" (the default), "no" or None (meaning
an answer is required of the user).
The "answer" return value is one of "yes" or "no".
"""
valid = {"yes":True, "y":True, "ye":True,
"no":False, "n":False}
if default == None:
prompt = " [y/n] "
elif default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)
while True:
sys.stdout.write(question + prompt)
choice = raw_input().lower()
if default is not None and choice == '':
return valid[default]
elif choice in valid:
return valid[choice]
else:
sys.stdout.write("Please respond with 'yes' or 'no' "\
"(or 'y' or 'n').\n")