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
78d88958
Commit
78d88958
authored
May 22, 2017
by
sanfordstudent
Committed by
GitHub
May 22, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #15138 from edx/sstudent/recalculate_for_date_range
recalculate for date range mgmt command
parents
52fbe6f1
78edd852
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 @
78d88958
"""
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 @
78d88958
"""
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