Merge branch 'feature/cale/cms-master' of github.com:MITx/mitx into bug/dhm/dec12
This commit is contained in:
31
cms/djangoapps/contentstore/management/commands/clone.py
Normal file
31
cms/djangoapps/contentstore/management/commands/clone.py
Normal 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)
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
33
cms/djangoapps/contentstore/management/commands/prompt.py
Normal file
33
cms/djangoapps/contentstore/management/commands/prompt.py
Normal 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")
|
||||
18
cms/djangoapps/contentstore/tests/test_utils.py
Normal file
18
cms/djangoapps/contentstore/tests/test_utils.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from django.test.testcases import TestCase
|
||||
from cms.djangoapps.contentstore import utils
|
||||
import mock
|
||||
|
||||
class LMSLinksTestCase(TestCase):
|
||||
def about_page_test(self):
|
||||
location = 'i4x','mitX','101','course', 'test'
|
||||
utils.get_course_id = mock.Mock(return_value="mitX/101/test")
|
||||
link = utils.get_lms_link_for_about_page(location)
|
||||
self.assertEquals(link, "//localhost:8000/courses/mitX/101/test/about")
|
||||
|
||||
def ls_link_test(self):
|
||||
location = 'i4x','mitX','101','vertical', 'contacting_us'
|
||||
utils.get_course_id = mock.Mock(return_value="mitX/101/test")
|
||||
link = utils.get_lms_link_for_item(location, False)
|
||||
self.assertEquals(link, "//localhost:8000/courses/mitX/101/test/jump_to/i4x://mitX/101/vertical/contacting_us")
|
||||
link = utils.get_lms_link_for_item(location, True)
|
||||
self.assertEquals(link, "//preview.localhost:8000/courses/mitX/101/test/jump_to/i4x://mitX/101/vertical/contacting_us")
|
||||
@@ -73,20 +73,38 @@ def get_course_for_item(location):
|
||||
|
||||
|
||||
def get_lms_link_for_item(location, preview=False):
|
||||
location = Location(location)
|
||||
if settings.LMS_BASE is not None:
|
||||
lms_link = "//{preview}{lms_base}/courses/{course_id}/jump_to/{location}".format(
|
||||
preview='preview.' if preview else '',
|
||||
lms_base=settings.LMS_BASE,
|
||||
# TODO: These will need to be changed to point to the particular instance of this problem in the particular course
|
||||
course_id=modulestore().get_containing_courses(location)[0].id,
|
||||
location=location,
|
||||
course_id=get_course_id(location),
|
||||
location=Location(location)
|
||||
)
|
||||
else:
|
||||
lms_link = None
|
||||
|
||||
return lms_link
|
||||
|
||||
def get_lms_link_for_about_page(location):
|
||||
"""
|
||||
Returns the url to the course about page from the location tuple.
|
||||
"""
|
||||
if settings.LMS_BASE is not None:
|
||||
lms_link = "//{lms_base}/courses/{course_id}/about".format(
|
||||
lms_base=settings.LMS_BASE,
|
||||
course_id=get_course_id(location)
|
||||
)
|
||||
else:
|
||||
lms_link = None
|
||||
|
||||
return lms_link
|
||||
|
||||
def get_course_id(location):
|
||||
"""
|
||||
Returns the course_id from a given the location tuple.
|
||||
"""
|
||||
# TODO: These will need to be changed to point to the particular instance of this problem in the particular course
|
||||
return modulestore().get_containing_courses(Location(location))[0].id
|
||||
|
||||
class UnitState(object):
|
||||
draft = 'draft'
|
||||
|
||||
Reference in New Issue
Block a user