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
79fe2e62
Commit
79fe2e62
authored
Oct 27, 2017
by
bmedx
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CMS management command cleanup for Django 1.11
parent
b57f1447
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
268 additions
and
258 deletions
+268
-258
cms/djangoapps/contentstore/management/commands/clean_cert_name.py
+6
-4
cms/djangoapps/contentstore/management/commands/cleanup_assets.py
+6
-6
cms/djangoapps/contentstore/management/commands/clone_course.py
+17
-9
cms/djangoapps/contentstore/management/commands/create_course.py
+28
-32
cms/djangoapps/contentstore/management/commands/delete_course.py
+4
-1
cms/djangoapps/contentstore/management/commands/delete_orphans.py
+7
-5
cms/djangoapps/contentstore/management/commands/edit_course_tabs.py
+45
-36
cms/djangoapps/contentstore/management/commands/empty_asset_trashcan.py
+9
-7
cms/djangoapps/contentstore/management/commands/export.py
+2
-1
cms/djangoapps/contentstore/management/commands/export_all_courses.py
+21
-19
cms/djangoapps/contentstore/management/commands/export_olx.py
+3
-4
cms/djangoapps/contentstore/management/commands/fix_not_found.py
+1
-1
cms/djangoapps/contentstore/management/commands/force_publish.py
+9
-9
cms/djangoapps/contentstore/management/commands/generate_courses.py
+2
-1
cms/djangoapps/contentstore/management/commands/git_export.py
+12
-19
cms/djangoapps/contentstore/management/commands/import.py
+1
-1
cms/djangoapps/contentstore/management/commands/migrate_to_split.py
+15
-22
cms/djangoapps/contentstore/management/commands/populate_creators.py
+16
-16
cms/djangoapps/contentstore/management/commands/reindex_course.py
+20
-26
cms/djangoapps/contentstore/management/commands/reindex_library.py
+11
-14
cms/djangoapps/contentstore/management/commands/restore_asset_from_trashcan.py
+4
-4
cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py
+10
-9
cms/djangoapps/contentstore/management/commands/xlint.py
+19
-12
No files found.
cms/djangoapps/contentstore/management/commands/clean_cert_name.py
View file @
79fe2e62
...
@@ -4,6 +4,8 @@ erroneous certificate names.
...
@@ -4,6 +4,8 @@ erroneous certificate names.
"""
"""
from
collections
import
namedtuple
from
collections
import
namedtuple
from
six.moves
import
input
from
six
import
text_type
from
django.core.management.base
import
BaseCommand
from
django.core.management.base
import
BaseCommand
...
@@ -150,10 +152,10 @@ class Command(BaseCommand):
...
@@ -150,10 +152,10 @@ class Command(BaseCommand):
"""
"""
headers
=
[
"Course Key"
,
"cert_name_short"
,
"cert_name_short"
,
"Should clean?"
]
headers
=
[
"Course Key"
,
"cert_name_short"
,
"cert_name_short"
,
"Should clean?"
]
col_widths
=
[
col_widths
=
[
max
(
len
(
unicod
e
(
result
[
col
]))
for
result
in
results
+
[
headers
])
max
(
len
(
text_typ
e
(
result
[
col
]))
for
result
in
results
+
[
headers
])
for
col
in
range
(
len
(
results
[
0
]))
for
col
in
range
(
len
(
results
[
0
]))
]
]
id_format
=
"{{:>{}}} |"
.
format
(
len
(
unicod
e
(
len
(
results
))))
id_format
=
"{{:>{}}} |"
.
format
(
len
(
text_typ
e
(
len
(
results
))))
col_format
=
"| {{:>{}}} |"
col_format
=
"| {{:>{}}} |"
self
.
stdout
.
write
(
id_format
.
format
(
""
),
ending
=
''
)
self
.
stdout
.
write
(
id_format
.
format
(
""
),
ending
=
''
)
...
@@ -165,7 +167,7 @@ class Command(BaseCommand):
...
@@ -165,7 +167,7 @@ class Command(BaseCommand):
for
idx
,
result
in
enumerate
(
results
):
for
idx
,
result
in
enumerate
(
results
):
self
.
stdout
.
write
(
id_format
.
format
(
idx
),
ending
=
''
)
self
.
stdout
.
write
(
id_format
.
format
(
idx
),
ending
=
''
)
for
col
,
width
in
zip
(
result
,
col_widths
):
for
col
,
width
in
zip
(
result
,
col_widths
):
self
.
stdout
.
write
(
col_format
.
format
(
width
)
.
format
(
unicod
e
(
col
)),
ending
=
''
)
self
.
stdout
.
write
(
col_format
.
format
(
width
)
.
format
(
text_typ
e
(
col
)),
ending
=
''
)
self
.
stdout
.
write
(
""
)
self
.
stdout
.
write
(
""
)
def
_commit
(
self
,
results
):
def
_commit
(
self
,
results
):
...
@@ -191,7 +193,7 @@ class Command(BaseCommand):
...
@@ -191,7 +193,7 @@ class Command(BaseCommand):
while
True
:
while
True
:
self
.
_display
(
results
)
self
.
_display
(
results
)
command
=
raw_
input
(
"<index>|commit|quit: "
)
.
strip
()
command
=
input
(
"<index>|commit|quit: "
)
.
strip
()
if
command
==
'quit'
:
if
command
==
'quit'
:
return
return
...
...
cms/djangoapps/contentstore/management/commands/cleanup_assets.py
View file @
79fe2e62
...
@@ -24,17 +24,17 @@ class Command(BaseCommand):
...
@@ -24,17 +24,17 @@ class Command(BaseCommand):
content_store
=
contentstore
()
content_store
=
contentstore
()
success
=
False
success
=
False
log
.
info
(
u
"-"
*
80
)
log
.
info
(
"-"
*
80
)
log
.
info
(
u
"Cleaning up assets for all courses"
)
log
.
info
(
"Cleaning up assets for all courses"
)
try
:
try
:
# Remove all redundant Mac OS metadata files
# Remove all redundant Mac OS metadata files
assets_deleted
=
content_store
.
remove_redundant_content_for_courses
()
assets_deleted
=
content_store
.
remove_redundant_content_for_courses
()
success
=
True
success
=
True
except
Exception
as
err
:
except
Exception
as
err
:
log
.
info
(
u
"="
*
30
+
u"> failed to cleanup"
)
log
.
info
(
"="
*
30
+
u"> failed to cleanup"
)
log
.
info
(
u
"Error:"
)
log
.
info
(
"Error:"
)
log
.
info
(
err
)
log
.
info
(
err
)
if
success
:
if
success
:
log
.
info
(
u
"="
*
80
)
log
.
info
(
"="
*
80
)
log
.
info
(
u
"Total number of assets deleted: {0}"
.
format
(
assets_deleted
))
log
.
info
(
"Total number of assets deleted: {0}"
.
format
(
assets_deleted
))
cms/djangoapps/contentstore/management/commands/clone_course.py
View file @
79fe2e62
"""
"""
Script for cloning a course
Script for cloning a course
"""
"""
from
django.core.management.base
import
BaseCommand
,
CommandError
from
__future__
import
print_function
from
django.core.management.base
import
BaseCommand
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
student.roles
import
CourseInstructorRole
,
CourseStaffRole
from
student.roles
import
CourseInstructorRole
,
CourseStaffRole
...
@@ -13,24 +15,30 @@ from xmodule.modulestore.django import modulestore
...
@@ -13,24 +15,30 @@ from xmodule.modulestore.django import modulestore
# To run from command line: ./manage.py cms clone_course --settings=dev master/300/cough edx/111/foo
# To run from command line: ./manage.py cms clone_course --settings=dev master/300/cough edx/111/foo
#
#
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
"""Clone a MongoDB-backed course to another location"""
"""
Clone a MongoDB-backed course to another location
"""
help
=
'Clone a MongoDB backed course to another location'
help
=
'Clone a MongoDB backed course to another location'
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'source_course_id'
,
help
=
'Course ID to copy from'
)
parser
.
add_argument
(
'dest_course_id'
,
help
=
'Course ID to copy to'
)
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
"
Execute the command
"
"
"
"
if
len
(
args
)
!=
2
:
Execute the command
raise
CommandError
(
"clone requires 2 arguments: <source-course_id> <dest-course_id>"
)
"""
source_course_id
=
CourseKey
.
from_string
(
args
[
0
])
source_course_id
=
CourseKey
.
from_string
(
options
[
'source_course_id'
])
dest_course_id
=
CourseKey
.
from_string
(
args
[
1
])
dest_course_id
=
CourseKey
.
from_string
(
options
[
'dest_course_id'
])
mstore
=
modulestore
()
mstore
=
modulestore
()
print
"Cloning course {0} to {1}"
.
format
(
source_course_id
,
dest_course_id
)
print
(
"Cloning course {0} to {1}"
.
format
(
source_course_id
,
dest_course_id
)
)
with
mstore
.
bulk_operations
(
dest_course_id
):
with
mstore
.
bulk_operations
(
dest_course_id
):
if
mstore
.
clone_course
(
source_course_id
,
dest_course_id
,
ModuleStoreEnum
.
UserID
.
mgmt_command
):
if
mstore
.
clone_course
(
source_course_id
,
dest_course_id
,
ModuleStoreEnum
.
UserID
.
mgmt_command
):
print
"copying User permissions..."
print
(
"copying User permissions..."
)
# purposely avoids auth.add_user b/c it doesn't have a caller to authorize
# purposely avoids auth.add_user b/c it doesn't have a caller to authorize
CourseInstructorRole
(
dest_course_id
)
.
add_users
(
CourseInstructorRole
(
dest_course_id
)
.
add_users
(
*
CourseInstructorRole
(
source_course_id
)
.
users_with_role
()
*
CourseInstructorRole
(
source_course_id
)
.
users_with_role
()
...
...
cms/djangoapps/contentstore/management/commands/create_course.py
View file @
79fe2e62
"""
"""
Django management command to create a course in a specific modulestore
Django management command to create a course in a specific modulestore
"""
"""
from
six
import
text_type
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.management.base
import
BaseCommand
,
CommandError
...
@@ -9,6 +11,9 @@ from contentstore.views.course import create_new_course_in_store
...
@@ -9,6 +11,9 @@ from contentstore.views.course import create_new_course_in_store
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore
import
ModuleStoreEnum
MODULESTORE_CHOICES
=
(
ModuleStoreEnum
.
Type
.
mongo
,
ModuleStoreEnum
.
Type
.
split
)
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
"""
"""
Create a course in a specific modulestore.
Create a course in a specific modulestore.
...
@@ -16,45 +21,36 @@ class Command(BaseCommand):
...
@@ -16,45 +21,36 @@ class Command(BaseCommand):
# can this query modulestore for the list of write accessible stores or does that violate command pattern?
# 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
])
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
):
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'modulestore'
,
choices
=
MODULESTORE_CHOICES
,
help
=
"Modulestore must be one of {}"
.
format
(
MODULESTORE_CHOICES
))
parser
.
add_argument
(
'user'
,
help
=
"The instructor's email address or integer ID."
)
parser
.
add_argument
(
'org'
,
help
=
"The organization to create the course within."
)
parser
.
add_argument
(
'course'
,
help
=
"The name of the course."
)
parser
.
add_argument
(
'run'
,
help
=
"The name of the course run."
)
def
parse_args
(
self
,
**
options
):
"""
"""
Return a tuple of passed in values for (modulestore, user, org, course, run).
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
:
try
:
user
=
user_from_str
(
args
[
1
])
user
=
user_from_str
(
options
[
'user'
])
except
User
.
DoesNotExist
:
except
User
.
DoesNotExist
:
raise
CommandError
(
raise
CommandError
(
"No user {user} found."
.
format
(
user
=
options
[
'user'
]))
"No user {user} found: expected args are {args}"
.
format
(
user
=
args
[
1
],
args
=
self
.
args
,
),
)
org
=
args
[
2
]
return
options
[
'modulestore'
],
user
,
options
[
'org'
],
options
[
'course'
],
options
[
'run'
]
course
=
args
[
3
]
run
=
args
[
4
]
return
storetype
,
user
,
org
,
course
,
run
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
storetype
,
user
,
org
,
course
,
run
=
self
.
parse_args
(
*
args
)
storetype
,
user
,
org
,
course
,
run
=
self
.
parse_args
(
**
options
)
if
storetype
==
ModuleStoreEnum
.
Type
.
mongo
:
self
.
stderr
.
write
(
"WARNING: The 'Old Mongo' store is deprecated. New courses should be added to split."
)
new_course
=
create_new_course_in_store
(
storetype
,
user
,
org
,
course
,
run
,
{})
new_course
=
create_new_course_in_store
(
storetype
,
user
,
org
,
course
,
run
,
{})
self
.
stdout
.
write
(
u"Created {}"
.
format
(
unicod
e
(
new_course
.
id
)))
self
.
stdout
.
write
(
u"Created {}"
.
format
(
text_typ
e
(
new_course
.
id
)))
cms/djangoapps/contentstore/management/commands/delete_course.py
View file @
79fe2e62
from
__future__
import
print_function
from
six
import
text_type
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.management.base
import
BaseCommand
,
CommandError
from
opaque_keys
import
InvalidKeyError
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
...
@@ -54,7 +57,7 @@ class Command(BaseCommand):
...
@@ -54,7 +57,7 @@ class Command(BaseCommand):
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
try
:
try
:
# a course key may have unicode chars in it
# a course key may have unicode chars in it
course_key
=
unicod
e
(
options
[
'course_key'
],
'utf8'
)
course_key
=
text_typ
e
(
options
[
'course_key'
],
'utf8'
)
course_key
=
CourseKey
.
from_string
(
course_key
)
course_key
=
CourseKey
.
from_string
(
course_key
)
except
InvalidKeyError
:
except
InvalidKeyError
:
raise
CommandError
(
'Invalid course_key: {}'
.
format
(
options
[
'course_key'
]))
raise
CommandError
(
'Invalid course_key: {}'
.
format
(
options
[
'course_key'
]))
...
...
cms/djangoapps/contentstore/management/commands/delete_orphans.py
View file @
79fe2e62
"""Script for deleting orphans"""
"""Script for deleting orphans"""
from
__future__
import
print_function
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.management.base
import
BaseCommand
,
CommandError
from
opaque_keys
import
InvalidKeyError
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
...
@@ -26,15 +28,15 @@ class Command(BaseCommand):
...
@@ -26,15 +28,15 @@ class Command(BaseCommand):
raise
CommandError
(
"Invalid course key."
)
raise
CommandError
(
"Invalid course key."
)
if
options
[
'commit'
]:
if
options
[
'commit'
]:
print
'Deleting orphans from the course:'
print
(
'Deleting orphans from the course:'
)
deleted_items
=
_delete_orphans
(
deleted_items
=
_delete_orphans
(
course_key
,
ModuleStoreEnum
.
UserID
.
mgmt_command
,
options
[
'commit'
]
course_key
,
ModuleStoreEnum
.
UserID
.
mgmt_command
,
options
[
'commit'
]
)
)
print
"Success! Deleted the following orphans from the course:"
print
(
"Success! Deleted the following orphans from the course:"
)
print
"
\n
"
.
join
(
deleted_items
)
print
(
"
\n
"
.
join
(
deleted_items
)
)
else
:
else
:
print
'Dry run. The following orphans would have been deleted from the course:'
print
(
'Dry run. The following orphans would have been deleted from the course:'
)
deleted_items
=
_delete_orphans
(
deleted_items
=
_delete_orphans
(
course_key
,
ModuleStoreEnum
.
UserID
.
mgmt_command
,
options
[
'commit'
]
course_key
,
ModuleStoreEnum
.
UserID
.
mgmt_command
,
options
[
'commit'
]
)
)
print
"
\n
"
.
join
(
deleted_items
)
print
(
"
\n
"
.
join
(
deleted_items
)
)
cms/djangoapps/contentstore/management/commands/edit_course_tabs.py
View file @
79fe2e62
...
@@ -6,7 +6,8 @@
...
@@ -6,7 +6,8 @@
# Run it this way:
# Run it this way:
# ./manage.py cms --settings dev edit_course_tabs --course Stanford/CS99/2013_spring
# ./manage.py cms --settings dev edit_course_tabs --course Stanford/CS99/2013_spring
#
#
from
optparse
import
make_option
from
__future__
import
print_function
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.management.base
import
BaseCommand
,
CommandError
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
...
@@ -18,10 +19,16 @@ from .prompt import query_yes_no
...
@@ -18,10 +19,16 @@ from .prompt import query_yes_no
def
print_course
(
course
):
def
print_course
(
course
):
"Prints out the course id and a numbered list of tabs."
"Prints out the course id and a numbered list of tabs."
print
course
.
id
try
:
print
'num type name'
print
(
course
.
id
)
for
index
,
item
in
enumerate
(
course
.
tabs
):
print
(
'num type name'
)
print
index
+
1
,
'"'
+
item
.
get
(
'type'
)
+
'"'
,
'"'
+
item
.
get
(
'name'
,
''
)
+
'"'
for
index
,
item
in
enumerate
(
course
.
tabs
):
print
(
index
+
1
,
'"'
+
item
.
get
(
'type'
)
+
'"'
,
'"'
+
item
.
get
(
'name'
,
''
)
+
'"'
)
# If a course is bad we will get an error descriptor here, dump it and die instead of
# just sending up the error that .id doesn't exist.
except
AttributeError
:
print
(
course
)
raise
# course.tabs looks like this
# course.tabs looks like this
...
@@ -42,48 +49,50 @@ As a first step, run the command with a courseid like this:
...
@@ -42,48 +49,50 @@ As a first step, run the command with a courseid like this:
This will print the existing tabs types and names. Then run the
This will print the existing tabs types and names. Then run the
command again, adding --insert or --delete to edit the list.
command again, adding --insert or --delete to edit the list.
"""
"""
# Making these option objects separately, so can refer to their .help below
course_option
=
make_option
(
'--course'
,
action
=
'store'
,
dest
=
'course'
,
default
=
False
,
help
=
'--course <id> required, e.g. Stanford/CS99/2013_spring'
)
delete_option
=
make_option
(
'--delete'
,
action
=
'store_true'
,
dest
=
'delete'
,
default
=
False
,
help
=
'--delete <tab-number>'
)
insert_option
=
make_option
(
'--insert'
,
action
=
'store_true'
,
dest
=
'insert'
,
default
=
False
,
help
=
'--insert <tab-number> <type> <name>, e.g. 2 "course_info" "Course Info"'
)
option_list
=
BaseCommand
.
option_list
+
(
course_option
,
delete_option
,
insert_option
)
def
handle
(
self
,
*
args
,
**
options
):
course_help
=
'--course <id> required, e.g. Stanford/CS99/2013_spring'
if
not
options
[
'course'
]:
delete_help
=
'--delete <tab-number>'
raise
CommandError
(
Command
.
course_option
.
help
)
insert_help
=
'--insert <tab-number> <type> <name>, e.g. 4 "course_info" "Course Info"'
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'--course'
,
dest
=
'course'
,
default
=
False
,
required
=
True
,
help
=
self
.
course_help
)
parser
.
add_argument
(
'--delete'
,
dest
=
'delete'
,
default
=
False
,
nargs
=
1
,
help
=
self
.
delete_help
)
parser
.
add_argument
(
'--insert'
,
dest
=
'insert'
,
default
=
False
,
nargs
=
3
,
help
=
self
.
insert_help
,
)
def
handle
(
self
,
*
args
,
**
options
):
course
=
get_course_by_id
(
CourseKey
.
from_string
(
options
[
'course'
]))
course
=
get_course_by_id
(
CourseKey
.
from_string
(
options
[
'course'
]))
print
'Warning: this command directly edits the list of course tabs in mongo.'
print
(
'Warning: this command directly edits the list of course tabs in mongo.'
)
print
'Tabs before any changes:'
print
(
'Tabs before any changes:'
)
print_course
(
course
)
print_course
(
course
)
try
:
try
:
if
options
[
'delete'
]:
if
options
[
'delete'
]:
if
len
(
args
)
!=
1
:
num
=
int
(
options
[
'delete'
][
0
])
raise
CommandError
(
Command
.
delete_option
.
help
)
if
num
<
3
:
num
=
int
(
args
[
0
])
raise
CommandError
(
"Tabs 1 and 2 cannot be changed."
)
if
query_yes_no
(
'Deleting tab {0} Confirm?'
.
format
(
num
),
default
=
'no'
):
if
query_yes_no
(
'Deleting tab {0} Confirm?'
.
format
(
num
),
default
=
'no'
):
tabs
.
primitive_delete
(
course
,
num
-
1
)
# -1 for 0-based indexing
tabs
.
primitive_delete
(
course
,
num
-
1
)
# -1 for 0-based indexing
elif
options
[
'insert'
]:
elif
options
[
'insert'
]:
if
len
(
args
)
!=
3
:
num
,
tab_type
,
name
=
options
[
'insert'
]
raise
CommandError
(
Command
.
insert_option
.
help
)
num
=
int
(
num
)
num
=
int
(
args
[
0
])
if
num
<
3
:
tab_type
=
args
[
1
]
raise
CommandError
(
"Tabs 1 and 2 cannot be changed."
)
name
=
args
[
2
]
if
query_yes_no
(
'Inserting tab {0} "{1}" "{2}" Confirm?'
.
format
(
num
,
tab_type
,
name
),
default
=
'no'
):
if
query_yes_no
(
'Inserting tab {0} "{1}" "{2}" Confirm?'
.
format
(
num
,
tab_type
,
name
),
default
=
'no'
):
tabs
.
primitive_insert
(
course
,
num
-
1
,
tab_type
,
name
)
# -1 as above
tabs
.
primitive_insert
(
course
,
num
-
1
,
tab_type
,
name
)
# -1 as above
except
ValueError
as
e
:
except
ValueError
as
e
:
...
...
cms/djangoapps/contentstore/management/commands/empty_asset_trashcan.py
View file @
79fe2e62
...
@@ -8,16 +8,18 @@ from .prompt import query_yes_no
...
@@ -8,16 +8,18 @@ from .prompt import query_yes_no
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
help
=
'
''Empty the trashcan. Can pass an optional course_id to limit the damage.''
'
help
=
'
Empty the trashcan. Can pass an optional course_id to limit the damage.
'
def
handle
(
self
,
*
args
,
**
options
):
def
add_arguments
(
self
,
parser
):
if
len
(
args
)
!=
1
and
len
(
args
)
!=
0
:
parser
.
add_argument
(
'course_id'
,
raise
CommandError
(
"empty_asset_trashcan requires one or no arguments: |<course_id>|"
)
help
=
'Course ID to empty, leave off to empty for all courses'
,
nargs
=
'?'
)
if
len
(
args
)
==
1
:
def
handle
(
self
,
*
args
,
**
options
):
course_ids
=
[
CourseKey
.
from_string
(
args
[
0
])]
if
options
[
'course_id'
]:
course_ids
=
[
CourseKey
.
from_string
(
options
[
'course_id'
])]
else
:
else
:
course_ids
=
[
course
.
id
for
course
in
modulestore
()
.
get_courses
()]
course_ids
=
[
course
.
id
for
course
in
modulestore
()
.
get_courses
()]
if
query_yes_no
(
"Emptying
trashcan. Confirm?"
,
default
=
"no"
):
if
query_yes_no
(
"Emptying
{} trashcan(s). Confirm?"
.
format
(
len
(
course_ids
))
,
default
=
"no"
):
empty_asset_trashcan
(
course_ids
)
empty_asset_trashcan
(
course_ids
)
cms/djangoapps/contentstore/management/commands/export.py
View file @
79fe2e62
"""
"""
Script for exporting courseware from Mongo to a tar.gz file
Script for exporting courseware from Mongo to a tar.gz file
"""
"""
from
__future__
import
print_function
import
os
import
os
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.management.base
import
BaseCommand
,
CommandError
...
@@ -37,7 +38,7 @@ class Command(BaseCommand):
...
@@ -37,7 +38,7 @@ class Command(BaseCommand):
output_path
=
options
[
'output_path'
]
output_path
=
options
[
'output_path'
]
print
"Exporting course id = {0} to {1}"
.
format
(
course_key
,
output_path
)
print
(
"Exporting course id = {0} to {1}"
.
format
(
course_key
,
output_path
)
)
if
not
output_path
.
endswith
(
'/'
):
if
not
output_path
.
endswith
(
'/'
):
output_path
+=
'/'
output_path
+=
'/'
...
...
cms/djangoapps/contentstore/management/commands/export_all_courses.py
View file @
79fe2e62
"""
"""
Script for exporting all courseware from Mongo to a directory and listing the courses which failed to export
Script for exporting all courseware from Mongo to a directory and listing the courses which failed to export
"""
"""
from
django.core.management.base
import
BaseCommand
,
CommandError
from
__future__
import
print_function
from
six
import
text_type
from
django.core.management.base
import
BaseCommand
from
xmodule.contentstore.django
import
contentstore
from
xmodule.contentstore.django
import
contentstore
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
...
@@ -14,23 +17,22 @@ class Command(BaseCommand):
...
@@ -14,23 +17,22 @@ class Command(BaseCommand):
"""
"""
help
=
'Export all courses from mongo to the specified data directory and list the courses which failed to export'
help
=
'Export all courses from mongo to the specified data directory and list the courses which failed to export'
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'output_path'
)
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
"""
"""
Execute the command
Execute the command
"""
"""
if
len
(
args
)
!=
1
:
courses
,
failed_export_courses
=
export_courses_to_output_path
(
options
[
'output_path'
])
raise
CommandError
(
"export requires one argument: <output path>"
)
output_path
=
args
[
0
]
courses
,
failed_export_courses
=
export_courses_to_output_path
(
output_path
)
print
"="
*
80
print
(
"="
*
80
)
print
u"="
*
30
+
u"> Export summary"
print
(
"="
*
30
+
"> Export summary"
)
print
u"Total number of courses to export: {0}"
.
format
(
len
(
courses
))
print
(
"Total number of courses to export: {0}"
.
format
(
len
(
courses
)
))
print
u"Total number of courses which failed to export: {0}"
.
format
(
len
(
failed_export_courses
))
print
(
"Total number of courses which failed to export: {0}"
.
format
(
len
(
failed_export_courses
)
))
print
u"List of export failed courses ids:"
print
(
"List of export failed courses ids:"
)
print
u"
\n
"
.
join
(
failed_export_courses
)
print
(
"
\n
"
.
join
(
failed_export_courses
)
)
print
"="
*
80
print
(
"="
*
80
)
def
export_courses_to_output_path
(
output_path
):
def
export_courses_to_output_path
(
output_path
):
...
@@ -46,15 +48,15 @@ def export_courses_to_output_path(output_path):
...
@@ -46,15 +48,15 @@ def export_courses_to_output_path(output_path):
failed_export_courses
=
[]
failed_export_courses
=
[]
for
course_id
in
course_ids
:
for
course_id
in
course_ids
:
print
u"-"
*
80
print
(
"-"
*
80
)
print
u"Exporting course id = {0} to {1}"
.
format
(
course_id
,
output_path
)
print
(
"Exporting course id = {0} to {1}"
.
format
(
course_id
,
output_path
)
)
try
:
try
:
course_dir
=
course_id
.
to_deprecated_string
()
.
replace
(
'/'
,
'...'
)
course_dir
=
course_id
.
to_deprecated_string
()
.
replace
(
'/'
,
'...'
)
export_course_to_xml
(
module_store
,
content_store
,
course_id
,
root_dir
,
course_dir
)
export_course_to_xml
(
module_store
,
content_store
,
course_id
,
root_dir
,
course_dir
)
except
Exception
as
err
:
# pylint: disable=broad-except
except
Exception
as
err
:
# pylint: disable=broad-except
failed_export_courses
.
append
(
unicod
e
(
course_id
))
failed_export_courses
.
append
(
text_typ
e
(
course_id
))
print
u"="
*
30
+
u"> Oops, failed to export {0}"
.
format
(
course_id
)
print
(
"="
*
30
+
"> Oops, failed to export {0}"
.
format
(
course_id
)
)
print
u"Error:"
print
(
"Error:"
)
print
err
print
(
err
)
return
courses
,
failed_export_courses
return
courses
,
failed_export_courses
cms/djangoapps/contentstore/management/commands/export_olx.py
View file @
79fe2e62
...
@@ -12,7 +12,6 @@ At present, it differs from Studio exports in several ways:
...
@@ -12,7 +12,6 @@ At present, it differs from Studio exports in several ways:
* The top-level directory in the resulting tarball is a "safe"
* The top-level directory in the resulting tarball is a "safe"
(i.e. ascii) version of the course_key, rather than the word "course".
(i.e. ascii) version of the course_key, rather than the word "course".
* It only supports the export of courses. It does not export libraries.
* It only supports the export of courses. It does not export libraries.
"""
"""
import
os
import
os
...
@@ -34,17 +33,16 @@ from xmodule.modulestore.xml_exporter import export_course_to_xml
...
@@ -34,17 +33,16 @@ from xmodule.modulestore.xml_exporter import export_course_to_xml
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
"""
"""
Export a course to XML. The output is compressed as a tar.gz file.
Export a course to XML. The output is compressed as a tar.gz file.
"""
"""
help
=
dedent
(
__doc__
)
.
strip
()
help
=
dedent
(
__doc__
)
.
strip
()
def
add_arguments
(
self
,
parser
):
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'course_id'
)
parser
.
add_argument
(
'course_id'
)
parser
.
add_argument
(
'--output'
,
default
=
None
)
parser
.
add_argument
(
'--output'
)
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
course_id
=
options
[
'course_id'
]
course_id
=
options
[
'course_id'
]
try
:
try
:
course_key
=
CourseKey
.
from_string
(
course_id
)
course_key
=
CourseKey
.
from_string
(
course_id
)
except
InvalidKeyError
:
except
InvalidKeyError
:
...
@@ -54,6 +52,7 @@ class Command(BaseCommand):
...
@@ -54,6 +52,7 @@ class Command(BaseCommand):
filename
=
options
[
'output'
]
filename
=
options
[
'output'
]
pipe_results
=
False
pipe_results
=
False
if
filename
is
None
:
if
filename
is
None
:
filename
=
mktemp
()
filename
=
mktemp
()
pipe_results
=
True
pipe_results
=
True
...
...
cms/djangoapps/contentstore/management/commands/fix_not_found.py
View file @
79fe2e62
...
@@ -20,7 +20,7 @@ class Command(BaseCommand):
...
@@ -20,7 +20,7 @@ class Command(BaseCommand):
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
"""Execute the command"""
"""Execute the command"""
course_id
=
options
.
get
(
'course_id'
,
None
)
course_id
=
options
[
'course_id'
]
course_key
=
CourseKey
.
from_string
(
course_id
)
course_key
=
CourseKey
.
from_string
(
course_id
)
# for now only support on split mongo
# for now only support on split mongo
...
...
cms/djangoapps/contentstore/management/commands/force_publish.py
View file @
79fe2e62
...
@@ -44,7 +44,7 @@ class Command(BaseCommand):
...
@@ -44,7 +44,7 @@ class Command(BaseCommand):
owning_store
=
modulestore
()
.
_get_modulestore_for_courselike
(
course_key
)
# pylint: disable=protected-access
owning_store
=
modulestore
()
.
_get_modulestore_for_courselike
(
course_key
)
# pylint: disable=protected-access
if
hasattr
(
owning_store
,
'force_publish_course'
):
if
hasattr
(
owning_store
,
'force_publish_course'
):
versions
=
get_course_versions
(
options
[
'course_key'
])
versions
=
get_course_versions
(
options
[
'course_key'
])
print
"Course versions : {0}"
.
format
(
versions
)
print
(
"Course versions : {0}"
.
format
(
versions
)
)
if
options
[
'commit'
]:
if
options
[
'commit'
]:
if
query_yes_no
(
"Are you sure to publish the {0} course forcefully?"
.
format
(
course_key
),
default
=
"no"
):
if
query_yes_no
(
"Are you sure to publish the {0} course forcefully?"
.
format
(
course_key
),
default
=
"no"
):
...
@@ -55,20 +55,20 @@ class Command(BaseCommand):
...
@@ -55,20 +55,20 @@ class Command(BaseCommand):
if
updated_versions
:
if
updated_versions
:
# if publish and draft were different
# if publish and draft were different
if
versions
[
'published-branch'
]
!=
versions
[
'draft-branch'
]:
if
versions
[
'published-branch'
]
!=
versions
[
'draft-branch'
]:
print
"Success! Published the course '{0}' forcefully."
.
format
(
course_key
)
print
(
"Success! Published the course '{0}' forcefully."
.
format
(
course_key
)
)
print
"Updated course versions :
\n
{0}"
.
format
(
updated_versions
)
print
(
"Updated course versions :
\n
{0}"
.
format
(
updated_versions
)
)
else
:
else
:
print
"Course '{0}' is already in published state."
.
format
(
course_key
)
print
(
"Course '{0}' is already in published state."
.
format
(
course_key
)
)
else
:
else
:
print
"Error! Could not publish course {0}."
.
format
(
course_key
)
print
(
"Error! Could not publish course {0}."
.
format
(
course_key
)
)
else
:
else
:
# if publish and draft were different
# if publish and draft were different
if
versions
[
'published-branch'
]
!=
versions
[
'draft-branch'
]:
if
versions
[
'published-branch'
]
!=
versions
[
'draft-branch'
]:
print
"Dry run. Following would have been changed : "
print
(
"Dry run. Following would have been changed : "
)
print
"Published branch version {0} changed to draft branch version {1}"
.
format
(
print
(
"Published branch version {0} changed to draft branch version {1}"
.
format
(
versions
[
'published-branch'
],
versions
[
'draft-branch'
]
versions
[
'published-branch'
],
versions
[
'draft-branch'
]
)
)
)
else
:
else
:
print
"Dry run. Course '{0}' is already in published state."
.
format
(
course_key
)
print
(
"Dry run. Course '{0}' is already in published state."
.
format
(
course_key
)
)
else
:
else
:
raise
CommandError
(
"The owning modulestore does not support this command."
)
raise
CommandError
(
"The owning modulestore does not support this command."
)
cms/djangoapps/contentstore/management/commands/generate_courses.py
View file @
79fe2e62
...
@@ -3,6 +3,7 @@ Django management command to generate a test course from a course config json
...
@@ -3,6 +3,7 @@ Django management command to generate a test course from a course config json
"""
"""
import
json
import
json
import
logging
import
logging
from
six
import
text_type
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.management.base
import
BaseCommand
,
CommandError
...
@@ -57,7 +58,7 @@ class Command(BaseCommand):
...
@@ -57,7 +58,7 @@ class Command(BaseCommand):
# Create the course
# Create the course
try
:
try
:
new_course
=
create_new_course_in_store
(
"split"
,
user
,
org
,
num
,
run
,
fields
)
new_course
=
create_new_course_in_store
(
"split"
,
user
,
org
,
num
,
run
,
fields
)
logger
.
info
(
"Created {}"
.
format
(
unicod
e
(
new_course
.
id
)))
logger
.
info
(
"Created {}"
.
format
(
text_typ
e
(
new_course
.
id
)))
except
DuplicateCourseError
:
except
DuplicateCourseError
:
logger
.
warning
(
"Course already exists for
%
s,
%
s,
%
s"
,
org
,
num
,
run
)
logger
.
warning
(
"Course already exists for
%
s,
%
s,
%
s"
,
org
,
num
,
run
)
...
...
cms/djangoapps/contentstore/management/commands/git_export.py
View file @
79fe2e62
...
@@ -14,7 +14,7 @@ attribute is set and the FEATURE['ENABLE_EXPORT_GIT'] is set.
...
@@ -14,7 +14,7 @@ attribute is set and the FEATURE['ENABLE_EXPORT_GIT'] is set.
"""
"""
import
logging
import
logging
from
optparse
import
make_option
from
six
import
text_type
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
...
@@ -31,41 +31,34 @@ class Command(BaseCommand):
...
@@ -31,41 +31,34 @@ class Command(BaseCommand):
"""
"""
Take a course from studio and export it to a git repository.
Take a course from studio and export it to a git repository.
"""
"""
option_list
=
BaseCommand
.
option_list
+
(
make_option
(
'--username'
,
'-u'
,
dest
=
'user'
,
help
=
(
'Specify a username from LMS/Studio to be used '
'as the commit author.'
)),
make_option
(
'--repo_dir'
,
'-r'
,
dest
=
'repo'
,
help
=
'Specify existing git repo directory.'
),
)
help
=
_
(
'Take the specified course and attempt to '
help
=
_
(
'Take the specified course and attempt to '
'export it to a git repository
\n
. Course directory '
'export it to a git repository
\n
. Course directory '
'must already be a git repository. Usage: '
'must already be a git repository. Usage: '
' git_export <course_loc> <git_url>'
)
' git_export <course_loc> <git_url>'
)
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'course_loc'
)
parser
.
add_argument
(
'git_url'
)
parser
.
add_argument
(
'--username'
,
'-u'
,
dest
=
'user'
,
help
=
'Specify a username from LMS/Studio to be used as the commit author.'
)
parser
.
add_argument
(
'--repo_dir'
,
'-r'
,
dest
=
'repo'
,
help
=
'Specify existing git repo directory.'
)
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
"""
"""
Checks arguments and runs export function if they are good
Checks arguments and runs export function if they are good
"""
"""
if
len
(
args
)
!=
2
:
raise
CommandError
(
'This script requires exactly two arguments: '
'course_loc and git_url'
)
# Rethrow GitExportError as CommandError for SystemExit
# Rethrow GitExportError as CommandError for SystemExit
try
:
try
:
course_key
=
CourseKey
.
from_string
(
args
[
0
])
course_key
=
CourseKey
.
from_string
(
options
[
'course_loc'
])
except
InvalidKeyError
:
except
InvalidKeyError
:
raise
CommandError
(
unicod
e
(
GitExportError
.
BAD_COURSE
))
raise
CommandError
(
text_typ
e
(
GitExportError
.
BAD_COURSE
))
try
:
try
:
git_export_utils
.
export_to_git
(
git_export_utils
.
export_to_git
(
course_key
,
course_key
,
args
[
1
],
options
[
'git_url'
],
options
.
get
(
'user'
,
''
),
options
.
get
(
'user'
,
''
),
options
.
get
(
'rdir'
,
None
)
options
.
get
(
'rdir'
,
None
)
)
)
except
git_export_utils
.
GitExportError
as
ex
:
except
git_export_utils
.
GitExportError
as
ex
:
raise
CommandError
(
unicod
e
(
ex
.
message
))
raise
CommandError
(
text_typ
e
(
ex
.
message
))
cms/djangoapps/contentstore/management/commands/import.py
View file @
79fe2e62
...
@@ -3,7 +3,7 @@ Script for importing courseware from XML format
...
@@ -3,7 +3,7 @@ Script for importing courseware from XML format
"""
"""
from
optparse
import
make_option
from
optparse
import
make_option
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.management.base
import
BaseCommand
from
django_comment_common.utils
import
are_permissions_roles_seeded
,
seed_permissions_roles
from
django_comment_common.utils
import
are_permissions_roles_seeded
,
seed_permissions_roles
from
xmodule.contentstore.django
import
contentstore
from
xmodule.contentstore.django
import
contentstore
...
...
cms/djangoapps/contentstore/management/commands/migrate_to_split.py
View file @
79fe2e62
...
@@ -18,41 +18,34 @@ class Command(BaseCommand):
...
@@ -18,41 +18,34 @@ class Command(BaseCommand):
Migrate a course from old-Mongo to split-Mongo. It reuses the old course id except where overridden.
Migrate a course from old-Mongo to split-Mongo. It reuses the old course id except where overridden.
"""
"""
help
=
"Migrate a course from old-Mongo to split-Mongo. The new org, course, and run will
default to the old one unless overridden"
help
=
"Migrate a course from old-Mongo to split-Mongo. The new org, course, and run will
"
\
args
=
"course_key email <new org> <new course> <new run>
"
"default to the old one unless overridden.
"
def
parse_args
(
self
,
*
args
):
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'course_key'
)
parser
.
add_argument
(
'email'
)
parser
.
add_argument
(
'--org'
,
help
=
'New org to migrate to.'
)
parser
.
add_argument
(
'--course'
,
help
=
'New course key to migrate to.'
)
parser
.
add_argument
(
'--run'
,
help
=
'New run to migrate to.'
)
def
parse_args
(
self
,
**
options
):
"""
"""
Return a 5-tuple of passed in values for (course_key, user, org, course, run).
Return a 5-tuple of passed in values for (course_key, user, org, course, run).
"""
"""
if
len
(
args
)
<
2
:
raise
CommandError
(
"migrate_to_split requires at least two arguments: "
"a course_key and a user identifier (email or ID)"
)
try
:
try
:
course_key
=
CourseKey
.
from_string
(
args
[
0
])
course_key
=
CourseKey
.
from_string
(
options
[
'course_key'
])
except
InvalidKeyError
:
except
InvalidKeyError
:
raise
CommandError
(
"Invalid location string"
)
raise
CommandError
(
"Invalid location string"
)
try
:
try
:
user
=
user_from_str
(
args
[
1
])
user
=
user_from_str
(
options
[
'email'
])
except
User
.
DoesNotExist
:
except
User
.
DoesNotExist
:
raise
CommandError
(
"No user found identified by {}"
.
format
(
args
[
1
]))
raise
CommandError
(
"No user found identified by {}"
.
format
(
options
[
'email'
]))
org
=
course
=
run
=
None
try
:
org
=
args
[
2
]
course
=
args
[
3
]
run
=
args
[
4
]
except
IndexError
:
pass
return
course_key
,
user
.
id
,
o
rg
,
course
,
run
return
course_key
,
user
.
id
,
o
ptions
[
'org'
],
options
[
'course'
],
options
[
'run'
]
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
course_key
,
user
,
org
,
course
,
run
=
self
.
parse_args
(
*
arg
s
)
course_key
,
user
,
org
,
course
,
run
=
self
.
parse_args
(
*
*
option
s
)
migrator
=
SplitMigrator
(
migrator
=
SplitMigrator
(
source_modulestore
=
modulestore
(),
source_modulestore
=
modulestore
(),
...
...
cms/djangoapps/contentstore/management/commands/populate_creators.py
View file @
79fe2e62
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
Script for granting existing course instructors course creator privileges.
Script for granting existing course instructors course creator privileges.
This script is only intended to be run once on a given environment.
This script is only intended to be run once on a given environment.
To run: ./manage.py cms populate_creators --settings=dev
"""
"""
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.core.management.base
import
BaseCommand
from
django.core.management.base
import
BaseCommand
...
@@ -11,9 +13,6 @@ from course_creators.views import add_user_with_status_granted, add_user_with_st
...
@@ -11,9 +13,6 @@ from course_creators.views import add_user_with_status_granted, add_user_with_st
from
student.roles
import
CourseInstructorRole
,
CourseStaffRole
from
student.roles
import
CourseInstructorRole
,
CourseStaffRole
#------------ to run: ./manage.py cms populate_creators --settings=dev
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
"""
"""
Script for granting existing course instructors course creator privileges.
Script for granting existing course instructors course creator privileges.
...
@@ -35,23 +34,24 @@ class Command(BaseCommand):
...
@@ -35,23 +34,24 @@ class Command(BaseCommand):
# the admin user will already exist.
# the admin user will already exist.
admin
=
User
.
objects
.
get
(
username
=
username
,
email
=
email
)
admin
=
User
.
objects
.
get
(
username
=
username
,
email
=
email
)
for
user
in
get_users_with_role
(
CourseInstructorRole
.
ROLE
):
try
:
add_user_with_status_granted
(
admin
,
user
)
for
user
in
get_users_with_role
(
CourseInstructorRole
.
ROLE
):
add_user_with_status_granted
(
admin
,
user
)
# Some users will be both staff and instructors. Those folks have been
# added with status granted above, and add_user_with_status_unrequested
# will not try to add them again if they already exist in the course creator database.
for
user
in
get_users_with_role
(
CourseStaffRole
.
ROLE
):
add_user_with_status_unrequested
(
user
)
# There could be users who are not in either staff or instructor (they've
# Some users will be both staff and instructors. Those folks have been
# never actually done anything in Studio). I plan to add those as unrequested
# added with status granted above, and add_user_with_status_unrequested
# when they first go to their dashboard.
# will not try to add them again if they already exist in the course creator database.
for
user
in
get_users_with_role
(
CourseStaffRole
.
ROLE
):
add_user_with_status_unrequested
(
user
)
admin
.
delete
()
# There could be users who are not in either staff or instructor (they've
# never actually done anything in Studio). I plan to add those as unrequested
# when they first go to their dashboard.
finally
:
# Let's not leave this lying around.
admin
.
delete
()
#=============================================================================================================
# Because these are expensive and far-reaching, I moved them here
# Because these are expensive and far-reaching, I moved them here
def
get_users_with_role
(
role_prefix
):
def
get_users_with_role
(
role_prefix
):
"""
"""
...
...
cms/djangoapps/contentstore/management/commands/reindex_course.py
View file @
79fe2e62
""" Management command to update courses' search index """
""" Management command to update courses' search index """
import
logging
import
logging
from
optparse
import
make_option
from
textwrap
import
dedent
from
textwrap
import
dedent
from
django.core.management
import
BaseCommand
,
CommandError
from
django.core.management
import
BaseCommand
,
CommandError
...
@@ -22,32 +21,25 @@ class Command(BaseCommand):
...
@@ -22,32 +21,25 @@ class Command(BaseCommand):
Examples:
Examples:
./manage.py reindex_course <course_id_1> <course_id_2>
- reindexes courses with keys course_id_1 and course_id_2
./manage.py reindex_course <course_id_1> <course_id_2>
... - reindexes courses with provided keys
./manage.py reindex_course --all - reindexes all available courses
./manage.py reindex_course --all - reindexes all available courses
./manage.py reindex_course --setup - reindexes all courses for devstack setup
./manage.py reindex_course --setup - reindexes all courses for devstack setup
"""
"""
help
=
dedent
(
__doc__
)
help
=
dedent
(
__doc__
)
can_import_settings
=
True
can_import_settings
=
True
args
=
"<course_id course_id ...>"
all_option
=
make_option
(
'--all'
,
action
=
'store_true'
,
dest
=
'all'
,
default
=
False
,
help
=
'Reindex all courses'
)
setup_option
=
make_option
(
'--setup'
,
action
=
'store_true'
,
dest
=
'setup'
,
default
=
False
,
help
=
'Reindex all courses on developers stack setup'
)
option_list
=
BaseCommand
.
option_list
+
(
all_option
,
setup_option
)
CONFIRMATION_PROMPT
=
u"Re-indexing all courses might be a time consuming operation. Do you want to continue?"
CONFIRMATION_PROMPT
=
u"Re-indexing all courses might be a time consuming operation. Do you want to continue?"
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'course_ids'
,
nargs
=
'*'
,
metavar
=
'course_id'
)
parser
.
add_argument
(
'--all'
,
action
=
'store_true'
,
help
=
'Reindex all courses'
)
parser
.
add_argument
(
'--setup'
,
action
=
'store_true'
,
help
=
'Reindex all courses on developers stack setup'
)
def
_parse_course_key
(
self
,
raw_value
):
def
_parse_course_key
(
self
,
raw_value
):
""" Parses course key from string """
""" Parses course key from string """
try
:
try
:
...
@@ -65,12 +57,14 @@ class Command(BaseCommand):
...
@@ -65,12 +57,14 @@ class Command(BaseCommand):
By convention set by Django developers, this method actually executes command's actions.
By convention set by Django developers, this method actually executes command's actions.
So, there could be no better docstring than emphasize this once again.
So, there could be no better docstring than emphasize this once again.
"""
"""
all_option
=
options
.
get
(
'all'
,
False
)
course_ids
=
options
[
'course_ids'
]
setup_option
=
options
.
get
(
'setup'
,
False
)
all_option
=
options
[
'all'
]
setup_option
=
options
[
'setup'
]
index_all_courses_option
=
all_option
or
setup_option
index_all_courses_option
=
all_option
or
setup_option
if
len
(
args
)
==
0
and
not
index_all_courses_option
:
if
(
not
len
(
course_ids
)
and
not
index_all_courses_option
)
or
\
raise
CommandError
(
u"reindex_course requires one or more arguments: <course_id>"
)
(
len
(
course_ids
)
and
index_all_courses_option
):
raise
CommandError
(
"reindex_course requires one or more <course_id>s OR the --all or --setup flags."
)
store
=
modulestore
()
store
=
modulestore
()
...
@@ -82,7 +76,7 @@ class Command(BaseCommand):
...
@@ -82,7 +76,7 @@ class Command(BaseCommand):
# try getting the ElasticSearch engine
# try getting the ElasticSearch engine
searcher
=
SearchEngine
.
get_search_engine
(
index_name
)
searcher
=
SearchEngine
.
get_search_engine
(
index_name
)
except
exceptions
.
ElasticsearchException
as
exc
:
except
exceptions
.
ElasticsearchException
as
exc
:
logging
.
exception
(
'Search Engine error -
%
s'
,
unicode
(
exc
)
)
logging
.
exception
(
'Search Engine error -
%
s'
,
exc
)
return
return
index_exists
=
searcher
.
_es
.
indices
.
exists
(
index
=
index_name
)
# pylint: disable=protected-access
index_exists
=
searcher
.
_es
.
indices
.
exists
(
index
=
index_name
)
# pylint: disable=protected-access
...
@@ -108,7 +102,7 @@ class Command(BaseCommand):
...
@@ -108,7 +102,7 @@ class Command(BaseCommand):
return
return
else
:
else
:
# in case course keys are provided as arguments
# in case course keys are provided as arguments
course_keys
=
map
(
self
.
_parse_course_key
,
arg
s
)
course_keys
=
map
(
self
.
_parse_course_key
,
course_id
s
)
for
course_key
in
course_keys
:
for
course_key
in
course_keys
:
CoursewareSearchIndexer
.
do_course_reindex
(
store
,
course_key
)
CoursewareSearchIndexer
.
do_course_reindex
(
store
,
course_key
)
cms/djangoapps/contentstore/management/commands/reindex_library.py
View file @
79fe2e62
""" Management command to update libraries' search index """
""" Management command to update libraries' search index """
from
optparse
import
make_op
tion
from
__future__
import
print_func
tion
from
textwrap
import
dedent
from
textwrap
import
dedent
from
django.core.management
import
BaseCommand
,
CommandError
from
django.core.management
import
BaseCommand
,
CommandError
...
@@ -22,21 +22,17 @@ class Command(BaseCommand):
...
@@ -22,21 +22,17 @@ class Command(BaseCommand):
./manage.py reindex_library --all - reindexes all available libraries
./manage.py reindex_library --all - reindexes all available libraries
"""
"""
help
=
dedent
(
__doc__
)
help
=
dedent
(
__doc__
)
can_import_settings
=
True
can_import_settings
=
True
CONFIRMATION_PROMPT
=
u"Reindexing all libraries might be a time consuming operation. Do you want to continue?"
args
=
"<library_id library_id ...>"
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'library_ids'
,
nargs
=
'*'
)
option_list
=
BaseCommand
.
option_list
+
(
parser
.
add_argument
(
make_option
(
'--all'
,
'--all'
,
action
=
'store_true'
,
action
=
'store_true'
,
dest
=
'all'
,
dest
=
'all'
,
default
=
False
,
help
=
'Reindex all libraries'
help
=
'Reindex all libraries'
),)
)
CONFIRMATION_PROMPT
=
u"Reindexing all libraries might be a time consuming operation. Do you want to continue?"
def
_parse_library_key
(
self
,
raw_value
):
def
_parse_library_key
(
self
,
raw_value
):
""" Parses library key from string """
""" Parses library key from string """
...
@@ -52,18 +48,19 @@ class Command(BaseCommand):
...
@@ -52,18 +48,19 @@ class Command(BaseCommand):
By convention set by django developers, this method actually executes command's actions.
By convention set by django developers, this method actually executes command's actions.
So, there could be no better docstring than emphasize this once again.
So, there could be no better docstring than emphasize this once again.
"""
"""
if
len
(
args
)
==
0
and
not
options
.
get
(
'all'
,
False
):
if
(
not
options
[
'library_ids'
]
and
not
options
[
'all'
])
or
(
options
[
'library_ids'
]
and
options
[
'all'
]
):
raise
CommandError
(
u"reindex_library requires one or more
arguments: <library_id>
"
)
raise
CommandError
(
u"reindex_library requires one or more
<library_id>s or the --all flag.
"
)
store
=
modulestore
()
store
=
modulestore
()
if
options
.
get
(
'all'
,
False
)
:
if
options
[
'all'
]
:
if
query_yes_no
(
self
.
CONFIRMATION_PROMPT
,
default
=
"no"
):
if
query_yes_no
(
self
.
CONFIRMATION_PROMPT
,
default
=
"no"
):
library_keys
=
[
library
.
location
.
library_key
.
replace
(
branch
=
None
)
for
library
in
store
.
get_libraries
()]
library_keys
=
[
library
.
location
.
library_key
.
replace
(
branch
=
None
)
for
library
in
store
.
get_libraries
()]
else
:
else
:
return
return
else
:
else
:
library_keys
=
map
(
self
.
_parse_library_key
,
args
)
library_keys
=
map
(
self
.
_parse_library_key
,
options
[
'library_ids'
]
)
for
library_key
in
library_keys
:
for
library_key
in
library_keys
:
print
(
"Indexing library {}"
.
format
(
library_key
))
LibrarySearchIndexer
.
do_library_reindex
(
store
,
library_key
)
LibrarySearchIndexer
.
do_library_reindex
(
store
,
library_key
)
cms/djangoapps/contentstore/management/commands/restore_asset_from_trashcan.py
View file @
79fe2e62
...
@@ -6,8 +6,8 @@ from xmodule.contentstore.utils import restore_asset_from_trashcan
...
@@ -6,8 +6,8 @@ from xmodule.contentstore.utils import restore_asset_from_trashcan
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
help
=
'''Restore a deleted asset from the trashcan back to it's original course'''
help
=
'''Restore a deleted asset from the trashcan back to it's original course'''
def
handle
(
self
,
*
args
,
**
options
):
def
add_arguments
(
self
,
parser
):
if
len
(
args
)
!=
1
and
len
(
args
)
!=
0
:
parser
.
add_argument
(
'location'
)
raise
CommandError
(
"restore_asset_from_trashcan requires one argument: <location>"
)
restore_asset_from_trashcan
(
args
[
0
])
def
handle
(
self
,
*
args
,
**
options
):
restore_asset_from_trashcan
(
options
[
'location'
])
cms/djangoapps/contentstore/management/commands/tests/test_reindex_courses.py
View file @
79fe2e62
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
import
ddt
import
ddt
from
django.core.management
import
call_command
,
CommandError
from
django.core.management
import
call_command
,
CommandError
import
mock
import
mock
from
six
import
text_type
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
...
@@ -60,34 +61,34 @@ class TestReindexCourse(ModuleStoreTestCase):
...
@@ -60,34 +61,34 @@ class TestReindexCourse(ModuleStoreTestCase):
def
test_given_library_key_raises_command_error
(
self
):
def
test_given_library_key_raises_command_error
(
self
):
""" Test that raises CommandError if library key is passed """
""" Test that raises CommandError if library key is passed """
with
self
.
assertRaisesRegexp
(
CommandError
,
".* is not a course key"
):
with
self
.
assertRaisesRegexp
(
CommandError
,
".* is not a course key"
):
call_command
(
'reindex_course'
,
unicod
e
(
self
.
_get_lib_key
(
self
.
first_lib
)))
call_command
(
'reindex_course'
,
text_typ
e
(
self
.
_get_lib_key
(
self
.
first_lib
)))
with
self
.
assertRaisesRegexp
(
CommandError
,
".* is not a course key"
):
with
self
.
assertRaisesRegexp
(
CommandError
,
".* is not a course key"
):
call_command
(
'reindex_course'
,
unicod
e
(
self
.
_get_lib_key
(
self
.
second_lib
)))
call_command
(
'reindex_course'
,
text_typ
e
(
self
.
_get_lib_key
(
self
.
second_lib
)))
with
self
.
assertRaisesRegexp
(
CommandError
,
".* is not a course key"
):
with
self
.
assertRaisesRegexp
(
CommandError
,
".* is not a course key"
):
call_command
(
call_command
(
'reindex_course'
,
'reindex_course'
,
unicod
e
(
self
.
second_course
.
id
),
text_typ
e
(
self
.
second_course
.
id
),
unicod
e
(
self
.
_get_lib_key
(
self
.
first_lib
))
text_typ
e
(
self
.
_get_lib_key
(
self
.
first_lib
))
)
)
def
test_given_id_list_indexes_courses
(
self
):
def
test_given_id_list_indexes_courses
(
self
):
""" Test that reindexes courses when given single course key or a list of course keys """
""" Test that reindexes courses when given single course key or a list of course keys """
with
mock
.
patch
(
self
.
REINDEX_PATH_LOCATION
)
as
patched_index
,
\
with
mock
.
patch
(
self
.
REINDEX_PATH_LOCATION
)
as
patched_index
,
\
mock
.
patch
(
self
.
MODULESTORE_PATCH_LOCATION
,
mock
.
Mock
(
return_value
=
self
.
store
)):
mock
.
patch
(
self
.
MODULESTORE_PATCH_LOCATION
,
mock
.
Mock
(
return_value
=
self
.
store
)):
call_command
(
'reindex_course'
,
unicod
e
(
self
.
first_course
.
id
))
call_command
(
'reindex_course'
,
text_typ
e
(
self
.
first_course
.
id
))
self
.
assertEqual
(
patched_index
.
mock_calls
,
self
.
_build_calls
(
self
.
first_course
))
self
.
assertEqual
(
patched_index
.
mock_calls
,
self
.
_build_calls
(
self
.
first_course
))
patched_index
.
reset_mock
()
patched_index
.
reset_mock
()
call_command
(
'reindex_course'
,
unicod
e
(
self
.
second_course
.
id
))
call_command
(
'reindex_course'
,
text_typ
e
(
self
.
second_course
.
id
))
self
.
assertEqual
(
patched_index
.
mock_calls
,
self
.
_build_calls
(
self
.
second_course
))
self
.
assertEqual
(
patched_index
.
mock_calls
,
self
.
_build_calls
(
self
.
second_course
))
patched_index
.
reset_mock
()
patched_index
.
reset_mock
()
call_command
(
call_command
(
'reindex_course'
,
'reindex_course'
,
unicod
e
(
self
.
first_course
.
id
),
text_typ
e
(
self
.
first_course
.
id
),
unicod
e
(
self
.
second_course
.
id
)
text_typ
e
(
self
.
second_course
.
id
)
)
)
expected_calls
=
self
.
_build_calls
(
self
.
first_course
,
self
.
second_course
)
expected_calls
=
self
.
_build_calls
(
self
.
first_course
,
self
.
second_course
)
self
.
assertEqual
(
patched_index
.
mock_calls
,
expected_calls
)
self
.
assertEqual
(
patched_index
.
mock_calls
,
expected_calls
)
...
@@ -121,4 +122,4 @@ class TestReindexCourse(ModuleStoreTestCase):
...
@@ -121,4 +122,4 @@ class TestReindexCourse(ModuleStoreTestCase):
patched_index
.
side_effect
=
SearchIndexingError
(
"message"
,
[])
patched_index
.
side_effect
=
SearchIndexingError
(
"message"
,
[])
with
self
.
assertRaises
(
SearchIndexingError
):
with
self
.
assertRaises
(
SearchIndexingError
):
call_command
(
'reindex_course'
,
unicod
e
(
self
.
second_course
.
id
))
call_command
(
'reindex_course'
,
text_typ
e
(
self
.
second_course
.
id
))
cms/djangoapps/contentstore/management/commands/xlint.py
View file @
79fe2e62
"""
"""
Verify the structure of courseware as to it's suitability for import
Verify the structure of courseware as to it's suitability for import
"""
"""
from
django.core.management.base
import
BaseCommand
,
CommandError
from
__future__
import
print_function
from
argparse
import
REMAINDER
from
django.core.management.base
import
BaseCommand
from
xmodule.modulestore.xml_importer
import
perform_xlint
from
xmodule.modulestore.xml_importer
import
perform_xlint
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
"""Verify the structure of courseware as to it's suitability for import"""
"""Verify the structure of courseware as to its suitability for import"""
help
=
"Verify the structure of courseware as to it's suitability for import"
help
=
"""
Verify the structure of courseware as to its suitability for import.
To run: manage.py cms <data directory> [<course dir>...]
"""
def
add_arguments
(
self
,
parser
):
parser
.
add_argument
(
'data_dir'
)
parser
.
add_argument
(
'source_dirs'
,
nargs
=
REMAINDER
)
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
"Execute the command"
"""Execute the command"""
if
len
(
args
)
==
0
:
raise
CommandError
(
"import requires at least one argument: <data directory> [<course dir>...]"
)
data_dir
=
options
[
'data_dir'
]
source_dirs
=
options
[
'source_dirs'
]
data_dir
=
args
[
0
]
if
len
(
args
)
>
1
:
source_dirs
=
args
[
1
:]
else
:
source_dirs
=
None
print
(
"Importing. Data_dir={data}, source_dirs={courses}"
.
format
(
print
(
"Importing. Data_dir={data}, source_dirs={courses}"
.
format
(
data
=
data_dir
,
data
=
data_dir
,
courses
=
source_dirs
))
courses
=
source_dirs
))
perform_xlint
(
data_dir
,
source_dirs
,
load_error_modules
=
False
)
perform_xlint
(
data_dir
,
source_dirs
,
load_error_modules
=
False
)
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