From 37f261f906411508e1d04031cb08d07664278196 Mon Sep 17 00:00:00 2001 From: Diana Huang Date: Wed, 2 Jan 2013 15:01:59 -0500 Subject: [PATCH] Move peer grading so that there are the individual problem pages and the problem list page --- .../peer_grading_service.py | 35 ++++++++-- lms/djangoapps/open_ended_grading/views.py | 68 +++++++++++++++++++ .../src/peer_grading/peer_grading.coffee | 9 +++ .../peer_grading/peer_grading_problem.coffee | 17 +++++ lms/static/sass/course/_staff_grading.scss | 3 +- lms/templates/peer_grading/peer_grading.html | 15 +++- .../peer_grading/peer_grading_problem.html | 22 ++++++ lms/urls.py | 2 + 8 files changed, 164 insertions(+), 7 deletions(-) create mode 100644 lms/static/coffee/src/peer_grading/peer_grading.coffee create mode 100644 lms/static/coffee/src/peer_grading/peer_grading_problem.coffee create mode 100644 lms/templates/peer_grading/peer_grading_problem.html diff --git a/lms/djangoapps/open_ended_grading/peer_grading_service.py b/lms/djangoapps/open_ended_grading/peer_grading_service.py index b2b1fab5d3..1b78a32c5d 100644 --- a/lms/djangoapps/open_ended_grading/peer_grading_service.py +++ b/lms/djangoapps/open_ended_grading/peer_grading_service.py @@ -24,12 +24,14 @@ class PeerGradingService(GradingService): self.get_next_submission_url = self.url + '/get_next_submission/' self.save_grade_url = self.url + '/save_grade/' self.is_student_calibrated_url = self.url + '/is_student_calibrated/' - self.show_calibration_essay = self.url + '/show_calibration_essay/' - self.save_calibration_essay = self.url + '/save_calibration_essay/' + self.show_calibration_essay_url = self.url + '/show_calibration_essay/' + self.save_calibration_essay_url = self.url + '/save_calibration_essay/' + self.get_problem_list_url = self.url + '/get_problem_list/' def get_next_submission(self, problem_location, grader_id): - return self.get(self.get_next_submission_url, False, + response = self.get(self.get_next_submission_url, False, {'location': problem_location, 'grader_id': grader_id}) + return response def save_grade(self, grader_id, submission_id, score, feedback, submission_key): data = {'grader_id' : grader_id, @@ -39,6 +41,29 @@ class PeerGradingService(GradingService): 'submission_key': submission_key} return self.post(self.save_grade_url, False, data) + def is_student_calibrated(self, problem_location, grader_id): + params = {'problem_id' : problem_location, 'student_id': grader_id} + return self.get(self.is_student_calibrated_url, False, params) + + def show_calibration_essay(self, problem_location, grader_id): + params = {'problem_id' : problem_location, 'student_id': grader_id} + return self.get(self.show_calibration_essay_url, False, params) + + def save_calibration_essay(self, problem_location, grader_id, calibration_essay_id, submission_key, score, feedback): + data = {'location': problem_location, + 'student_id': grader_id, + 'calibration_essay_id': calibration_essay_id, + 'submission_key': submission_key, + 'score': score, + 'feedback': feedback} + return self.post(self.save_calibration_essay_url, False, data) + + def get_problem_list(self, course_id, grader_id): + params = {'course_id': course_id, 'student_id': grader_id} + response = self.get(self.get_problem_list_url, False, params) + log.debug("Response! {0}".format(response)) + return response + def peer_grading_service(): """ @@ -64,6 +89,9 @@ def _err_response(msg): mimetype="application/json") def get_next_submission(request, course_id): + """ + TODO: fill in this documentation + """ required = set(['location']) if request.method != 'POST': raise Http404 @@ -91,4 +119,3 @@ def _get_next_submission(course_id, grader_id, location): return json.dumps({'success': False, 'error': 'Could not connect to grading service'}) - diff --git a/lms/djangoapps/open_ended_grading/views.py b/lms/djangoapps/open_ended_grading/views.py index 41eb0fbccf..d4967aa0e9 100644 --- a/lms/djangoapps/open_ended_grading/views.py +++ b/lms/djangoapps/open_ended_grading/views.py @@ -26,6 +26,10 @@ from xmodule.modulestore import Location from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError, NoPathToItem from xmodule.modulestore.search import path_to_location + +from peer_grading_service import PeerGradingService +from grading_service import GradingServiceError +import json import track.views from .staff_grading import StaffGrading @@ -34,6 +38,8 @@ from .staff_grading import StaffGrading log = logging.getLogger(__name__) template_imports = {'urllib': urllib} +peer_gs = PeerGradingService(settings.PEER_GRADING_INTERFACE) + @cache_control(no_cache=True, no_store=True, must_revalidate=True) def staff_grading(request, course_id): """ @@ -62,6 +68,22 @@ def peer_grading(request, course_id): ''' course = get_course_with_access(request.user, course_id, 'load') + # call problem list service + success = False + error_text = "" + try: + problem_list_text = peer_gs.get_problem_list(course_id, request.user.id) + problem_list_json = json.loads(problem_list_text) + success = problem_list_json['success'] + if 'error' in problem_list_json: + error_text = problem_list_json['error'] + + problem_list = problem_list_json['problem_list'] + + except GradingServiceError: + error_text = "Error occured while contacting the grading service" + success = False + ajax_url = reverse('peer_grading', kwargs={'course_id': course_id}) if not ajax_url.endswith('/'): ajax_url += '/' @@ -71,6 +93,52 @@ def peer_grading(request, course_id): 'course': course, 'course_id': course_id, 'ajax_url': ajax_url, + 'success': success, + 'problem_list': problem_list, + 'error_text': error_text, + # Checked above + 'staff_access': False, }) + + +def peer_grading_problem(request, course_id, problem_location): + ''' + Show individual problem interface + ''' + course = get_course_with_access(request.user, course_id, 'load') + + # TODO: make sure that we show calibration or next submission correctly + # TODO: figure out if we want to make this page pure ajax or not + + problem_info_text = "" + error_text = "" + # if we are still in calibration + + # show a calibration essay + + # else, show an actual problem + try: + problem_info_text = peer_gs.get_next_submission(problem_location, request.user.id) + log.debug(problem_info_text) + problem_info = json.loads(problem_info_text) + success = problem_info['success'] + if 'error' in problem_info: + error_text = problem_info['error'] + except GradingServiceError: + success = False + + + ajax_url = reverse('peer_grading', kwargs={'course_id': course_id}) + if not ajax_url.endswith('/'): + ajax_url += '/' + + return render_to_response('peer_grading/peer_grading_problem.html', { + 'view_html': '', + 'course': course, + 'course_id': course_id, + 'success' : success, + 'problem_info': problem_info_text, + 'ajax_url': ajax_url, + 'error_text': error_text, # Checked above 'staff_access': False, }) diff --git a/lms/static/coffee/src/peer_grading/peer_grading.coffee b/lms/static/coffee/src/peer_grading/peer_grading.coffee new file mode 100644 index 0000000000..46f0206bbf --- /dev/null +++ b/lms/static/coffee/src/peer_grading/peer_grading.coffee @@ -0,0 +1,9 @@ +class PeerGrading + constructor: (backend) -> + @problem_list = $('.problem-list') + @error_container = $('.error-container') + @error_container.toggle(not @error_container.is(':empty')) + + +backend = {} +$(document).ready(() -> new PeerGrading(backend)) diff --git a/lms/static/coffee/src/peer_grading/peer_grading_problem.coffee b/lms/static/coffee/src/peer_grading/peer_grading_problem.coffee new file mode 100644 index 0000000000..461089b79c --- /dev/null +++ b/lms/static/coffee/src/peer_grading/peer_grading_problem.coffee @@ -0,0 +1,17 @@ +class PeerGradingProblemBackend + constructor: (ajax_url, mock_backend) -> + @mock_backend = mock_backend + +class PeerGradingProblem + constructor: (backend) -> + @error_container = $('.error-container') + + @render_problem() + + render_problem: () -> + # do this when it makes sense + @error_container.toggle(not @error_container.is(':empty')) + + +backend = {} +$(document).ready(() -> new PeerGradingProblem(backend)) diff --git a/lms/static/sass/course/_staff_grading.scss b/lms/static/sass/course/_staff_grading.scss index f1b6c5845d..bb7f6cef45 100644 --- a/lms/static/sass/course/_staff_grading.scss +++ b/lms/static/sass/course/_staff_grading.scss @@ -1,4 +1,5 @@ -div.staff-grading { +div.staff-grading, +div.peer-grading{ textarea.feedback-area { height: 75px; margin: 20px; diff --git a/lms/templates/peer_grading/peer_grading.html b/lms/templates/peer_grading/peer_grading.html index 0254d4cd67..b5a1408fde 100644 --- a/lms/templates/peer_grading/peer_grading.html +++ b/lms/templates/peer_grading/peer_grading.html @@ -16,7 +16,18 @@
-
-
+
${error_text}
+

Peer Grading

+

Instructions

+

+ % if success: + + %endif
diff --git a/lms/templates/peer_grading/peer_grading_problem.html b/lms/templates/peer_grading/peer_grading_problem.html new file mode 100644 index 0000000000..7ea47f04f7 --- /dev/null +++ b/lms/templates/peer_grading/peer_grading_problem.html @@ -0,0 +1,22 @@ + +<%inherit file="/main.html" /> +<%block name="bodyclass">${course.css_class} +<%namespace name='static' file='/static_content.html'/> + +<%block name="headextra"> + <%static:css group='course'/> + + +<%block name="title">${course.number} Peer Grading. + +<%include file="/courseware/course_navigation.html" args="active_page='staff_grading'" /> + +<%block name="js_extra"> + <%static:js group='peer_grading'/> + + +
+
+
${error_text}
+
+
diff --git a/lms/urls.py b/lms/urls.py index 4f5dfeb666..7f30224ad5 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -254,6 +254,8 @@ if settings.COURSEWARE_ENABLED: 'open_ended_grading.peer_grading_service.get_next_submission', name='peer_grading_get_next_submission'), url(r'^courses/(?P[^/]+/[^/]+/[^/]+)/peer_grading$', 'open_ended_grading.views.peer_grading', name='peer_grading'), + url(r'^courses/(?P[^/]+/[^/]+/[^/]+)/peer_grading/problem/(?P.*)$', + 'open_ended_grading.views.peer_grading_problem', name='peer_grading_problem'), )