Merge pull request #18170 from open-craft/eugeny/instructor_report_popup_backend
Answers report: Return task ID and generated filename for frontend to consume
This commit is contained in:
@@ -2776,6 +2776,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
status = res_json['status']
|
||||
self.assertIn('is being created', status)
|
||||
self.assertNotIn('already in progress', status)
|
||||
self.assertIn("task_id", res_json)
|
||||
|
||||
@valid_problem_location
|
||||
def test_get_problem_responses_already_running(self):
|
||||
@@ -3158,15 +3159,16 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
|
||||
kwargs.update(extra_instructor_api_kwargs)
|
||||
url = reverse(instructor_api_endpoint, kwargs=kwargs)
|
||||
success_status = "The {report_type} report is being created.".format(report_type=report_type)
|
||||
if report_type == 'problem responses':
|
||||
with patch(task_api_endpoint):
|
||||
with patch(task_api_endpoint) as patched_task_api_endpoint:
|
||||
patched_task_api_endpoint.return_value.task_id = "12345667-9abc-deff-ffed-cba987654321"
|
||||
|
||||
if report_type == 'problem responses':
|
||||
response = self.client.post(url, {'problem_location': ''})
|
||||
self.assertIn(success_status, response.content)
|
||||
else:
|
||||
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
|
||||
with patch(task_api_endpoint):
|
||||
self.assertIn(success_status, response.content)
|
||||
else:
|
||||
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
|
||||
response = self.client.post(url, {})
|
||||
self.assertIn(success_status, response.content)
|
||||
self.assertIn(success_status, response.content)
|
||||
|
||||
@ddt.data(*EXECUTIVE_SUMMARY_DATA)
|
||||
@ddt.unpack
|
||||
|
||||
@@ -996,7 +996,7 @@ def get_problem_responses(request, course_id):
|
||||
to a given problem.
|
||||
|
||||
Responds with JSON
|
||||
{"status": "... status message ..."}
|
||||
{"status": "... status message ...", "task_id": created_task_UUID}
|
||||
|
||||
if initiation is successful (or generation task is already running).
|
||||
|
||||
@@ -1017,10 +1017,12 @@ def get_problem_responses(request, course_id):
|
||||
except InvalidKeyError:
|
||||
return JsonResponseBadRequest(_("Could not find problem with this location."))
|
||||
|
||||
lms.djangoapps.instructor_task.api.submit_calculate_problem_responses_csv(request, course_key, problem_location)
|
||||
task = lms.djangoapps.instructor_task.api.submit_calculate_problem_responses_csv(
|
||||
request, course_key, problem_location
|
||||
)
|
||||
success_status = SUCCESS_MESSAGE_TEMPLATE.format(report_type=report_type)
|
||||
|
||||
return JsonResponse({"status": success_status})
|
||||
return JsonResponse({"status": success_status, "task_id": task.task_id})
|
||||
|
||||
|
||||
@require_POST
|
||||
@@ -2380,17 +2382,21 @@ def list_entrance_exam_instructor_tasks(request, course_id): # pylint: disable=
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_level('staff')
|
||||
def list_report_downloads(_request, course_id):
|
||||
def list_report_downloads(request, course_id):
|
||||
"""
|
||||
List grade CSV files that are available for download for this course.
|
||||
|
||||
Takes the following query parameters:
|
||||
- (optional) report_name - name of the report
|
||||
"""
|
||||
course_id = CourseKey.from_string(course_id)
|
||||
report_store = ReportStore.from_config(config_name='GRADES_DOWNLOAD')
|
||||
report_name = request.POST.get("report_name", None)
|
||||
|
||||
response_payload = {
|
||||
'downloads': [
|
||||
dict(name=name, url=url, link=HTML('<a href="{}">{}</a>').format(HTML(url), Text(name)))
|
||||
for name, url in report_store.links_for(course_id)
|
||||
for name, url in report_store.links_for(course_id) if report_name is None or name == report_name
|
||||
]
|
||||
}
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
@@ -681,6 +681,7 @@ class ProblemResponses(object):
|
||||
# Perform the upload
|
||||
problem_location = re.sub(r'[:/]', '_', problem_location)
|
||||
csv_name = 'student_state_from_{}'.format(problem_location)
|
||||
upload_csv_to_report_store(rows, csv_name, course_id, start_date)
|
||||
report_name = upload_csv_to_report_store(rows, csv_name, course_id, start_date)
|
||||
current_step = {'step': 'CSV uploaded', 'report_name': report_name}
|
||||
|
||||
return task_progress.update_task_state(extra_meta=current_step)
|
||||
|
||||
@@ -26,18 +26,20 @@ def upload_csv_to_report_store(rows, csv_name, course_id, timestamp, config_name
|
||||
]
|
||||
csv_name: Name of the resulting CSV
|
||||
course_id: ID of the course
|
||||
|
||||
Returns:
|
||||
report_name: string - Name of the generated report
|
||||
"""
|
||||
report_store = ReportStore.from_config(config_name)
|
||||
report_store.store_rows(
|
||||
course_id,
|
||||
u"{course_prefix}_{csv_name}_{timestamp_str}.csv".format(
|
||||
course_prefix=course_filename_prefix_generator(course_id),
|
||||
csv_name=csv_name,
|
||||
timestamp_str=timestamp.strftime("%Y-%m-%d-%H%M")
|
||||
),
|
||||
rows
|
||||
report_name = u"{course_prefix}_{csv_name}_{timestamp_str}.csv".format(
|
||||
course_prefix=course_filename_prefix_generator(course_id),
|
||||
csv_name=csv_name,
|
||||
timestamp_str=timestamp.strftime("%Y-%m-%d-%H%M")
|
||||
)
|
||||
|
||||
report_store.store_rows(course_id, report_name, rows)
|
||||
tracker_emit(csv_name)
|
||||
return report_name
|
||||
|
||||
|
||||
def tracker_emit(report_name):
|
||||
|
||||
@@ -637,6 +637,7 @@ class TestProblemResponsesReport(TestReportMixin, InstructorTaskModuleTestCase):
|
||||
|
||||
self.assertEquals(len(links), 1)
|
||||
self.assertDictContainsSubset({'attempted': 3, 'succeeded': 3, 'failed': 0}, result)
|
||||
self.assertIn("report_name", result)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
|
||||
Reference in New Issue
Block a user