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
6939a581
Unverified
Commit
6939a581
authored
Nov 01, 2017
by
Brian Mesick
Committed by
GitHub
Nov 01, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #16384 from edx/bmedx/django111_student_mgmt_cmds
Student management command cleanup for Django 1.11
parents
7cd3e723
ce50c9e6
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
320 additions
and
360 deletions
+320
-360
common/djangoapps/student/management/commands/add_to_group.py
+21
-27
common/djangoapps/student/management/commands/anonymized_id_mapping.py
+4
-10
common/djangoapps/student/management/commands/assigngroups.py
+34
-29
common/djangoapps/student/management/commands/bulk_change_enrollment.py
+25
-42
common/djangoapps/student/management/commands/cert_restriction.py
+41
-56
common/djangoapps/student/management/commands/change_enrollment.py
+42
-44
common/djangoapps/student/management/commands/create_random_users.py
+12
-11
common/djangoapps/student/management/commands/create_user.py
+36
-50
common/djangoapps/student/management/commands/populate_created_on_site_user_attribute.py
+2
-3
common/djangoapps/student/management/commands/set_staff.py
+28
-30
common/djangoapps/student/management/commands/set_superuser.py
+17
-17
common/djangoapps/student/management/tests/test_bulk_change_enrollment.py
+40
-22
common/djangoapps/student/management/tests/test_change_enrollment.py
+18
-19
No files found.
common/djangoapps/student/management/commands/add_to_group.py
View file @
6939a581
from
optparse
import
make_op
tion
from
__future__
import
print_func
tion
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.contrib.auth.models
import
User
,
Group
from
django.contrib.auth.models
import
User
,
Group
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
option_list
=
BaseCommand
.
option_list
+
(
def
add_arguments
(
self
,
parser
):
make_option
(
'--list'
,
parser
.
add_argument
(
'name_or_email'
,
action
=
'store_true'
,
help
=
'Username or email address of the user to add or remove'
)
dest
=
'list'
,
parser
.
add_argument
(
'group_name'
,
default
=
False
,
help
=
'Name of the group to change'
)
help
=
'List available groups'
),
parser
.
add_argument
(
'--list'
,
make_option
(
'--create'
,
action
=
'store_true'
,
action
=
'store_true'
,
help
=
'List available groups'
)
dest
=
'create'
,
parser
.
add_argument
(
'--create'
,
default
=
False
,
action
=
'store_true'
,
help
=
'Create the group if it does not exist'
),
help
=
'Create the group if it does not exist'
)
make_option
(
'--remove'
,
parser
.
add_argument
(
'--remove'
,
action
=
'store_true'
,
action
=
'store_true'
,
dest
=
'remove'
,
help
=
'Remove the user from the group instead of adding it'
)
default
=
False
,
help
=
'Remove the user from the group instead of adding it'
),
)
args
=
'<user|email> <group>'
help
=
'Add a user to a group'
help
=
'Add a user to a group'
def
print_groups
(
self
):
def
print_groups
(
self
):
print
'Groups available:'
print
(
'Groups available:'
)
for
group
in
Group
.
objects
.
all
()
.
distinct
():
for
group
in
Group
.
objects
.
all
()
.
distinct
():
print
' '
,
group
.
name
print
(
' {}'
.
format
(
group
.
name
))
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
if
options
[
'list'
]:
if
options
[
'list'
]:
self
.
print_groups
()
self
.
print_groups
()
return
return
if
len
(
args
)
!=
2
:
name_or_email
=
options
[
'name_or_email'
]
raise
CommandError
(
'Usage is add_to_group {0}'
.
format
(
self
.
args
))
group_name
=
options
[
'group_name'
]
name_or_email
,
group_name
=
args
if
'@'
in
name_or_email
:
if
'@'
in
name_or_email
:
user
=
User
.
objects
.
get
(
email
=
name_or_email
)
user
=
User
.
objects
.
get
(
email
=
name_or_email
)
...
@@ -60,4 +54,4 @@ class Command(BaseCommand):
...
@@ -60,4 +54,4 @@ class Command(BaseCommand):
else
:
else
:
user
.
groups
.
add
(
group
)
user
.
groups
.
add
(
group
)
print
'Success!'
print
(
'Success!'
)
common/djangoapps/student/management/commands/anonymized_id_mapping.py
View file @
6939a581
...
@@ -20,23 +20,17 @@ from opaque_keys.edx.keys import CourseKey
...
@@ -20,23 +20,17 @@ from opaque_keys.edx.keys import CourseKey
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
"""Add our handler to the space where django-admin looks up commands."""
"""Add our handler to the space where django-admin looks up commands."""
# TODO: revisit now that rake has been deprecated
# It appears that with the way Rake invokes these commands, we can't
# have more than one arg passed through...annoying.
args
=
(
"course_id"
,
)
help
=
"""Export a CSV mapping usernames to anonymized ids
help
=
"""Export a CSV mapping usernames to anonymized ids
Exports a CSV document mapping each username in the specified course to
Exports a CSV document mapping each username in the specified course to
the anonymized, unique user ID.
the anonymized, unique user ID.
"""
"""
def
handle
(
self
,
*
args
,
**
options
):
def
add_arguments
(
self
,
parser
):
if
len
(
args
)
!=
1
:
parser
.
add_argument
(
'course_id'
)
raise
CommandError
(
"Usage: unique_id_mapping
%
s"
%
" "
.
join
((
"<
%
s>"
%
arg
for
arg
in
Command
.
args
)))
course_key
=
CourseKey
.
from_string
(
args
[
0
])
def
handle
(
self
,
*
args
,
**
options
):
course_key
=
CourseKey
.
from_string
(
options
[
'course_id'
])
# Generate the output filename from the course ID.
# Generate the output filename from the course ID.
# Change slashes to dashes first, and then append .csv extension.
# Change slashes to dashes first, and then append .csv extension.
...
...
common/djangoapps/student/management/commands/assigngroups.py
View file @
6939a581
from
__future__
import
print_function
from
django.core.management.base
import
BaseCommand
from
django.core.management.base
import
BaseCommand
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
...
@@ -11,22 +13,27 @@ from textwrap import dedent
...
@@ -11,22 +13,27 @@ from textwrap import dedent
import
json
import
json
from
pytz
import
UTC
from
pytz
import
UTC
# Examples:
# python manage.py assigngroups summary_test:0.3,skip_summary_test:0.7 log.txt "Do previews of future materials help?"
# python manage.py assigngroups skip_capacitor:0.3,capacitor:0.7 log.txt "Do we show capacitor in linearity tutorial?"
def
group_from_value
(
groups
,
v
):
def
group_from_value
(
groups
,
v
):
''' Given group: (('a',0.3),('b',0.4),('c',0.3)) And random value
"""
Given group: (('a',0.3),('b',0.4),('c',0.3)) And random value
in [0,1], return the associated group (in the above case, return
in [0,1], return the associated group (in the above case, return
'a' if v<0.3, 'b' if 0.3<=v<0.7, and 'c' if v>0.7
'a' if v<0.3, 'b' if 0.3<=v<0.7, and 'c' if v>0.7
'''
"""
sum
=
0
curr_
sum
=
0
for
(
g
,
p
)
in
groups
:
for
(
g
roup
,
p_value
)
in
groups
:
sum
=
sum
+
p
curr_sum
=
curr_sum
+
p_value
if
sum
>
v
:
if
curr_
sum
>
v
:
return
g
return
g
roup
return
g
# For round-off errors
return
g
roup
# For round-off errors
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
help
=
dedent
(
"""
\
help
=
dedent
(
"""
Assign users to test groups. Takes a list of groups:
Assign users to test groups. Takes a list of groups:
a:0.3,b:0.4,c:0.3 file.txt "Testing something"
a:0.3,b:0.4,c:0.3 file.txt "Testing something"
Will assign each user to group a, b, or c with
Will assign each user to group a, b, or c with
...
@@ -36,48 +43,49 @@ class Command(BaseCommand):
...
@@ -36,48 +43,49 @@ class Command(BaseCommand):
Will log what happened to file.txt.
Will log what happened to file.txt.
"""
)
"""
)
def
handle
(
self
,
*
args
,
**
options
):
def
add_arguments
(
self
,
parser
):
if
len
(
args
)
!=
3
:
parser
.
add_argument
(
'group_and_score'
)
print
"Invalid number of options"
parser
.
add_argument
(
'log_name'
)
sys
.
exit
(
-
1
)
parser
.
add_argument
(
'description'
)
def
handle
(
self
,
*
args
,
**
options
):
# Extract groups from string
# Extract groups from string
group_strs
=
[
x
.
split
(
':'
)
for
x
in
args
[
0
]
.
split
(
','
)]
group_strs
=
[
x
.
split
(
':'
)
for
x
in
options
[
'group_and_score'
]
.
split
(
','
)]
groups
=
[(
group
,
float
(
value
))
for
group
,
value
in
group_strs
]
groups
=
[(
group
,
float
(
value
))
for
group
,
value
in
group_strs
]
print
"Groups"
,
groups
print
(
"Groups"
,
groups
)
#
#
Confirm group probabilities add up to 1
# Confirm group probabilities add up to 1
total
=
sum
(
zip
(
*
groups
)[
1
])
total
=
sum
(
zip
(
*
groups
)[
1
])
print
"Total:"
,
total
print
(
"Total:"
,
total
)
if
abs
(
total
-
1
)
>
0.01
:
if
abs
(
total
-
1
)
>
0.01
:
print
"Total not 1"
print
(
"Total not 1"
)
sys
.
exit
(
-
1
)
sys
.
exit
(
-
1
)
#
#
Confirm groups don't already exist
# Confirm groups don't already exist
for
group
in
dict
(
groups
):
for
group
in
dict
(
groups
):
if
UserTestGroup
.
objects
.
filter
(
name
=
group
)
.
count
()
!=
0
:
if
UserTestGroup
.
objects
.
filter
(
name
=
group
)
.
count
()
!=
0
:
print
group
,
"already exists!"
print
(
group
,
"already exists!"
)
sys
.
exit
(
-
1
)
sys
.
exit
(
-
1
)
group_objects
=
{}
group_objects
=
{}
f
=
open
(
args
[
1
],
"a+"
)
f
=
open
(
options
[
'log_name'
],
"a+"
)
#
#
Create groups
# Create groups
for
group
in
dict
(
groups
):
for
group
in
dict
(
groups
):
utg
=
UserTestGroup
()
utg
=
UserTestGroup
()
utg
.
name
=
group
utg
.
name
=
group
utg
.
description
=
json
.
dumps
({
"description"
:
args
[
2
]},
utg
.
description
=
json
.
dumps
({
"description"
:
options
[
'description'
]},
{
"time"
:
datetime
.
datetime
.
now
(
UTC
)
.
isoformat
()})
{
"time"
:
datetime
.
datetime
.
now
(
UTC
)
.
isoformat
()})
group_objects
[
group
]
=
utg
group_objects
[
group
]
=
utg
group_objects
[
group
]
.
save
()
group_objects
[
group
]
.
save
()
#
#
Assign groups
# Assign groups
users
=
list
(
User
.
objects
.
all
())
users
=
list
(
User
.
objects
.
all
())
count
=
0
count
=
0
for
user
in
users
:
for
user
in
users
:
if
count
%
1000
==
0
:
if
count
%
1000
==
0
:
print
count
print
(
count
)
count
=
count
+
1
count
=
count
+
1
v
=
random
.
uniform
(
0
,
1
)
v
=
random
.
uniform
(
0
,
1
)
group
=
group_from_value
(
groups
,
v
)
group
=
group_from_value
(
groups
,
v
)
...
@@ -88,10 +96,7 @@ class Command(BaseCommand):
...
@@ -88,10 +96,7 @@ class Command(BaseCommand):
group
=
group
group
=
group
)
.
encode
(
'utf-8'
))
)
.
encode
(
'utf-8'
))
#
#
Save groups
# Save groups
for
group
in
group_objects
:
for
group
in
group_objects
:
group_objects
[
group
]
.
save
()
group_objects
[
group
]
.
save
()
f
.
close
()
f
.
close
()
# python manage.py assigngroups summary_test:0.3,skip_summary_test:0.7 log.txt "Do previews of future materials help?"
# python manage.py assigngroups skip_capacitor:0.3,capacitor:0.7 log.txt "Do we show capacitor in linearity tutorial?"
common/djangoapps/student/management/commands/bulk_change_enrollment.py
View file @
6939a581
...
@@ -6,6 +6,7 @@ from django.db import transaction
...
@@ -6,6 +6,7 @@ from django.db import transaction
from
opaque_keys
import
InvalidKeyError
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
optparse
import
make_option
from
optparse
import
make_option
from
six
import
text_type
from
openedx.core.djangoapps.content.course_overviews.models
import
CourseOverview
from
openedx.core.djangoapps.content.course_overviews.models
import
CourseOverview
from
course_modes.models
import
CourseMode
from
course_modes.models
import
CourseMode
...
@@ -31,54 +32,36 @@ class Command(BaseCommand):
...
@@ -31,54 +32,36 @@ class Command(BaseCommand):
Without the --commit option, the command will have no effect.
Without the --commit option, the command will have no effect.
"""
"""
option_list
=
BaseCommand
.
option_list
+
(
def
add_arguments
(
self
,
parser
):
make_option
(
group
=
parser
.
add_mutually_exclusive_group
()
'-f'
,
'--from_mode'
,
group
.
add_argument
(
dest
=
'from_mode'
,
default
=
None
,
help
=
'move from this enrollment mode'
),
make_option
(
'-t'
,
'--to_mode'
,
dest
=
'to_mode'
,
default
=
None
,
help
=
'move to this enrollment mode'
),
make_option
(
'-c'
,
'--course'
,
'-c'
,
'--course'
,
dest
=
'course'
,
help
=
'The course to change enrollments in'
)
default
=
None
,
group
.
add_argument
(
help
=
'the course to change enrollments in'
),
make_option
(
'-o'
,
'--org'
,
'-o'
,
'--org'
,
dest
=
'org'
,
help
=
'All courses belonging to this org will be selected for changing the enrollments'
)
default
=
None
,
help
=
'all courses belonging to this org will be selected for changing the enrollments'
parser
.
add_argument
(
),
'-f'
,
'--from_mode'
,
make_option
(
required
=
True
,
help
=
'Move from this enrollment mode'
)
parser
.
add_argument
(
'-t'
,
'--to_mode'
,
required
=
True
,
help
=
'Move to this enrollment mode'
)
parser
.
add_argument
(
'--commit'
,
'--commit'
,
action
=
'store_true'
,
action
=
'store_true'
,
dest
=
'commit'
,
help
=
'Save the changes, without this flag only a dry run will be performed and nothing will be changed'
)
default
=
False
,
help
=
'display what will be done without any effect'
)
)
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
course_id
=
options
.
get
(
'course'
)
course_id
=
options
[
'course'
]
org
=
options
.
get
(
'org'
)
org
=
options
[
'org'
]
from_mode
=
options
.
get
(
'from_mode'
)
from_mode
=
options
[
'from_mode'
]
to_mode
=
options
.
get
(
'to_mode'
)
to_mode
=
options
[
'to_mode'
]
commit
=
options
.
get
(
'commit'
)
commit
=
options
[
'commit'
]
if
(
not
course_id
and
not
org
)
or
(
course_id
and
org
):
raise
CommandError
(
'You must provide either a course ID or an org, but not both.'
)
if
from_mode
is
None
or
to_mode
is
None
:
raise
CommandError
(
'Both `from` and `to` course modes must be given.'
)
course_keys
=
[]
course_keys
=
[]
if
course_id
:
if
course_id
:
try
:
try
:
course_key
=
CourseKey
.
from_string
(
course_id
)
course_key
=
CourseKey
.
from_string
(
course_id
)
...
@@ -111,7 +94,7 @@ class Command(BaseCommand):
...
@@ -111,7 +94,7 @@ class Command(BaseCommand):
commit (bool): required to make the change to the database. Otherwise
commit (bool): required to make the change to the database. Otherwise
just a count will be displayed.
just a count will be displayed.
"""
"""
unicode_course_key
=
unicod
e
(
course_key
)
unicode_course_key
=
text_typ
e
(
course_key
)
if
CourseMode
.
mode_for_course
(
course_key
,
to_mode
)
is
None
:
if
CourseMode
.
mode_for_course
(
course_key
,
to_mode
)
is
None
:
logger
.
info
(
'Mode ({}) does not exist for course ({}).'
.
format
(
to_mode
,
unicode_course_key
))
logger
.
info
(
'Mode ({}) does not exist for course ({}).'
.
format
(
to_mode
,
unicode_course_key
))
return
return
...
...
common/djangoapps/student/management/commands/cert_restriction.py
View file @
6939a581
from
django.core.management.base
import
BaseCommand
,
CommandError
from
__future__
import
print_function
import
csv
import
os
import
os
from
optparse
import
make_option
from
django.core.management.base
import
BaseCommand
,
CommandError
from
student.models
import
UserProfile
from
student.models
import
UserProfile
import
csv
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
help
=
"""
help
=
"""
Sets or gets certificate restrictions for users
Sets or gets certificate restrictions for users
from embargoed countries. (allow_certificate in
from embargoed countries. (allow_certificate in
...
@@ -31,79 +33,62 @@ class Command(BaseCommand):
...
@@ -31,79 +33,62 @@ class Command(BaseCommand):
"""
"""
option_list
=
BaseCommand
.
option_list
+
(
def
add_arguments
(
self
,
parser
):
make_option
(
'-i'
,
'--import'
,
# This command can only take one of these arguments per run, this enforces that.
metavar
=
'IMPORT_FILE'
,
group
=
parser
.
add_mutually_exclusive_group
(
required
=
True
)
dest
=
'import'
,
group
.
add_argument
(
'-i'
,
'--import'
,
default
=
False
,
metavar
=
'IMPORT_FILE'
,
help
=
'csv file to import, comma delimitted file with '
nargs
=
'?'
,
'double-quoted entries'
),
help
=
'CSV file to import, comma delimitted file with double-quoted entries'
)
make_option
(
'-o'
,
'--output'
,
group
.
add_argument
(
'-o'
,
'--output'
,
metavar
=
'EXPORT_FILE'
,
metavar
=
'EXPORT_FILE'
,
dest
=
'output'
,
nargs
=
'?'
,
default
=
False
,
help
=
'CSV file to export'
)
help
=
'csv file to export'
),
group
.
add_argument
(
'-e'
,
'--enable'
,
make_option
(
'-e'
,
'--enable'
,
metavar
=
'STUDENT'
,
metavar
=
'STUDENT'
,
nargs
=
'?'
,
dest
=
'enable'
,
help
=
'Enable a certificate for a single student'
)
default
=
False
,
group
.
add_argument
(
'-d'
,
'--disable'
,
help
=
"enable a single student's certificate"
),
metavar
=
'STUDENT'
,
make_option
(
'-d'
,
'--disable'
,
nargs
=
'?'
,
metavar
=
'STUDENT'
,
help
=
'Disable a certificate for a single student'
)
dest
=
'disable'
,
default
=
False
,
help
=
"disable a single student's certificate"
)
)
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
if
options
[
'output'
]:
if
options
[
'output'
]:
if
os
.
path
.
exists
(
options
[
'output'
]):
if
os
.
path
.
exists
(
options
[
'output'
]):
raise
CommandError
(
"File {0} already exists"
.
format
(
raise
CommandError
(
"File {0} already exists"
.
format
(
options
[
'output'
]))
options
[
'output'
]))
disabled_users
=
UserProfile
.
objects
.
filter
(
allow_certificate
=
False
)
disabled_users
=
UserProfile
.
objects
.
filter
(
allow_certificate
=
False
)
with
open
(
options
[
'output'
],
'w'
)
as
csvfile
:
with
open
(
options
[
'output'
],
'w'
)
as
csvfile
:
csvwriter
=
csv
.
writer
(
csvfile
,
delimiter
=
','
,
quotechar
=
'"'
,
csvwriter
=
csv
.
writer
(
csvfile
,
delimiter
=
','
,
quotechar
=
'"'
,
quoting
=
csv
.
QUOTE_MINIMAL
)
quoting
=
csv
.
QUOTE_MINIMAL
)
for
user
in
disabled_users
:
for
user
in
disabled_users
:
csvwriter
.
writerow
([
user
.
user
.
username
])
csvwriter
.
writerow
([
user
.
user
.
username
])
print
(
'{} disabled users written'
.
format
(
len
(
disabled_users
)))
elif
options
[
'import'
]:
elif
options
[
'import'
]:
if
not
os
.
path
.
exists
(
options
[
'import'
]):
if
not
os
.
path
.
exists
(
options
[
'import'
]):
raise
CommandError
(
"File {0} does not exist"
.
format
(
raise
CommandError
(
"File {0} does not exist"
.
format
(
options
[
'import'
]))
options
[
'import'
]))
print
"Importing students from {0}"
.
format
(
options
[
'import'
]
)
print
(
"Importing students from {0}"
.
format
(
options
[
'import'
])
)
students
=
None
with
open
(
options
[
'import'
])
as
csvfile
:
with
open
(
options
[
'import'
])
as
csvfile
:
student_list
=
csv
.
reader
(
csvfile
,
delimiter
=
','
,
student_list
=
csv
.
reader
(
csvfile
,
delimiter
=
','
,
quotechar
=
'"'
)
quotechar
=
'"'
)
students
=
[
student
[
0
]
for
student
in
student_list
]
students
=
[
student
[
0
]
for
student
in
student_list
]
if
not
students
:
if
not
students
:
raise
CommandError
(
raise
CommandError
(
"Unable to read student data from {0}"
.
format
(
options
[
'import'
]))
"Unable to read student data from {0}"
.
format
(
options
[
'import'
]))
UserProfile
.
objects
.
filter
(
user__username__in
=
students
)
.
update
(
allow_certificate
=
False
)
elif
options
[
'enable'
]:
update_cnt
=
UserProfile
.
objects
.
filter
(
user__username__in
=
students
)
.
update
(
allow_certificate
=
False
)
print
(
'{} user(s) disabled out of {} in CSV file'
.
format
(
update_cnt
,
len
(
students
)))
print
"Enabling {0} for certificate download"
.
format
(
elif
options
[
'enable'
]:
options
[
'enable'
])
print
(
"Enabling {0} for certificate download"
.
format
(
options
[
'enable'
]))
cert_allow
=
UserProfile
.
objects
.
get
(
cert_allow
=
UserProfile
.
objects
.
get
(
user__username
=
options
[
'enable'
])
user__username
=
options
[
'enable'
])
cert_allow
.
allow_certificate
=
True
cert_allow
.
allow_certificate
=
True
cert_allow
.
save
()
cert_allow
.
save
()
elif
options
[
'disable'
]:
elif
options
[
'disable'
]:
print
(
"Disabling {0} for certificate download"
.
format
(
options
[
'disable'
]))
print
"Disabling {0} for certificate download"
.
format
(
cert_allow
=
UserProfile
.
objects
.
get
(
user__username
=
options
[
'disable'
])
options
[
'disable'
])
cert_allow
=
UserProfile
.
objects
.
get
(
user__username
=
options
[
'disable'
])
cert_allow
.
allow_certificate
=
False
cert_allow
.
allow_certificate
=
False
cert_allow
.
save
()
cert_allow
.
save
()
common/djangoapps/student/management/commands/change_enrollment.py
View file @
6939a581
...
@@ -4,8 +4,8 @@ import logging
...
@@ -4,8 +4,8 @@ import logging
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.core.management.base
import
BaseCommand
,
CommandError
from
django.db
import
transaction
from
django.db
import
transaction
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
optparse
import
make_option
from
student.models
import
CourseEnrollment
,
User
from
student.models
import
CourseEnrollment
,
User
...
@@ -33,64 +33,60 @@ class Command(BaseCommand):
...
@@ -33,64 +33,60 @@ class Command(BaseCommand):
Or
Or
$ ... change_enrollment -e "joe@example.com,frank@example.com,
bill@example.com
" -c some/course/id --from audit --to honor
$ ... change_enrollment -e "joe@example.com,frank@example.com,
...
" -c some/course/id --from audit --to honor
See what would have been changed from audit to honor without making that change
See what would have been changed from audit to honor without making that change
$ ... change_enrollment -u joe,frank,bill -c some/course/id --from audit --to honor -n
$ ... change_enrollment -u joe,frank,bill -c some/course/id --from audit --to honor -n
"""
"""
option_list
=
BaseCommand
.
option_list
+
(
enrollment_modes
=
(
'audit'
,
'verified'
,
'honor'
)
make_option
(
'-f'
,
'--from'
,
metavar
=
'FROM_MODE'
,
def
add_arguments
(
self
,
parser
):
dest
=
'from_mode'
,
parser
.
add_argument
(
'-f'
,
'--from'
,
default
=
False
,
metavar
=
'FROM_MODE'
,
help
=
'move from this enrollment mode'
),
dest
=
'from_mode'
,
make_option
(
'-t'
,
'--to'
,
required
=
True
,
metavar
=
'TO_MODE'
,
choices
=
self
.
enrollment_modes
,
dest
=
'to_mode'
,
help
=
'Move from this enrollment mode'
)
default
=
False
,
parser
.
add_argument
(
'-t'
,
'--to'
,
help
=
'move to this enrollment mode'
),
metavar
=
'TO_MODE'
,
make_option
(
'-u'
,
'--usernames'
,
dest
=
'to_mode'
,
metavar
=
'USERNAME'
,
required
=
True
,
dest
=
'username'
,
choices
=
self
.
enrollment_modes
,
default
=
False
,
help
=
'Move to this enrollment mode'
)
help
=
"Comma-separated list of usernames to move in the course"
),
parser
.
add_argument
(
'-u'
,
'--username'
,
make_option
(
'-e'
,
'--emails'
,
metavar
=
'USERNAME'
,
metavar
=
'EMAIL'
,
help
=
'Comma-separated list of usernames to move in the course'
)
dest
=
'email'
,
parser
.
add_argument
(
'-e'
,
'--email'
,
default
=
False
,
metavar
=
'EMAIL'
,
help
=
"Comma-separated list of email addresses to move in the course"
),
help
=
'Comma-separated list of email addresses to move in the course'
)
make_option
(
'-c'
,
'--course'
,
parser
.
add_argument
(
'-c'
,
'--course'
,
metavar
=
'COURSE_ID'
,
metavar
=
'COURSE_ID'
,
dest
=
'course_id'
,
dest
=
'course_id'
,
default
=
False
,
required
=
True
,
help
=
"course id to use for transfer"
),
help
=
'Course id to use for transfer'
)
make_option
(
'-n'
,
'--noop'
,
parser
.
add_argument
(
'-n'
,
'--noop'
,
action
=
'store_true'
,
action
=
'store_true'
,
dest
=
'noop'
,
help
=
'Display what will be done but do not actually do anything'
)
default
=
False
,
help
=
"display what will be done but don't actually do anything"
)
)
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
error_users
=
[]
try
:
success_users
=
[]
course_key
=
CourseKey
.
from_string
(
options
[
'course_id'
])
except
InvalidKeyError
:
raise
CommandError
(
'Invalid or non-existant course id {}'
.
format
(
options
[
'course_id'
]))
if
not
options
[
'course_id'
]:
if
not
options
[
'username'
]
and
not
options
[
'email'
]:
raise
CommandError
(
'You must specify a course id for this command'
)
raise
CommandError
(
'You must include usernames (-u) or emails (-e) to select users to update'
)
if
not
options
[
'from_mode'
]
or
not
options
[
'to_mode'
]:
raise
CommandError
(
'You must specify a "to" and "from" mode as parameters'
)
course_key
=
CourseKey
.
from_string
(
options
[
'course_id'
])
enrollment_args
=
dict
(
enrollment_args
=
dict
(
course_id
=
course_key
,
course_id
=
course_key
,
mode
=
options
[
'from_mode'
]
mode
=
options
[
'from_mode'
]
)
)
error_users
=
[]
success_users
=
[]
if
options
[
'username'
]:
if
options
[
'username'
]:
self
.
update_enrollments
(
'username'
,
enrollment_args
,
options
,
error_users
,
success_users
)
self
.
update_enrollments
(
'username'
,
enrollment_args
,
options
,
error_users
,
success_users
)
...
@@ -102,8 +98,10 @@ class Command(BaseCommand):
...
@@ -102,8 +98,10 @@ class Command(BaseCommand):
def
update_enrollments
(
self
,
identifier
,
enrollment_args
,
options
,
error_users
,
success_users
):
def
update_enrollments
(
self
,
identifier
,
enrollment_args
,
options
,
error_users
,
success_users
):
""" Update enrollments for a specific user identifier (email or username). """
""" Update enrollments for a specific user identifier (email or username). """
users
=
options
[
identifier
]
.
split
(
","
)
users
=
options
[
identifier
]
.
split
(
","
)
for
identified_user
in
users
:
for
identified_user
in
users
:
logger
.
info
(
identified_user
)
logger
.
info
(
identified_user
)
try
:
try
:
user_args
=
{
user_args
=
{
identifier
:
identified_user
identifier
:
identified_user
...
...
common/djangoapps/student/management/commands/create_random_users.py
View file @
6939a581
"""
"""
A script to create some dummy users
A script to create some dummy users
"""
"""
from
__future__
import
print_function
import
uuid
import
uuid
from
django.core.management.base
import
BaseCommand
from
django.core.management.base
import
BaseCommand
...
@@ -32,6 +33,7 @@ def create(num, course_key):
...
@@ -32,6 +33,7 @@ def create(num, course_key):
(
user
,
_
,
_
)
=
_do_create_account
(
make_random_form
())
(
user
,
_
,
_
)
=
_do_create_account
(
make_random_form
())
if
course_key
is
not
None
:
if
course_key
is
not
None
:
CourseEnrollment
.
enroll
(
user
,
course_key
)
CourseEnrollment
.
enroll
(
user
,
course_key
)
print
(
'Created user {}'
.
format
(
user
.
username
))
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
...
@@ -45,16 +47,15 @@ Examples:
...
@@ -45,16 +47,15 @@ Examples:
create_random_users.py 100 HarvardX/CS50x/2012
create_random_users.py 100 HarvardX/CS50x/2012
"""
"""
def
handle
(
self
,
*
args
,
**
options
):
def
add_arguments
(
self
,
parser
):
if
len
(
args
)
<
1
or
len
(
args
)
>
2
:
parser
.
add_argument
(
'num_users'
,
print
Command
.
help
help
=
'Number of users to create'
,
return
type
=
int
)
parser
.
add_argument
(
'course_key'
,
num
=
int
(
args
[
0
])
help
=
'Add newly created users to this course'
,
nargs
=
'?'
)
if
len
(
args
)
==
2
:
course_key
=
CourseKey
.
from_string
(
args
[
1
])
else
:
course_key
=
None
def
handle
(
self
,
*
args
,
**
options
):
num
=
options
[
'num_users'
]
course_key
=
CourseKey
.
from_string
(
options
[
'course_key'
])
if
options
[
'course_key'
]
else
None
create
(
num
,
course_key
)
create
(
num
,
course_key
)
common/djangoapps/student/management/commands/create_user.py
View file @
6939a581
from
optparse
import
make_op
tion
from
__future__
import
print_func
tion
from
django.conf
import
settings
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.core.management.base
import
BaseCommand
from
django.utils
import
translation
from
django.utils
import
translation
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
...
@@ -23,56 +22,39 @@ class Command(TrackedCommand):
...
@@ -23,56 +22,39 @@ class Command(TrackedCommand):
manage.py ... create_user -e test@example.com -p insecure -c edX/Open_DemoX/edx_demo_course -m verified
manage.py ... create_user -e test@example.com -p insecure -c edX/Open_DemoX/edx_demo_course -m verified
"""
"""
option_list
=
BaseCommand
.
option_list
+
(
def
add_arguments
(
self
,
parser
):
make_option
(
'-m'
,
'--mode'
,
parser
.
add_argument
(
'-m'
,
'--mode'
,
metavar
=
'ENROLLMENT_MODE'
,
metavar
=
'ENROLLMENT_MODE'
,
dest
=
'mode'
,
default
=
'honor'
,
default
=
'honor'
,
choices
=
(
'audit'
,
'verified'
,
'honor'
),
choices
=
(
'audit'
,
'verified'
,
'honor'
),
help
=
'Enrollment type for user for a specific course, defaults to "honor"'
)
help
=
'Enrollment type for user for a specific course'
),
parser
.
add_argument
(
'-u'
,
'--username'
,
make_option
(
'-u'
,
'--username'
,
metavar
=
'USERNAME'
,
metavar
=
'USERNAME'
,
help
=
'Username, defaults to "user" in the email'
)
dest
=
'username'
,
parser
.
add_argument
(
'-n'
,
'--name'
,
default
=
None
,
metavar
=
'NAME'
,
help
=
'Username, defaults to "user" in the email'
),
help
=
'Name, defaults to "user" in the email'
)
make_option
(
'-n'
,
'--name'
,
parser
.
add_argument
(
'-p'
,
'--password'
,
metavar
=
'NAME'
,
metavar
=
'PASSWORD'
,
dest
=
'name'
,
help
=
'Password for user'
,
default
=
None
,
required
=
True
)
help
=
'Name, defaults to "user" in the email'
),
parser
.
add_argument
(
'-e'
,
'--email'
,
make_option
(
'-p'
,
'--password'
,
metavar
=
'EMAIL'
,
metavar
=
'PASSWORD'
,
help
=
'Email for user'
,
dest
=
'password'
,
required
=
True
)
default
=
None
,
parser
.
add_argument
(
'-c'
,
'--course'
,
help
=
'Password for user'
),
metavar
=
'COURSE_ID'
,
make_option
(
'-e'
,
'--email'
,
help
=
'Course to enroll the user in (optional)'
)
metavar
=
'EMAIL'
,
parser
.
add_argument
(
'-s'
,
'--staff'
,
dest
=
'email'
,
action
=
'store_true'
,
default
=
None
,
help
=
'Give user the staff bit, defaults to off'
)
help
=
'Email for user'
),
make_option
(
'-c'
,
'--course'
,
metavar
=
'COURSE_ID'
,
dest
=
'course'
,
default
=
None
,
help
=
'course to enroll the user in (optional)'
),
make_option
(
'-s'
,
'--staff'
,
dest
=
'staff'
,
default
=
False
,
action
=
'store_true'
,
help
=
'give user the staff bit'
),
)
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
username
=
options
[
'username'
]
username
=
options
[
'username'
]
if
options
[
'username'
]
else
options
[
'email'
]
.
split
(
'@'
)[
0
]
name
=
options
[
'name'
]
name
=
options
[
'name'
]
if
options
[
'name'
]
else
options
[
'email'
]
.
split
(
'@'
)[
0
]
if
not
username
:
username
=
options
[
'email'
]
.
split
(
'@'
)[
0
]
if
not
name
:
name
=
options
[
'email'
]
.
split
(
'@'
)[
0
]
# parse out the course into a coursekey
# parse out the course into a coursekey
if
options
[
'course'
]:
course
=
CourseKey
.
from_string
(
options
[
'course'
])
if
options
[
'course'
]
else
None
course
=
CourseKey
.
from_string
(
options
[
'course'
])
form
=
AccountCreationForm
(
form
=
AccountCreationForm
(
data
=
{
data
=
{
...
@@ -83,11 +65,13 @@ class Command(TrackedCommand):
...
@@ -83,11 +65,13 @@ class Command(TrackedCommand):
},
},
tos_required
=
False
tos_required
=
False
)
)
# django.utils.translation.get_language() will be used to set the new
# django.utils.translation.get_language() will be used to set the new
# user's preferred language. This line ensures that the result will
# user's preferred language. This line ensures that the result will
# match this installation's default locale. Otherwise, inside a
# match this installation's default locale. Otherwise, inside a
# management command, it will always return "en-us".
# management command, it will always return "en-us".
translation
.
activate
(
settings
.
LANGUAGE_CODE
)
translation
.
activate
(
settings
.
LANGUAGE_CODE
)
try
:
try
:
user
,
_
,
reg
=
_do_create_account
(
form
)
user
,
_
,
reg
=
_do_create_account
(
form
)
if
options
[
'staff'
]:
if
options
[
'staff'
]:
...
@@ -97,8 +81,10 @@ class Command(TrackedCommand):
...
@@ -97,8 +81,10 @@ class Command(TrackedCommand):
reg
.
save
()
reg
.
save
()
create_comments_service_user
(
user
)
create_comments_service_user
(
user
)
except
AccountValidationError
as
e
:
except
AccountValidationError
as
e
:
print
e
.
message
print
(
e
.
message
)
user
=
User
.
objects
.
get
(
email
=
options
[
'email'
])
user
=
User
.
objects
.
get
(
email
=
options
[
'email'
])
if
options
[
'course'
]:
if
course
:
CourseEnrollment
.
enroll
(
user
,
course
,
mode
=
options
[
'mode'
])
CourseEnrollment
.
enroll
(
user
,
course
,
mode
=
options
[
'mode'
])
translation
.
deactivate
()
translation
.
deactivate
()
common/djangoapps/student/management/commands/populate_created_on_site_user_attribute.py
View file @
6939a581
...
@@ -14,7 +14,7 @@ class Command(BaseCommand):
...
@@ -14,7 +14,7 @@ class Command(BaseCommand):
This command back-populates domain of the site the user account was created on.
This command back-populates domain of the site the user account was created on.
"""
"""
help
=
"""./manage.py lms populate_created_on_site_user_attribute --users <user_id1>,<user_id2>...
help
=
"""./manage.py lms populate_created_on_site_user_attribute --users <user_id1>,<user_id2>...
'--activation-keys <key1>,<key2>... --site-domain <site_domain> --settings=devstack"""
'--activation-keys <key1>,<key2>... --site-domain <site_domain> --settings=devstack
_docker
"""
def
add_arguments
(
self
,
parser
):
def
add_arguments
(
self
,
parser
):
"""
"""
...
@@ -35,6 +35,7 @@ class Command(BaseCommand):
...
@@ -35,6 +35,7 @@ class Command(BaseCommand):
parser
.
add_argument
(
parser
.
add_argument
(
'--site-domain'
,
'--site-domain'
,
help
=
'Enter an existing site domain.'
,
help
=
'Enter an existing site domain.'
,
required
=
True
)
)
def
handle
(
self
,
*
args
,
**
options
):
def
handle
(
self
,
*
args
,
**
options
):
...
@@ -42,8 +43,6 @@ class Command(BaseCommand):
...
@@ -42,8 +43,6 @@ class Command(BaseCommand):
user_ids
=
options
[
'users'
]
.
split
(
','
)
if
options
[
'users'
]
else
[]
user_ids
=
options
[
'users'
]
.
split
(
','
)
if
options
[
'users'
]
else
[]
activation_keys
=
options
[
'activation_keys'
]
.
split
(
','
)
if
options
[
'activation_keys'
]
else
[]
activation_keys
=
options
[
'activation_keys'
]
.
split
(
','
)
if
options
[
'activation_keys'
]
else
[]
if
not
site_domain
:
raise
CommandError
(
'You must provide site-domain argument.'
)
if
not
user_ids
and
not
activation_keys
:
if
not
user_ids
and
not
activation_keys
:
raise
CommandError
(
'You must provide user ids or activation keys.'
)
raise
CommandError
(
'You must provide user ids or activation keys.'
)
...
...
common/djangoapps/student/management/commands/set_staff.py
View file @
6939a581
from
optparse
import
make_option
from
__future__
import
print_function
import
re
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
import
re
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
option_list
=
BaseCommand
.
option_list
+
(
make_option
(
'--unset'
,
action
=
'store_true'
,
dest
=
'unset'
,
default
=
False
,
help
=
'Set is_staff to False instead of True'
),
)
args
=
'<user|email> [user|email ...]>'
help
=
"""
help
=
"""
This command will set is_staff to true for one or more users.
This command will set is_staff to true for one or more users.
Lookup by username or email address, assumes usernames
Lookup by username or email address, assumes usernames
do not look like email addresses.
do not look like email addresses.
"""
"""
def
handle
(
self
,
*
args
,
**
options
):
def
add_arguments
(
self
,
parser
):
if
len
(
args
)
<
1
:
parser
.
add_argument
(
'users'
,
raise
CommandError
(
'Usage is set_staff {0}'
.
format
(
self
.
args
))
nargs
=
'+'
,
help
=
'Users to set or unset (with the --unset flag) as superusers'
)
parser
.
add_argument
(
'--unset'
,
action
=
'store_true'
,
dest
=
'unset'
,
default
=
False
,
help
=
'Set is_staff to False instead of True'
)
for
user
in
args
:
def
handle
(
self
,
*
args
,
**
options
):
if
re
.
match
(
r'[^@]+@[^@]+\.[^@]+'
,
user
):
for
user
in
options
[
'users'
]:
try
:
try
:
if
re
.
match
(
r'[^@]+@[^@]+\.[^@]+'
,
user
):
v
=
User
.
objects
.
get
(
email
=
user
)
v
=
User
.
objects
.
get
(
email
=
user
)
except
:
else
:
raise
CommandError
(
"User {0} does not exist"
.
format
(
user
))
else
:
try
:
v
=
User
.
objects
.
get
(
username
=
user
)
v
=
User
.
objects
.
get
(
username
=
user
)
except
:
raise
CommandError
(
"User {0} does not exist"
.
format
(
user
))
if
options
[
'unset'
]:
if
options
[
'unset'
]:
v
.
is_staff
=
False
v
.
is_staff
=
False
else
:
else
:
v
.
is_staff
=
True
v
.
is_staff
=
True
v
.
save
()
print
(
'Modified {} sucessfully.'
.
format
(
user
))
v
.
save
()
except
Exception
as
err
:
# pylint: disable=broad-except
print
(
"Error modifying user with identifier {}: {}: {}"
.
format
(
user
,
type
(
err
)
.
__name__
,
err
.
message
))
print
'Success!'
print
(
'Complete!'
)
common/djangoapps/student/management/commands/set_superuser.py
View file @
6939a581
"""Management command to grant or revoke superuser access for one or more users"""
"""Management command to grant or revoke superuser access for one or more users"""
from
__future__
import
print_function
from
optparse
import
make_option
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
class
Command
(
BaseCommand
):
class
Command
(
BaseCommand
):
"""Management command to grant or revoke superuser access for one or more users"""
"""Management command to grant or revoke superuser access for one or more users"""
option_list
=
BaseCommand
.
option_list
+
(
make_option
(
'--unset'
,
action
=
'store_true'
,
dest
=
'unset'
,
default
=
False
,
help
=
'Set is_superuser to False instead of True'
),
)
args
=
'<user|email> [user|email ...]>'
help
=
"""
help
=
"""
This command will set is_superuser to true for one or more users.
This command will set is_superuser to true for one or more users.
Lookup by username or email address, assumes usernames
Lookup by username or email address, assumes usernames
do not look like email addresses.
do not look like email addresses.
"""
"""
def
handle
(
self
,
*
args
,
**
options
):
def
add_arguments
(
self
,
parser
):
if
len
(
args
)
<
1
:
parser
.
add_argument
(
'users'
,
raise
CommandError
(
'Usage is set_superuser {0}'
.
format
(
self
.
args
))
nargs
=
'+'
,
help
=
'Users to set or unset (with the --unset flag) as superusers'
)
parser
.
add_argument
(
'--unset'
,
action
=
'store_true'
,
dest
=
'unset'
,
default
=
False
,
help
=
'Set is_superuser to False instead of True'
)
for
user
in
args
:
def
handle
(
self
,
*
args
,
**
options
):
for
user
in
options
[
'users'
]:
try
:
try
:
if
'@'
in
user
:
if
'@'
in
user
:
userobj
=
User
.
objects
.
get
(
email
=
user
)
userobj
=
User
.
objects
.
get
(
email
=
user
)
...
@@ -39,8 +38,9 @@ class Command(BaseCommand):
...
@@ -39,8 +38,9 @@ class Command(BaseCommand):
userobj
.
is_superuser
=
True
userobj
.
is_superuser
=
True
userobj
.
save
()
userobj
.
save
()
print
(
'Modified {} sucessfully.'
.
format
(
user
))
except
Exception
as
err
:
# pylint: disable=broad-except
except
Exception
as
err
:
# pylint: disable=broad-except
print
"Error modifying user with identifier {}: {}: {}"
.
format
(
user
,
type
(
err
)
.
__name__
,
err
.
message
)
print
(
"Error modifying user with identifier {}: {}: {}"
.
format
(
user
,
type
(
err
)
.
__name__
,
err
.
message
)
)
print
'Success!'
print
(
'Complete!'
)
common/djangoapps/student/management/tests/test_bulk_change_enrollment.py
View file @
6939a581
"""Tests for the bulk_change_enrollment command."""
"""Tests for the bulk_change_enrollment command."""
import
ddt
import
ddt
from
six
import
text_type
from
django.core.management
import
call_command
from
django.core.management
import
call_command
from
django.core.management.base
import
CommandError
from
django.core.management.base
import
CommandError
from
mock
import
patch
,
call
from
mock
import
patch
,
call
...
@@ -35,12 +37,15 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -35,12 +37,15 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
# Verify that no users are in the `from` mode yet.
# Verify that no users are in the `from` mode yet.
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
to_mode
,
course_id
=
self
.
course
.
id
)),
0
)
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
to_mode
,
course_id
=
self
.
course
.
id
)),
0
)
args
=
'--course {course} --from_mode {from_mode} --to_mode {to_mode} --commit'
.
format
(
course
=
text_type
(
self
.
course
.
id
),
from_mode
=
from_mode
,
to_mode
=
to_mode
)
call_command
(
call_command
(
'bulk_change_enrollment'
,
'bulk_change_enrollment'
,
course
=
unicode
(
self
.
course
.
id
),
*
args
.
split
(
' '
)
from_mode
=
from_mode
,
to_mode
=
to_mode
,
commit
=
True
,
)
)
# Verify that all users have been moved -- if not, this will
# Verify that all users have been moved -- if not, this will
...
@@ -67,12 +72,15 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -67,12 +72,15 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
to_mode
,
course_id
=
self
.
course
.
id
)),
0
)
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
to_mode
,
course_id
=
self
.
course
.
id
)),
0
)
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
to_mode
,
course_id
=
course_2
.
id
)),
0
)
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
to_mode
,
course_id
=
course_2
.
id
)),
0
)
call_command
(
args
=
'--org {org} --from_mode {from_mode} --to_mode {to_mode} --commit'
.
format
(
'bulk_change_enrollment'
,
org
=
self
.
org
,
org
=
self
.
org
,
from_mode
=
from_mode
,
from_mode
=
from_mode
,
to_mode
=
to_mode
,
to_mode
=
to_mode
commit
=
True
,
)
call_command
(
'bulk_change_enrollment'
,
*
args
.
split
(
' '
)
)
)
# Verify that all users have been moved -- if not, this will
# Verify that all users have been moved -- if not, this will
...
@@ -91,7 +99,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -91,7 +99,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
call_command
(
call_command
(
'bulk_change_enrollment'
,
'bulk_change_enrollment'
,
org
=
self
.
org
,
org
=
self
.
org
,
course
=
unicod
e
(
self
.
course
.
id
),
course
=
text_typ
e
(
self
.
course
.
id
),
from_mode
=
'audit'
,
from_mode
=
'audit'
,
to_mode
=
'no-id-professional'
,
to_mode
=
'no-id-professional'
,
commit
=
True
,
commit
=
True
,
...
@@ -114,12 +122,15 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -114,12 +122,15 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
to_mode
,
course_id
=
self
.
course
.
id
)),
0
)
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
to_mode
,
course_id
=
self
.
course
.
id
)),
0
)
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
to_mode
,
course_id
=
course_2
.
id
)),
0
)
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
to_mode
,
course_id
=
course_2
.
id
)),
0
)
call_command
(
args
=
'--org {org} --from_mode {from_mode} --to_mode {to_mode} --commit'
.
format
(
'bulk_change_enrollment'
,
org
=
self
.
org
,
org
=
self
.
org
,
from_mode
=
from_mode
,
from_mode
=
from_mode
,
to_mode
=
to_mode
,
to_mode
=
to_mode
commit
=
True
,
)
call_command
(
'bulk_change_enrollment'
,
*
args
.
split
(
' '
)
)
)
# Verify that users were not moved for the invalid course/mode combination
# Verify that users were not moved for the invalid course/mode combination
...
@@ -139,12 +150,15 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -139,12 +150,15 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
CourseModeFactory
(
course_id
=
self
.
course
.
id
,
mode_slug
=
'no-id-professional'
)
CourseModeFactory
(
course_id
=
self
.
course
.
id
,
mode_slug
=
'no-id-professional'
)
with
self
.
assertRaises
(
CommandError
):
with
self
.
assertRaises
(
CommandError
):
call_command
(
args
=
'--org {org} --from_mode {from_mode} --to_mode {to_mode} --commit'
.
format
(
'bulk_change_enrollment'
,
org
=
'fakeX'
,
org
=
'fakeX'
,
from_mode
=
'audit'
,
from_mode
=
'audit'
,
to_mode
=
'no-id-professional'
,
to_mode
=
'no-id-professional'
,
commit
=
True
,
)
call_command
(
'bulk_change_enrollment'
,
*
args
.
split
(
' '
)
)
)
def
test_without_commit
(
self
):
def
test_without_commit
(
self
):
...
@@ -152,11 +166,15 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -152,11 +166,15 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
self
.
_enroll_users
(
self
.
course
,
self
.
users
,
'audit'
)
self
.
_enroll_users
(
self
.
course
,
self
.
users
,
'audit'
)
CourseModeFactory
(
course_id
=
self
.
course
.
id
,
mode_slug
=
'honor'
)
CourseModeFactory
(
course_id
=
self
.
course
.
id
,
mode_slug
=
'honor'
)
args
=
'--course {course} --from_mode {from_mode} --to_mode {to_mode}'
.
format
(
course
=
text_type
(
self
.
course
.
id
),
from_mode
=
'audit'
,
to_mode
=
'honor'
)
call_command
(
call_command
(
'bulk_change_enrollment'
,
'bulk_change_enrollment'
,
course
=
unicode
(
self
.
course
.
id
),
*
args
.
split
(
' '
)
from_mode
=
'audit'
,
to_mode
=
'honor'
,
)
)
# Verify that no users are in the honor mode.
# Verify that no users are in the honor mode.
...
@@ -170,7 +188,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -170,7 +188,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
with
self
.
assertRaises
(
CommandError
):
with
self
.
assertRaises
(
CommandError
):
call_command
(
call_command
(
'bulk_change_enrollment'
,
'bulk_change_enrollment'
,
course
=
unicod
e
(
self
.
course
.
id
),
course
=
text_typ
e
(
self
.
course
.
id
),
from_mode
=
'audit'
,
from_mode
=
'audit'
,
)
)
...
@@ -180,7 +198,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -180,7 +198,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
command_options
=
{
command_options
=
{
'from_mode'
:
'audit'
,
'from_mode'
:
'audit'
,
'to_mode'
:
'honor'
,
'to_mode'
:
'honor'
,
'course'
:
unicod
e
(
self
.
course
.
id
),
'course'
:
text_typ
e
(
self
.
course
.
id
),
}
}
command_options
.
pop
(
option
)
command_options
.
pop
(
option
)
...
@@ -209,7 +227,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -209,7 +227,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
[
[
call
(
call
(
EVENT_NAME_ENROLLMENT_MODE_CHANGED
,
EVENT_NAME_ENROLLMENT_MODE_CHANGED
,
{
'course_id'
:
unicod
e
(
course
.
id
),
'user_id'
:
user
.
id
,
'mode'
:
to_mode
}
{
'course_id'
:
text_typ
e
(
course
.
id
),
'user_id'
:
user
.
id
,
'mode'
:
to_mode
}
),
),
]
]
)
)
...
...
common/djangoapps/student/management/tests/test_change_enrollment.py
View file @
6939a581
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
import
ddt
import
ddt
from
mock
import
patch
from
mock
import
patch
from
six
import
text_type
from
django.core.management
import
call_command
from
django.core.management
import
call_command
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.factories
import
CourseFactory
...
@@ -53,13 +54,6 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -53,13 +54,6 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
""" The command should update the user's enrollment. """
""" The command should update the user's enrollment. """
user_str
=
','
.
join
([
getattr
(
user
,
method
)
for
user
in
self
.
users
])
user_str
=
','
.
join
([
getattr
(
user
,
method
)
for
user
in
self
.
users
])
user_ids
=
[
u
.
id
for
u
in
self
.
users
]
user_ids
=
[
u
.
id
for
u
in
self
.
users
]
command_args
=
{
'course_id'
:
unicode
(
self
.
course
.
id
),
'to_mode'
:
'honor'
,
'from_mode'
:
'audit'
,
'noop'
:
noop
,
method
:
user_str
,
}
# Verify users are not in honor mode yet
# Verify users are not in honor mode yet
self
.
assertEqual
(
self
.
assertEqual
(
...
@@ -67,11 +61,19 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -67,11 +61,19 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
0
0
)
)
call_command
(
noop
=
" --noop"
if
noop
else
""
'change_enrollment'
,
**
command_args
# Hack around call_command bugs dealing with required options see:
# https://stackoverflow.com/questions/32036562/call-command-argument-is-required
command_args
=
'--course {course} --to honor --from audit --{method} {user_str}{noop}'
.
format
(
course
=
text_type
(
self
.
course
.
id
),
noop
=
noop
,
method
=
method
,
user_str
=
user_str
)
)
call_command
(
'change_enrollment'
,
*
command_args
.
split
(
' '
))
# Verify correct number of users are now in honor mode
# Verify correct number of users are now in honor mode
self
.
assertEqual
(
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
'honor'
,
user_id__in
=
user_ids
)),
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
'honor'
,
user_id__in
=
user_ids
)),
...
@@ -95,12 +97,6 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -95,12 +97,6 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
all_users
.
append
(
fake_user
)
all_users
.
append
(
fake_user
)
user_str
=
','
.
join
(
all_users
)
user_str
=
','
.
join
(
all_users
)
real_user_ids
=
[
u
.
id
for
u
in
self
.
users
]
real_user_ids
=
[
u
.
id
for
u
in
self
.
users
]
command_args
=
{
'course_id'
:
unicode
(
self
.
course
.
id
),
'to_mode'
:
'honor'
,
'from_mode'
:
'audit'
,
method
:
user_str
,
}
# Verify users are not in honor mode yet
# Verify users are not in honor mode yet
self
.
assertEqual
(
self
.
assertEqual
(
...
@@ -108,11 +104,14 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
...
@@ -108,11 +104,14 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
0
0
)
)
call_command
(
command_args
=
'--course {course} --to honor --from audit --{method} {user_str}'
.
format
(
'change_enrollment'
,
course
=
text_type
(
self
.
course
.
id
),
**
command_args
method
=
method
,
user_str
=
user_str
)
)
call_command
(
'change_enrollment'
,
*
command_args
.
split
(
' '
))
# Verify correct number of users are now in honor mode
# Verify correct number of users are now in honor mode
self
.
assertEqual
(
self
.
assertEqual
(
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
'honor'
,
user_id__in
=
real_user_ids
)),
len
(
CourseEnrollment
.
objects
.
filter
(
mode
=
'honor'
,
user_id__in
=
real_user_ids
)),
...
...
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