From 8da550c7e14f4c98ff5b0900bd0b8181e4f744bd Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 15:43:34 -0500 Subject: [PATCH 01/27] display exceptions functionality --- course/templates/course/exception-table.html | 27 +++++++++ course/views.py | 64 ++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 course/templates/course/exception-table.html diff --git a/course/templates/course/exception-table.html b/course/templates/course/exception-table.html new file mode 100644 index 00000000..7df03b80 --- /dev/null +++ b/course/templates/course/exception-table.html @@ -0,0 +1,27 @@ +{% load i18n %} +

{% trans "Existing Exceptions" %}

+{% if permissions %} +

{% trans "Permissions" %}

+ +{% endif %} + +{% if gradings %} + +

{% trans "Gradings" %}

+
+ + + {% for g in gradings %} + + + + + {% endfor %} + +
{{ g.0 }}{{ g.1 }}
+
+{% endif %} diff --git a/course/views.py b/course/views.py index 6f1f14cd..59667fda 100644 --- a/course/views.py +++ b/course/views.py @@ -836,6 +836,62 @@ class ExceptionStage2Form(StyledForm): " »")))) +''' +given the participation and flow_id, find the latest exception record +and build an exception table according to this record +''' +def exception_table(participation, flow_id): + try: + last_exception = FlowRuleException.objects.filter( + participation=participation, + flow_id=flow_id).order_by("creation_time").last() + except FlowRuleException.DoesNotExist: + last_exception = False + + # if the session of the given participation and flow id does not exist, + # do not build the exception table + if not last_exception: + return "" + + last_modify_time = last_exception.creation_time + + # assuming permissions and gradings will be written into database within 1 second of delta time + from datetime import timedelta + curr_exceptions = list(FlowRuleException.objects + .filter( + participation=participation, + flow_id=flow_id, + creation_time__gt=last_modify_time-timedelta(seconds=1))) + + # convert all underscore in exception rulee to space + def tostr(items): + l = list() + for it in items: + l.append(_(it.replace('_', ' '))) + return l + + # find the permission rules and grading rules according to the latest exception record + permissions, gradings = False, False + for excpt in curr_exceptions: + if 'permissions' in excpt.rule: + permissions = tostr(excpt.rule['permissions']) + else: + gradings = excpt.rule.items() + + # fill the exceptions to the exception table template + from django.template import loader, Context, Template + template = loader.get_template('course/exception-table.html') + context = Context({ 'permissions': permissions, 'gradings': gradings }) + rendered = template.render(context) + excpt_table = string_concat( + "
", + "{}", + "
" + ).format(rendered) + + return excpt_table + + @course_view def grant_exception_stage_2(pctx, participation_id, flow_id): # type: (CoursePageContext, Text, Text) -> http.HttpResponse @@ -857,6 +913,14 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): 'participation': participation, 'flow_id': flow_id}) + # {{{ create the exception table and append to form_text + + form_text = string_concat( + form_text, + exception_table(participation, flow_id)) + + # }}} + from course.content import get_flow_desc try: flow_desc = get_flow_desc(pctx.repo, pctx.course, flow_id, -- GitLab From 6c3e9507649483a8f8f688c1ec29c8c9a14bdac4 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 16:20:14 -0500 Subject: [PATCH 02/27] flake8 delete trailing space --- course/views.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/course/views.py b/course/views.py index 59667fda..ef636fb0 100644 --- a/course/views.py +++ b/course/views.py @@ -836,26 +836,28 @@ class ExceptionStage2Form(StyledForm): " »")))) -''' -given the participation and flow_id, find the latest exception record -and build an exception table according to this record -''' + def exception_table(participation, flow_id): + ''' + given the participation and flow_id, find the latest exception record + and build an exception table according to this record + ''' try: - last_exception = FlowRuleException.objects.filter( + last_exception = FlowRuleException.objects.filter( participation=participation, flow_id=flow_id).order_by("creation_time").last() except FlowRuleException.DoesNotExist: last_exception = False # if the session of the given participation and flow id does not exist, - # do not build the exception table + # do not build the exception table if not last_exception: return "" last_modify_time = last_exception.creation_time - # assuming permissions and gradings will be written into database within 1 second of delta time + # assuming permissions and gradings will be written into database + # within 1 second of delta time from datetime import timedelta curr_exceptions = list(FlowRuleException.objects .filter( @@ -870,7 +872,8 @@ def exception_table(participation, flow_id): l.append(_(it.replace('_', ' '))) return l - # find the permission rules and grading rules according to the latest exception record + # find the permission rules and grading rules according to + # the time of the latest exception record permissions, gradings = False, False for excpt in curr_exceptions: if 'permissions' in excpt.rule: @@ -879,9 +882,9 @@ def exception_table(participation, flow_id): gradings = excpt.rule.items() # fill the exceptions to the exception table template - from django.template import loader, Context, Template + from django.template import loader, Context template = loader.get_template('course/exception-table.html') - context = Context({ 'permissions': permissions, 'gradings': gradings }) + context = Context({'permissions': permissions, 'gradings': gradings}) rendered = template.render(context) excpt_table = string_concat( "
", @@ -913,8 +916,8 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): 'participation': participation, 'flow_id': flow_id}) - # {{{ create the exception table and append to form_text - + # {{{ create the exception table and append to form_text + form_text = string_concat( form_text, exception_table(participation, flow_id)) -- GitLab From dcf231ee8557bbb90ccdc94c21b7ac3cf29695d2 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 16:27:44 -0500 Subject: [PATCH 03/27] flake8 issues delete trailing space --- course/views.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/course/views.py b/course/views.py index ef636fb0..2bd4a1e2 100644 --- a/course/views.py +++ b/course/views.py @@ -836,7 +836,6 @@ class ExceptionStage2Form(StyledForm): " »")))) - def exception_table(participation, flow_id): ''' given the participation and flow_id, find the latest exception record @@ -847,7 +846,7 @@ def exception_table(participation, flow_id): participation=participation, flow_id=flow_id).order_by("creation_time").last() except FlowRuleException.DoesNotExist: - last_exception = False + last_exception = None # if the session of the given participation and flow id does not exist, # do not build the exception table @@ -872,9 +871,9 @@ def exception_table(participation, flow_id): l.append(_(it.replace('_', ' '))) return l - # find the permission rules and grading rules according to + # find the permission rules and grading rules according to # the time of the latest exception record - permissions, gradings = False, False + permissions, gradings = None, None for excpt in curr_exceptions: if 'permissions' in excpt.rule: permissions = tostr(excpt.rule['permissions']) -- GitLab From 115596585ce583f0e6469347eb27936832f3236c Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 16:34:21 -0500 Subject: [PATCH 04/27] flake8 delete extra lines --- course/views.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/course/views.py b/course/views.py index 2bd4a1e2..7faa69ca 100644 --- a/course/views.py +++ b/course/views.py @@ -836,11 +836,9 @@ class ExceptionStage2Form(StyledForm): " »")))) -def exception_table(participation, flow_id): - ''' - given the participation and flow_id, find the latest exception record - and build an exception table according to this record - ''' +def exception_table(participation, flow_id): + # given the participation and flow_id, find the latest exception record + # and build an exception table according to this record try: last_exception = FlowRuleException.objects.filter( participation=participation, @@ -850,7 +848,7 @@ def exception_table(participation, flow_id): # if the session of the given participation and flow id does not exist, # do not build the exception table - if not last_exception: + if last_exception is None: return "" last_modify_time = last_exception.creation_time @@ -916,11 +914,8 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): 'flow_id': flow_id}) # {{{ create the exception table and append to form_text - - form_text = string_concat( - form_text, - exception_table(participation, flow_id)) - + excpt_table_str = exception_table(participation, flow_id) + form_text = string_concat(form_text, excpt_table_str) # }}} from course.content import get_flow_desc -- GitLab From 61538efdf82df608619d35b6a718c4bba56017fa Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 17:34:33 -0500 Subject: [PATCH 05/27] mypy checking --- course/templates/course/exception-table.html | 2 +- course/views.py | 111 +++++++++---------- 2 files changed, 55 insertions(+), 58 deletions(-) diff --git a/course/templates/course/exception-table.html b/course/templates/course/exception-table.html index 7df03b80..d657aaf0 100644 --- a/course/templates/course/exception-table.html +++ b/course/templates/course/exception-table.html @@ -1,4 +1,5 @@ {% load i18n %} +

{% trans "Existing Exceptions" %}

{% if permissions %}

{% trans "Permissions" %}

@@ -10,7 +11,6 @@ {% endif %} {% if gradings %} -

{% trans "Gradings" %}

diff --git a/course/views.py b/course/views.py index 7faa69ca..fa62bd57 100644 --- a/course/views.py +++ b/course/views.py @@ -836,62 +836,6 @@ class ExceptionStage2Form(StyledForm): " »")))) -def exception_table(participation, flow_id): - # given the participation and flow_id, find the latest exception record - # and build an exception table according to this record - try: - last_exception = FlowRuleException.objects.filter( - participation=participation, - flow_id=flow_id).order_by("creation_time").last() - except FlowRuleException.DoesNotExist: - last_exception = None - - # if the session of the given participation and flow id does not exist, - # do not build the exception table - if last_exception is None: - return "" - - last_modify_time = last_exception.creation_time - - # assuming permissions and gradings will be written into database - # within 1 second of delta time - from datetime import timedelta - curr_exceptions = list(FlowRuleException.objects - .filter( - participation=participation, - flow_id=flow_id, - creation_time__gt=last_modify_time-timedelta(seconds=1))) - - # convert all underscore in exception rulee to space - def tostr(items): - l = list() - for it in items: - l.append(_(it.replace('_', ' '))) - return l - - # find the permission rules and grading rules according to - # the time of the latest exception record - permissions, gradings = None, None - for excpt in curr_exceptions: - if 'permissions' in excpt.rule: - permissions = tostr(excpt.rule['permissions']) - else: - gradings = excpt.rule.items() - - # fill the exceptions to the exception table template - from django.template import loader, Context - template = loader.get_template('course/exception-table.html') - context = Context({'permissions': permissions, 'gradings': gradings}) - rendered = template.render(context) - excpt_table = string_concat( - "
", - "{}", - "
" - ).format(rendered) - - return excpt_table - - @course_view def grant_exception_stage_2(pctx, participation_id, flow_id): # type: (CoursePageContext, Text, Text) -> http.HttpResponse @@ -914,7 +858,60 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): 'flow_id': flow_id}) # {{{ create the exception table and append to form_text - excpt_table_str = exception_table(participation, flow_id) + def create_exception_table(): + # given the participation and flow_id, find the latest exception record + # and build an exception table according to this record + + last_exception = FlowRuleException.objects.filter( + participation=participation, + flow_id=flow_id).order_by("creation_time").last() + + # if the session of the given participation and flow id does not exist, + # do not build the exception table + if last_exception is None: + return "" + + last_modify_time = last_exception.creation_time + + # assuming permissions and gradings will be written into database + # within 1 second of delta time + from datetime import timedelta + curr_exceptions = list(FlowRuleException.objects + .filter( + participation=participation, + flow_id=flow_id, + creation_time__gt=last_modify_time-timedelta(seconds=1))) + + # convert all underscore in exception rulee to space + def replace_underscore(items): + l = list() + for it in items: + l.append(_(it.replace('_', ' '))) + return l + + # find the permission rules and grading rules according to + # the time of the latest exception record + permissions, gradings = [], [] + for excpt in curr_exceptions: + if 'permissions' in excpt.rule: + permissions = replace_underscore(excpt.rule['permissions']) + else: + gradings = excpt.rule.items() + + # fill the exceptions to the exception table template + from django.template import loader, Context + template = loader.get_template('course/exception-table.html') + context = Context({'permissions': permissions, 'gradings': gradings}) + rendered = template.render(context) + excpt_table = string_concat( + "
", + "{}", + "
" + ).format(rendered) + + return excpt_table + + excpt_table_str = create_exception_table() form_text = string_concat(form_text, excpt_table_str) # }}} -- GitLab From 2bcaba40cc5dfb0b0da22e2d56170b2289f4f33d Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 17:39:46 -0500 Subject: [PATCH 06/27] add type annoation --- course/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/course/views.py b/course/views.py index fa62bd57..3ad32dce 100644 --- a/course/views.py +++ b/course/views.py @@ -858,7 +858,7 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): 'flow_id': flow_id}) # {{{ create the exception table and append to form_text - def create_exception_table(): + def create_exception_table() -> str: # given the participation and flow_id, find the latest exception record # and build an exception table according to this record -- GitLab From 35736d839170362f91055f6243f93a379e707419 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 17:53:18 -0500 Subject: [PATCH 07/27] try to resolve mypy check --- course/views.py | 99 +++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/course/views.py b/course/views.py index 3ad32dce..19b9411c 100644 --- a/course/views.py +++ b/course/views.py @@ -858,58 +858,59 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): 'flow_id': flow_id}) # {{{ create the exception table and append to form_text - def create_exception_table() -> str: + def create_exception_table(): # given the participation and flow_id, find the latest exception record # and build an exception table according to this record - last_exception = FlowRuleException.objects.filter( - participation=participation, - flow_id=flow_id).order_by("creation_time").last() - - # if the session of the given participation and flow id does not exist, - # do not build the exception table - if last_exception is None: - return "" - - last_modify_time = last_exception.creation_time - - # assuming permissions and gradings will be written into database - # within 1 second of delta time - from datetime import timedelta - curr_exceptions = list(FlowRuleException.objects - .filter( - participation=participation, - flow_id=flow_id, - creation_time__gt=last_modify_time-timedelta(seconds=1))) - - # convert all underscore in exception rulee to space - def replace_underscore(items): - l = list() - for it in items: - l.append(_(it.replace('_', ' '))) - return l - - # find the permission rules and grading rules according to - # the time of the latest exception record - permissions, gradings = [], [] - for excpt in curr_exceptions: - if 'permissions' in excpt.rule: - permissions = replace_underscore(excpt.rule['permissions']) - else: - gradings = excpt.rule.items() - - # fill the exceptions to the exception table template - from django.template import loader, Context - template = loader.get_template('course/exception-table.html') - context = Context({'permissions': permissions, 'gradings': gradings}) - rendered = template.render(context) - excpt_table = string_concat( - "
", - "{}", - "
" - ).format(rendered) - - return excpt_table + # last_exception = FlowRuleException.objects.filter( + # participation=participation, + # flow_id=flow_id).order_by("creation_time").last() + + # # if the session of the given participation and flow id does not exist, + # # do not build the exception table + # if last_exception is None: + # return "" + + # last_modify_time = last_exception.creation_time + + # # assuming permissions and gradings will be written into database + # # within 1 second of delta time + # from datetime import timedelta + # curr_exceptions = list(FlowRuleException.objects + # .filter( + # participation=participation, + # flow_id=flow_id, + # creation_time__gt=last_modify_time-timedelta(seconds=1))) + + # # convert all underscore in exception rulee to space + # def replace_underscore(items): + # l = list() + # for it in items: + # l.append(_(it.replace('_', ' '))) + # return l + + # # find the permission rules and grading rules according to + # # the time of the latest exception record + # permissions, gradings = [], [] + # for excpt in curr_exceptions: + # if 'permissions' in excpt.rule: + # permissions = replace_underscore(excpt.rule['permissions']) + # else: + # gradings = excpt.rule.items() + + # # fill the exceptions to the exception table template + # from django.template import loader, Context + # template = loader.get_template('course/exception-table.html') + # context = Context({'permissions': permissions, 'gradings': gradings}) + # rendered = template.render(context) + # excpt_table = string_concat( + # "
", + # "{}", + # "
" + # ).format(rendered) + + # return excpt_table + return "" excpt_table_str = create_exception_table() form_text = string_concat(form_text, excpt_table_str) -- GitLab From 8872fd7f1e90f66f32bb412d2f9e52fbf7a957f7 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 18:03:26 -0500 Subject: [PATCH 08/27] add type annotations --- course/views.py | 100 ++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/course/views.py b/course/views.py index 19b9411c..bc91ab06 100644 --- a/course/views.py +++ b/course/views.py @@ -859,58 +859,60 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): # {{{ create the exception table and append to form_text def create_exception_table(): + # type: () -> str + # given the participation and flow_id, find the latest exception record # and build an exception table according to this record - # last_exception = FlowRuleException.objects.filter( - # participation=participation, - # flow_id=flow_id).order_by("creation_time").last() - - # # if the session of the given participation and flow id does not exist, - # # do not build the exception table - # if last_exception is None: - # return "" - - # last_modify_time = last_exception.creation_time - - # # assuming permissions and gradings will be written into database - # # within 1 second of delta time - # from datetime import timedelta - # curr_exceptions = list(FlowRuleException.objects - # .filter( - # participation=participation, - # flow_id=flow_id, - # creation_time__gt=last_modify_time-timedelta(seconds=1))) - - # # convert all underscore in exception rulee to space - # def replace_underscore(items): - # l = list() - # for it in items: - # l.append(_(it.replace('_', ' '))) - # return l - - # # find the permission rules and grading rules according to - # # the time of the latest exception record - # permissions, gradings = [], [] - # for excpt in curr_exceptions: - # if 'permissions' in excpt.rule: - # permissions = replace_underscore(excpt.rule['permissions']) - # else: - # gradings = excpt.rule.items() - - # # fill the exceptions to the exception table template - # from django.template import loader, Context - # template = loader.get_template('course/exception-table.html') - # context = Context({'permissions': permissions, 'gradings': gradings}) - # rendered = template.render(context) - # excpt_table = string_concat( - # "
", - # "{}", - # "
" - # ).format(rendered) - - # return excpt_table - return "" + last_exception = FlowRuleException.objects.filter( + participation=participation, + flow_id=flow_id).order_by("creation_time").last() + + # if the session of the given participation and flow id does not exist, + # do not build the exception table + if last_exception is None: + return "" + + last_modify_time = last_exception.creation_time + + # assuming permissions and gradings will be written into database + # within 1 second of delta time + from datetime import timedelta + curr_exceptions = list(FlowRuleException.objects + .filter( + participation=participation, + flow_id=flow_id, + creation_time__gt=last_modify_time-timedelta(seconds=1))) + + # convert all underscore in exception rulee to space + def replace_underscore(items): + # type: ([str]) -> [str] + l = list() + for it in items: + l.append(_(it.replace('_', ' '))) + return l + + # find the permission rules and grading rules according to + # the time of the latest exception record + permissions, gradings = [], [] + for excpt in curr_exceptions: + if 'permissions' in excpt.rule: + permissions = replace_underscore(excpt.rule['permissions']) + else: + gradings = excpt.rule.items() + + # fill the exceptions to the exception table template + from django.template import loader, Context + template = loader.get_template('course/exception-table.html') + context = Context({'permissions': permissions, 'gradings': gradings}) + rendered = template.render(context) + excpt_table = string_concat( + "
", + "{}", + "
" + ).format(rendered) + + return excpt_table excpt_table_str = create_exception_table() form_text = string_concat(form_text, excpt_table_str) -- GitLab From bc68b525903a5ab914274adcdca7a19991e379b5 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 18:13:33 -0500 Subject: [PATCH 09/27] format function annotations --- course/views.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/course/views.py b/course/views.py index bc91ab06..01a32e50 100644 --- a/course/views.py +++ b/course/views.py @@ -861,9 +861,6 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): def create_exception_table(): # type: () -> str - # given the participation and flow_id, find the latest exception record - # and build an exception table according to this record - last_exception = FlowRuleException.objects.filter( participation=participation, flow_id=flow_id).order_by("creation_time").last() @@ -886,7 +883,8 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): # convert all underscore in exception rulee to space def replace_underscore(items): - # type: ([str]) -> [str] + # type: (List[str]) -> List[str] + l = list() for it in items: l.append(_(it.replace('_', ' '))) -- GitLab From cd64b1cd9bcdfcc5cee0ec1c6a60dce018cc5de2 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 18:25:07 -0500 Subject: [PATCH 10/27] annotations for variables --- course/views.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/course/views.py b/course/views.py index 01a32e50..a0d73d72 100644 --- a/course/views.py +++ b/course/views.py @@ -884,15 +884,16 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): # convert all underscore in exception rulee to space def replace_underscore(items): # type: (List[str]) -> List[str] - - l = list() + + l = list() # type: List[str] for it in items: - l.append(_(it.replace('_', ' '))) + l.append(str(_(it.replace('_', ' ')))) + return l # find the permission rules and grading rules according to # the time of the latest exception record - permissions, gradings = [], [] + permissions, gradings = None, None for excpt in curr_exceptions: if 'permissions' in excpt.rule: permissions = replace_underscore(excpt.rule['permissions']) -- GitLab From 3d3440dfbe507a89492f6766dd81ea373b1a833e Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 18:38:38 -0500 Subject: [PATCH 11/27] add annotations for variables --- course/views.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/course/views.py b/course/views.py index a0d73d72..daf7b11f 100644 --- a/course/views.py +++ b/course/views.py @@ -879,15 +879,16 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): .filter( participation=participation, flow_id=flow_id, - creation_time__gt=last_modify_time-timedelta(seconds=1))) + creation_time__gt=last_modify_time-timedelta(seconds=1))) # type: List[FlowRuleException] + print(type(curr_exceptions[0])) # convert all underscore in exception rulee to space def replace_underscore(items): # type: (List[str]) -> List[str] - l = list() # type: List[str] - for it in items: - l.append(str(_(it.replace('_', ' ')))) + l = items.copy() # type: List[str] + for i in range(len(items)): + l[i] = str(_(items[i].replace('_', ' '))) return l -- GitLab From cd8ddec6fa616fee0ff8bb6293d74be41992ff40 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 18:44:30 -0500 Subject: [PATCH 12/27] add annotations for variables --- course/views.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/course/views.py b/course/views.py index daf7b11f..0e1250db 100644 --- a/course/views.py +++ b/course/views.py @@ -886,7 +886,8 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): def replace_underscore(items): # type: (List[str]) -> List[str] - l = items.copy() # type: List[str] + l = items.copy() + print(type(l[0])) for i in range(len(items)): l[i] = str(_(items[i].replace('_', ' '))) @@ -894,7 +895,8 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): # find the permission rules and grading rules according to # the time of the latest exception record - permissions, gradings = None, None + permissions = None # type: List[str] + gradings = None # type: List[Tuple[str, str]] for excpt in curr_exceptions: if 'permissions' in excpt.rule: permissions = replace_underscore(excpt.rule['permissions']) -- GitLab From 5da8840fb4e78c13c540af6f1869fc0062cb1d46 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 18:49:51 -0500 Subject: [PATCH 13/27] add annotations for variables --- course/views.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/course/views.py b/course/views.py index 0e1250db..7a8014a3 100644 --- a/course/views.py +++ b/course/views.py @@ -895,13 +895,13 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): # find the permission rules and grading rules according to # the time of the latest exception record - permissions = None # type: List[str] - gradings = None # type: List[Tuple[str, str]] + permissions = None + gradings = None for excpt in curr_exceptions: if 'permissions' in excpt.rule: - permissions = replace_underscore(excpt.rule['permissions']) + permissions = replace_underscore(excpt.rule['permissions']) # type: List[str] else: - gradings = excpt.rule.items() + gradings = excpt.rule.items() # type: List[Tuple[str, str]] # fill the exceptions to the exception table template from django.template import loader, Context -- GitLab From 5d01bdf2da8d335af1c6b79796d3b630d7cc073c Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 18:54:40 -0500 Subject: [PATCH 14/27] add annotations for variables --- course/views.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/course/views.py b/course/views.py index 7a8014a3..12ee0c59 100644 --- a/course/views.py +++ b/course/views.py @@ -879,15 +879,13 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): .filter( participation=participation, flow_id=flow_id, - creation_time__gt=last_modify_time-timedelta(seconds=1))) # type: List[FlowRuleException] - print(type(curr_exceptions[0])) + creation_time__gt=last_modify_time-timedelta(seconds=1))) # type: List[FlowRuleException] # convert all underscore in exception rulee to space def replace_underscore(items): # type: (List[str]) -> List[str] - l = items.copy() - print(type(l[0])) + l = items.copy() # type: List[str] for i in range(len(items)): l[i] = str(_(items[i].replace('_', ' '))) @@ -895,13 +893,12 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): # find the permission rules and grading rules according to # the time of the latest exception record - permissions = None - gradings = None + permissions, gradings = None, None for excpt in curr_exceptions: if 'permissions' in excpt.rule: permissions = replace_underscore(excpt.rule['permissions']) # type: List[str] else: - gradings = excpt.rule.items() # type: List[Tuple[str, str]] + gradings = excpt.rule.items() # type: List[Tuple[str, str]] # fill the exceptions to the exception table template from django.template import loader, Context -- GitLab From a7363dcb867eb3898efb329130c0e25e423f991e Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 18:58:59 -0500 Subject: [PATCH 15/27] add annotations for variables --- course/views.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/course/views.py b/course/views.py index 12ee0c59..8a78f1e9 100644 --- a/course/views.py +++ b/course/views.py @@ -879,7 +879,8 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): .filter( participation=participation, flow_id=flow_id, - creation_time__gt=last_modify_time-timedelta(seconds=1))) # type: List[FlowRuleException] + creation_time__gt=last_modify_time-timedelta(seconds=1))) + # type: List[FlowRuleException] # convert all underscore in exception rulee to space def replace_underscore(items): @@ -896,9 +897,9 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): permissions, gradings = None, None for excpt in curr_exceptions: if 'permissions' in excpt.rule: - permissions = replace_underscore(excpt.rule['permissions']) # type: List[str] + permissions = replace_underscore(excpt.rule['permissions']) else: - gradings = excpt.rule.items() # type: List[Tuple[str, str]] + gradings = excpt.rule.items() # fill the exceptions to the exception table template from django.template import loader, Context -- GitLab From 902fff436c78818f25742d9adddc01fc3ab11ac3 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 19:04:24 -0500 Subject: [PATCH 16/27] format code --- course/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/course/views.py b/course/views.py index 8a78f1e9..579f424c 100644 --- a/course/views.py +++ b/course/views.py @@ -879,8 +879,9 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): .filter( participation=participation, flow_id=flow_id, - creation_time__gt=last_modify_time-timedelta(seconds=1))) - # type: List[FlowRuleException] + creation_time__gt=last_modify_time-timedelta(seconds=1) + )) # type: List[FlowRuleException] + # convert all underscore in exception rulee to space def replace_underscore(items): -- GitLab From d520b7b824bc737d1fa56cd1067fbe70dabbacc6 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Tue, 30 May 2017 19:07:34 -0500 Subject: [PATCH 17/27] delete blank lines --- course/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/course/views.py b/course/views.py index 579f424c..5f6abd4e 100644 --- a/course/views.py +++ b/course/views.py @@ -881,7 +881,6 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): flow_id=flow_id, creation_time__gt=last_modify_time-timedelta(seconds=1) )) # type: List[FlowRuleException] - # convert all underscore in exception rulee to space def replace_underscore(items): -- GitLab From a7be4f86ed65e0a075f12ae52f57746c0b2e7d2d Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Mon, 19 Jun 2017 03:44:15 -0500 Subject: [PATCH 18/27] add title attr to grant exception button --- course/grades.py | 104 +++++++++++++++++- course/templates/course/exception-table.html | 27 ----- course/templates/course/gradebook-single.html | 4 +- course/views.py | 61 ---------- 4 files changed, 102 insertions(+), 94 deletions(-) delete mode 100644 course/templates/course/exception-table.html diff --git a/course/grades.py b/course/grades.py index 012a474c..d8d2face 100644 --- a/course/grades.py +++ b/course/grades.py @@ -792,10 +792,84 @@ def average_grade(opportunity): return None, 0 +def parse(new_key, new_val=""): + # type: (Any, Any) -> str + return str(_(str(new_key))) + str(_(str(new_val))) + "\n" + + +def parse_access_rule(access_rule): + # type: (FlowSessionAccessRule) -> str + + access_rule_str = "ACCESS RULE" + "\n" + + print(type(access_rule.permissions)) + if 'view' in access_rule.permissions: + access_rule_str += parse("View the flow") + + if 'submit_answer' in access_rule.permissions: + access_rule_str += parse("Submit answers") + + if 'end_session' in access_rule.permissions: + access_rule_str += parse("End session") + + if 'change_answer' in access_rule.permissions: + access_rule_str += parse("Change already-graded answer") + + if 'see_correctness' in access_rule.permissions: + access_rule_str += parse("See whether an answer is correct") + + if 'see_answer_before_submission' in access_rule.permissions: + access_rule_str += parse("See the correct answer before answering") + + if 'see_answer_after_submission' in access_rule.permissions: + access_rule_str += parse("See the correct answer after answering") + + if 'cannot_see_flow_result' in access_rule.permissions: + access_rule_str += parse("Cannot see flow result") + + if 'set_roll_over_expiration_mode' in access_rule.permissions: + access_rule_str += parse("Set the session to 'roll over' expiration mode") + + if 'see_session_time' in access_rule.permissions: + access_rule_str += parse("See session time") + + if 'lock_down_as_exam_session' in access_rule.permissions: + access_rule_str += parse("Lock down as exam session") + + if 'send_email_about_flow_page' in access_rule.permissions: + access_rule_str += parse("Send emails about the flow page to course staff") + + return access_rule_str + "\n" + + +def parse_grading_rule(grading_rule): + # type: (FlowSessionGradingRule) -> str + + grading_rule_str = "GRADING RULE" + "\n" + + if grading_rule.generates_grade: + grading_rule_str += parse("Generates grade: ", True) + + if grading_rule.credit_percent is not None: + grading_rule_str += parse("Credit percent: ", grading_rule.credit_percent) + + if grading_rule.bonus_points is not None: + grading_rule_str += parse("Bonus points: ", grading_rule.bonus_points) + + if grading_rule.max_points is not None: + grading_rule_str += parse("Max points: ", grading_rule.max_points) + + if grading_rule.max_points_enforced_cap is not None: + grading_rule_str += parse("Max points enforced cap: ", grading_rule.max_points_enforced_cap) + + return grading_rule_str + + @course_view def view_single_grade(pctx, participation_id, opportunity_id): # type: (CoursePageContext, Text, Text) -> http.HttpResponse + print("single grade") now_datetime = get_now_or_fake_time(pctx.request) participation = get_object_or_404(Participation, @@ -804,8 +878,12 @@ def view_single_grade(pctx, participation_id, opportunity_id): if participation.course != pctx.course: raise SuspiciousOperation(_("participation does not match course")) + + opportunity = get_object_or_404(GradingOpportunity, id=int(opportunity_id)) + print("opportunity", opportunity, opportunity_id) + my_grade = participation == pctx.participation is_privileged_view = pctx.has_permission(pperm.view_gradebook) @@ -831,8 +909,14 @@ def view_single_grade(pctx, participation_id, opportunity_id): # {{{ modify sessions buttons + + print("request type", pctx.request.method) + request = pctx.request if pctx.request.method == "POST": + + print("post request") + action_re = re.compile("^([a-z]+)_([0-9]+)$") for key in request.POST.keys(): action_match = action_re.match(key) @@ -932,9 +1016,9 @@ def view_single_grade(pctx, participation_id, opportunity_id): from collections import namedtuple SessionProperties = namedtuple( # noqa "SessionProperties", - ["due", "grade_description"]) + ["due", "grade_description", "grading_rule", "access_rule"]) - from course.utils import get_session_grading_rule + from course.utils import get_session_grading_rule, get_session_access_rule from course.content import get_flow_desc try: @@ -949,15 +1033,27 @@ def view_single_grade(pctx, participation_id, opportunity_id): pctx.repo, session, pctx.course.identifier, flow_desc, respect_preview=False) + access_rule = get_session_access_rule( + session, flow_desc, now_datetime) grading_rule = get_session_grading_rule( session, flow_desc, now_datetime) + access_rule_str = parse_access_rule(access_rule) + grading_rule_str = parse_grading_rule(grading_rule) session_properties = SessionProperties( due=grading_rule.due, - grade_description=grading_rule.description) + grade_description=grading_rule.description, + grading_rule=grading_rule_str, + access_rule=access_rule_str) + flow_sessions_and_session_properties.append( (session, session_properties)) + + + + + else: flow_sessions_and_session_properties = None @@ -995,7 +1091,7 @@ def view_single_grade(pctx, participation_id, opportunity_id): pperm.impose_flow_session_deadline or pperm.end_flow_session or pperm.regrade_flow_session - or pperm.recalculate_flow_session_grade), + or pperm.recalculate_flow_session_grade) }) # }}} diff --git a/course/templates/course/exception-table.html b/course/templates/course/exception-table.html deleted file mode 100644 index d657aaf0..00000000 --- a/course/templates/course/exception-table.html +++ /dev/null @@ -1,27 +0,0 @@ -{% load i18n %} - -

{% trans "Existing Exceptions" %}

-{% if permissions %} -

{% trans "Permissions" %}

-
    - {% for p in permissions %} -
  • {{ p }}
  • - {% endfor %} -
-{% endif %} - -{% if gradings %} -

{% trans "Gradings" %}

-
-
- - {% for g in gradings %} - - - - - {% endfor %} - -
{{ g.0 }}{{ g.1 }}
-
-{% endif %} diff --git a/course/templates/course/gradebook-single.html b/course/templates/course/gradebook-single.html index 757010c3..805dabbe 100644 --- a/course/templates/course/gradebook-single.html +++ b/course/templates/course/gradebook-single.html @@ -307,7 +307,8 @@ {% endif %} {% endif %} {% if pperm.grant_exception %} - {% trans "Grant exception" %} @@ -330,7 +331,6 @@
{% endif %} {# }}} #} - {% endblock %} {# vim: set foldmethod=marker: #} diff --git a/course/views.py b/course/views.py index 5f6abd4e..6f1f14cd 100644 --- a/course/views.py +++ b/course/views.py @@ -857,67 +857,6 @@ def grant_exception_stage_2(pctx, participation_id, flow_id): 'participation': participation, 'flow_id': flow_id}) - # {{{ create the exception table and append to form_text - def create_exception_table(): - # type: () -> str - - last_exception = FlowRuleException.objects.filter( - participation=participation, - flow_id=flow_id).order_by("creation_time").last() - - # if the session of the given participation and flow id does not exist, - # do not build the exception table - if last_exception is None: - return "" - - last_modify_time = last_exception.creation_time - - # assuming permissions and gradings will be written into database - # within 1 second of delta time - from datetime import timedelta - curr_exceptions = list(FlowRuleException.objects - .filter( - participation=participation, - flow_id=flow_id, - creation_time__gt=last_modify_time-timedelta(seconds=1) - )) # type: List[FlowRuleException] - - # convert all underscore in exception rulee to space - def replace_underscore(items): - # type: (List[str]) -> List[str] - - l = items.copy() # type: List[str] - for i in range(len(items)): - l[i] = str(_(items[i].replace('_', ' '))) - - return l - - # find the permission rules and grading rules according to - # the time of the latest exception record - permissions, gradings = None, None - for excpt in curr_exceptions: - if 'permissions' in excpt.rule: - permissions = replace_underscore(excpt.rule['permissions']) - else: - gradings = excpt.rule.items() - - # fill the exceptions to the exception table template - from django.template import loader, Context - template = loader.get_template('course/exception-table.html') - context = Context({'permissions': permissions, 'gradings': gradings}) - rendered = template.render(context) - excpt_table = string_concat( - "
", - "{}", - "
" - ).format(rendered) - - return excpt_table - - excpt_table_str = create_exception_table() - form_text = string_concat(form_text, excpt_table_str) - # }}} - from course.content import get_flow_desc try: flow_desc = get_flow_desc(pctx.repo, pctx.course, flow_id, -- GitLab From 825602006adf27270a2d570ecd52be8c7c4f59ea Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Mon, 19 Jun 2017 03:59:49 -0500 Subject: [PATCH 19/27] delete redundent lines import class for mypy --- course/grades.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/course/grades.py b/course/grades.py index d8d2face..be706ef5 100644 --- a/course/grades.py +++ b/course/grades.py @@ -64,6 +64,7 @@ from course.constants import ( if False: from typing import Tuple, Text, Optional, Any, Iterable, List # noqa from course.utils import CoursePageContext # noqa + from course.utils import FlowSessionAccessRule, FlowSessionGradingRule # noqa from course.content import FlowDesc # noqa from course.models import Course, FlowPageVisitGrade # noqa @@ -846,10 +847,10 @@ def parse_grading_rule(grading_rule): # type: (FlowSessionGradingRule) -> str grading_rule_str = "GRADING RULE" + "\n" - + if grading_rule.generates_grade: grading_rule_str += parse("Generates grade: ", True) - + if grading_rule.credit_percent is not None: grading_rule_str += parse("Credit percent: ", grading_rule.credit_percent) @@ -860,7 +861,8 @@ def parse_grading_rule(grading_rule): grading_rule_str += parse("Max points: ", grading_rule.max_points) if grading_rule.max_points_enforced_cap is not None: - grading_rule_str += parse("Max points enforced cap: ", grading_rule.max_points_enforced_cap) + grading_rule_str += parse("Max points enforced cap: ", + grading_rule.max_points_enforced_cap) return grading_rule_str @@ -878,8 +880,6 @@ def view_single_grade(pctx, participation_id, opportunity_id): if participation.course != pctx.course: raise SuspiciousOperation(_("participation does not match course")) - - opportunity = get_object_or_404(GradingOpportunity, id=int(opportunity_id)) print("opportunity", opportunity, opportunity_id) @@ -909,7 +909,6 @@ def view_single_grade(pctx, participation_id, opportunity_id): # {{{ modify sessions buttons - print("request type", pctx.request.method) request = pctx.request @@ -1049,11 +1048,6 @@ def view_single_grade(pctx, participation_id, opportunity_id): flow_sessions_and_session_properties.append( (session, session_properties)) - - - - - else: flow_sessions_and_session_properties = None -- GitLab From 5ed0c5cdc8792afd4d61adc2aa5c1ff9081cba37 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Sun, 25 Jun 2017 00:15:07 -0500 Subject: [PATCH 20/27] display exception info --- course/grades.py | 144 +++++++----------- course/templates/course/gradebook-single.html | 19 ++- 2 files changed, 76 insertions(+), 87 deletions(-) diff --git a/course/grades.py b/course/grades.py index be706ef5..e0424f3b 100644 --- a/course/grades.py +++ b/course/grades.py @@ -793,85 +793,43 @@ def average_grade(opportunity): return None, 0 -def parse(new_key, new_val=""): - # type: (Any, Any) -> str - return str(_(str(new_key))) + str(_(str(new_val))) + "\n" - - -def parse_access_rule(access_rule): - # type: (FlowSessionAccessRule) -> str - - access_rule_str = "ACCESS RULE" + "\n" - - print(type(access_rule.permissions)) - if 'view' in access_rule.permissions: - access_rule_str += parse("View the flow") - - if 'submit_answer' in access_rule.permissions: - access_rule_str += parse("Submit answers") - - if 'end_session' in access_rule.permissions: - access_rule_str += parse("End session") - - if 'change_answer' in access_rule.permissions: - access_rule_str += parse("Change already-graded answer") - - if 'see_correctness' in access_rule.permissions: - access_rule_str += parse("See whether an answer is correct") - - if 'see_answer_before_submission' in access_rule.permissions: - access_rule_str += parse("See the correct answer before answering") - - if 'see_answer_after_submission' in access_rule.permissions: - access_rule_str += parse("See the correct answer after answering") - - if 'cannot_see_flow_result' in access_rule.permissions: - access_rule_str += parse("Cannot see flow result") - - if 'set_roll_over_expiration_mode' in access_rule.permissions: - access_rule_str += parse("Set the session to 'roll over' expiration mode") - - if 'see_session_time' in access_rule.permissions: - access_rule_str += parse("See session time") - - if 'lock_down_as_exam_session' in access_rule.permissions: - access_rule_str += parse("Lock down as exam session") - - if 'send_email_about_flow_page' in access_rule.permissions: - access_rule_str += parse("Send emails about the flow page to course staff") - - return access_rule_str + "\n" - - -def parse_grading_rule(grading_rule): - # type: (FlowSessionGradingRule) -> str - - grading_rule_str = "GRADING RULE" + "\n" - - if grading_rule.generates_grade: - grading_rule_str += parse("Generates grade: ", True) - - if grading_rule.credit_percent is not None: - grading_rule_str += parse("Credit percent: ", grading_rule.credit_percent) - - if grading_rule.bonus_points is not None: - grading_rule_str += parse("Bonus points: ", grading_rule.bonus_points) - - if grading_rule.max_points is not None: - grading_rule_str += parse("Max points: ", grading_rule.max_points) - - if grading_rule.max_points_enforced_cap is not None: - grading_rule_str += parse("Max points enforced cap: ", - grading_rule.max_points_enforced_cap) +def parse_exception(last_access_exc, last_grading_exc): + # type: (FlowRuleException, FlowRuleException) -> FlowRuleException, str + + if last_grading_exc: + def has_grading_exc(rule): + if 'bonus_points' in rule and rule['bonus_points'] != 0.0: + return True + elif 'credit_percent' in rule and rule['credit_percent'] != 100.0: + return True + elif 'max_points' in rule or 'max_points_enforced_cap' in rule: + return True + else: + return False + if not has_grading_exc(last_grading_exc.rule): + last_grading_exc = None + + if last_access_exc and last_grading_exc: + last_exception = (last_access_exc # noqa + if last_access_exc.creation_time > last_grading_exc.creation_time # noqa + else last_grading_exc) + kind = str(_("access and grading")) + elif last_access_exc or last_grading_exc: + last_exception = (last_access_exc + if last_access_exc is not None + else last_grading_exc) + kind = str(_(str(last_exception.kind))) + else: + last_exception = None + kind = None - return grading_rule_str + return last_exception, kind @course_view def view_single_grade(pctx, participation_id, opportunity_id): # type: (CoursePageContext, Text, Text) -> http.HttpResponse - print("single grade") now_datetime = get_now_or_fake_time(pctx.request) participation = get_object_or_404(Participation, @@ -882,8 +840,6 @@ def view_single_grade(pctx, participation_id, opportunity_id): opportunity = get_object_or_404(GradingOpportunity, id=int(opportunity_id)) - print("opportunity", opportunity, opportunity_id) - my_grade = participation == pctx.participation is_privileged_view = pctx.has_permission(pperm.view_gradebook) @@ -909,13 +865,9 @@ def view_single_grade(pctx, participation_id, opportunity_id): # {{{ modify sessions buttons - print("request type", pctx.request.method) - request = pctx.request if pctx.request.method == "POST": - print("post request") - action_re = re.compile("^([a-z]+)_([0-9]+)$") for key in request.POST.keys(): action_match = action_re.match(key) @@ -1015,7 +967,7 @@ def view_single_grade(pctx, participation_id, opportunity_id): from collections import namedtuple SessionProperties = namedtuple( # noqa "SessionProperties", - ["due", "grade_description", "grading_rule", "access_rule"]) + ["due", "grade_description", "exception"]) from course.utils import get_session_grading_rule, get_session_access_rule from course.content import get_flow_desc @@ -1032,18 +984,40 @@ def view_single_grade(pctx, participation_id, opportunity_id): pctx.repo, session, pctx.course.identifier, flow_desc, respect_preview=False) - access_rule = get_session_access_rule( - session, flow_desc, now_datetime) grading_rule = get_session_grading_rule( session, flow_desc, now_datetime) - access_rule_str = parse_access_rule(access_rule) - grading_rule_str = parse_grading_rule(grading_rule) + ExcInfo = namedtuple( # noqa + "ExcInfo", + ["kind", "creation_time", "creator"]) + from course.models import FlowRuleException + from course.constants import flow_rule_kind + last_access_exc = FlowRuleException.objects.filter( + participation=session.participation, + kind=flow_rule_kind.access, + active=True, + flow_id=session.flow_id).order_by("creation_time").last() + + last_grading_exc = FlowRuleException.objects.filter( + participation=session.participation, + active=True, + kind=flow_rule_kind.grading, + flow_id=session.flow_id).order_by("creation_time").last() + + last_exception, kind = parse_exception(last_access_exc, last_grading_exc) + + if last_exception is not None: + exc_info = ExcInfo( + kind=kind, + creation_time=last_exception.creation_time, + creator=last_exception.creator + ) + else: + exc_info = None session_properties = SessionProperties( due=grading_rule.due, grade_description=grading_rule.description, - grading_rule=grading_rule_str, - access_rule=access_rule_str) + exception=exc_info) flow_sessions_and_session_properties.append( (session, session_properties)) diff --git a/course/templates/course/gradebook-single.html b/course/templates/course/gradebook-single.html index 805dabbe..a2fe8e40 100644 --- a/course/templates/course/gradebook-single.html +++ b/course/templates/course/gradebook-single.html @@ -184,6 +184,22 @@ {% trans "Last activity" %}: {{ flow_session.last_activity }}

{% endif %} +
+ {# display exceptions #} + {% if pperm.grant_exception %} + {% if session_properties.exception %} +

{% trans "Exsiting exception:" %}

+

{% trans "Created: " %}{{session_properties.exception.creation_time}}

+

{% trans "Creator: " %}{{session_properties.exception.creator}}

+

{% trans "Kind: " %}{{session_properties.exception.kind}}

+ + {% trans "Edit exception" %} + + {% else %} +

{% trans "Exsiting Exception: " %}None

+ {% endif %} + {% endif %} @@ -307,8 +323,7 @@ {% endif %} {% endif %} {% if pperm.grant_exception %} - {% trans "Grant exception" %} -- GitLab From c84631aa775bc539fa5443c5fb09fe3e91a80aca Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Sun, 25 Jun 2017 00:16:26 -0500 Subject: [PATCH 21/27] display exceptions --- course/grades.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/course/grades.py b/course/grades.py index e0424f3b..aaf7ad63 100644 --- a/course/grades.py +++ b/course/grades.py @@ -796,6 +796,7 @@ def average_grade(opportunity): def parse_exception(last_access_exc, last_grading_exc): # type: (FlowRuleException, FlowRuleException) -> FlowRuleException, str + # if grading exception is the same as the default exception, we ignore it if last_grading_exc: def has_grading_exc(rule): if 'bonus_points' in rule and rule['bonus_points'] != 0.0: @@ -809,6 +810,7 @@ def parse_exception(last_access_exc, last_grading_exc): if not has_grading_exc(last_grading_exc.rule): last_grading_exc = None + # if both exceptions exist if last_access_exc and last_grading_exc: last_exception = (last_access_exc # noqa if last_access_exc.creation_time > last_grading_exc.creation_time # noqa @@ -819,6 +821,7 @@ def parse_exception(last_access_exc, last_grading_exc): if last_access_exc is not None else last_grading_exc) kind = str(_(str(last_exception.kind))) + # no exception exists else: last_exception = None kind = None @@ -990,30 +993,32 @@ def view_single_grade(pctx, participation_id, opportunity_id): ExcInfo = namedtuple( # noqa "ExcInfo", ["kind", "creation_time", "creator"]) + from course.models import FlowRuleException from course.constants import flow_rule_kind + + # get the latest access and grading exceptions last_access_exc = FlowRuleException.objects.filter( participation=session.participation, kind=flow_rule_kind.access, active=True, flow_id=session.flow_id).order_by("creation_time").last() - last_grading_exc = FlowRuleException.objects.filter( participation=session.participation, active=True, kind=flow_rule_kind.grading, flow_id=session.flow_id).order_by("creation_time").last() - + # kind: whether the exception is both access and grading exceptions of only one of them last_exception, kind = parse_exception(last_access_exc, last_grading_exc) + exc_info = None if last_exception is not None: exc_info = ExcInfo( kind=kind, creation_time=last_exception.creation_time, creator=last_exception.creator ) - else: - exc_info = None + session_properties = SessionProperties( due=grading_rule.due, grade_description=grading_rule.description, -- GitLab From 58ec3ddb62b04dd798c250361f37279870696af2 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Sun, 25 Jun 2017 00:29:19 -0500 Subject: [PATCH 22/27] fix flake --- course/grades.py | 55 ++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/course/grades.py b/course/grades.py index aaf7ad63..b48755ac 100644 --- a/course/grades.py +++ b/course/grades.py @@ -793,11 +793,11 @@ def average_grade(opportunity): return None, 0 -def parse_exception(last_access_exc, last_grading_exc): - # type: (FlowRuleException, FlowRuleException) -> FlowRuleException, str +def parse_exception(access_exc, grading_exc): + # type: (FlowRuleException, FlowRuleException) -> Tuple[FlowRuleException, str] # if grading exception is the same as the default exception, we ignore it - if last_grading_exc: + if grading_exc: def has_grading_exc(rule): if 'bonus_points' in rule and rule['bonus_points'] != 0.0: return True @@ -807,19 +807,19 @@ def parse_exception(last_access_exc, last_grading_exc): return True else: return False - if not has_grading_exc(last_grading_exc.rule): - last_grading_exc = None + if not has_grading_exc(grading_exc.rule): + grading_exc = None # if both exceptions exist - if last_access_exc and last_grading_exc: - last_exception = (last_access_exc # noqa - if last_access_exc.creation_time > last_grading_exc.creation_time # noqa - else last_grading_exc) + if access_exc and grading_exc: + last_exception = (access_exc # noqa + if access_exc.creation_time > grading_exc.creation_time # noqa + else grading_exc) kind = str(_("access and grading")) - elif last_access_exc or last_grading_exc: - last_exception = (last_access_exc - if last_access_exc is not None - else last_grading_exc) + elif access_exc or grading_exc: + last_exception = (access_exc + if access_exc is not None + else grading_exc) kind = str(_(str(last_exception.kind))) # no exception exists else: @@ -998,27 +998,28 @@ def view_single_grade(pctx, participation_id, opportunity_id): from course.constants import flow_rule_kind # get the latest access and grading exceptions - last_access_exc = FlowRuleException.objects.filter( - participation=session.participation, - kind=flow_rule_kind.access, - active=True, - flow_id=session.flow_id).order_by("creation_time").last() - last_grading_exc = FlowRuleException.objects.filter( - participation=session.participation, - active=True, - kind=flow_rule_kind.grading, - flow_id=session.flow_id).order_by("creation_time").last() - # kind: whether the exception is both access and grading exceptions of only one of them - last_exception, kind = parse_exception(last_access_exc, last_grading_exc) + access_exc = FlowRuleException.objects.filter( + participation=session.participation, + kind=flow_rule_kind.access, + active=True, + flow_id=session.flow_id).order_by("creation_time").last() + grading_exc = FlowRuleException.objects.filter( + participation=session.participation, + active=True, + kind=flow_rule_kind.grading, + flow_id=session.flow_id).order_by("creation_time").last() + # kind: whether the exception is both access and grading exceptions + # or only one of them + last_exception, kind = parse_exception(access_exc, grading_exc) exc_info = None - if last_exception is not None: + if last_exception is not None: exc_info = ExcInfo( kind=kind, creation_time=last_exception.creation_time, creator=last_exception.creator ) - + session_properties = SessionProperties( due=grading_rule.due, grade_description=grading_rule.description, -- GitLab From e6bd1237d632ddab6c6e0fbaaf3682a8e3783934 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Sun, 25 Jun 2017 00:37:56 -0500 Subject: [PATCH 23/27] fix flake --- course/grades.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/course/grades.py b/course/grades.py index b48755ac..2ecb4005 100644 --- a/course/grades.py +++ b/course/grades.py @@ -52,7 +52,7 @@ from course.models import ( Participation, participation_status, GradingOpportunity, GradeChange, GradeStateMachine, grade_state_change_types, - FlowSession, FlowPageVisit) + FlowSession, FlowPageVisit, FlowRuleException) from course.flow import adjust_flow_session_page_data from course.views import get_now_or_fake_time from course.constants import ( @@ -799,6 +799,8 @@ def parse_exception(access_exc, grading_exc): # if grading exception is the same as the default exception, we ignore it if grading_exc: def has_grading_exc(rule): + # type: (Dict[str, float]) -> bool + if 'bonus_points' in rule and rule['bonus_points'] != 0.0: return True elif 'credit_percent' in rule and rule['credit_percent'] != 100.0: @@ -817,8 +819,8 @@ def parse_exception(access_exc, grading_exc): else grading_exc) kind = str(_("access and grading")) elif access_exc or grading_exc: - last_exception = (access_exc - if access_exc is not None + last_exception = (access_exc + if access_exc is not None else grading_exc) kind = str(_(str(last_exception.kind))) # no exception exists @@ -972,7 +974,7 @@ def view_single_grade(pctx, participation_id, opportunity_id): "SessionProperties", ["due", "grade_description", "exception"]) - from course.utils import get_session_grading_rule, get_session_access_rule + from course.utils import get_session_grading_rule from course.content import get_flow_desc try: @@ -996,7 +998,7 @@ def view_single_grade(pctx, participation_id, opportunity_id): from course.models import FlowRuleException from course.constants import flow_rule_kind - + # get the latest access and grading exceptions access_exc = FlowRuleException.objects.filter( participation=session.participation, -- GitLab From 848f49e0f110deae38f09b134a411c923bc6ef58 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Sun, 25 Jun 2017 00:54:59 -0500 Subject: [PATCH 24/27] fix flake --- course/grades.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/course/grades.py b/course/grades.py index 2ecb4005..93b5b049 100644 --- a/course/grades.py +++ b/course/grades.py @@ -800,7 +800,7 @@ def parse_exception(access_exc, grading_exc): if grading_exc: def has_grading_exc(rule): # type: (Dict[str, float]) -> bool - + if 'bonus_points' in rule and rule['bonus_points'] != 0.0: return True elif 'credit_percent' in rule and rule['credit_percent'] != 100.0: @@ -810,7 +810,7 @@ def parse_exception(access_exc, grading_exc): else: return False if not has_grading_exc(grading_exc.rule): - grading_exc = None + grading_exc = None # type: FlowRuleException # if both exceptions exist if access_exc and grading_exc: @@ -825,8 +825,8 @@ def parse_exception(access_exc, grading_exc): kind = str(_(str(last_exception.kind))) # no exception exists else: - last_exception = None - kind = None + last_exception = None # type: FlowRuleException + kind = str(_("None")) return last_exception, kind @@ -996,7 +996,6 @@ def view_single_grade(pctx, participation_id, opportunity_id): "ExcInfo", ["kind", "creation_time", "creator"]) - from course.models import FlowRuleException from course.constants import flow_rule_kind # get the latest access and grading exceptions -- GitLab From 31560daf736f81e01d5d50c9a00b31660014c498 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Sun, 25 Jun 2017 01:08:58 -0500 Subject: [PATCH 25/27] fix flake --- course/grades.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/course/grades.py b/course/grades.py index 93b5b049..cd4bf7de 100644 --- a/course/grades.py +++ b/course/grades.py @@ -810,12 +810,13 @@ def parse_exception(access_exc, grading_exc): else: return False if not has_grading_exc(grading_exc.rule): - grading_exc = None # type: FlowRuleException + grading_exc = None + last_exception = None # type: FlowRuleException # if both exceptions exist if access_exc and grading_exc: - last_exception = (access_exc # noqa - if access_exc.creation_time > grading_exc.creation_time # noqa + last_exception = (access_exc # noqa + if access_exc.creation_time > grading_exc.creation_time # noqa else grading_exc) kind = str(_("access and grading")) elif access_exc or grading_exc: @@ -825,7 +826,6 @@ def parse_exception(access_exc, grading_exc): kind = str(_(str(last_exception.kind))) # no exception exists else: - last_exception = None # type: FlowRuleException kind = str(_("None")) return last_exception, kind -- GitLab From 1be169551f9843043689c3c8124f44d75ebbbb46 Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Sun, 25 Jun 2017 01:17:29 -0500 Subject: [PATCH 26/27] fix flake --- course/grades.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/course/grades.py b/course/grades.py index cd4bf7de..77f3bd70 100644 --- a/course/grades.py +++ b/course/grades.py @@ -793,11 +793,14 @@ def average_grade(opportunity): return None, 0 -def parse_exception(access_exc, grading_exc): +def parse_exception(access, grading): # type: (FlowRuleException, FlowRuleException) -> Tuple[FlowRuleException, str] - # if grading exception is the same as the default exception, we ignore it - if grading_exc: + access_exc = access # type: FlowRuleException + grading_exc = None # type: FlowRuleException + + # if grading exception is the same as the default exception, ignore it + if grading: def has_grading_exc(rule): # type: (Dict[str, float]) -> bool @@ -809,8 +812,8 @@ def parse_exception(access_exc, grading_exc): return True else: return False - if not has_grading_exc(grading_exc.rule): - grading_exc = None + if has_grading_exc(grading.rule): + grading_exc = grading last_exception = None # type: FlowRuleException # if both exceptions exist -- GitLab From 7b6563bb5ece3e23cdb731a4241a1e697034490d Mon Sep 17 00:00:00 2001 From: Heting Gao Date: Sun, 25 Jun 2017 01:32:59 -0500 Subject: [PATCH 27/27] fix mypy --- course/grades.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/course/grades.py b/course/grades.py index 77f3bd70..fa126741 100644 --- a/course/grades.py +++ b/course/grades.py @@ -793,14 +793,14 @@ def average_grade(opportunity): return None, 0 -def parse_exception(access, grading): - # type: (FlowRuleException, FlowRuleException) -> Tuple[FlowRuleException, str] - - access_exc = access # type: FlowRuleException - grading_exc = None # type: FlowRuleException +def parse_exception( + access_exc, # type: Optional[FlowRuleException] + grading_exc # type: Optional[FlowRuleException] + ): + # type: (...) -> Tuple[Optional[FlowRuleException], Optional[str]] # if grading exception is the same as the default exception, ignore it - if grading: + if grading_exc: def has_grading_exc(rule): # type: (Dict[str, float]) -> bool @@ -812,10 +812,10 @@ def parse_exception(access, grading): return True else: return False - if has_grading_exc(grading.rule): - grading_exc = grading + if has_grading_exc(grading_exc.rule): + grading_exc = None - last_exception = None # type: FlowRuleException + last_exception = None # type: Optional[FlowRuleException] # if both exceptions exist if access_exc and grading_exc: last_exception = (access_exc # noqa @@ -829,7 +829,7 @@ def parse_exception(access, grading): kind = str(_(str(last_exception.kind))) # no exception exists else: - kind = str(_("None")) + kind = None return last_exception, kind -- GitLab