prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Add "totals" to "view feedback" page
  ### Description
  
  It would be useful to add totals for each column in the "view feedback" page.
  
  ### Code of Conduct
  
  - [X] I agree to follow the [IETF's Code of Conduct](https://github.com/ietf-tools/.github/blob/main/CODE_OF_CONDUCT.md)
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `ietf/nomcom/templatetags/nomcom_tags.py`
  Content:
  ```
  1 # Copyright The IETF Trust 2013-2019, All Rights Reserved
  2 import os
  3 import tempfile
  4 import re
  5 
  6 from django import template
  7 from django.conf import settings
  8 from django.template.defaultfilters import linebreaksbr, force_escape
  9 from django.utils.encoding import force_str, DjangoUnicodeDecodeError
  10 from django.utils.safestring import mark_safe
  11 
  12 import debug           # pyflakes:ignore
  13 
  14 from ietf.nomcom.utils import get_nomcom_by_year, retrieve_nomcom_private_key
  15 from ietf.person.models import Person
  16 from ietf.utils.log import log
  17 from ietf.utils.pipe import pipe
  18 
  19 
  20 register = template.Library()
  21 
  22 
  23 @register.filter
  24 def is_chair_or_advisor(user, year):
  25     if not user or not year:
  26         return False
  27     nomcom = get_nomcom_by_year(year=year)
  28     return nomcom.group.has_role(user, ["chair","advisor"])
  29 
  30 
  31 @register.filter
  32 def has_publickey(nomcom):
  33     return nomcom and nomcom.public_key and True or False
  34 
  35 @register.filter
  36 def lookup(container,key):
  37     return container and container.get(key,None)
  38 
  39 @register.filter
  40 def formatted_email(address):
  41     person = None
  42     addrmatch = re.search('<([^>]+)>',address)
  43     if addrmatch:
  44         addr = addrmatch.group(1)
  45     else:
  46         addr = address
  47     if addr:
  48         persons = Person.objects.filter(email__address__in=[addr])
  49         person = persons and persons[0] or None
  50     if person and person.name:
  51         return "%s <%s>" % (person.plain_name(), addr) 
  52     else:
  53         return address
  54 
  55 
  56 @register.simple_tag
  57 def decrypt(string, request, year, plain=False):
  58     try:
  59         key = retrieve_nomcom_private_key(request, year)
  60     except UnicodeError:
  61         return f"-*- Encrypted text [Error retrieving private key, contact the secretariat ({settings.SECRETARIAT_SUPPORT_EMAIL})]"
  62     if not key:
  63         return '-*- Encrypted text [No private key provided] -*-'
  64 
  65     encrypted_file = tempfile.NamedTemporaryFile(delete=False)
  66     encrypted_file.write(string)
  67     encrypted_file.close()
  68 
  69     command = "%s smime -decrypt -in %s -inkey /dev/stdin"
  70     code, out, error = pipe(command % (settings.OPENSSL_COMMAND,
  71                             encrypted_file.name), key)
  72     try:
  73         out = force_str(out)
  74     except DjangoUnicodeDecodeError:
  75         pass
  76     if code != 0:
  77         log("openssl error: %s:\n  Error %s: %s" %(command, code, error))
  78 
  79     os.unlink(encrypted_file.name)
  80 
  81     if error:
  82         return '-*- Encrypted text [Your private key is invalid] -*-'
  83 
  84     if not plain:
  85         return force_escape(linebreaksbr(out))
  86     return mark_safe(force_escape(out))
  87
  ```
  --- 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/ietf/nomcom/templatetags/nomcom_tags.py b/ietf/nomcom/templatetags/nomcom_tags.py
  --- a/ietf/nomcom/templatetags/nomcom_tags.py
  +++ b/ietf/nomcom/templatetags/nomcom_tags.py
  @@ -1,8 +1,10 @@
  -# Copyright The IETF Trust 2013-2019, All Rights Reserved
  +# Copyright The IETF Trust 2013-2023, All Rights Reserved
   import os
   import tempfile
   import re
   
  +from collections import defaultdict
  +
   from django import template
   from django.conf import settings
   from django.template.defaultfilters import linebreaksbr, force_escape
  @@ -84,3 +86,11 @@
       if not plain:
           return force_escape(linebreaksbr(out))
       return mark_safe(force_escape(out))
  +
  +@register.filter
  +def feedback_totals(staterank_list):
  +    totals = defaultdict(lambda: 0)
  +    for fb_dict in staterank_list:
  +        for fbtype_name, fbtype_count, _ in fb_dict['feedback']:
  +            totals[fbtype_name] += fbtype_count
  +    return totals.values()
  
verification_info: {"golden_diff": "diff --git a/ietf/nomcom/templatetags/nomcom_tags.py b/ietf/nomcom/templatetags/nomcom_tags.py\n--- a/ietf/nomcom/templatetags/nomcom_tags.py\n+++ b/ietf/nomcom/templatetags/nomcom_tags.py\n@@ -1,8 +1,10 @@\n-# Copyright The IETF Trust 2013-2019, All Rights Reserved\n+# Copyright The IETF Trust 2013-2023, All Rights Reserved\n import os\n import tempfile\n import re\n \n+from collections import defaultdict\n+\n from django import template\n from django.conf import settings\n from django.template.defaultfilters import linebreaksbr, force_escape\n@@ -84,3 +86,11 @@\n     if not plain:\n         return force_escape(linebreaksbr(out))\n     return mark_safe(force_escape(out))\n+\n+@register.filter\n+def feedback_totals(staterank_list):\n+    totals = defaultdict(lambda: 0)\n+    for fb_dict in staterank_list:\n+        for fbtype_name, fbtype_count, _ in fb_dict['feedback']:\n+            totals[fbtype_name] += fbtype_count\n+    return totals.values()\n", "issue": "Add \"totals\" to \"view feedback\" page\n### Description\n\nIt would be useful to add totals for each column in the \"view feedback\" page.\n\n### Code of Conduct\n\n- [X] I agree to follow the [IETF's Code of Conduct](https://github.com/ietf-tools/.github/blob/main/CODE_OF_CONDUCT.md)\n", "before_files": [{"content": "# Copyright The IETF Trust 2013-2019, All Rights Reserved\nimport os\nimport tempfile\nimport re\n\nfrom django import template\nfrom django.conf import settings\nfrom django.template.defaultfilters import linebreaksbr, force_escape\nfrom django.utils.encoding import force_str, DjangoUnicodeDecodeError\nfrom django.utils.safestring import mark_safe\n\nimport debug           # pyflakes:ignore\n\nfrom ietf.nomcom.utils import get_nomcom_by_year, retrieve_nomcom_private_key\nfrom ietf.person.models import Person\nfrom ietf.utils.log import log\nfrom ietf.utils.pipe import pipe\n\n\nregister = template.Library()\n\n\n@register.filter\ndef is_chair_or_advisor(user, year):\n    if not user or not year:\n        return False\n    nomcom = get_nomcom_by_year(year=year)\n    return nomcom.group.has_role(user, [\"chair\",\"advisor\"])\n\n\n@register.filter\ndef has_publickey(nomcom):\n    return nomcom and nomcom.public_key and True or False\n\n@register.filter\ndef lookup(container,key):\n    return container and container.get(key,None)\n\n@register.filter\ndef formatted_email(address):\n    person = None\n    addrmatch = re.search('<([^>]+)>',address)\n    if addrmatch:\n        addr = addrmatch.group(1)\n    else:\n        addr = address\n    if addr:\n        persons = Person.objects.filter(email__address__in=[addr])\n        person = persons and persons[0] or None\n    if person and person.name:\n        return \"%s <%s>\" % (person.plain_name(), addr) \n    else:\n        return address\n\n\n@register.simple_tag\ndef decrypt(string, request, year, plain=False):\n    try:\n        key = retrieve_nomcom_private_key(request, year)\n    except UnicodeError:\n        return f\"-*- Encrypted text [Error retrieving private key, contact the secretariat ({settings.SECRETARIAT_SUPPORT_EMAIL})]\"\n    if not key:\n        return '-*- Encrypted text [No private key provided] -*-'\n\n    encrypted_file = tempfile.NamedTemporaryFile(delete=False)\n    encrypted_file.write(string)\n    encrypted_file.close()\n\n    command = \"%s smime -decrypt -in %s -inkey /dev/stdin\"\n    code, out, error = pipe(command % (settings.OPENSSL_COMMAND,\n                            encrypted_file.name), key)\n    try:\n        out = force_str(out)\n    except DjangoUnicodeDecodeError:\n        pass\n    if code != 0:\n        log(\"openssl error: %s:\\n  Error %s: %s\" %(command, code, error))\n\n    os.unlink(encrypted_file.name)\n\n    if error:\n        return '-*- Encrypted text [Your private key is invalid] -*-'\n\n    if not plain:\n        return force_escape(linebreaksbr(out))\n    return mark_safe(force_escape(out))\n", "path": "ietf/nomcom/templatetags/nomcom_tags.py"}], "after_files": [{"content": "# Copyright The IETF Trust 2013-2023, All Rights Reserved\nimport os\nimport tempfile\nimport re\n\nfrom collections import defaultdict\n\nfrom django import template\nfrom django.conf import settings\nfrom django.template.defaultfilters import linebreaksbr, force_escape\nfrom django.utils.encoding import force_str, DjangoUnicodeDecodeError\nfrom django.utils.safestring import mark_safe\n\nimport debug           # pyflakes:ignore\n\nfrom ietf.nomcom.utils import get_nomcom_by_year, retrieve_nomcom_private_key\nfrom ietf.person.models import Person\nfrom ietf.utils.log import log\nfrom ietf.utils.pipe import pipe\n\n\nregister = template.Library()\n\n\n@register.filter\ndef is_chair_or_advisor(user, year):\n    if not user or not year:\n        return False\n    nomcom = get_nomcom_by_year(year=year)\n    return nomcom.group.has_role(user, [\"chair\",\"advisor\"])\n\n\n@register.filter\ndef has_publickey(nomcom):\n    return nomcom and nomcom.public_key and True or False\n\n@register.filter\ndef lookup(container,key):\n    return container and container.get(key,None)\n\n@register.filter\ndef formatted_email(address):\n    person = None\n    addrmatch = re.search('<([^>]+)>',address)\n    if addrmatch:\n        addr = addrmatch.group(1)\n    else:\n        addr = address\n    if addr:\n        persons = Person.objects.filter(email__address__in=[addr])\n        person = persons and persons[0] or None\n    if person and person.name:\n        return \"%s <%s>\" % (person.plain_name(), addr) \n    else:\n        return address\n\n\n@register.simple_tag\ndef decrypt(string, request, year, plain=False):\n    try:\n        key = retrieve_nomcom_private_key(request, year)\n    except UnicodeError:\n        return f\"-*- Encrypted text [Error retrieving private key, contact the secretariat ({settings.SECRETARIAT_SUPPORT_EMAIL})]\"\n    if not key:\n        return '-*- Encrypted text [No private key provided] -*-'\n\n    encrypted_file = tempfile.NamedTemporaryFile(delete=False)\n    encrypted_file.write(string)\n    encrypted_file.close()\n\n    command = \"%s smime -decrypt -in %s -inkey /dev/stdin\"\n    code, out, error = pipe(command % (settings.OPENSSL_COMMAND,\n                            encrypted_file.name), key)\n    try:\n        out = force_str(out)\n    except DjangoUnicodeDecodeError:\n        pass\n    if code != 0:\n        log(\"openssl error: %s:\\n  Error %s: %s\" %(command, code, error))\n\n    os.unlink(encrypted_file.name)\n\n    if error:\n        return '-*- Encrypted text [Your private key is invalid] -*-'\n\n    if not plain:\n        return force_escape(linebreaksbr(out))\n    return mark_safe(force_escape(out))\n\n@register.filter\ndef feedback_totals(staterank_list):\n    totals = defaultdict(lambda: 0)\n    for fb_dict in staterank_list:\n        for fbtype_name, fbtype_count, _ in fb_dict['feedback']:\n            totals[fbtype_name] += fbtype_count\n    return totals.values()\n", "path": "ietf/nomcom/templatetags/nomcom_tags.py"}]}