prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Evaluation preview button visibility
  As a teaching assistant, I might be a contributor to a given course and therefore get my own feedback in the main evaluation. If that course also has an exam evaluation, I see that listed on my "own evaluations" page with the option to preview the questionnaire. However, as not being responsible, I miss the access rights to preview the linked page, resulting in an error.
  
  I would like to either don't have the preview button (it already knows while rendering that page that I am not a contributor, shown through the corresponding icon next to the exam evaluation title) or to give me the rights to preview the questionnaire.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `evap/evaluation/templatetags/evaluation_filters.py`
  Content:
  ```
  1 from django.forms import TypedChoiceField
  2 from django.template import Library
  3 
  4 from evap.evaluation.models import BASE_UNIPOLAR_CHOICES
  5 from evap.evaluation.tools import STATES_ORDERED, STATE_DESCRIPTIONS
  6 from evap.rewards.tools import can_reward_points_be_used_by
  7 from evap.student.forms import HeadingField
  8 
  9 
  10 register = Library()
  11 
  12 
  13 @register.filter(name='zip')
  14 def _zip(a, b):
  15     return zip(a, b)
  16 
  17 
  18 @register.filter
  19 def ordering_index(evaluation):
  20     if evaluation.state in ['new', 'prepared', 'editor_approved', 'approved']:
  21         return evaluation.days_until_evaluation
  22     elif evaluation.state == "in_evaluation":
  23         return 100000 + evaluation.days_left_for_evaluation
  24     return 200000 + evaluation.days_left_for_evaluation
  25 
  26 
  27 # from http://www.jongales.com/blog/2009/10/19/percentage-django-template-tag/
  28 @register.filter
  29 def percentage(fraction, population):
  30     try:
  31         return "{0:.0f}%".format(int(float(fraction) / float(population) * 100))
  32     except ValueError:
  33         return None
  34     except ZeroDivisionError:
  35         return None
  36 
  37 
  38 @register.filter
  39 def percentage_one_decimal(fraction, population):
  40     try:
  41         return "{0:.1f}%".format((float(fraction) / float(population)) * 100)
  42     except ValueError:
  43         return None
  44     except ZeroDivisionError:
  45         return None
  46 
  47 
  48 @register.filter
  49 def percentage_value(fraction, population):
  50     try:
  51         return "{0:0f}".format((float(fraction) / float(population)) * 100)
  52     except ValueError:
  53         return None
  54     except ZeroDivisionError:
  55         return None
  56 
  57 
  58 @register.filter
  59 def to_colors(choices):
  60     if not choices:
  61         # When displaying the course distribution, there are no associated voting choices.
  62         # In that case, we just use the colors of a unipolar scale.
  63         return BASE_UNIPOLAR_CHOICES['colors']
  64     return choices.colors
  65 
  66 
  67 @register.filter
  68 def statename(state):
  69     return STATES_ORDERED.get(state)
  70 
  71 
  72 @register.filter
  73 def statedescription(state):
  74     return STATE_DESCRIPTIONS.get(state)
  75 
  76 
  77 @register.filter
  78 def can_results_page_be_seen_by(evaluation, user):
  79     return evaluation.can_results_page_be_seen_by(user)
  80 
  81 
  82 @register.filter(name='can_reward_points_be_used_by')
  83 def _can_reward_points_be_used_by(user):
  84     return can_reward_points_be_used_by(user)
  85 
  86 
  87 @register.filter
  88 def is_choice_field(field):
  89     return isinstance(field.field, TypedChoiceField)
  90 
  91 
  92 @register.filter
  93 def is_heading_field(field):
  94     return isinstance(field.field, HeadingField)
  95 
  96 
  97 @register.filter
  98 def is_user_editor_or_delegate(evaluation, user):
  99     return evaluation.is_user_editor_or_delegate(user)
  100 
  101 
  102 @register.filter
  103 def message_class(level):
  104     return {
  105         'debug': 'info',
  106         'info': 'info',
  107         'success': 'success',
  108         'warning': 'warning',
  109         'error': 'danger',
  110     }.get(level, 'info')
  111 
  112 
  113 @register.filter
  114 def hours_and_minutes(time_left_for_evaluation):
  115     hours = time_left_for_evaluation.seconds // 3600
  116     minutes = (time_left_for_evaluation.seconds // 60) % 60
  117     return "{:02}:{:02}".format(hours, minutes)
  118 
  119 
  120 @register.filter
  121 def has_nonresponsible_editor(evaluation):
  122     return evaluation.contributions.filter(can_edit=True).exclude(contributor__in=evaluation.course.responsibles.all()).exists()
  123
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/evap/evaluation/templatetags/evaluation_filters.py b/evap/evaluation/templatetags/evaluation_filters.py
  --- a/evap/evaluation/templatetags/evaluation_filters.py
  +++ b/evap/evaluation/templatetags/evaluation_filters.py
  @@ -99,6 +99,10 @@
       return evaluation.is_user_editor_or_delegate(user)
   
   
  +@register.filter
  +def is_user_responsible_or_contributor_or_delegate(evaluation, user):
  +    return evaluation.is_user_responsible_or_contributor_or_delegate(user)
  +
   @register.filter
   def message_class(level):
       return {
  
verification_info: {"golden_diff": "diff --git a/evap/evaluation/templatetags/evaluation_filters.py b/evap/evaluation/templatetags/evaluation_filters.py\n--- a/evap/evaluation/templatetags/evaluation_filters.py\n+++ b/evap/evaluation/templatetags/evaluation_filters.py\n@@ -99,6 +99,10 @@\n     return evaluation.is_user_editor_or_delegate(user)\n \n \n+@register.filter\n+def is_user_responsible_or_contributor_or_delegate(evaluation, user):\n+    return evaluation.is_user_responsible_or_contributor_or_delegate(user)\n+\n @register.filter\n def message_class(level):\n     return {\n", "issue": "Evaluation preview button visibility\nAs a teaching assistant, I might be a contributor to a given course and therefore get my own feedback in the main evaluation. If that course also has an exam evaluation, I see that listed on my \"own evaluations\" page with the option to preview the questionnaire. However, as not being responsible, I miss the access rights to preview the linked page, resulting in an error.\r\n\r\nI would like to either don't have the preview button (it already knows while rendering that page that I am not a contributor, shown through the corresponding icon next to the exam evaluation title) or to give me the rights to preview the questionnaire.\n", "before_files": [{"content": "from django.forms import TypedChoiceField\nfrom django.template import Library\n\nfrom evap.evaluation.models import BASE_UNIPOLAR_CHOICES\nfrom evap.evaluation.tools import STATES_ORDERED, STATE_DESCRIPTIONS\nfrom evap.rewards.tools import can_reward_points_be_used_by\nfrom evap.student.forms import HeadingField\n\n\nregister = Library()\n\n\n@register.filter(name='zip')\ndef _zip(a, b):\n    return zip(a, b)\n\n\n@register.filter\ndef ordering_index(evaluation):\n    if evaluation.state in ['new', 'prepared', 'editor_approved', 'approved']:\n        return evaluation.days_until_evaluation\n    elif evaluation.state == \"in_evaluation\":\n        return 100000 + evaluation.days_left_for_evaluation\n    return 200000 + evaluation.days_left_for_evaluation\n\n\n# from http://www.jongales.com/blog/2009/10/19/percentage-django-template-tag/\n@register.filter\ndef percentage(fraction, population):\n    try:\n        return \"{0:.0f}%\".format(int(float(fraction) / float(population) * 100))\n    except ValueError:\n        return None\n    except ZeroDivisionError:\n        return None\n\n\n@register.filter\ndef percentage_one_decimal(fraction, population):\n    try:\n        return \"{0:.1f}%\".format((float(fraction) / float(population)) * 100)\n    except ValueError:\n        return None\n    except ZeroDivisionError:\n        return None\n\n\n@register.filter\ndef percentage_value(fraction, population):\n    try:\n        return \"{0:0f}\".format((float(fraction) / float(population)) * 100)\n    except ValueError:\n        return None\n    except ZeroDivisionError:\n        return None\n\n\n@register.filter\ndef to_colors(choices):\n    if not choices:\n        # When displaying the course distribution, there are no associated voting choices.\n        # In that case, we just use the colors of a unipolar scale.\n        return BASE_UNIPOLAR_CHOICES['colors']\n    return choices.colors\n\n\n@register.filter\ndef statename(state):\n    return STATES_ORDERED.get(state)\n\n\n@register.filter\ndef statedescription(state):\n    return STATE_DESCRIPTIONS.get(state)\n\n\n@register.filter\ndef can_results_page_be_seen_by(evaluation, user):\n    return evaluation.can_results_page_be_seen_by(user)\n\n\n@register.filter(name='can_reward_points_be_used_by')\ndef _can_reward_points_be_used_by(user):\n    return can_reward_points_be_used_by(user)\n\n\n@register.filter\ndef is_choice_field(field):\n    return isinstance(field.field, TypedChoiceField)\n\n\n@register.filter\ndef is_heading_field(field):\n    return isinstance(field.field, HeadingField)\n\n\n@register.filter\ndef is_user_editor_or_delegate(evaluation, user):\n    return evaluation.is_user_editor_or_delegate(user)\n\n\n@register.filter\ndef message_class(level):\n    return {\n        'debug': 'info',\n        'info': 'info',\n        'success': 'success',\n        'warning': 'warning',\n        'error': 'danger',\n    }.get(level, 'info')\n\n\n@register.filter\ndef hours_and_minutes(time_left_for_evaluation):\n    hours = time_left_for_evaluation.seconds // 3600\n    minutes = (time_left_for_evaluation.seconds // 60) % 60\n    return \"{:02}:{:02}\".format(hours, minutes)\n\n\n@register.filter\ndef has_nonresponsible_editor(evaluation):\n    return evaluation.contributions.filter(can_edit=True).exclude(contributor__in=evaluation.course.responsibles.all()).exists()\n", "path": "evap/evaluation/templatetags/evaluation_filters.py"}], "after_files": [{"content": "from django.forms import TypedChoiceField\nfrom django.template import Library\n\nfrom evap.evaluation.models import BASE_UNIPOLAR_CHOICES\nfrom evap.evaluation.tools import STATES_ORDERED, STATE_DESCRIPTIONS\nfrom evap.rewards.tools import can_reward_points_be_used_by\nfrom evap.student.forms import HeadingField\n\n\nregister = Library()\n\n\n@register.filter(name='zip')\ndef _zip(a, b):\n    return zip(a, b)\n\n\n@register.filter\ndef ordering_index(evaluation):\n    if evaluation.state in ['new', 'prepared', 'editor_approved', 'approved']:\n        return evaluation.days_until_evaluation\n    elif evaluation.state == \"in_evaluation\":\n        return 100000 + evaluation.days_left_for_evaluation\n    return 200000 + evaluation.days_left_for_evaluation\n\n\n# from http://www.jongales.com/blog/2009/10/19/percentage-django-template-tag/\n@register.filter\ndef percentage(fraction, population):\n    try:\n        return \"{0:.0f}%\".format(int(float(fraction) / float(population) * 100))\n    except ValueError:\n        return None\n    except ZeroDivisionError:\n        return None\n\n\n@register.filter\ndef percentage_one_decimal(fraction, population):\n    try:\n        return \"{0:.1f}%\".format((float(fraction) / float(population)) * 100)\n    except ValueError:\n        return None\n    except ZeroDivisionError:\n        return None\n\n\n@register.filter\ndef percentage_value(fraction, population):\n    try:\n        return \"{0:0f}\".format((float(fraction) / float(population)) * 100)\n    except ValueError:\n        return None\n    except ZeroDivisionError:\n        return None\n\n\n@register.filter\ndef to_colors(choices):\n    if not choices:\n        # When displaying the course distribution, there are no associated voting choices.\n        # In that case, we just use the colors of a unipolar scale.\n        return BASE_UNIPOLAR_CHOICES['colors']\n    return choices.colors\n\n\n@register.filter\ndef statename(state):\n    return STATES_ORDERED.get(state)\n\n\n@register.filter\ndef statedescription(state):\n    return STATE_DESCRIPTIONS.get(state)\n\n\n@register.filter\ndef can_results_page_be_seen_by(evaluation, user):\n    return evaluation.can_results_page_be_seen_by(user)\n\n\n@register.filter(name='can_reward_points_be_used_by')\ndef _can_reward_points_be_used_by(user):\n    return can_reward_points_be_used_by(user)\n\n\n@register.filter\ndef is_choice_field(field):\n    return isinstance(field.field, TypedChoiceField)\n\n\n@register.filter\ndef is_heading_field(field):\n    return isinstance(field.field, HeadingField)\n\n\n@register.filter\ndef is_user_editor_or_delegate(evaluation, user):\n    return evaluation.is_user_editor_or_delegate(user)\n\n\n@register.filter\ndef is_user_responsible_or_contributor_or_delegate(evaluation, user):\n    return evaluation.is_user_responsible_or_contributor_or_delegate(user)\n\n@register.filter\ndef message_class(level):\n    return {\n        'debug': 'info',\n        'info': 'info',\n        'success': 'success',\n        'warning': 'warning',\n        'error': 'danger',\n    }.get(level, 'info')\n\n\n@register.filter\ndef hours_and_minutes(time_left_for_evaluation):\n    hours = time_left_for_evaluation.seconds // 3600\n    minutes = (time_left_for_evaluation.seconds // 60) % 60\n    return \"{:02}:{:02}\".format(hours, minutes)\n\n\n@register.filter\ndef has_nonresponsible_editor(evaluation):\n    return evaluation.contributions.filter(can_edit=True).exclude(contributor__in=evaluation.course.responsibles.all()).exists()\n", "path": "evap/evaluation/templatetags/evaluation_filters.py"}]}