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()

```

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 {

{"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"}]}