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
4b671d11
Commit
4b671d11
authored
Jul 30, 2013
by
Miles Steele
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix pylint violations
parent
2760938e
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
86 additions
and
74 deletions
+86
-74
lms/djangoapps/analytics/distributions.py
+6
-0
lms/djangoapps/analytics/tests/test_distributions.py
+5
-2
lms/djangoapps/instructor/access.py
+1
-1
lms/djangoapps/instructor/tests/test_access.py
+1
-2
lms/djangoapps/instructor/tests/test_api.py
+6
-4
lms/djangoapps/instructor/tests/test_enrollment.py
+40
-34
lms/djangoapps/instructor/tests/test_legacy_download_csv.py
+3
-2
lms/djangoapps/instructor/views/api.py
+16
-18
lms/djangoapps/instructor/views/instructor_dashboard.py
+8
-11
No files found.
lms/djangoapps/analytics/distributions.py
View file @
4b671d11
...
@@ -56,6 +56,11 @@ class ProfileDistribution(object):
...
@@ -56,6 +56,11 @@ class ProfileDistribution(object):
self
.
feature
=
feature
self
.
feature
=
feature
self
.
feature_display_name
=
DISPLAY_NAMES
.
get
(
feature
,
feature
)
self
.
feature_display_name
=
DISPLAY_NAMES
.
get
(
feature
,
feature
)
# to be set later
self
.
type
=
None
self
.
data
=
None
self
.
choices_display_names
=
None
def
validate
(
self
):
def
validate
(
self
):
"""
"""
Validate this profile distribution.
Validate this profile distribution.
...
@@ -63,6 +68,7 @@ class ProfileDistribution(object):
...
@@ -63,6 +68,7 @@ class ProfileDistribution(object):
Throws ProfileDistribution.ValidationError
Throws ProfileDistribution.ValidationError
"""
"""
def
validation_assert
(
predicate
):
def
validation_assert
(
predicate
):
""" Throw a ValidationError if false. """
if
not
predicate
:
if
not
predicate
:
raise
ProfileDistribution
.
ValidationError
()
raise
ProfileDistribution
.
ValidationError
()
...
...
lms/djangoapps/analytics/tests/test_distributions.py
View file @
4b671d11
...
@@ -45,7 +45,8 @@ class TestAnalyticsDistributions(TestCase):
...
@@ -45,7 +45,8 @@ class TestAnalyticsDistributions(TestCase):
distribution
=
profile_distribution
(
self
.
course_id
,
feature
)
distribution
=
profile_distribution
(
self
.
course_id
,
feature
)
print
distribution
print
distribution
self
.
assertEqual
(
distribution
.
type
,
'OPEN_CHOICE'
)
self
.
assertEqual
(
distribution
.
type
,
'OPEN_CHOICE'
)
self
.
assertFalse
(
hasattr
(
distribution
,
'choices_display_names'
))
self
.
assertTrue
(
hasattr
(
distribution
,
'choices_display_names'
))
self
.
assertEqual
(
distribution
.
choices_display_names
,
None
)
self
.
assertNotIn
(
'no_data'
,
distribution
.
data
)
self
.
assertNotIn
(
'no_data'
,
distribution
.
data
)
self
.
assertEqual
(
distribution
.
data
[
1930
],
1
)
self
.
assertEqual
(
distribution
.
data
[
1930
],
1
)
...
@@ -76,6 +77,7 @@ class TestAnalyticsDistributionsNoData(TestCase):
...
@@ -76,6 +77,7 @@ class TestAnalyticsDistributionsNoData(TestCase):
print
distribution
print
distribution
self
.
assertEqual
(
distribution
.
type
,
'EASY_CHOICE'
)
self
.
assertEqual
(
distribution
.
type
,
'EASY_CHOICE'
)
self
.
assertTrue
(
hasattr
(
distribution
,
'choices_display_names'
))
self
.
assertTrue
(
hasattr
(
distribution
,
'choices_display_names'
))
self
.
assertNotEqual
(
distribution
.
choices_display_names
,
None
)
self
.
assertIn
(
'no_data'
,
distribution
.
data
)
self
.
assertIn
(
'no_data'
,
distribution
.
data
)
self
.
assertEqual
(
distribution
.
data
[
'no_data'
],
len
(
self
.
nodata_users
))
self
.
assertEqual
(
distribution
.
data
[
'no_data'
],
len
(
self
.
nodata_users
))
...
@@ -85,6 +87,7 @@ class TestAnalyticsDistributionsNoData(TestCase):
...
@@ -85,6 +87,7 @@ class TestAnalyticsDistributionsNoData(TestCase):
distribution
=
profile_distribution
(
self
.
course_id
,
feature
)
distribution
=
profile_distribution
(
self
.
course_id
,
feature
)
print
distribution
print
distribution
self
.
assertEqual
(
distribution
.
type
,
'OPEN_CHOICE'
)
self
.
assertEqual
(
distribution
.
type
,
'OPEN_CHOICE'
)
self
.
assertFalse
(
hasattr
(
distribution
,
'choices_display_names'
))
self
.
assertTrue
(
hasattr
(
distribution
,
'choices_display_names'
))
self
.
assertEqual
(
distribution
.
choices_display_names
,
None
)
self
.
assertIn
(
'no_data'
,
distribution
.
data
)
self
.
assertIn
(
'no_data'
,
distribution
.
data
)
self
.
assertEqual
(
distribution
.
data
[
'no_data'
],
len
(
self
.
nodata_users
))
self
.
assertEqual
(
distribution
.
data
[
'no_data'
],
len
(
self
.
nodata_users
))
lms/djangoapps/instructor/access.py
View file @
4b671d11
...
@@ -3,7 +3,7 @@ Access control operations for use by instructor APIs.
...
@@ -3,7 +3,7 @@ Access control operations for use by instructor APIs.
Does not include any access control, be sure to check access before calling.
Does not include any access control, be sure to check access before calling.
TODO sync instructor and staff flags
TO
DO sync instructor and staff flags
e.g. should these be possible?
e.g. should these be possible?
{instructor: true, staff: false}
{instructor: true, staff: false}
{instructor: true, staff: true}
{instructor: true, staff: true}
...
...
lms/djangoapps/instructor/tests/test_access.py
View file @
4b671d11
...
@@ -11,8 +11,7 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
...
@@ -11,8 +11,7 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from
django.test.utils
import
override_settings
from
django.test.utils
import
override_settings
from
courseware.tests.modulestore_config
import
TEST_DATA_MONGO_MODULESTORE
from
courseware.tests.modulestore_config
import
TEST_DATA_MONGO_MODULESTORE
from
courseware.access
import
(
get_access_group_name
,
from
courseware.access
import
get_access_group_name
course_beta_test_group_name
)
from
django_comment_common.models
import
(
Role
,
from
django_comment_common.models
import
(
Role
,
FORUM_ROLE_MODERATOR
)
FORUM_ROLE_MODERATOR
)
from
instructor.access
import
(
allow_access
,
from
instructor.access
import
(
allow_access
,
...
...
lms/djangoapps/instructor/tests/test_api.py
View file @
4b671d11
...
@@ -103,9 +103,10 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
...
@@ -103,9 +103,10 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
self
.
notregistered_email
=
'robot-not-an-email-yet@robot.org'
self
.
notregistered_email
=
'robot-not-an-email-yet@robot.org'
self
.
assertEqual
(
User
.
objects
.
filter
(
email
=
self
.
notregistered_email
)
.
count
(),
0
)
self
.
assertEqual
(
User
.
objects
.
filter
(
email
=
self
.
notregistered_email
)
.
count
(),
0
)
# enable printing of large diffs
#
uncomment to enable
enable printing of large diffs
# from failed assertions in the event of a test failure.
# from failed assertions in the event of a test failure.
self
.
maxDiff
=
None
# (comment because pylint C0103)
# self.maxDiff = None
def
test_missing_params
(
self
):
def
test_missing_params
(
self
):
""" Test missing all query parameters. """
""" Test missing all query parameters. """
...
@@ -605,11 +606,12 @@ class TestInstructorAPITaskLists(ModuleStoreTestCase, LoginEnrollmentTestCase):
...
@@ -605,11 +606,12 @@ class TestInstructorAPITaskLists(ModuleStoreTestCase, LoginEnrollmentTestCase):
""" Fake task object """
""" Fake task object """
FEATURES
=
[
'task_type'
,
'task_input'
,
'task_id'
,
'requester'
,
'created'
,
'task_state'
]
FEATURES
=
[
'task_type'
,
'task_input'
,
'task_id'
,
'requester'
,
'created'
,
'task_state'
]
def
__init__
(
self
,
i
):
def
__init__
(
self
):
for
feature
in
self
.
FEATURES
:
for
feature
in
self
.
FEATURES
:
setattr
(
self
,
feature
,
'expected'
)
setattr
(
self
,
feature
,
'expected'
)
def
to_dict
(
self
):
def
to_dict
(
self
):
""" Convert fake task to dictionary representation. """
return
{
key
:
'expected'
for
key
in
self
.
FEATURES
}
return
{
key
:
'expected'
for
key
in
self
.
FEATURES
}
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -631,7 +633,7 @@ class TestInstructorAPITaskLists(ModuleStoreTestCase, LoginEnrollmentTestCase):
...
@@ -631,7 +633,7 @@ class TestInstructorAPITaskLists(ModuleStoreTestCase, LoginEnrollmentTestCase):
state
=
json
.
dumps
({
'attempts'
:
10
}),
state
=
json
.
dumps
({
'attempts'
:
10
}),
)
)
self
.
tasks
=
[
self
.
FakeTask
(
i
)
for
i
in
xrange
(
6
)]
self
.
tasks
=
[
self
.
FakeTask
(
)
for
_
in
xrange
(
6
)]
def
test_list_instructor_tasks_running
(
self
):
def
test_list_instructor_tasks_running
(
self
):
""" Test list of all running tasks. """
""" Test list of all running tasks. """
...
...
lms/djangoapps/instructor/tests/test_enrollment.py
View file @
4b671d11
...
@@ -30,8 +30,9 @@ class TestSettableEnrollmentState(TestCase):
...
@@ -30,8 +30,9 @@ class TestSettableEnrollmentState(TestCase):
allowed
=
False
,
allowed
=
False
,
auto_enroll
=
False
auto_enroll
=
False
)
)
email
,
user
,
cenr
,
cea
=
mes
.
create_user
(
self
.
course_id
)
# enrollment objects
ees
=
EmailEnrollmentState
(
self
.
course_id
,
email
)
eobjs
=
mes
.
create_user
(
self
.
course_id
)
ees
=
EmailEnrollmentState
(
self
.
course_id
,
eobjs
.
email
)
self
.
assertEqual
(
mes
,
ees
)
self
.
assertEqual
(
mes
,
ees
)
...
@@ -58,23 +59,20 @@ class TestEnrollmentChangeBase(TestCase):
...
@@ -58,23 +59,20 @@ class TestEnrollmentChangeBase(TestCase):
`action` should transition the world from before_ideal to after_ideal
`action` should transition the world from before_ideal to after_ideal
`action` will be supplied the following arguments (None-able arguments)
`action` will be supplied the following arguments (None-able arguments)
`email` is an email string
`email` is an email string
`user` is a User
`cenr` is a CourseEnrollment
`cea` is a CourseEnrollmentAllowed
"""
"""
# initialize & check before
# initialize & check before
print
"checking initialization..."
print
"checking initialization..."
e
mail
,
user
,
cenr
,
cea
=
before_ideal
.
create_user
(
self
.
course_id
)
e
objs
=
before_ideal
.
create_user
(
self
.
course_id
)
before
=
EmailEnrollmentState
(
self
.
course_id
,
email
)
before
=
EmailEnrollmentState
(
self
.
course_id
,
e
objs
.
e
mail
)
self
.
assertEqual
(
before
,
before_ideal
)
self
.
assertEqual
(
before
,
before_ideal
)
# do action
# do action
print
"running action..."
print
"running action..."
action
(
e
mail
,
user
,
cenr
,
cea
)
action
(
e
objs
.
email
)
# check after
# check after
print
"checking effects..."
print
"checking effects..."
after
=
EmailEnrollmentState
(
self
.
course_id
,
email
)
after
=
EmailEnrollmentState
(
self
.
course_id
,
e
objs
.
e
mail
)
self
.
assertEqual
(
after
,
after_ideal
)
self
.
assertEqual
(
after
,
after_ideal
)
...
@@ -95,8 +93,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
...
@@ -95,8 +93,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
auto_enroll
=
False
auto_enroll
=
False
)
)
def
action
(
email
,
user
,
cenr
,
cea
):
action
=
lambda
email
:
enroll_email
(
self
.
course_id
,
email
)
enroll_email
(
self
.
course_id
,
email
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
...
@@ -115,8 +112,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
...
@@ -115,8 +112,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
auto_enroll
=
False
,
auto_enroll
=
False
,
)
)
def
action
(
email
,
user
,
cenr
,
cea
):
action
=
lambda
email
:
enroll_email
(
self
.
course_id
,
email
)
enroll_email
(
self
.
course_id
,
email
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
...
@@ -135,8 +131,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
...
@@ -135,8 +131,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
auto_enroll
=
False
,
auto_enroll
=
False
,
)
)
def
action
(
email
,
user
,
cenr
,
cea
):
action
=
lambda
email
:
enroll_email
(
self
.
course_id
,
email
)
enroll_email
(
self
.
course_id
,
email
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
...
@@ -155,8 +150,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
...
@@ -155,8 +150,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
auto_enroll
=
False
,
auto_enroll
=
False
,
)
)
def
action
(
email
,
user
,
cenr
,
cea
):
action
=
lambda
email
:
enroll_email
(
self
.
course_id
,
email
)
enroll_email
(
self
.
course_id
,
email
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
...
@@ -175,8 +169,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
...
@@ -175,8 +169,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
auto_enroll
=
True
,
auto_enroll
=
True
,
)
)
def
action
(
email
,
user
,
cenr
,
cea
):
action
=
lambda
email
:
enroll_email
(
self
.
course_id
,
email
,
auto_enroll
=
True
)
enroll_email
(
self
.
course_id
,
email
,
auto_enroll
=
True
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
...
@@ -195,8 +188,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
...
@@ -195,8 +188,7 @@ class TestInstructorEnrollDB(TestEnrollmentChangeBase):
auto_enroll
=
False
,
auto_enroll
=
False
,
)
)
def
action
(
email
,
user
,
cenr
,
cea
):
action
=
lambda
email
:
enroll_email
(
self
.
course_id
,
email
,
auto_enroll
=
False
)
enroll_email
(
self
.
course_id
,
email
,
auto_enroll
=
False
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
...
@@ -218,8 +210,7 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
...
@@ -218,8 +210,7 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
auto_enroll
=
False
auto_enroll
=
False
)
)
def
action
(
email
,
user
,
cenr
,
cea
):
action
=
lambda
email
:
unenroll_email
(
self
.
course_id
,
email
)
unenroll_email
(
self
.
course_id
,
email
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
...
@@ -238,8 +229,7 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
...
@@ -238,8 +229,7 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
auto_enroll
=
False
auto_enroll
=
False
)
)
def
action
(
email
,
user
,
cenr
,
cea
):
action
=
lambda
email
:
unenroll_email
(
self
.
course_id
,
email
)
unenroll_email
(
self
.
course_id
,
email
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
...
@@ -258,8 +248,7 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
...
@@ -258,8 +248,7 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
auto_enroll
=
False
auto_enroll
=
False
)
)
def
action
(
email
,
user
,
cenr
,
cea
):
action
=
lambda
email
:
unenroll_email
(
self
.
course_id
,
email
)
unenroll_email
(
self
.
course_id
,
email
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
...
@@ -278,8 +267,7 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
...
@@ -278,8 +267,7 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
auto_enroll
=
False
auto_enroll
=
False
)
)
def
action
(
email
,
user
,
cenr
,
cea
):
action
=
lambda
email
:
unenroll_email
(
self
.
course_id
,
email
)
unenroll_email
(
self
.
course_id
,
email
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
return
self
.
_run_state_change_test
(
before_ideal
,
after_ideal
,
action
)
...
@@ -310,6 +298,24 @@ class TestInstructorEnrollmentStudentModule(TestCase):
...
@@ -310,6 +298,24 @@ class TestInstructorEnrollmentStudentModule(TestCase):
self
.
assertEqual
(
StudentModule
.
objects
.
filter
(
student
=
user
,
course_id
=
self
.
course_id
,
module_state_key
=
msk
)
.
count
(),
0
)
self
.
assertEqual
(
StudentModule
.
objects
.
filter
(
student
=
user
,
course_id
=
self
.
course_id
,
module_state_key
=
msk
)
.
count
(),
0
)
class
EnrollmentObjects
(
object
):
"""
Container for enrollment objects.
`email` - student email
`user` - student User object
`cenr` - CourseEnrollment object
`cea` - CourseEnrollmentAllowed object
Any of the objects except email can be None.
"""
def
__init__
(
self
,
email
,
user
,
cenr
,
cea
):
self
.
email
=
email
self
.
user
=
user
self
.
cenr
=
cenr
self
.
cea
=
cea
class
SettableEnrollmentState
(
EmailEnrollmentState
):
class
SettableEnrollmentState
(
EmailEnrollmentState
):
"""
"""
Settable enrollment state.
Settable enrollment state.
...
@@ -318,7 +324,7 @@ class SettableEnrollmentState(EmailEnrollmentState):
...
@@ -318,7 +324,7 @@ class SettableEnrollmentState(EmailEnrollmentState):
a call to create_user will make objects which
a call to create_user will make objects which
correspond to the state represented in the SettableEnrollmentState.
correspond to the state represented in the SettableEnrollmentState.
"""
"""
def
__init__
(
self
,
user
=
False
,
enrollment
=
False
,
allowed
=
False
,
auto_enroll
=
False
):
def
__init__
(
self
,
user
=
False
,
enrollment
=
False
,
allowed
=
False
,
auto_enroll
=
False
):
# pylint: disable=W0231
self
.
user
=
user
self
.
user
=
user
self
.
enrollment
=
enrollment
self
.
enrollment
=
enrollment
self
.
allowed
=
allowed
self
.
allowed
=
allowed
...
@@ -351,15 +357,15 @@ class SettableEnrollmentState(EmailEnrollmentState):
...
@@ -351,15 +357,15 @@ class SettableEnrollmentState(EmailEnrollmentState):
user
=
user
,
user
=
user
,
course_id
=
course_id
course_id
=
course_id
)
)
return
(
email
,
user
,
cenr
,
None
)
return
EnrollmentObjects
(
email
,
user
,
cenr
,
None
)
else
:
else
:
return
(
email
,
user
,
None
,
None
)
return
EnrollmentObjects
(
email
,
user
,
None
,
None
)
elif
self
.
allowed
:
elif
self
.
allowed
:
cea
=
CourseEnrollmentAllowed
.
objects
.
create
(
cea
=
CourseEnrollmentAllowed
.
objects
.
create
(
email
=
email
,
email
=
email
,
course_id
=
course_id
,
course_id
=
course_id
,
auto_enroll
=
self
.
auto_enroll
,
auto_enroll
=
self
.
auto_enroll
,
)
)
return
(
email
,
None
,
None
,
cea
)
return
EnrollmentObjects
(
email
,
None
,
None
,
cea
)
else
:
else
:
return
(
email
,
None
,
None
,
None
)
return
EnrollmentObjects
(
email
,
None
,
None
,
None
)
lms/djangoapps/instructor/tests/test_legacy_download_csv.py
View file @
4b671d11
...
@@ -44,9 +44,10 @@ class TestInstructorDashboardGradeDownloadCSV(LoginEnrollmentTestCase):
...
@@ -44,9 +44,10 @@ class TestInstructorDashboardGradeDownloadCSV(LoginEnrollmentTestCase):
self
.
activate_user
(
self
.
instructor
)
self
.
activate_user
(
self
.
instructor
)
def
make_instructor
(
course
):
def
make_instructor
(
course
):
""" Create an instructor for the course. """
group_name
=
_course_staff_group_name
(
course
.
location
)
group_name
=
_course_staff_group_name
(
course
.
location
)
g
=
Group
.
objects
.
create
(
name
=
group_name
)
g
roup
=
Group
.
objects
.
create
(
name
=
group_name
)
g
.
user_set
.
add
(
User
.
objects
.
get
(
email
=
self
.
instructor
))
g
roup
.
user_set
.
add
(
User
.
objects
.
get
(
email
=
self
.
instructor
))
make_instructor
(
self
.
toy
)
make_instructor
(
self
.
toy
)
...
...
lms/djangoapps/instructor/views/api.py
View file @
4b671d11
...
@@ -3,7 +3,7 @@ Instructor Dashboard API views
...
@@ -3,7 +3,7 @@ Instructor Dashboard API views
JSON views which the instructor dashboard requests.
JSON views which the instructor dashboard requests.
TODO a lot of these GETs should be PUTs
Many of these GETs may become PUTs in the future.
"""
"""
import
re
import
re
...
@@ -41,7 +41,7 @@ def common_exceptions_400(func):
...
@@ -41,7 +41,7 @@ def common_exceptions_400(func):
Catches common exceptions and renders matching 400 errors.
Catches common exceptions and renders matching 400 errors.
(decorator without arguments)
(decorator without arguments)
"""
"""
def
wrapped
(
*
args
,
**
kwargs
):
def
wrapped
(
*
args
,
**
kwargs
):
# pylint: disable=C0111
try
:
try
:
return
func
(
*
args
,
**
kwargs
)
return
func
(
*
args
,
**
kwargs
)
except
User
.
DoesNotExist
:
except
User
.
DoesNotExist
:
...
@@ -65,8 +65,8 @@ def require_query_params(*args, **kwargs):
...
@@ -65,8 +65,8 @@ def require_query_params(*args, **kwargs):
required_params
+=
[(
key
,
kwargs
[
key
])
for
key
in
kwargs
]
required_params
+=
[(
key
,
kwargs
[
key
])
for
key
in
kwargs
]
# required_params = e.g. [('action', 'enroll or unenroll'), ['emails', None]]
# required_params = e.g. [('action', 'enroll or unenroll'), ['emails', None]]
def
decorator
(
func
):
def
decorator
(
func
):
# pylint: disable=C0111
def
wrapped
(
*
args
,
**
kwargs
):
def
wrapped
(
*
args
,
**
kwargs
):
# pylint: disable=C0111
request
=
args
[
0
]
request
=
args
[
0
]
error_response_data
=
{
error_response_data
=
{
...
@@ -108,8 +108,8 @@ def require_level(level):
...
@@ -108,8 +108,8 @@ def require_level(level):
if
level
not
in
[
'instructor'
,
'staff'
]:
if
level
not
in
[
'instructor'
,
'staff'
]:
raise
ValueError
(
"unrecognized level '{}'"
.
format
(
level
))
raise
ValueError
(
"unrecognized level '{}'"
.
format
(
level
))
def
decorator
(
func
):
def
decorator
(
func
):
# pylint: disable=C0111
def
wrapped
(
*
args
,
**
kwargs
):
def
wrapped
(
*
args
,
**
kwargs
):
# pylint: disable=C0111
request
=
args
[
0
]
request
=
args
[
0
]
course
=
get_course_by_id
(
kwargs
[
'course_id'
])
course
=
get_course_by_id
(
kwargs
[
'course_id'
])
...
@@ -339,14 +339,14 @@ def get_grading_config(request, course_id):
...
@@ -339,14 +339,14 @@ def get_grading_config(request, course_id):
@ensure_csrf_cookie
@ensure_csrf_cookie
@cache_control
(
no_cache
=
True
,
no_store
=
True
,
must_revalidate
=
True
)
@cache_control
(
no_cache
=
True
,
no_store
=
True
,
must_revalidate
=
True
)
@require_level
(
'staff'
)
@require_level
(
'staff'
)
def
get_students_features
(
request
,
course_id
,
csv
=
False
):
def
get_students_features
(
request
,
course_id
,
csv
=
False
):
# pylint: disable=W0613
"""
"""
Respond with json which contains a summary of all enrolled students profile information.
Respond with json which contains a summary of all enrolled students profile information.
Responds with JSON
Responds with JSON
{"students": [{-student-info-}, ...]}
{"students": [{-student-info-}, ...]}
TODO accept requests for different attribute sets.
TO
DO accept requests for different attribute sets.
"""
"""
available_features
=
analytics
.
basic
.
AVAILABLE_FEATURES
available_features
=
analytics
.
basic
.
AVAILABLE_FEATURES
query_features
=
[
'username'
,
'name'
,
'email'
,
'language'
,
'location'
,
'year_of_birth'
,
'gender'
,
query_features
=
[
'username'
,
'name'
,
'email'
,
'language'
,
'location'
,
'year_of_birth'
,
'gender'
,
...
@@ -382,8 +382,6 @@ def get_distribution(request, course_id):
...
@@ -382,8 +382,6 @@ def get_distribution(request, course_id):
If no `feature` is supplied, will return response with an
If no `feature` is supplied, will return response with an
empty response['feature_results'] object.
empty response['feature_results'] object.
A list of available will be available in the response['available_features']
A list of available will be available in the response['available_features']
TODO respond to csv requests as well
"""
"""
feature
=
request
.
GET
.
get
(
'feature'
)
feature
=
request
.
GET
.
get
(
'feature'
)
# alternate notations of None
# alternate notations of None
...
@@ -392,9 +390,9 @@ def get_distribution(request, course_id):
...
@@ -392,9 +390,9 @@ def get_distribution(request, course_id):
else
:
else
:
feature
=
str
(
feature
)
feature
=
str
(
feature
)
AVAILABLE_FEATURES
=
analytics
.
distributions
.
AVAILABLE_PROFILE_FEATURES
available_features
=
analytics
.
distributions
.
AVAILABLE_PROFILE_FEATURES
# allow None so that requests for no feature can list available features
# allow None so that requests for no feature can list available features
if
not
feature
in
AVAILABLE_FEATURES
+
(
None
,):
if
not
feature
in
available_features
+
(
None
,):
return
HttpResponseBadRequest
(
return
HttpResponseBadRequest
(
"feature '{}' not available."
.
format
(
feature
)
"feature '{}' not available."
.
format
(
feature
)
)
)
...
@@ -402,7 +400,7 @@ def get_distribution(request, course_id):
...
@@ -402,7 +400,7 @@ def get_distribution(request, course_id):
response_payload
=
{
response_payload
=
{
'course_id'
:
course_id
,
'course_id'
:
course_id
,
'queried_feature'
:
feature
,
'queried_feature'
:
feature
,
'available_features'
:
AVAILABLE_FEATURES
,
'available_features'
:
available_features
,
'feature_display_names'
:
analytics
.
distributions
.
DISPLAY_NAMES
,
'feature_display_names'
:
analytics
.
distributions
.
DISPLAY_NAMES
,
}
}
...
@@ -518,7 +516,7 @@ def reset_student_attempts(request, course_id):
...
@@ -518,7 +516,7 @@ def reset_student_attempts(request, course_id):
except
StudentModule
.
DoesNotExist
:
except
StudentModule
.
DoesNotExist
:
return
HttpResponseBadRequest
(
"Module does not exist."
)
return
HttpResponseBadRequest
(
"Module does not exist."
)
elif
all_students
:
elif
all_students
:
task
=
instructor_task
.
api
.
submit_reset_problem_attempts_for_all_students
(
request
,
course_id
,
module_state_key
)
instructor_task
.
api
.
submit_reset_problem_attempts_for_all_students
(
request
,
course_id
,
module_state_key
)
response_payload
[
'task'
]
=
'created'
response_payload
[
'task'
]
=
'created'
else
:
else
:
return
HttpResponseBadRequest
()
return
HttpResponseBadRequest
()
...
@@ -566,10 +564,10 @@ def rescore_problem(request, course_id):
...
@@ -566,10 +564,10 @@ def rescore_problem(request, course_id):
if
student_email
:
if
student_email
:
response_payload
[
'student_email'
]
=
student_email
response_payload
[
'student_email'
]
=
student_email
student
=
User
.
objects
.
get
(
email
=
student_email
)
student
=
User
.
objects
.
get
(
email
=
student_email
)
task
=
instructor_task
.
api
.
submit_rescore_problem_for_student
(
request
,
course_id
,
module_state_key
,
student
)
instructor_task
.
api
.
submit_rescore_problem_for_student
(
request
,
course_id
,
module_state_key
,
student
)
response_payload
[
'task'
]
=
'created'
response_payload
[
'task'
]
=
'created'
elif
all_students
:
elif
all_students
:
task
=
instructor_task
.
api
.
submit_rescore_problem_for_all_students
(
request
,
course_id
,
module_state_key
)
instructor_task
.
api
.
submit_rescore_problem_for_all_students
(
request
,
course_id
,
module_state_key
)
response_payload
[
'task'
]
=
'created'
response_payload
[
'task'
]
=
'created'
else
:
else
:
return
HttpResponseBadRequest
()
return
HttpResponseBadRequest
()
...
@@ -614,8 +612,8 @@ def list_instructor_tasks(request, course_id):
...
@@ -614,8 +612,8 @@ def list_instructor_tasks(request, course_id):
def
extract_task_features
(
task
):
def
extract_task_features
(
task
):
""" Convert task to dict for json rendering """
""" Convert task to dict for json rendering """
FEATURES
=
[
'task_type'
,
'task_input'
,
'task_id'
,
'requester'
,
'created'
,
'task_state'
]
features
=
[
'task_type'
,
'task_input'
,
'task_id'
,
'requester'
,
'created'
,
'task_state'
]
return
dict
((
feature
,
str
(
getattr
(
task
,
feature
)))
for
feature
in
FEATURES
)
return
dict
((
feature
,
str
(
getattr
(
task
,
feature
)))
for
feature
in
features
)
response_payload
=
{
response_payload
=
{
'tasks'
:
map
(
extract_task_features
,
tasks
),
'tasks'
:
map
(
extract_task_features
,
tasks
),
...
...
lms/djangoapps/instructor/views/instructor_dashboard.py
View file @
4b671d11
...
@@ -12,10 +12,7 @@ from django.http import Http404
...
@@ -12,10 +12,7 @@ from django.http import Http404
from
courseware.access
import
has_access
from
courseware.access
import
has_access
from
courseware.courses
import
get_course_by_id
from
courseware.courses
import
get_course_by_id
from
django_comment_client.utils
import
has_forum_access
from
django_comment_client.utils
import
has_forum_access
from
django_comment_common.models
import
(
Role
,
from
django_comment_common.models
import
FORUM_ROLE_ADMINISTRATOR
FORUM_ROLE_ADMINISTRATOR
,
FORUM_ROLE_MODERATOR
,
FORUM_ROLE_COMMUNITY_TA
)
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.django
import
modulestore
from
student.models
import
CourseEnrollment
from
student.models
import
CourseEnrollment
...
@@ -64,9 +61,9 @@ The dictionary must include at least {
...
@@ -64,9 +61,9 @@ The dictionary must include at least {
'section_display_name': 'Circus Expo'
'section_display_name': 'Circus Expo'
}
}
section_key will be used as a css attribute, javascript tie-in, and template import filename.
section_display_name will be used to generate link titles in the nav bar.
section_display_name will be used to generate link titles in the nav bar.
sek will be used as a css attribute, javascript tie-in, and template import filename.
"""
# pylint: disable=W0105
"""
def
_section_course_info
(
course_id
):
def
_section_course_info
(
course_id
):
...
@@ -81,16 +78,16 @@ def _section_course_info(course_id):
...
@@ -81,16 +78,16 @@ def _section_course_info(course_id):
section_data
[
'enrollment_count'
]
=
CourseEnrollment
.
objects
.
filter
(
course_id
=
course_id
)
.
count
()
section_data
[
'enrollment_count'
]
=
CourseEnrollment
.
objects
.
filter
(
course_id
=
course_id
)
.
count
()
section_data
[
'has_started'
]
=
course
.
has_started
()
section_data
[
'has_started'
]
=
course
.
has_started
()
section_data
[
'has_ended'
]
=
course
.
has_ended
()
section_data
[
'has_ended'
]
=
course
.
has_ended
()
try
:
try
:
def
next
(
memo
,
(
letter
,
score
)):
advance
=
lambda
memo
,
(
letter
,
score
):
"{}: {}, "
.
format
(
letter
,
score
)
+
memo
return
"{}: {}, "
.
format
(
letter
,
score
)
+
memo
section_data
[
'grade_cutoffs'
]
=
reduce
(
advance
,
course
.
grade_cutoffs
.
items
(),
""
)[:
-
2
]
section_data
[
'grade_cutoffs'
]
=
reduce
(
next
,
course
.
grade_cutoffs
.
items
(),
""
)[:
-
2
]
except
Exception
:
except
:
section_data
[
'grade_cutoffs'
]
=
"Not Available"
section_data
[
'grade_cutoffs'
]
=
"Not Available"
# section_data['offline_grades'] = offline_grades_available(course_id)
# section_data['offline_grades'] = offline_grades_available(course_id)
try
:
try
:
section_data
[
'course_errors'
]
=
[(
escape
(
a
),
''
)
for
(
a
,
b
)
in
modulestore
()
.
get_item_errors
(
course
.
location
)]
section_data
[
'course_errors'
]
=
[(
escape
(
a
),
''
)
for
(
a
,
_
)
in
modulestore
()
.
get_item_errors
(
course
.
location
)]
except
Exception
:
except
Exception
:
section_data
[
'course_errors'
]
=
[(
'Error fetching errors'
,
''
)]
section_data
[
'course_errors'
]
=
[(
'Error fetching errors'
,
''
)]
...
...
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