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
2ac069a6
Commit
2ac069a6
authored
Oct 22, 2014
by
Don Mitchell
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5653 from edx/dhm/PLAT-189
Add command line command to create course in either split or mongo
parents
def3467e
a4d13dc4
Show 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 @
2ac069a6
"""
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 @
2ac069a6
...
...
@@ -9,21 +9,7 @@ from xmodule.modulestore.split_migrator import SplitMigrator
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys
import
InvalidKeyError
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 @
2ac069a6
"""
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 @
2ac069a6
"""
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 @
2ac069a6
...
...
@@ -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