From da0a217a8cb8ea27598ce8ab83e4661235ffdf6f Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Thu, 6 Jun 2024 15:10:24 -0300 Subject: [PATCH 1/4] feat: use surname/initials for author name (#7510) * feat: use surname/initials for author name * test: test new method * fix: handle case where author name is empty --- ietf/templates/submit/announce_to_lists.txt | 2 +- ietf/templates/submit/approval_request.txt | 2 +- ietf/templates/submit/manual_post_request.txt | 2 +- ietf/templates/submit/submission_status.html | 2 +- ietf/templates/submit/submitter_form.html | 14 +++--- ietf/utils/tests.py | 45 +++++++++++++++++++ ietf/utils/xmldraft.py | 25 ++++++++++- 7 files changed, 81 insertions(+), 11 deletions(-) diff --git a/ietf/templates/submit/announce_to_lists.txt b/ietf/templates/submit/announce_to_lists.txt index d7a3739af6..cf1c8b325b 100644 --- a/ietf/templates/submit/announce_to_lists.txt +++ b/ietf/templates/submit/announce_to_lists.txt @@ -1,7 +1,7 @@ {% autoescape off %}{% filter wordwrap:78 %}Internet-Draft {{ submission.name }}-{{ submission.rev }}.txt is now available.{% if submission.group %} It is a work item of the {{ submission.group.name }} ({{ submission.group.acronym|upper }}){% if submission.group.type.name %} {{ submission.group.type.name }}{% endif %} of the {% if submission.group.type_id == "rg" %}IRTF{% else %}IETF{% endif %}.{% endif %}{% endfilter %} Title: {{ submission.title }} - Author{{ submission.authors|pluralize:",s" }}: {% if submission.authors|length == 1 %} {% endif %}{% for author in submission.authors %}{{ author.name }}{% if not forloop.last %} + Author{{ submission.authors|pluralize:",s" }}: {% if submission.authors|length == 1 %} {% endif %}{% for author in submission.authors %}{% firstof author.name author.affiliation "Unknown" %}{% if not forloop.last %} {% endif %}{% endfor %} Name: {{ submission.name }}-{{ submission.rev }}.txt Pages: {{ submission.pages }} diff --git a/ietf/templates/submit/approval_request.txt b/ietf/templates/submit/approval_request.txt index 9186e556fc..7b9609a129 100644 --- a/ietf/templates/submit/approval_request.txt +++ b/ietf/templates/submit/approval_request.txt @@ -24,7 +24,7 @@ To approve the Internet-Draft, go to this URL (note: you need to login to be abl Authors: -{% for author in submission.authors %} {{ author.name }}{% if author.email %} <{{ author.email }}>{% endif%} +{% for author in submission.authors %} {% if author.name or author.affiliation %}{% firstof author.name author.affiliation %} {% endif %}{% if author.email %}<{{ author.email }}>{% endif %} {% endfor %} {% endautoescape %} diff --git a/ietf/templates/submit/manual_post_request.txt b/ietf/templates/submit/manual_post_request.txt index 7b515fbeb0..7fe19e9a23 100644 --- a/ietf/templates/submit/manual_post_request.txt +++ b/ietf/templates/submit/manual_post_request.txt @@ -33,7 +33,7 @@ I-D Submission Tool URL: Authors: -{% for author in submission.authors %} {{ author.name }}{% if author.email %} <{{ author.email }}>{% endif%} +{% for author in submission.authors %} {% if author.name or author.affiliation %}{% firstof author.name author.affiliation %} {% endif %}{% if author.email %}<{{ author.email }}>{% endif %} {% endfor %} Comment to the secretariat: diff --git a/ietf/templates/submit/submission_status.html b/ietf/templates/submit/submission_status.html index 733b4217a0..cdc5dd4007 100644 --- a/ietf/templates/submit/submission_status.html +++ b/ietf/templates/submit/submission_status.html @@ -285,7 +285,7 @@

Meta-data from the submission

Author {{ forloop.counter }} - {{ author.name }} + {% if author.name %}{{ author.name }}{% endif %} {% if author.email %}<{{ author.email|linkify }}>{% endif %}
{% if author.affiliation %} diff --git a/ietf/templates/submit/submitter_form.html b/ietf/templates/submit/submitter_form.html index 1cf77260ee..65b9ba5094 100644 --- a/ietf/templates/submit/submitter_form.html +++ b/ietf/templates/submit/submitter_form.html @@ -11,12 +11,14 @@

Submitter

{% load ietf_filters %} {% for author in submission.authors %} - + {% if author.name %} + + {% endif %} {% endfor %} {% bootstrap_form_errors submitter_form %} {% bootstrap_field submitter_form.name %} diff --git a/ietf/utils/tests.py b/ietf/utils/tests.py index 4ac2732ed8..08adefc826 100644 --- a/ietf/utils/tests.py +++ b/ietf/utils/tests.py @@ -486,6 +486,51 @@ def test_parse_docname(self): ("-01", None), ) + def test_render_author_name(self): + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element("author", fullname="Joanna Q. Public")), + "Joanna Q. Public", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + fullname="Joanna Q. Public", + asciiFullname="Not the Same at All", + )), + "Joanna Q. Public", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + fullname="Joanna Q. Public", + initials="J. Q.", + surname="Public-Private", + )), + "Joanna Q. Public", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + initials="J. Q.", + surname="Public", + )), + "J. Q. Public", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + surname="Public", + )), + "Public", + ) + self.assertEqual( + XMLDraft.render_author_name(lxml.etree.Element( + "author", + initials="J. Q.", + )), + "J. Q.", + ) + class NameTests(TestCase): diff --git a/ietf/utils/xmldraft.py b/ietf/utils/xmldraft.py index 3a9ac02b1d..c39c4d0a06 100644 --- a/ietf/utils/xmldraft.py +++ b/ietf/utils/xmldraft.py @@ -179,6 +179,29 @@ def get_creation_date(self): # abstract = self.xmlroot.findtext('front/abstract') # return abstract.strip() if abstract else '' + @staticmethod + def render_author_name(author_elt): + """Get a displayable name for an author, if possible + + Based on TextWriter.render_author_name() from xml2rfc. If fullname is present, uses that. + If not, uses either initials + surname or just surname. Finally, returns None because this + author is evidently an organization, not a person. + + Does not involve ascii* attributes because rfc7991 requires fullname if any of those are + present. + """ + # Use fullname attribute, if present + fullname = author_elt.attrib.get("fullname", "").strip() + if fullname: + return fullname + surname = author_elt.attrib.get("surname", "").strip() + initials = author_elt.attrib.get("initials", "").strip() + if surname or initials: + # This allows the possibility that only initials are used, which is a bit nonsensical + # but seems to be technically allowed by RFC 7991. + return f"{initials} {surname}".strip() + return None + def get_author_list(self): """Get detailed author list @@ -197,7 +220,7 @@ def get_author_list(self): for author in self.xmlroot.findall('front/author'): info = { - 'name': author.attrib.get('fullname'), + 'name': self.render_author_name(author), 'email': author.findtext('address/email'), 'affiliation': author.findtext('organization'), } From c5aaab74b86975664157f72d27a1f93533e6908b Mon Sep 17 00:00:00 2001 From: Robert Sparks Date: Thu, 6 Jun 2024 13:11:54 -0500 Subject: [PATCH 2/4] fix: mailman3 links for nonwg lists (#7507) --- ietf/group/views.py | 2 +- ietf/mailinglists/admin.py | 4 +- ietf/mailinglists/factories.py | 1 + .../0004_nonwgmailinglist_domain.py | 59 +++++++++++++++++++ ietf/mailinglists/models.py | 3 +- ietf/mailinglists/resources.py | 1 + ietf/mailinglists/tests.py | 2 + ietf/settings.py | 2 +- 8 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 ietf/mailinglists/migrations/0004_nonwgmailinglist_domain.py diff --git a/ietf/group/views.py b/ietf/group/views.py index 7ad6e5bf02..0c37cca3a0 100644 --- a/ietf/group/views.py +++ b/ietf/group/views.py @@ -313,7 +313,7 @@ def active_wgs(request): if group.list_subscribe.startswith('http'): group.list_subscribe_url = group.list_subscribe elif group.list_email.endswith('@ietf.org'): - group.list_subscribe_url = MAILING_LIST_INFO_URL % {'list_addr':group.list_email.split('@')[0]} + group.list_subscribe_url = MAILING_LIST_INFO_URL % {'list_addr':group.list_email.split('@')[0].lower(),'domain':'ietf.org'} else: group.list_subscribe_url = "mailto:"+group.list_subscribe diff --git a/ietf/mailinglists/admin.py b/ietf/mailinglists/admin.py index 51b906053f..081ee6477c 100644 --- a/ietf/mailinglists/admin.py +++ b/ietf/mailinglists/admin.py @@ -8,8 +8,8 @@ class NonWgMailingListAdmin(admin.ModelAdmin): - list_display = ('id', 'name', 'description') - search_fields = ('name',) + list_display = ('id', 'name', 'domain', 'description') + search_fields = ('name', 'domain') admin.site.register(NonWgMailingList, NonWgMailingListAdmin) diff --git a/ietf/mailinglists/factories.py b/ietf/mailinglists/factories.py index 1a3b0ffa1f..3be5770d76 100644 --- a/ietf/mailinglists/factories.py +++ b/ietf/mailinglists/factories.py @@ -11,6 +11,7 @@ class Meta: model = NonWgMailingList name = factory.Sequence(lambda n: "list-name-%s" % n) + domain = factory.Sequence(lambda n: "domain-%s.org" % n) description = factory.Faker('sentence', nb_words=10) diff --git a/ietf/mailinglists/migrations/0004_nonwgmailinglist_domain.py b/ietf/mailinglists/migrations/0004_nonwgmailinglist_domain.py new file mode 100644 index 0000000000..b977313a87 --- /dev/null +++ b/ietf/mailinglists/migrations/0004_nonwgmailinglist_domain.py @@ -0,0 +1,59 @@ +# Generated by Django 4.2.13 on 2024-06-05 17:51 + +from django.db import migrations, models +from django.db.models.functions import Lower + +IAB_NAMES = ["iab", "iab-stream"] +RFCED_NAMES = [ + "auth48archive", + "rfc-dist", + "rfc-editor-rfi", + "rfc-interest", + "rpat", + "rsab", +] +IRTF_NAMES = [ + "anrp-select", + "anrw-sc", + "anrw-tpc", + "crypto-panel", + "dtn-interest", + "irsg", + "irtf-announce", + "smart", + "teaching", + "travel-grants-commitee", +] + + +def forward(apps, schema_editor): + NonWgMailingList = apps.get_model("mailinglists", "NonWgMailingList") + NonWgMailingList.objects.annotate(lowername=Lower("name")).filter( + lowername__in=IAB_NAMES + ).update(domain="iab.org") + NonWgMailingList.objects.annotate(lowername=Lower("name")).filter( + lowername__in=IRTF_NAMES + ).update(domain="irtf.org") + NonWgMailingList.objects.annotate(lowername=Lower("name")).filter( + lowername__in=RFCED_NAMES + ).update(domain="rfc-editor.org") + + +def reverse(apps, schema_editor): + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ("mailinglists", "0003_remove_subscribed_lists_delete_list_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="nonwgmailinglist", + name="domain", + field=models.CharField(default="ietf.org", max_length=32), + ), + migrations.RunPython(forward, reverse), + ] diff --git a/ietf/mailinglists/models.py b/ietf/mailinglists/models.py index f575ffe5a4..828d3823a4 100644 --- a/ietf/mailinglists/models.py +++ b/ietf/mailinglists/models.py @@ -14,12 +14,13 @@ # while decoupling from mailman2 until we integrate with mailman3 class NonWgMailingList(models.Model): name = models.CharField(max_length=32) + domain = models.CharField(max_length=32, default="ietf.org") description = models.CharField(max_length=256) def __str__(self): return "" % self.name def info_url(self): - return settings.MAILING_LIST_INFO_URL % {'list_addr': self.name } + return settings.MAILING_LIST_INFO_URL % {'list_addr': self.name.lower(), 'domain': self.domain.lower() } # Allowlisted is unused, but is not being dropped until its human-curated content # is archived outside this database. diff --git a/ietf/mailinglists/resources.py b/ietf/mailinglists/resources.py index b075d18079..4d1713b7b6 100644 --- a/ietf/mailinglists/resources.py +++ b/ietf/mailinglists/resources.py @@ -41,6 +41,7 @@ class Meta: filtering = { "id": ALL, "name": ALL, + "domain": ALL, "description": ALL, } api.mailinglists.register(NonWgMailingListResource()) diff --git a/ietf/mailinglists/tests.py b/ietf/mailinglists/tests.py index 0b44d28c71..8c5a550dfc 100644 --- a/ietf/mailinglists/tests.py +++ b/ietf/mailinglists/tests.py @@ -38,7 +38,9 @@ def test_nonwg(self): url = urlreverse("ietf.mailinglists.views.nonwg") r = self.client.get(url) + q = PyQuery(r.content) for l in lists: self.assertContains(r, l.name) self.assertContains(r, l.description) + self.assertNotEqual(q(f"a[href=\"{l.info_url()}\"]"), []) diff --git a/ietf/settings.py b/ietf/settings.py index 95a8ad4e45..4f0bba20a9 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -690,7 +690,7 @@ def skip_unreadable_post(record): DOCUMENT_FORMAT_ALLOWLIST = ["txt", "ps", "pdf", "xml", "html", ] # Mailing list info URL for lists hosted on the IETF servers -MAILING_LIST_INFO_URL = "https://www.ietf.org/mailman/listinfo/%(list_addr)s" +MAILING_LIST_INFO_URL = "https://mailman3.%(domain)s/mailman3/lists/%(list_addr)s.%(domain)s" MAILING_LIST_ARCHIVE_URL = "https://mailarchive.ietf.org" # Liaison Statement Tool settings (one is used in DOC_HREFS below) From 3e09c14a81d2712040ae8871c22f3cc81f04e41e Mon Sep 17 00:00:00 2001 From: Matthew Holloway Date: Fri, 7 Jun 2024 06:38:14 +1200 Subject: [PATCH 3/4] fix: Scroll metadata sidebar tab content (#7499) * Scroll metadata sidebar tab content * Increase spacing for scrollbars for browsers that allow overlapping --------- Co-authored-by: Matthew Holloway --- ietf/templates/doc/document_html.html | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/ietf/templates/doc/document_html.html b/ietf/templates/doc/document_html.html index ef1ba7d48f..40223d0fd1 100644 --- a/ietf/templates/doc/document_html.html +++ b/ietf/templates/doc/document_html.html @@ -172,9 +172,10 @@