ci: merge main to release (#7513)

ci: merge main to release
This commit is contained in:
Robert Sparks 2024-06-07 08:57:21 -05:00 committed by GitHub
commit 3509d75822
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 168 additions and 27 deletions

View file

@ -355,7 +355,7 @@ have been written, has been sent by email and thus don't exist as a collection
in one place.</p> in one place.</p>
<p>With my recent investigations of code analysis tools, I thought it might be <p>With my recent investigations of code analysis tools, I thought it might be
a good idea to start collecting these in one place for the project.</p> a good idea to start collecting these in one place for the project.</p>
<blockquote> <blockquote style="border-left: 0">
<cite>Henrik &lt;henrik&#64;levkowetz.com&gt;, 23 Mar 2014</cite></blockquote> <cite>Henrik &lt;henrik&#64;levkowetz.com&gt;, 23 Mar 2014</cite></blockquote>
</div> </div>
<div class="section" id="code-analysis-tools"> <div class="section" id="code-analysis-tools">
@ -398,8 +398,9 @@ the possibility of triggering unwanted side effects of doing an analysis run.</p
do the right thing, but once it was made to run on the datatracker code, and do the right thing, but once it was made to run on the datatracker code, and
ignore the django code, it didn't report anything that PyFlakes hadn't already ignore the django code, it didn't report anything that PyFlakes hadn't already
caught.</p> caught.</p>
<blockquote> <blockquote style="border-left: 0">
<cite>Henrik &lt;henrik&#64;levkowetz.com&gt;, 23 Mar 2014</cite></blockquote> <cite>Henrik &lt;henrik&#64;levkowetz.com&gt;, 23 Mar 2014</cite>
</blockquote>
</div> </div>
</div> </div>
</div> </div>

View file

@ -313,7 +313,7 @@ def active_wgs(request):
if group.list_subscribe.startswith('http'): if group.list_subscribe.startswith('http'):
group.list_subscribe_url = group.list_subscribe group.list_subscribe_url = group.list_subscribe
elif group.list_email.endswith('@ietf.org'): 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: else:
group.list_subscribe_url = "mailto:"+group.list_subscribe group.list_subscribe_url = "mailto:"+group.list_subscribe

View file

@ -8,8 +8,8 @@ from ietf.mailinglists.models import NonWgMailingList, Allowlisted
class NonWgMailingListAdmin(admin.ModelAdmin): class NonWgMailingListAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'description') list_display = ('id', 'name', 'domain', 'description')
search_fields = ('name',) search_fields = ('name', 'domain')
admin.site.register(NonWgMailingList, NonWgMailingListAdmin) admin.site.register(NonWgMailingList, NonWgMailingListAdmin)

View file

@ -11,6 +11,7 @@ class NonWgMailingListFactory(factory.django.DjangoModelFactory):
model = NonWgMailingList model = NonWgMailingList
name = factory.Sequence(lambda n: "list-name-%s" % n) 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) description = factory.Faker('sentence', nb_words=10)

View file

@ -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),
]

View file

@ -14,12 +14,13 @@ from ietf.utils.models import ForeignKey
# while decoupling from mailman2 until we integrate with mailman3 # while decoupling from mailman2 until we integrate with mailman3
class NonWgMailingList(models.Model): class NonWgMailingList(models.Model):
name = models.CharField(max_length=32) name = models.CharField(max_length=32)
domain = models.CharField(max_length=32, default="ietf.org")
description = models.CharField(max_length=256) description = models.CharField(max_length=256)
def __str__(self): def __str__(self):
return "<NonWgMailingList: %s>" % self.name return "<NonWgMailingList: %s>" % self.name
def info_url(self): 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 # Allowlisted is unused, but is not being dropped until its human-curated content
# is archived outside this database. # is archived outside this database.

View file

@ -41,6 +41,7 @@ class NonWgMailingListResource(ModelResource):
filtering = { filtering = {
"id": ALL, "id": ALL,
"name": ALL, "name": ALL,
"domain": ALL,
"description": ALL, "description": ALL,
} }
api.mailinglists.register(NonWgMailingListResource()) api.mailinglists.register(NonWgMailingListResource())

View file

@ -38,7 +38,9 @@ class MailingListTests(TestCase):
url = urlreverse("ietf.mailinglists.views.nonwg") url = urlreverse("ietf.mailinglists.views.nonwg")
r = self.client.get(url) r = self.client.get(url)
q = PyQuery(r.content)
for l in lists: for l in lists:
self.assertContains(r, l.name) self.assertContains(r, l.name)
self.assertContains(r, l.description) self.assertContains(r, l.description)
self.assertNotEqual(q(f"a[href=\"{l.info_url()}\"]"), [])

View file

@ -3,7 +3,7 @@
<b>Does anyone have an objection to the creation of this working group being sent for EXTERNAL REVIEW?</b><br><br> <b>Does anyone have an objection to the creation of this working group being sent for EXTERNAL REVIEW?</b><br><br>
<input type="radio" name="wg_action_status" value="1"> External Review APPROVED; "The Secretariat will send a Working Group Review announcement with a copy to new-work and place it back on the agenda for the next telechat."<br><br> <input type="radio" name="wg_action_status" value="1"> External Review APPROVED; "The Secretariat will send a Working Group Review announcement with a copy to new-work and place it back on the agenda for the next telechat."<br><br>
<input type="radio" name="wg_action_status" value="2"> External Review NOT APPROVED; <input type="radio" name="wg_action_status" value="2"> External Review NOT APPROVED;
<blockquote> <blockquote style="border-left: 0">
<input type="radio" name="wg_action_status_sub" value="1"> The Secretariat will wait for instructions from <select name="note_draft_by"></select><br> <input type="radio" name="wg_action_status_sub" value="1"> The Secretariat will wait for instructions from <select name="note_draft_by"></select><br>
<input type="radio" name="wg_action_status_sub" value="2"> The IESG decides the document needs more time in INTERNAL REVIEW. The Secretariat will put it back on the agenda for the next teleconference in the same category.<br> <input type="radio" name="wg_action_status_sub" value="2"> The IESG decides the document needs more time in INTERNAL REVIEW. The Secretariat will put it back on the agenda for the next teleconference in the same category.<br>
<input type="radio" name="wg_action_status_sub" value="3"> The IESG has made changes since the charter was seen in INTERNAL REVIEW, and decides to send it back to INTERNAL REVIEW the charter again. <input type="radio" name="wg_action_status_sub" value="3"> The IESG has made changes since the charter was seen in INTERNAL REVIEW, and decides to send it back to INTERNAL REVIEW the charter again.

View file

@ -690,7 +690,7 @@ ALL_ID_DOWNLOAD_DIR = '/a/www/www6s/download'
DOCUMENT_FORMAT_ALLOWLIST = ["txt", "ps", "pdf", "xml", "html", ] DOCUMENT_FORMAT_ALLOWLIST = ["txt", "ps", "pdf", "xml", "html", ]
# Mailing list info URL for lists hosted on the IETF servers # 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" MAILING_LIST_ARCHIVE_URL = "https://mailarchive.ietf.org"
# Liaison Statement Tool settings (one is used in DOC_HREFS below) # Liaison Statement Tool settings (one is used in DOC_HREFS below)

View file

@ -1183,3 +1183,8 @@ td.position-empty {
} }
} }
} }
blockquote {
padding-left: 1rem;
border-left: solid 1px var(--bs-body-color);
}

View file

@ -172,9 +172,10 @@
</div> </div>
<div class="d-print-none col-md-3 bg-light-subtle collapse{% if request.COOKIES.sidebar != 'off'%} show{% endif %}" id="sidebar"> <div class="d-print-none col-md-3 bg-light-subtle collapse{% if request.COOKIES.sidebar != 'off'%} show{% endif %}" id="sidebar">
<div class="position-fixed border-start sidebar overflow-scroll overscroll-none no-scrollbar"> <div class="position-fixed border-start sidebar overflow-scroll overscroll-none no-scrollbar">
<div class="pt-2 pt-lg-3 px-md-2 px-lg-3"> <div class="d-flex flex-column vh-100 pt-2 pt-lg-3 ps-3 pl-md-2 pl-lg-3">
<a class="btn btn-primary btn-sm" href="{% url 'ietf.doc.views_doc.document_main' name=doc.name %}">Datatracker</a> <div>
<p class="fw-bold pt-2"> <a class="btn btn-primary btn-sm" href="{% url 'ietf.doc.views_doc.document_main' name=doc.name %}">Datatracker</a>
<p class="fw-bold pt-2">
{% if doc.type_id == "rfc" %} {% if doc.type_id == "rfc" %}
RFC {{ doc.rfc_number }} RFC {{ doc.rfc_number }}
{% else %} {% else %}
@ -188,8 +189,8 @@
Internet-Draft Internet-Draft
{% endif %} {% endif %}
</span> </span>
</p>
</p> </div>
{% if request.COOKIES.htmlconf and request.COOKIES.htmlconf != 'html' and html %} {% if request.COOKIES.htmlconf and request.COOKIES.htmlconf != 'html' and html %}
<div class="alert alert-info small"> <div class="alert alert-info small">
You are viewing the legacy <code><a class="text-decoration-none text-reset" href="https://github.com/ietf-tools/rfc2html">rfc2html</a></code> You are viewing the legacy <code><a class="text-decoration-none text-reset" href="https://github.com/ietf-tools/rfc2html">rfc2html</a></code>
@ -204,7 +205,7 @@
HTML is available for this document. HTML is available for this document.
</div> </div>
{% endif %} {% endif %}
<ul class="nav nav-tabs nav-fill small" role="tablist"> <ul class="nav nav-tabs nav-fill small me-2" role="tablist">
<li class="nav-item" role="presentation" title="Document information"> <li class="nav-item" role="presentation" title="Document information">
<button class="nav-link px-2" <button class="nav-link px-2"
id="docinfo-tab" id="docinfo-tab"
@ -242,7 +243,7 @@
</button> </button>
</li> </li>
</ul> </ul>
<div class="tab-content pt-2"> <div class="overflow-auto tab-content pt-2 me-2">
<div class="tab-pane" <div class="tab-pane"
id="docinfo-tab-pane" id="docinfo-tab-pane"
role="tabpanel" role="tabpanel"

View file

@ -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 %} {% 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 }} 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 %} {% endif %}{% endfor %}
Name: {{ submission.name }}-{{ submission.rev }}.txt Name: {{ submission.name }}-{{ submission.rev }}.txt
Pages: {{ submission.pages }} Pages: {{ submission.pages }}

View file

@ -24,7 +24,7 @@ To approve the Internet-Draft, go to this URL (note: you need to login to be abl
Authors: 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 %} {% endfor %}
{% endautoescape %} {% endautoescape %}

View file

@ -33,7 +33,7 @@ I-D Submission Tool URL:
Authors: 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 %} {% endfor %}
Comment to the secretariat: Comment to the secretariat:

View file

@ -285,7 +285,7 @@
<tr> <tr>
<th scope="row">Author {{ forloop.counter }}</th> <th scope="row">Author {{ forloop.counter }}</th>
<td> <td>
{{ author.name }} {% if author.name %}{{ author.name }}{% endif %}
{% if author.email %}&lt;{{ author.email|linkify }}&gt;{% endif %} {% if author.email %}&lt;{{ author.email|linkify }}&gt;{% endif %}
<br> <br>
{% if author.affiliation %} {% if author.affiliation %}

View file

@ -11,12 +11,14 @@
</p> </p>
{% load ietf_filters %} {% load ietf_filters %}
{% for author in submission.authors %} {% for author in submission.authors %}
<button type="button" {% if author.name %}
class="author btn btn-primary mb-3" <button type="button"
data-name="{{ author.name }}" class="author btn btn-primary mb-3"
data-email="{% if author.email %}{{ author.email }}{% endif %}"> data-name="{{ author.name }}"
{{ author.name }} data-email="{% if author.email %}{{ author.email }}{% endif %}">
</button> {{ author.name }}
</button>
{% endif %}
{% endfor %} {% endfor %}
{% bootstrap_form_errors submitter_form %} {% bootstrap_form_errors submitter_form %}
{% bootstrap_field submitter_form.name %} {% bootstrap_field submitter_form.name %}

View file

@ -486,6 +486,51 @@ class XMLDraftTests(TestCase):
("-01", None), ("-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): class NameTests(TestCase):

View file

@ -179,6 +179,29 @@ class XMLDraft(Draft):
# abstract = self.xmlroot.findtext('front/abstract') # abstract = self.xmlroot.findtext('front/abstract')
# return abstract.strip() if abstract else '' # 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): def get_author_list(self):
"""Get detailed author list """Get detailed author list
@ -197,7 +220,7 @@ class XMLDraft(Draft):
for author in self.xmlroot.findall('front/author'): for author in self.xmlroot.findall('front/author'):
info = { info = {
'name': author.attrib.get('fullname'), 'name': self.render_author_name(author),
'email': author.findtext('address/email'), 'email': author.findtext('address/email'),
'affiliation': author.findtext('organization'), 'affiliation': author.findtext('organization'),
} }