Commit a64fd58c by Eric Fischer Committed by GitHub

Merge pull request #954 from edx/efischer/localize_time

Localize times for cancelled workflow
parents 71395afb eba36c54
"""
Django admin models for openassessment
"""
import json import json
from django.contrib import admin from django.contrib import admin
...@@ -12,6 +15,9 @@ from openassessment.assessment.serializers import RubricSerializer ...@@ -12,6 +15,9 @@ from openassessment.assessment.serializers import RubricSerializer
class RubricAdmin(admin.ModelAdmin): class RubricAdmin(admin.ModelAdmin):
"""
Django admin model for Rubrics.
"""
list_per_page = 20 # Loads of criteria summary are moderately expensive list_per_page = 20 # Loads of criteria summary are moderately expensive
list_display = ('id', 'content_hash', 'criteria_summary') list_display = ('id', 'content_hash', 'criteria_summary')
...@@ -40,6 +46,9 @@ class RubricAdmin(admin.ModelAdmin): ...@@ -40,6 +46,9 @@ class RubricAdmin(admin.ModelAdmin):
class PeerWorkflowItemInline(admin.StackedInline): class PeerWorkflowItemInline(admin.StackedInline):
"""
Django admin model for PeerWorkflowItems.
"""
model = PeerWorkflowItem model = PeerWorkflowItem
fk_name = 'author' fk_name = 'author'
raw_id_fields = ('author', 'scorer', 'assessment') raw_id_fields = ('author', 'scorer', 'assessment')
...@@ -47,23 +56,29 @@ class PeerWorkflowItemInline(admin.StackedInline): ...@@ -47,23 +56,29 @@ class PeerWorkflowItemInline(admin.StackedInline):
class PeerWorkflowAdmin(admin.ModelAdmin): class PeerWorkflowAdmin(admin.ModelAdmin):
"""
Django admin model for PeerWorkflows.
"""
list_display = ( list_display = (
'id', 'student_id', 'item_id', 'course_id', 'submission_uuid', 'id', 'student_id', 'item_id', 'course_id', 'submission_uuid',
'created_at', 'completed_at', 'grading_completed_at', 'created_at', 'completed_at', 'grading_completed_at',
) )
search_fields = ( search_fields = (
'id', 'student_id', 'item_id', 'course_id', 'submission_uuid', 'id', 'student_id', 'item_id', 'course_id', 'submission_uuid',
) )
inlines = (PeerWorkflowItemInline,) inlines = (PeerWorkflowItemInline,)
class AssessmentAdmin(admin.ModelAdmin): class AssessmentAdmin(admin.ModelAdmin):
"""
Django admin model for Assessments.
"""
list_display = ( list_display = (
'id', 'submission_uuid', 'score_type', 'scorer_id', 'scored_at', 'id', 'submission_uuid', 'score_type', 'scorer_id', 'scored_at',
'rubric_link', 'rubric_link',
) )
search_fields = ( search_fields = (
'id', 'submission_uuid', 'score_type', 'scorer_id', 'scored_at', 'id', 'submission_uuid', 'score_type', 'scorer_id', 'scored_at',
'rubric__content_hash', 'rubric__content_hash',
) )
readonly_fields = ( readonly_fields = (
...@@ -74,6 +89,9 @@ class AssessmentAdmin(admin.ModelAdmin): ...@@ -74,6 +89,9 @@ class AssessmentAdmin(admin.ModelAdmin):
exclude = ('rubric', 'submission_uuid') exclude = ('rubric', 'submission_uuid')
def rubric_link(self, assessment_obj): def rubric_link(self, assessment_obj):
"""
Returns the rubric link for this assessment.
"""
url = reverse( url = reverse(
'admin:assessment_rubric_change', 'admin:assessment_rubric_change',
args=[assessment_obj.rubric.id] args=[assessment_obj.rubric.id]
...@@ -86,6 +104,9 @@ class AssessmentAdmin(admin.ModelAdmin): ...@@ -86,6 +104,9 @@ class AssessmentAdmin(admin.ModelAdmin):
rubric_link.short_description = 'Rubric' rubric_link.short_description = 'Rubric'
def parts_summary(self, assessment_obj): def parts_summary(self, assessment_obj):
"""
Returns the parts summary of this assessment as HTML.
"""
return "<br/>".join( return "<br/>".join(
html.escape( html.escape(
u"{}/{} - {} - {}: {} - {} - {}".format( u"{}/{} - {} - {}: {} - {} - {}".format(
...@@ -104,6 +125,9 @@ class AssessmentAdmin(admin.ModelAdmin): ...@@ -104,6 +125,9 @@ class AssessmentAdmin(admin.ModelAdmin):
class AssessmentFeedbackAdmin(admin.ModelAdmin): class AssessmentFeedbackAdmin(admin.ModelAdmin):
"""
Django admin model for AssessmentFeedbacks.
"""
list_display = ('id', 'submission_uuid',) list_display = ('id', 'submission_uuid',)
search_fields = ('id', 'submission_uuid',) search_fields = ('id', 'submission_uuid',)
readonly_fields = ( readonly_fields = (
...@@ -112,6 +136,9 @@ class AssessmentFeedbackAdmin(admin.ModelAdmin): ...@@ -112,6 +136,9 @@ class AssessmentFeedbackAdmin(admin.ModelAdmin):
exclude = ('assessments',) exclude = ('assessments',)
def assessments_by(self, assessment_feedback): def assessments_by(self, assessment_feedback):
"""
Gets all assessments for this feedback.
"""
links = [ links = [
u'<a href="{}">{}</a>'.format( u'<a href="{}">{}</a>'.format(
reverse('admin:assessment_assessment_change', args=[asmt.id]), reverse('admin:assessment_assessment_change', args=[asmt.id]),
...@@ -124,22 +151,34 @@ class AssessmentFeedbackAdmin(admin.ModelAdmin): ...@@ -124,22 +151,34 @@ class AssessmentFeedbackAdmin(admin.ModelAdmin):
class AIGradingWorkflowAdmin(admin.ModelAdmin): class AIGradingWorkflowAdmin(admin.ModelAdmin):
"""
Django admin model for AIGradingWorkflows.
"""
list_display = ('uuid', 'submission_uuid') list_display = ('uuid', 'submission_uuid')
search_fields = ('uuid', 'submission_uuid', 'student_id', 'item_id', 'course_id') search_fields = ('uuid', 'submission_uuid', 'student_id', 'item_id', 'course_id')
readonly_fields = ('uuid', 'submission_uuid', 'student_id', 'item_id', 'course_id') readonly_fields = ('uuid', 'submission_uuid', 'student_id', 'item_id', 'course_id')
class AITrainingWorkflowAdmin(admin.ModelAdmin): class AITrainingWorkflowAdmin(admin.ModelAdmin):
"""
Django admin model for AITrainingWorkflows.
"""
list_display = ('uuid',) list_display = ('uuid',)
search_fields = ('uuid', 'course_id', 'item_id',) search_fields = ('uuid', 'course_id', 'item_id',)
readonly_fields = ('uuid', 'course_id', 'item_id',) readonly_fields = ('uuid', 'course_id', 'item_id',)
class AIClassifierInline(admin.TabularInline): class AIClassifierInline(admin.TabularInline):
"""
Django admin model for AIClassifiers.
"""
model = AIClassifier model = AIClassifier
class AIClassifierSetAdmin(admin.ModelAdmin): class AIClassifierSetAdmin(admin.ModelAdmin):
"""
Django admin model for AICLassifierSets.
"""
list_display = ('id',) list_display = ('id',)
search_fields = ('id',) search_fields = ('id',)
inlines = [AIClassifierInline] inlines = [AIClassifierInline]
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
<p> <p>
{% trans "Enter your response to the question." %} {% trans "Enter your response to the question." %}
{% if submission_due %} {% if submission_due %}
{% trans "You can save your progress and return to complete your response at any time before the due date" %} (<span class="step__deadline"><span class="date">{{ submission_due|utc|date:"l, N j, Y H:i e" }}</span></span>). {% trans "You can save your progress and return to complete your response at any time before the due date" %} (<span class="step__deadline"><span class="date">{{ submission_due|timezone:time_zone|date:"l, N j, Y H:i e" }}</span></span>).
{% else %} {% else %}
{% trans "You can save your progress and return to complete your response at any time." %} {% trans "You can save your progress and return to complete your response at any time." %}
{% endif %} {% endif %}
......
...@@ -32,11 +32,11 @@ ...@@ -32,11 +32,11 @@
{% trans "Your submission was cancelled. " %} {% trans "Your submission was cancelled. " %}
<p> <p>
{% if workflow_cancellation.cancelled_by %} {% if workflow_cancellation.cancelled_by %}
{% blocktrans with removed_datetime=workflow_cancellation.cancelled_at|utc|date:"N j, Y H:i e" removed_by_username=workflow_cancellation.cancelled_by %} {% blocktrans with removed_datetime=workflow_cancellation.cancelled_at|timezone:time_zone|date:"N j, Y H:i e" removed_by_username=workflow_cancellation.cancelled_by %}
Your submission has been cancelled by {{ removed_by_username }} on {{ removed_datetime }} Your submission has been cancelled by {{ removed_by_username }} on {{ removed_datetime }}
{% endblocktrans %} {% endblocktrans %}
{% else %} {% else %}
{% blocktrans with removed_datetime=workflow_cancellation.cancelled_at|utc|date:"N j, Y H:i e" %} {% blocktrans with removed_datetime=workflow_cancellation.cancelled_at|timezone:time_zone|date:"N j, Y H:i e" %}
Your submission was cancelled on {{ removed_datetime }} Your submission was cancelled on {{ removed_datetime }}
{% endblocktrans %} {% endblocktrans %}
{% endif %} {% endif %}
......
...@@ -26,11 +26,11 @@ ...@@ -26,11 +26,11 @@
{% if workflow_cancellation %} {% if workflow_cancellation %}
<p> <p>
{% if workflow_cancellation.cancelled_by %} {% if workflow_cancellation.cancelled_by %}
{% blocktrans with removed_by_username=workflow_cancellation.cancelled_by removed_datetime=workflow_cancellation.cancelled_at|utc|date:"F j, Y H:i e" %} {% blocktrans with removed_by_username=workflow_cancellation.cancelled_by removed_datetime=workflow_cancellation.cancelled_at|timezone:time_zone|date:"F j, Y H:i e" %}
Learner submission removed by {{ removed_by_username }} on {{ removed_datetime }} Learner submission removed by {{ removed_by_username }} on {{ removed_datetime }}
{% endblocktrans %} {% endblocktrans %}
{% else %} {% else %}
{% blocktrans with removed_datetime=workflow_cancellation.cancelled_at|utc|date:"F j, Y H:i e" %} {% blocktrans with removed_datetime=workflow_cancellation.cancelled_at|timezone:time_zone|date:"F j, Y H:i e" %}
Learner submission removed on {{ removed_datetime }} Learner submission removed on {{ removed_datetime }}
{% endblocktrans %} {% endblocktrans %}
{% endif %} {% endif %}
......
...@@ -24,6 +24,7 @@ from openassessment.assessment.api import self as self_api ...@@ -24,6 +24,7 @@ from openassessment.assessment.api import self as self_api
from openassessment.assessment.api import ai as ai_api from openassessment.assessment.api import ai as ai_api
from openassessment.workflow import api as workflow_api from openassessment.workflow import api as workflow_api
from openassessment.assessment.api import staff as staff_api from openassessment.assessment.api import staff as staff_api
from .resolve_dates import get_current_time_zone
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -322,6 +323,7 @@ class StaffAreaMixin(object): ...@@ -322,6 +323,7 @@ class StaffAreaMixin(object):
'submission': create_submission_dict(submission, self.prompts) if submission else None, 'submission': create_submission_dict(submission, self.prompts) if submission else None,
'rubric_criteria': copy.deepcopy(self.rubric_criteria_with_labels), 'rubric_criteria': copy.deepcopy(self.rubric_criteria_with_labels),
'student_username': student_username, 'student_username': student_username,
'time_zone': get_current_time_zone(self.runtime.service(self, 'user')), # localize for staff user
} }
if submission: if submission:
......
...@@ -892,7 +892,8 @@ ...@@ -892,7 +892,8 @@
"cancelled_by": "staff", "cancelled_by": "staff",
"cancelled_at": "2015-10-01T04:53", "cancelled_at": "2015-10-01T04:53",
"comments": "Cancelled!" "comments": "Cancelled!"
} },
"time_zone": "utc"
}, },
"output": "oa_staff_cancelled_submission.html" "output": "oa_staff_cancelled_submission.html"
}, },
......
...@@ -3,7 +3,7 @@ from collections import namedtuple ...@@ -3,7 +3,7 @@ from collections import namedtuple
import json import json
import datetime import datetime
import urllib import urllib
from mock import Mock, patch from mock import MagicMock, Mock, patch
from django.test.utils import override_settings from django.test.utils import override_settings
from openassessment.assessment.api import peer as peer_api from openassessment.assessment.api import peer as peer_api
...@@ -55,6 +55,10 @@ class NullUserService(object): ...@@ -55,6 +55,10 @@ class NullUserService(object):
def get_anonymous_user_id(username, _): def get_anonymous_user_id(username, _):
return username return username
@staticmethod
def get_current_user():
return MagicMock(opt_attrs={})
class TestCourseStaff(XBlockHandlerTestCase): class TestCourseStaff(XBlockHandlerTestCase):
""" """
......
#!/usr/bin/env bash #!/usr/bin/env bash
MAX_PEP8_VIOLATIONS=111 MAX_PEP8_VIOLATIONS=106
mkdir -p test/logs mkdir -p test/logs
PEP8_VIOLATIONS=test/logs/pep8.txt PEP8_VIOLATIONS=test/logs/pep8.txt
......
#!/usr/bin/env bash #!/usr/bin/env bash
MAX_PYLINT_VIOLATIONS=472 MAX_PYLINT_VIOLATIONS=457
mkdir -p test/logs mkdir -p test/logs
PYLINT_VIOLATIONS=test/logs/pylint.txt PYLINT_VIOLATIONS=test/logs/pylint.txt
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment