Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
a4d13dc4
Commit
a4d13dc4
authored
Oct 20, 2014
by
Don Mitchell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add command line command to create course in either split or mongo
PLAT-189
parent
7496041f
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
164 additions
and
30 deletions
+164
-30
cms/djangoapps/contentstore/management/commands/create_course.py
+54
-0
cms/djangoapps/contentstore/management/commands/migrate_to_split.py
+1
-15
cms/djangoapps/contentstore/management/commands/tests/test_create_course.py
+68
-0
cms/djangoapps/contentstore/management/commands/utils.py
+19
-0
cms/djangoapps/contentstore/views/course.py
+22
-15
No files found.
cms/djangoapps/contentstore/management/commands/create_course.py
0 → 100644
View file @
a4d13dc4
"""
Django management command to create a course in a specific modulestore
"""
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.contrib.auth.models
import
User
from
xmodule.modulestore
import
ModuleStoreEnum
from
contentstore.views.course
import
create_new_course_in_store
from
contentstore.management.commands.utils
import
user_from_str
class
Command
(
BaseCommand
):
"""
Create a course in a specific modulestore.
"""
# can this query modulestore for the list of write accessible stores or does that violate command pattern?
help
=
"Create a course in one of {}"
.
format
([
ModuleStoreEnum
.
Type
.
mongo
,
ModuleStoreEnum
.
Type
.
split
])
args
=
"modulestore user org course run"
def
parse_args
(
self
,
*
args
):
"""
Return a tuple of passed in values for (modulestore, user, org, course, run).
"""
if
len
(
args
)
!=
5
:
raise
CommandError
(
"create_course requires 5 arguments: "
"a modulestore, user, org, course, run. Modulestore is one of {}"
.
format
(
[
ModuleStoreEnum
.
Type
.
mongo
,
ModuleStoreEnum
.
Type
.
split
]
)
)
if
args
[
0
]
not
in
[
ModuleStoreEnum
.
Type
.
mongo
,
ModuleStoreEnum
.
Type
.
split
]:
raise
CommandError
(
"Modulestore (first arg) must be one of {}"
.
format
(
[
ModuleStoreEnum
.
Type
.
mongo
,
ModuleStoreEnum
.
Type
.
split
]
)
)
storetype
=
args
[
0
]
try
:
user
=
user_from_str
(
args
[
1
])
except
User
.
DoesNotExist
:
raise
CommandError
(
"No user {} found: expected args are "
.
format
(
args
[
1
],
self
.
args
))
org
=
args
[
2
]
course
=
args
[
3
]
run
=
args
[
4
]
return
storetype
,
user
,
org
,
course
,
run
def
handle
(
self
,
*
args
,
**
options
):
storetype
,
user
,
org
,
course
,
run
=
self
.
parse_args
(
*
args
)
new_course
=
create_new_course_in_store
(
storetype
,
user
,
org
,
course
,
run
,
{})
self
.
stdout
.
write
(
u"Created {}"
.
format
(
unicode
(
new_course
.
id
)))
cms/djangoapps/contentstore/management/commands/migrate_to_split.py
View file @
a4d13dc4
...
...
@@ -10,21 +10,7 @@ from opaque_keys.edx.keys import CourseKey
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.modulestore
import
ModuleStoreEnum
def
user_from_str
(
identifier
):
"""
Return a user identified by the given string. The string could be an email
address, or a stringified integer corresponding to the ID of the user in
the database. If no user could be found, a User.DoesNotExist exception
will be raised.
"""
try
:
user_id
=
int
(
identifier
)
except
ValueError
:
return
User
.
objects
.
get
(
email
=
identifier
)
return
User
.
objects
.
get
(
id
=
user_id
)
from
contentstore.management.commands.utils
import
user_from_str
class
Command
(
BaseCommand
):
...
...
cms/djangoapps/contentstore/management/commands/tests/test_create_course.py
0 → 100644
View file @
a4d13dc4
"""
Unittests for creating a course in an chosen modulestore
"""
import
unittest
import
ddt
from
django.core.management
import
CommandError
,
call_command
from
contentstore.management.commands.create_course
import
Command
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.django
import
modulestore
class
TestArgParsing
(
unittest
.
TestCase
):
"""
Tests for parsing arguments for the `create_course` management command
"""
def
setUp
(
self
):
self
.
command
=
Command
()
def
test_no_args
(
self
):
errstring
=
"create_course requires 5 arguments"
with
self
.
assertRaisesRegexp
(
CommandError
,
errstring
):
self
.
command
.
handle
(
'create_course'
)
def
test_invalid_store
(
self
):
with
self
.
assertRaises
(
CommandError
):
self
.
command
.
handle
(
"foo"
,
"user@foo.org"
,
"org"
,
"course"
,
"run"
)
def
test_xml_store
(
self
):
with
self
.
assertRaises
(
CommandError
):
self
.
command
.
handle
(
ModuleStoreEnum
.
Type
.
xml
,
"user@foo.org"
,
"org"
,
"course"
,
"run"
)
def
test_nonexistent_user_id
(
self
):
errstring
=
"No user 99 found"
with
self
.
assertRaisesRegexp
(
CommandError
,
errstring
):
self
.
command
.
handle
(
"split"
,
"99"
,
"org"
,
"course"
,
"run"
)
def
test_nonexistent_user_email
(
self
):
errstring
=
"No user fake@example.com found"
with
self
.
assertRaisesRegexp
(
CommandError
,
errstring
):
self
.
command
.
handle
(
"mongo"
,
"fake@example.com"
,
"org"
,
"course"
,
"run"
)
@ddt.ddt
class
TestCreateCourse
(
ModuleStoreTestCase
):
"""
Unit tests for creating a course in either old mongo or split mongo via command line
"""
def
setUp
(
self
):
super
(
TestCreateCourse
,
self
)
.
setUp
(
create_user
=
True
)
@ddt.data
(
ModuleStoreEnum
.
Type
.
mongo
,
ModuleStoreEnum
.
Type
.
split
)
def
test_all_stores_user_email
(
self
,
store
):
call_command
(
"create_course"
,
store
,
str
(
self
.
user
.
email
),
"org"
,
"course"
,
"run"
)
new_key
=
modulestore
()
.
make_course_key
(
"org"
,
"course"
,
"run"
)
self
.
assertTrue
(
modulestore
()
.
has_course
(
new_key
),
"Could not find course in {}"
.
format
(
store
)
)
# pylint: disable=protected-access
self
.
assertEqual
(
store
,
modulestore
()
.
_get_modulestore_for_courseid
(
new_key
)
.
get_modulestore_type
())
cms/djangoapps/contentstore/management/commands/utils.py
0 → 100644
View file @
a4d13dc4
"""
Common methods for cms commands to use
"""
from
django.contrib.auth.models
import
User
def
user_from_str
(
identifier
):
"""
Return a user identified by the given string. The string could be an email
address, or a stringified integer corresponding to the ID of the user in
the database. If no user could be found, a User.DoesNotExist exception
will be raised.
"""
try
:
user_id
=
int
(
identifier
)
except
ValueError
:
return
User
.
objects
.
get
(
email
=
identifier
)
return
User
.
objects
.
get
(
id
=
user_id
)
cms/djangoapps/contentstore/views/course.py
View file @
a4d13dc4
...
...
@@ -564,6 +564,22 @@ def _create_new_course(request, org, number, run, fields):
Returns the URL for the course overview page.
Raises DuplicateCourseError if the course already exists
"""
store_for_new_course
=
(
settings
.
FEATURES
.
get
(
'DEFAULT_STORE_FOR_NEW_COURSE'
)
or
modulestore
()
.
default_modulestore
.
get_modulestore_type
()
)
new_course
=
create_new_course_in_store
(
store_for_new_course
,
request
.
user
,
org
,
number
,
run
,
fields
)
return
JsonResponse
({
'url'
:
reverse_course_url
(
'course_handler'
,
new_course
.
id
),
'course_key'
:
unicode
(
new_course
.
id
),
})
def
create_new_course_in_store
(
store
,
user
,
org
,
number
,
run
,
fields
):
"""
Create course in store w/ handling instructor enrollment, permissions, and defaulting the wiki slug.
Separated out b/c command line course creation uses this as well as the web interface.
"""
# Set a unique wiki_slug for newly created courses. To maintain active wiki_slugs for
# existing xml courses this cannot be changed in CourseDescriptor.
# # TODO get rid of defining wiki slug in this org/course/run specific way and reconcile
...
...
@@ -572,31 +588,22 @@ def _create_new_course(request, org, number, run, fields):
definition_data
=
{
'wiki_slug'
:
wiki_slug
}
fields
.
update
(
definition_data
)
store
=
modulestore
()
store_for_new_course
=
(
settings
.
FEATURES
.
get
(
'DEFAULT_STORE_FOR_NEW_COURSE'
)
or
store
.
default_modulestore
.
get_modulestore_type
()
)
with
store
.
default_store
(
store_for_new_course
):
with
modulestore
()
.
default_store
(
store
):
# Creating the course raises DuplicateCourseError if an existing course with this org/name is found
new_course
=
store
.
create_course
(
new_course
=
modulestore
()
.
create_course
(
org
,
number
,
run
,
request
.
user
.
id
,
user
.
id
,
fields
=
fields
,
)
# Make sure user has instructor and staff access to the new course
add_instructor
(
new_course
.
id
,
request
.
user
,
request
.
user
)
add_instructor
(
new_course
.
id
,
user
,
user
)
# Initialize permissions for user in the new course
initialize_permissions
(
new_course
.
id
,
request
.
user
)
return
JsonResponse
({
'url'
:
reverse_course_url
(
'course_handler'
,
new_course
.
id
),
'course_key'
:
unicode
(
new_course
.
id
),
})
initialize_permissions
(
new_course
.
id
,
user
)
return
new_course
def
_rerun_course
(
request
,
org
,
number
,
run
,
fields
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment