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
78edd852
Commit
78edd852
authored
May 17, 2017
by
Sanford Student
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add command
parent
9380b6b5
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
169 additions
and
0 deletions
+169
-0
lms/djangoapps/grades/management/commands/recalculate_subsection_grades.py
+91
-0
lms/djangoapps/grades/management/commands/tests/test_recalculate_subsection_grades.py
+78
-0
No files found.
lms/djangoapps/grades/management/commands/recalculate_subsection_grades.py
0 → 100644
View file @
78edd852
"""
Command to recalculate grades for all subsections with problem submissions
in the specified time range.
"""
from
__future__
import
absolute_import
,
division
,
print_function
,
unicode_literals
from
datetime
import
datetime
import
logging
from
pytz
import
utc
from
django.core.management.base
import
BaseCommand
,
CommandError
from
lms.djangoapps.grades.constants
import
ScoreDatabaseTableEnum
from
lms.djangoapps.grades.signals.handlers
import
PROBLEM_SUBMITTED_EVENT_TYPE
from
lms.djangoapps.grades.tasks
import
recalculate_subsection_grade_v3
from
courseware.models
import
StudentModule
from
student.models
import
user_by_anonymous_id
from
submissions.models
import
Submission
from
track.event_transaction_utils
import
create_new_event_transaction_id
,
set_event_transaction_type
from
util.date_utils
import
to_timestamp
log
=
logging
.
getLogger
(
__name__
)
DATE_FORMAT
=
"
%
Y-
%
m-
%
d
%
H:
%
M"
class
Command
(
BaseCommand
):
"""
Example usage:
$ ./manage.py lms recalculate_subsection_grades
--modified_start '2016-08-23 16:43' --modified_end '2016-08-25 16:43' --settings=devstack
"""
args
=
'fill this in'
help
=
'Recalculates subsection grades for all subsections modified within the given time range.'
def
add_arguments
(
self
,
parser
):
"""
Entry point for subclassed commands to add custom arguments.
"""
parser
.
add_argument
(
'--modified_start'
,
dest
=
'modified_start'
,
help
=
'Starting range for modified date (inclusive): e.g. "2016-08-23 16:43"; expected in UTC.'
,
)
parser
.
add_argument
(
'--modified_end'
,
dest
=
'modified_end'
,
help
=
'Ending range for modified date (inclusive): e.g. "2016-12-23 16:43"; expected in UTC.'
,
)
def
handle
(
self
,
*
args
,
**
options
):
if
'modified_start'
not
in
options
:
raise
CommandError
(
'modified_start must be provided.'
)
if
'modified_end'
not
in
options
:
raise
CommandError
(
'modified_end must be provided.'
)
modified_start
=
utc
.
localize
(
datetime
.
strptime
(
options
[
'modified_start'
],
DATE_FORMAT
))
modified_end
=
utc
.
localize
(
datetime
.
strptime
(
options
[
'modified_end'
],
DATE_FORMAT
))
event_transaction_id
=
create_new_event_transaction_id
()
set_event_transaction_type
(
PROBLEM_SUBMITTED_EVENT_TYPE
)
kwargs
=
{
'modified__range'
:
(
modified_start
,
modified_end
),
'module_type'
:
'problem'
}
for
record
in
StudentModule
.
objects
.
filter
(
**
kwargs
):
task_args
=
{
"user_id"
:
record
.
student_id
,
"course_id"
:
unicode
(
record
.
course_id
),
"usage_id"
:
unicode
(
record
.
module_state_key
),
"only_if_higher"
:
False
,
"expected_modified_time"
:
to_timestamp
(
record
.
modified
),
"score_deleted"
:
False
,
"event_transaction_id"
:
unicode
(
event_transaction_id
),
"event_transaction_type"
:
PROBLEM_SUBMITTED_EVENT_TYPE
,
"score_db_table"
:
ScoreDatabaseTableEnum
.
courseware_student_module
,
}
recalculate_subsection_grade_v3
.
apply_async
(
kwargs
=
task_args
)
kwargs
=
{
'created_at__range'
:
(
modified_start
,
modified_end
)}
for
record
in
Submission
.
objects
.
filter
(
**
kwargs
):
task_args
=
{
"user_id"
:
user_by_anonymous_id
(
record
.
student_item
.
student_id
)
.
id
,
"anonymous_user_id"
:
record
.
student_item
.
student_id
,
"course_id"
:
unicode
(
record
.
student_item
.
course_id
),
"usage_id"
:
unicode
(
record
.
student_item
.
item_id
),
"only_if_higher"
:
False
,
"expected_modified_time"
:
to_timestamp
(
record
.
created_at
),
"score_deleted"
:
False
,
"event_transaction_id"
:
unicode
(
event_transaction_id
),
"event_transaction_type"
:
PROBLEM_SUBMITTED_EVENT_TYPE
,
"score_db_table"
:
ScoreDatabaseTableEnum
.
submissions
,
}
recalculate_subsection_grade_v3
.
apply_async
(
kwargs
=
task_args
)
lms/djangoapps/grades/management/commands/tests/test_recalculate_subsection_grades.py
0 → 100644
View file @
78edd852
"""
Tests for reset_grades management command.
"""
import
ddt
from
datetime
import
datetime
from
django.conf
import
settings
from
mock
import
patch
,
MagicMock
from
pytz
import
utc
from
lms.djangoapps.grades.management.commands
import
recalculate_subsection_grades
from
lms.djangoapps.grades.constants
import
ScoreDatabaseTableEnum
from
lms.djangoapps.grades.tests.test_tasks
import
HasCourseWithProblemsMixin
from
track.event_transaction_utils
import
get_event_transaction_id
from
util.date_utils
import
to_timestamp
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
DATE_FORMAT
=
"
%
Y-
%
m-
%
d
%
H:
%
M"
@patch.dict
(
settings
.
FEATURES
,
{
'PERSISTENT_GRADES_ENABLED_FOR_ALL_TESTS'
:
False
})
@ddt.ddt
class
TestRecalculateSubsectionGrades
(
HasCourseWithProblemsMixin
,
ModuleStoreTestCase
):
"""
Tests recalculate subsection grades management command.
"""
def
setUp
(
self
):
super
(
TestRecalculateSubsectionGrades
,
self
)
.
setUp
()
self
.
command
=
recalculate_subsection_grades
.
Command
()
@patch
(
'lms.djangoapps.grades.management.commands.recalculate_subsection_grades.Submission'
)
@patch
(
'lms.djangoapps.grades.management.commands.recalculate_subsection_grades.user_by_anonymous_id'
)
@patch
(
'lms.djangoapps.grades.management.commands.recalculate_subsection_grades.recalculate_subsection_grade_v3'
)
def
test_submissions
(
self
,
task_mock
,
id_mock
,
subs_mock
):
submission
=
MagicMock
()
submission
.
student_item
=
MagicMock
(
student_id
=
"anonymousID"
,
course_id
=
'x/y/z'
,
item_id
=
'abc'
,
)
submission
.
created_at
=
utc
.
localize
(
datetime
.
strptime
(
'2016-08-23 16:43'
,
DATE_FORMAT
))
subs_mock
.
objects
.
filter
.
return_value
=
[
submission
]
id_mock
.
return_value
=
MagicMock
()
id_mock
.
return_value
.
id
=
"ID"
self
.
_run_command_and_check_output
(
task_mock
,
ScoreDatabaseTableEnum
.
submissions
,
include_anonymous_id
=
True
)
@patch
(
'lms.djangoapps.grades.management.commands.recalculate_subsection_grades.StudentModule'
)
@patch
(
'lms.djangoapps.grades.management.commands.recalculate_subsection_grades.user_by_anonymous_id'
)
@patch
(
'lms.djangoapps.grades.management.commands.recalculate_subsection_grades.recalculate_subsection_grade_v3'
)
def
test_csm
(
self
,
task_mock
,
id_mock
,
csm_mock
):
csm_record
=
MagicMock
()
csm_record
.
student_id
=
"ID"
csm_record
.
course_id
=
"x/y/z"
csm_record
.
module_state_key
=
"abc"
csm_record
.
modified
=
utc
.
localize
(
datetime
.
strptime
(
'2016-08-23 16:43'
,
DATE_FORMAT
))
csm_mock
.
objects
.
filter
.
return_value
=
[
csm_record
]
id_mock
.
return_value
=
MagicMock
()
id_mock
.
return_value
.
id
=
"ID"
self
.
_run_command_and_check_output
(
task_mock
,
ScoreDatabaseTableEnum
.
courseware_student_module
)
def
_run_command_and_check_output
(
self
,
task_mock
,
score_db_table
,
include_anonymous_id
=
False
):
self
.
command
.
handle
(
modified_start
=
'2016-08-25 16:42'
,
modified_end
=
'2018-08-25 16:44'
)
kwargs
=
{
"user_id"
:
"ID"
,
"course_id"
:
u'x/y/z'
,
"usage_id"
:
u'abc'
,
"only_if_higher"
:
False
,
"expected_modified_time"
:
to_timestamp
(
utc
.
localize
(
datetime
.
strptime
(
'2016-08-23 16:43'
,
DATE_FORMAT
))),
"score_deleted"
:
False
,
"event_transaction_id"
:
unicode
(
get_event_transaction_id
()),
"event_transaction_type"
:
u'edx.grades.problem.submitted'
,
"score_db_table"
:
score_db_table
,
}
if
include_anonymous_id
:
kwargs
[
'anonymous_user_id'
]
=
'anonymousID'
task_mock
.
apply_async
.
assert_called_with
(
kwargs
=
kwargs
)
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