prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Missing chair email aliases for research area groups
  ### Describe the issue
  
  There are two Research Area Groups in the datatracker, anrw and irtfopen. These groups have a chair listed, but the email expansions at https://datatracker.ietf.org/group/irtfopen/email/ appear to be missing the chairs alias (irtfopen-chair@ietf.org) and email sent to that address bounces. Similarly, presumably, for anrw.
  
  
  
  ### 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)
  
  </issue>
  <code>
  [start of ietf/group/management/commands/generate_group_aliases.py]
  1 # Copyright The IETF Trust 2012-2021, All Rights Reserved
  2 # -*- coding: utf-8 -*-
  3 
  4 # This was written as a script by Markus Stenberg <markus.stenberg@iki.fi>.
  5 # It was turned into a management command by Russ Housley <housley@vigisec.com>.
  6 
  7 import datetime
  8 import io
  9 import os
  10 import shutil
  11 import stat
  12 import time
  13 
  14 from tempfile import mkstemp
  15     
  16 from django.conf import settings
  17 from django.core.management.base import BaseCommand
  18 from django.utils import timezone
  19 
  20 import debug                            # pyflakes:ignore
  21 
  22 from ietf.group.models import Group
  23 from ietf.group.utils import get_group_ad_emails, get_group_role_emails, get_child_group_role_emails
  24 from ietf.name.models import GroupTypeName
  25 from ietf.utils.aliases import dump_sublist
  26 
  27 DEFAULT_YEARS = 5
  28 ACTIVE_STATES=['active', 'bof', 'proposed']
  29 GROUP_TYPES=['wg', 'rg', 'dir', 'team', 'review', 'program', 'rfcedtyp']
  30 NO_AD_GROUP_TYPES=['rg', 'team', 'program', 'rfcedtyp']
  31 IETF_DOMAIN=['ietf.org', ]
  32 IRTF_DOMAIN=['irtf.org', ]
  33 IAB_DOMAIN=['iab.org', ]
  34 
  35 class Command(BaseCommand):
  36     help = ('Generate the group-aliases and group-virtual files for Internet-Draft '
  37             'mail aliases, placing them in the file configured in '
  38             'settings.GROUP_ALIASES_PATH and settings.GROUP_VIRTUAL_PATH, '
  39             'respectively.  The generation includes aliases for groups that '
  40             'have seen activity in the last %s years.' % (DEFAULT_YEARS))
  41 
  42     def handle(self, *args, **options):
  43         show_since = timezone.now() - datetime.timedelta(DEFAULT_YEARS*365)
  44 
  45         date = time.strftime("%Y-%m-%d_%H:%M:%S")
  46         signature = '# Generated by %s at %s\n' % (os.path.abspath(__file__), date)
  47 
  48         ahandle, aname = mkstemp()
  49         os.close(ahandle)
  50         afile = io.open(aname,"w")
  51 
  52         vhandle, vname = mkstemp()
  53         os.close(vhandle)
  54         vfile = io.open(vname,"w")
  55 
  56         afile.write(signature)
  57         vfile.write(signature)
  58         vfile.write("%s anything\n" % settings.GROUP_VIRTUAL_DOMAIN)
  59 
  60         # Loop through each group type and build -ads and -chairs entries
  61         for g in GROUP_TYPES:
  62             domains = []
  63             domains += IETF_DOMAIN
  64             if g == 'rg':
  65                 domains += IRTF_DOMAIN
  66             if g == 'program':
  67                 domains += IAB_DOMAIN
  68 
  69             entries = Group.objects.filter(type=g).all()
  70             active_entries = entries.filter(state__in=ACTIVE_STATES)
  71             inactive_recent_entries = entries.exclude(state__in=ACTIVE_STATES).filter(time__gte=show_since)
  72             interesting_entries = active_entries | inactive_recent_entries
  73 
  74             for e in interesting_entries.distinct().iterator():
  75                 name = e.acronym
  76                 
  77                 # Research groups, teams, and programs do not have -ads lists
  78                 if not g in NO_AD_GROUP_TYPES:
  79                     dump_sublist(afile, vfile, name+'-ads', domains, settings.GROUP_VIRTUAL_DOMAIN, get_group_ad_emails(e))
  80                 # All group types have -chairs lists
  81                 dump_sublist(afile, vfile, name+'-chairs', domains, settings.GROUP_VIRTUAL_DOMAIN, get_group_role_emails(e, ['chair', 'secr']))
  82 
  83         # The area lists include every chair in active working groups in the area
  84         areas = Group.objects.filter(type='area').all()
  85         active_areas = areas.filter(state__in=ACTIVE_STATES)
  86         for area in active_areas:
  87             name = area.acronym
  88             area_ad_emails = get_group_role_emails(area, ['pre-ad', 'ad', 'chair'])
  89             dump_sublist(afile, vfile, name+'-ads', IETF_DOMAIN, settings.GROUP_VIRTUAL_DOMAIN, area_ad_emails)
  90             dump_sublist(afile, vfile, name+'-chairs', IETF_DOMAIN, settings.GROUP_VIRTUAL_DOMAIN, (get_child_group_role_emails(area, ['chair', 'secr']) | area_ad_emails))
  91 
  92         # Other groups with chairs that require Internet-Draft submission approval
  93         gtypes = GroupTypeName.objects.values_list('slug', flat=True)
  94         special_groups = Group.objects.filter(type__features__req_subm_approval=True, acronym__in=gtypes, state='active')
  95         for group in special_groups:
  96             dump_sublist(afile, vfile, group.acronym+'-chairs', IETF_DOMAIN, settings.GROUP_VIRTUAL_DOMAIN, get_group_role_emails(group, ['chair', 'delegate']))
  97 
  98         afile.close()
  99         vfile.close()
  100 
  101         os.chmod(aname, stat.S_IWUSR|stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) 
  102         os.chmod(vname, stat.S_IWUSR|stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) 
  103 
  104         shutil.move(aname, settings.GROUP_ALIASES_PATH)
  105         shutil.move(vname, settings.GROUP_VIRTUAL_PATH)
  106
  [end of ietf/group/management/commands/generate_group_aliases.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/ietf/group/management/commands/generate_group_aliases.py b/ietf/group/management/commands/generate_group_aliases.py
  --- a/ietf/group/management/commands/generate_group_aliases.py
  +++ b/ietf/group/management/commands/generate_group_aliases.py
  @@ -26,8 +26,8 @@
   
   DEFAULT_YEARS = 5
   ACTIVE_STATES=['active', 'bof', 'proposed']
  -GROUP_TYPES=['wg', 'rg', 'dir', 'team', 'review', 'program', 'rfcedtyp']
  -NO_AD_GROUP_TYPES=['rg', 'team', 'program', 'rfcedtyp']
  +GROUP_TYPES=['wg', 'rg', 'rag', 'dir', 'team', 'review', 'program', 'rfcedtyp']
  +NO_AD_GROUP_TYPES=['rg', 'rag', 'team', 'program', 'rfcedtyp']
   IETF_DOMAIN=['ietf.org', ]
   IRTF_DOMAIN=['irtf.org', ]
   IAB_DOMAIN=['iab.org', ]
  @@ -61,7 +61,7 @@
           for g in GROUP_TYPES:
               domains = []
               domains += IETF_DOMAIN
  -            if g == 'rg':
  +            if g in ('rg', 'rag'):
                   domains += IRTF_DOMAIN
               if g == 'program':
                   domains += IAB_DOMAIN
  
verification_info: {"golden_diff": "diff --git a/ietf/group/management/commands/generate_group_aliases.py b/ietf/group/management/commands/generate_group_aliases.py\n--- a/ietf/group/management/commands/generate_group_aliases.py\n+++ b/ietf/group/management/commands/generate_group_aliases.py\n@@ -26,8 +26,8 @@\n \n DEFAULT_YEARS = 5\n ACTIVE_STATES=['active', 'bof', 'proposed']\n-GROUP_TYPES=['wg', 'rg', 'dir', 'team', 'review', 'program', 'rfcedtyp']\n-NO_AD_GROUP_TYPES=['rg', 'team', 'program', 'rfcedtyp']\n+GROUP_TYPES=['wg', 'rg', 'rag', 'dir', 'team', 'review', 'program', 'rfcedtyp']\n+NO_AD_GROUP_TYPES=['rg', 'rag', 'team', 'program', 'rfcedtyp']\n IETF_DOMAIN=['ietf.org', ]\n IRTF_DOMAIN=['irtf.org', ]\n IAB_DOMAIN=['iab.org', ]\n@@ -61,7 +61,7 @@\n         for g in GROUP_TYPES:\n             domains = []\n             domains += IETF_DOMAIN\n-            if g == 'rg':\n+            if g in ('rg', 'rag'):\n                 domains += IRTF_DOMAIN\n             if g == 'program':\n                 domains += IAB_DOMAIN\n", "issue": "Missing chair email aliases for research area groups\n### Describe the issue\n\nThere are two Research Area Groups in the datatracker, anrw and irtfopen. These groups have a chair listed, but the email expansions at https://datatracker.ietf.org/group/irtfopen/email/ appear to be missing the chairs alias (irtfopen-chair@ietf.org) and email sent to that address bounces. Similarly, presumably, for anrw.\r\n\r\n\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 2012-2021, All Rights Reserved\n# -*- coding: utf-8 -*-\n\n# This was written as a script by Markus Stenberg <markus.stenberg@iki.fi>.\n# It was turned into a management command by Russ Housley <housley@vigisec.com>.\n\nimport datetime\nimport io\nimport os\nimport shutil\nimport stat\nimport time\n\nfrom tempfile import mkstemp\n    \nfrom django.conf import settings\nfrom django.core.management.base import BaseCommand\nfrom django.utils import timezone\n\nimport debug                            # pyflakes:ignore\n\nfrom ietf.group.models import Group\nfrom ietf.group.utils import get_group_ad_emails, get_group_role_emails, get_child_group_role_emails\nfrom ietf.name.models import GroupTypeName\nfrom ietf.utils.aliases import dump_sublist\n\nDEFAULT_YEARS = 5\nACTIVE_STATES=['active', 'bof', 'proposed']\nGROUP_TYPES=['wg', 'rg', 'dir', 'team', 'review', 'program', 'rfcedtyp']\nNO_AD_GROUP_TYPES=['rg', 'team', 'program', 'rfcedtyp']\nIETF_DOMAIN=['ietf.org', ]\nIRTF_DOMAIN=['irtf.org', ]\nIAB_DOMAIN=['iab.org', ]\n\nclass Command(BaseCommand):\n    help = ('Generate the group-aliases and group-virtual files for Internet-Draft '\n            'mail aliases, placing them in the file configured in '\n            'settings.GROUP_ALIASES_PATH and settings.GROUP_VIRTUAL_PATH, '\n            'respectively.  The generation includes aliases for groups that '\n            'have seen activity in the last %s years.' % (DEFAULT_YEARS))\n\n    def handle(self, *args, **options):\n        show_since = timezone.now() - datetime.timedelta(DEFAULT_YEARS*365)\n\n        date = time.strftime(\"%Y-%m-%d_%H:%M:%S\")\n        signature = '# Generated by %s at %s\\n' % (os.path.abspath(__file__), date)\n\n        ahandle, aname = mkstemp()\n        os.close(ahandle)\n        afile = io.open(aname,\"w\")\n\n        vhandle, vname = mkstemp()\n        os.close(vhandle)\n        vfile = io.open(vname,\"w\")\n\n        afile.write(signature)\n        vfile.write(signature)\n        vfile.write(\"%s anything\\n\" % settings.GROUP_VIRTUAL_DOMAIN)\n\n        # Loop through each group type and build -ads and -chairs entries\n        for g in GROUP_TYPES:\n            domains = []\n            domains += IETF_DOMAIN\n            if g == 'rg':\n                domains += IRTF_DOMAIN\n            if g == 'program':\n                domains += IAB_DOMAIN\n\n            entries = Group.objects.filter(type=g).all()\n            active_entries = entries.filter(state__in=ACTIVE_STATES)\n            inactive_recent_entries = entries.exclude(state__in=ACTIVE_STATES).filter(time__gte=show_since)\n            interesting_entries = active_entries | inactive_recent_entries\n\n            for e in interesting_entries.distinct().iterator():\n                name = e.acronym\n                \n                # Research groups, teams, and programs do not have -ads lists\n                if not g in NO_AD_GROUP_TYPES:\n                    dump_sublist(afile, vfile, name+'-ads', domains, settings.GROUP_VIRTUAL_DOMAIN, get_group_ad_emails(e))\n                # All group types have -chairs lists\n                dump_sublist(afile, vfile, name+'-chairs', domains, settings.GROUP_VIRTUAL_DOMAIN, get_group_role_emails(e, ['chair', 'secr']))\n\n        # The area lists include every chair in active working groups in the area\n        areas = Group.objects.filter(type='area').all()\n        active_areas = areas.filter(state__in=ACTIVE_STATES)\n        for area in active_areas:\n            name = area.acronym\n            area_ad_emails = get_group_role_emails(area, ['pre-ad', 'ad', 'chair'])\n            dump_sublist(afile, vfile, name+'-ads', IETF_DOMAIN, settings.GROUP_VIRTUAL_DOMAIN, area_ad_emails)\n            dump_sublist(afile, vfile, name+'-chairs', IETF_DOMAIN, settings.GROUP_VIRTUAL_DOMAIN, (get_child_group_role_emails(area, ['chair', 'secr']) | area_ad_emails))\n\n        # Other groups with chairs that require Internet-Draft submission approval\n        gtypes = GroupTypeName.objects.values_list('slug', flat=True)\n        special_groups = Group.objects.filter(type__features__req_subm_approval=True, acronym__in=gtypes, state='active')\n        for group in special_groups:\n            dump_sublist(afile, vfile, group.acronym+'-chairs', IETF_DOMAIN, settings.GROUP_VIRTUAL_DOMAIN, get_group_role_emails(group, ['chair', 'delegate']))\n\n        afile.close()\n        vfile.close()\n\n        os.chmod(aname, stat.S_IWUSR|stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) \n        os.chmod(vname, stat.S_IWUSR|stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) \n\n        shutil.move(aname, settings.GROUP_ALIASES_PATH)\n        shutil.move(vname, settings.GROUP_VIRTUAL_PATH)\n", "path": "ietf/group/management/commands/generate_group_aliases.py"}]}