From c89f7c89c5f04202877bc3a93a41c99a00b476f8 Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Fri, 20 May 2022 12:22:17 -0500 Subject: [PATCH] feat: begin supporting the new rfc editor model (#3960) * feat: restructure rfcedtype groups. add rpc, rswg, rsab. * feat: show rfc editor groups on menu * feat: add the editorial stream * fix: repair broken html and extent dest coverage. * chore: address Lars review comment * chore: update copyright notices. --- ietf/doc/templatetags/wg_menu.py | 9 +++- .../group/migrations/0055_editorial_stream.py | 38 +++++++++++++++++ ietf/group/tests_info.py | 6 +-- ietf/group/views.py | 11 ++++- ietf/ietfauth/utils.py | 6 +-- ietf/name/admin.py | 6 +-- ietf/name/migrations/0041_update_rfcedtyp.py | 21 ++++++++++ ietf/name/migrations/0042_editorial_stream.py | 30 +++++++++++++ .../0043_editorial_stream_grouptype.py | 26 ++++++++++++ ietf/templates/base/menu.html | 6 +++ ietf/templates/group/active_rfced.html | 42 +++++++++++++++++++ ietf/templates/group/index.html | 6 +-- ietf/urls.py | 6 +-- ietf/utils/test_data.py | 6 +-- 14 files changed, 197 insertions(+), 22 deletions(-) create mode 100644 ietf/group/migrations/0055_editorial_stream.py create mode 100644 ietf/name/migrations/0041_update_rfcedtyp.py create mode 100644 ietf/name/migrations/0042_editorial_stream.py create mode 100644 ietf/name/migrations/0043_editorial_stream_grouptype.py create mode 100644 ietf/templates/group/active_rfced.html diff --git a/ietf/doc/templatetags/wg_menu.py b/ietf/doc/templatetags/wg_menu.py index 1fea3fae4..e82f125c0 100644 --- a/ietf/doc/templatetags/wg_menu.py +++ b/ietf/doc/templatetags/wg_menu.py @@ -1,3 +1,5 @@ +# Copyright The IETF Trust 2009-2022, All Rights Reserved + # Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). # All rights reserved. Contact: Pasi Eronen # @@ -50,7 +52,8 @@ parents = Group.objects.filter( models.Q(type="area") | models.Q(type="irtf", acronym="irtf") | models.Q(acronym="iab") - | models.Q(acronym="ietfadminllc"), + | models.Q(acronym="ietfadminllc") + | models.Q(acronym="rfceditor"), state="active", ).order_by("type__order", "type_id", "acronym") @@ -72,7 +75,9 @@ def wg_menu(flavor): p.menu_url = "/program/" elif p.acronym == "ietfadminllc": p.menu_url = "/adm/" + elif p.acronym == "rfceditor": + p.menu_url = "/rfcedtyp/" return render_to_string( "base/menu_wg.html", {"parents": parents, "flavor": flavor} - ) \ No newline at end of file + ) diff --git a/ietf/group/migrations/0055_editorial_stream.py b/ietf/group/migrations/0055_editorial_stream.py new file mode 100644 index 000000000..a7dc9ca9c --- /dev/null +++ b/ietf/group/migrations/0055_editorial_stream.py @@ -0,0 +1,38 @@ +# Copyright The IETF Trust 2022 All Rights Reserved + +from django.db import migrations + +def forward(apps, schema_editor): + Group = apps.get_model('group', 'Group') + GroupFeatures = apps.get_model('group', 'GroupFeatures') + Group.objects.create( + acronym='editorial', + name='Editorial Stream', + state_id='active', + type_id='editorial', + parent=None, + ) + templ = GroupFeatures.objects.get(type='rfcedtyp') + templ.pk = None + templ.type_id='editorial' + templ.save() + + + +def reverse(apps, schema_editor): + Group = apps.get_model('group', 'Group') + GroupFeatures = apps.get_model('group', 'GroupFeatures') + GroupFeatures.objects.filter(type='editorial').delete() + Group.objects.filter(acronym='editorial').delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('group', '0054_enable_delegation'), + ('name', '0043_editorial_stream_grouptype'), + ] + + operations = [ + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/group/tests_info.py b/ietf/group/tests_info.py index 3487a9371..d015f270f 100644 --- a/ietf/group/tests_info.py +++ b/ietf/group/tests_info.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2009-2020, All Rights Reserved +# Copyright The IETF Trust 2009-2022, All Rights Reserved # -*- coding: utf-8 -*- @@ -68,7 +68,7 @@ class GroupPagesTests(TestCase): self.assertContains(r, group.name) self.assertContains(r, escape(group.ad_role().person.name)) - for t in ('rg','area','ag', 'rag', 'dir','review','team','program','iabasg','adm'): + for t in ('rg','area','ag', 'rag', 'dir','review','team','program','iabasg','adm','rfcedtyp'): g = GroupFactory.create(type_id=t,state_id='active') if t in ['dir','review']: g.parent = GroupFactory.create(type_id='area',state_id='active') @@ -84,7 +84,7 @@ class GroupPagesTests(TestCase): self.assertContains(r, "Directorate") self.assertContains(r, "AG") - for slug in GroupTypeName.objects.exclude(slug__in=['wg','rg','ag','rag','area','dir','review','team','program','adhoc','ise','adm','iabasg']).values_list('slug',flat=True): + for slug in GroupTypeName.objects.exclude(slug__in=['wg','rg','ag','rag','area','dir','review','team','program','adhoc','ise','adm','iabasg','rfcedtyp']).values_list('slug',flat=True): with self.assertRaises(NoReverseMatch): url=urlreverse('ietf.group.views.active_groups', kwargs=dict(group_type=slug)) diff --git a/ietf/group/views.py b/ietf/group/views.py index 5105c78ae..88267e788 100644 --- a/ietf/group/views.py +++ b/ietf/group/views.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright The IETF Trust 2009-2020, All Rights Reserved +# Copyright The IETF Trust 2009-2022, All Rights Reserved # # Portion Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). # All rights reserved. Contact: Pasi Eronen @@ -295,6 +295,8 @@ def active_groups(request, group_type=None): return active_iab(request) elif group_type == "adm": return active_adm(request) + elif group_type == "rfcedtyp": + return active_rfced(request) else: raise Http404 @@ -332,6 +334,11 @@ def active_adm(request): adm = Group.objects.filter(type="adm", state="active").order_by("parent","name") return render(request, 'group/active_adm.html', {'adm' : adm }) +def active_rfced(request): + rfced = Group.objects.filter(type="rfcedtyp", state="active").order_by("parent", "name") + return render(request, 'group/active_rfced.html', {'rfced' : rfced}) + + def active_areas(request): areas = Group.objects.filter(type="area", state="active").order_by("name") return render(request, 'group/active_areas.html', {'areas': areas }) @@ -1293,7 +1300,7 @@ def stream_edit(request, acronym): @cache_control(public=True, max_age=30*60) @cache_page(30 * 60) def group_menu_data(request): - groups = Group.objects.filter(state="active", parent__state="active").filter(Q(type__features__acts_like_wg=True)|Q(type_id__in=['program','iabasg'])|Q(parent__acronym='ietfadminllc')).order_by("-type_id","acronym") + groups = Group.objects.filter(state="active", parent__state="active").filter(Q(type__features__acts_like_wg=True)|Q(type_id__in=['program','iabasg'])|Q(parent__acronym='ietfadminllc')|Q(parent__acronym='rfceditor')).order_by("-type_id","acronym") groups_by_parent = defaultdict(list) for g in groups: diff --git a/ietf/ietfauth/utils.py b/ietf/ietfauth/utils.py index 087674686..c626b98b9 100644 --- a/ietf/ietfauth/utils.py +++ b/ietf/ietfauth/utils.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2013-2020, All Rights Reserved +# Copyright The IETF Trust 2013-2022, All Rights Reserved # -*- coding: utf-8 -*- @@ -64,7 +64,7 @@ def has_role(user, role_names, *args, **kwargs): "Secretariat": Q(person=person, name="secr", group__acronym="secretariat"), "IAB" : Q(person=person, name="member", group__acronym="iab"), "IANA": Q(person=person, name="auth", group__acronym="iana"), - "RFC Editor": Q(person=person, name="auth", group__acronym="rfceditor"), + "RFC Editor": Q(person=person, name="auth", group__acronym="rpc"), "ISE" : Q(person=person, name="chair", group__acronym="ise"), "IAD": Q(person=person, name="admdir", group__acronym="ietf"), "IETF Chair": Q(person=person, name="chair", group__acronym="ietf"), @@ -305,4 +305,4 @@ class OidcExtraScopeClaims(oidc_provider.lib.claims.ScopeClaims): } return info - \ No newline at end of file + diff --git a/ietf/name/admin.py b/ietf/name/admin.py index 0cd6265e8..dd659d113 100644 --- a/ietf/name/admin.py +++ b/ietf/name/admin.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2010-2020, All Rights Reserved +# Copyright The IETF Trust 2010-2022, All Rights Reserved from django.contrib import admin from ietf.name.models import ( @@ -18,7 +18,7 @@ from ietf.name.models import ( from ietf.stats.models import CountryAlias class NameAdmin(admin.ModelAdmin): - list_display = ["slug", "name", "desc", "used"] + list_display = ["slug", "name", "desc", "used", "order"] search_fields = ["slug", "name"] prepopulate_from = { "slug": ("name",) } @@ -96,4 +96,4 @@ admin.site.register(TopicAudienceName, NameAdmin) admin.site.register(DocUrlTagName, NameAdmin) admin.site.register(ExtResourceTypeName, NameAdmin) admin.site.register(SlideSubmissionStatusName, NameAdmin) -admin.site.register(SessionPurposeName, NameAdmin) \ No newline at end of file +admin.site.register(SessionPurposeName, NameAdmin) diff --git a/ietf/name/migrations/0041_update_rfcedtyp.py b/ietf/name/migrations/0041_update_rfcedtyp.py new file mode 100644 index 000000000..8ebae6aa1 --- /dev/null +++ b/ietf/name/migrations/0041_update_rfcedtyp.py @@ -0,0 +1,21 @@ +# Copyright The IETF Trust 2022 All Rights Reserved + +from django.db import migrations + +def forward(apps, schema_editor): + GroupTypeName = apps.get_model('name', 'GroupTypeName') + GroupTypeName.objects.filter(slug='rfcedtyp').update(order=2, verbose_name='RFC Editor Group') + +def reverse(apps, schema_editor): + GroupTypeName = apps.get_model('name', 'GroupTypeName') + GroupTypeName.objects.filter(slug='rfcedtyp').update(order=0, verbose_name='The RFC Editor') + +class Migration(migrations.Migration): + + dependencies = [ + ('name', '0040_remove_constraintname_editor_label'), + ] + + operations = [ + migrations.RunPython(forward,reverse), + ] diff --git a/ietf/name/migrations/0042_editorial_stream.py b/ietf/name/migrations/0042_editorial_stream.py new file mode 100644 index 000000000..1b9aaaf07 --- /dev/null +++ b/ietf/name/migrations/0042_editorial_stream.py @@ -0,0 +1,30 @@ +# Copyright The IETF Trust 2022 All Rights Reserved + +from django.db import migrations + +def forward(apps, schema_editor): + StreamName = apps.get_model('name', 'StreamName') + StreamName.objects.create( + slug = 'editorial', + name = 'Editorial', + desc = 'Editorial', + used = True, + order = 5, + ) + StreamName.objects.filter(slug='legacy').update(order=6) + + +def reverse(apps, schema_editor): + StreamName = apps.get_model('name', 'StreamName') + StreamName.objects.filter(slug='editorial').delete() + StreamName.objects.filter(slug='legacy').update(order=5) + +class Migration(migrations.Migration): + + dependencies = [ + ('name', '0041_update_rfcedtyp'), + ] + + operations = [ + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/name/migrations/0043_editorial_stream_grouptype.py b/ietf/name/migrations/0043_editorial_stream_grouptype.py new file mode 100644 index 000000000..5fe839174 --- /dev/null +++ b/ietf/name/migrations/0043_editorial_stream_grouptype.py @@ -0,0 +1,26 @@ +# Copyright The IETF Trust 2022 All Rights Reserved + +from django.db import migrations + +def forward(apps, schema_editor): + GroupTypeName = apps.get_model('name', 'GroupTypeName') + GroupTypeName.objects.create( + slug = 'editorial', + name = 'Editorial', + desc = 'Editorial Stream Group', + used = True, + ) + +def reverse(apps, schema_editor): + GroupTypeName = apps.get_model('name', 'GroupTypeName') + GroupTypeName.objects.filter(slug='editorial').delete() + +class Migration(migrations.Migration): + + dependencies = [ + ('name', '0042_editorial_stream'), + ] + + operations = [ + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/templates/base/menu.html b/ietf/templates/base/menu.html index 33a1cda0a..2d6f53de5 100644 --- a/ietf/templates/base/menu.html +++ b/ietf/templates/base/menu.html @@ -208,6 +208,12 @@ ISE +
  • + + Editorial + +
  • {% if flavor == 'top' %} diff --git a/ietf/templates/group/active_rfced.html b/ietf/templates/group/active_rfced.html new file mode 100644 index 000000000..78dacfa4c --- /dev/null +++ b/ietf/templates/group/active_rfced.html @@ -0,0 +1,42 @@ +{% extends "base.html" %} +{# Copyright The IETF Trust 2022, All Rights Reserved #} +{% load origin static person_filters %} +{% block pagehead %} + +{% endblock %} +{% block title %}Active RFC Editor Groups{% endblock %} +{% block content %} + {% origin %} +

    Active RFC Editor Groups

    + + + + + + + + {% regroup rfced by parent as grouped_groups %} + {% for grouptype in grouped_groups %} + + + + + + + {% for group in grouptype.list %} + + + + + {% endfor %} + + {% endfor %} +
    GroupName
    + Active {% firstof grouptype.grouper.verbose_name grouptype.grouper.name 'Top-level Organization' %} Groups +
    + {{ group.acronym }} + {{ group.name }}
    +{% endblock %} +{% block js %} + +{% endblock %} diff --git a/ietf/templates/group/index.html b/ietf/templates/group/index.html index a2e0be706..9930c140a 100644 --- a/ietf/templates/group/index.html +++ b/ietf/templates/group/index.html @@ -1,5 +1,5 @@ {% extends "base.html" %} -{# Copyright The IETF Trust 2015, All Rights Reserved #} +{# Copyright The IETF Trust 2015-2022, All Rights Reserved #} {% load origin static person_filters %} {% load ietf_filters %} {% block pagehead %} @@ -27,7 +27,7 @@ {% with stream.get_chair as role %} {% person_link role.person %} - {{ role.name }} + {% if role %}{{ role.name }}{% endif %} {% endwith %} @@ -37,4 +37,4 @@ {% endblock %} {% block js %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/ietf/urls.py b/ietf/urls.py index fbe746751..17a0fd5f4 100644 --- a/ietf/urls.py +++ b/ietf/urls.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2007-2019, All Rights Reserved +# Copyright The IETF Trust 2007-2022, All Rights Reserved from django.conf import settings from django.conf.urls import include @@ -67,7 +67,7 @@ urlpatterns = [ url(r'^submit/', include('ietf.submit.urls')), url(r'^sync/', include('ietf.sync.urls')), url(r'^templates/', include('ietf.dbtemplate.urls')), - url(r'^(?P(wg|rg|ag|rag|team|dir|review|area|program|iabasg|adhoc|ise|adm))/', include(grouptype_urls)), + url(r'^(?P(wg|rg|ag|rag|team|dir|review|area|program|iabasg|adhoc|ise|adm|rfcedtyp))/', include(grouptype_urls)), # Redirects url(r'^(?Ppublic)/', include('ietf.redirects.urls')), @@ -96,4 +96,4 @@ if getattr(settings, 'USE_DEBUG_TOOLBAR', False): import debug_toolbar urlpatterns = urlpatterns + [path('__debug__/', include(debug_toolbar.urls)), ] except ImportError: - pass \ No newline at end of file + pass diff --git a/ietf/utils/test_data.py b/ietf/utils/test_data.py index 1281756da..7a7a77af4 100644 --- a/ietf/utils/test_data.py +++ b/ietf/utils/test_data.py @@ -1,4 +1,4 @@ -# Copyright The IETF Trust 2011-2020, All Rights Reserved +# Copyright The IETF Trust 2011-2022, All Rights Reserved # -*- coding: utf-8 -*- @@ -89,8 +89,8 @@ def make_immutable_base_data(): iana = create_group(name="IANA", acronym="iana", type_id="iana") create_person(iana, "auth", name="Iña Iana", username="iana", email_address="iana@ia.na") - rfc_editor = create_group(name="RFC Editor", acronym="rfceditor", type_id="rfcedtyp") - create_person(rfc_editor, "auth", name="Rfc Editor", username="rfc", email_address="rfc@edit.or") + rpc = create_group(name="RFC Production Center", acronym="rpc", type_id="rfcedtyp") + create_person(rpc, "auth", name="Rfc Editor", username="rfc", email_address="rfc@edit.or") iesg = create_group(name="Internet Engineering Steering Group", acronym="iesg", type_id="ietf", parent=ietf) # pyflakes:ignore irsg = create_group(name="Internet Research Steering Group", acronym="irsg", type_id="irtf", parent=irtf) # pyflakes:ignore