commit
3509d75822
|
@ -355,7 +355,7 @@ have been written, has been sent by email and thus don't exist as a collection
|
|||
in one place.</p>
|
||||
<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>
|
||||
<blockquote>
|
||||
<blockquote style="border-left: 0">
|
||||
<cite>Henrik <henrik@levkowetz.com>, 23 Mar 2014</cite></blockquote>
|
||||
</div>
|
||||
<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
|
||||
ignore the django code, it didn't report anything that PyFlakes hadn't already
|
||||
caught.</p>
|
||||
<blockquote>
|
||||
<cite>Henrik <henrik@levkowetz.com>, 23 Mar 2014</cite></blockquote>
|
||||
<blockquote style="border-left: 0">
|
||||
<cite>Henrik <henrik@levkowetz.com>, 23 Mar 2014</cite>
|
||||
</blockquote>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ from ietf.mailinglists.models import NonWgMailingList, Allowlisted
|
|||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ class NonWgMailingListFactory(factory.django.DjangoModelFactory):
|
|||
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)
|
||||
|
||||
|
||||
|
|
59
ietf/mailinglists/migrations/0004_nonwgmailinglist_domain.py
Normal file
59
ietf/mailinglists/migrations/0004_nonwgmailinglist_domain.py
Normal 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),
|
||||
]
|
|
@ -14,12 +14,13 @@ from ietf.utils.models import ForeignKey
|
|||
# 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 "<NonWgMailingList: %s>" % 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.
|
||||
|
|
|
@ -41,6 +41,7 @@ class NonWgMailingListResource(ModelResource):
|
|||
filtering = {
|
||||
"id": ALL,
|
||||
"name": ALL,
|
||||
"domain": ALL,
|
||||
"description": ALL,
|
||||
}
|
||||
api.mailinglists.register(NonWgMailingListResource())
|
||||
|
|
|
@ -38,7 +38,9 @@ class MailingListTests(TestCase):
|
|||
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()}\"]"), [])
|
||||
|
||||
|
|
|
@ -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>
|
||||
<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;
|
||||
<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="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.
|
||||
|
|
|
@ -690,7 +690,7 @@ ALL_ID_DOWNLOAD_DIR = '/a/www/www6s/download'
|
|||
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)
|
||||
|
|
|
@ -1183,3 +1183,8 @@ td.position-empty {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding-left: 1rem;
|
||||
border-left: solid 1px var(--bs-body-color);
|
||||
}
|
||||
|
|
|
@ -172,9 +172,10 @@
|
|||
</div>
|
||||
<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="pt-2 pt-lg-3 px-md-2 px-lg-3">
|
||||
<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">
|
||||
<div class="d-flex flex-column vh-100 pt-2 pt-lg-3 ps-3 pl-md-2 pl-lg-3">
|
||||
<div>
|
||||
<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" %}
|
||||
RFC {{ doc.rfc_number }}
|
||||
{% else %}
|
||||
|
@ -188,8 +189,8 @@
|
|||
Internet-Draft
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
</p>
|
||||
</p>
|
||||
</div>
|
||||
{% if request.COOKIES.htmlconf and request.COOKIES.htmlconf != 'html' and html %}
|
||||
<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>
|
||||
|
@ -204,7 +205,7 @@
|
|||
HTML is available for this document.
|
||||
</div>
|
||||
{% 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">
|
||||
<button class="nav-link px-2"
|
||||
id="docinfo-tab"
|
||||
|
@ -242,7 +243,7 @@
|
|||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content pt-2">
|
||||
<div class="overflow-auto tab-content pt-2 me-2">
|
||||
<div class="tab-pane"
|
||||
id="docinfo-tab-pane"
|
||||
role="tabpanel"
|
||||
|
|
|
@ -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 }}
|
||||
|
|
|
@ -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 %}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -285,7 +285,7 @@
|
|||
<tr>
|
||||
<th scope="row">Author {{ forloop.counter }}</th>
|
||||
<td>
|
||||
{{ author.name }}
|
||||
{% if author.name %}{{ author.name }}{% endif %}
|
||||
{% if author.email %}<{{ author.email|linkify }}>{% endif %}
|
||||
<br>
|
||||
{% if author.affiliation %}
|
||||
|
|
|
@ -11,12 +11,14 @@
|
|||
</p>
|
||||
{% load ietf_filters %}
|
||||
{% for author in submission.authors %}
|
||||
<button type="button"
|
||||
class="author btn btn-primary mb-3"
|
||||
data-name="{{ author.name }}"
|
||||
data-email="{% if author.email %}{{ author.email }}{% endif %}">
|
||||
{{ author.name }}
|
||||
</button>
|
||||
{% if author.name %}
|
||||
<button type="button"
|
||||
class="author btn btn-primary mb-3"
|
||||
data-name="{{ author.name }}"
|
||||
data-email="{% if author.email %}{{ author.email }}{% endif %}">
|
||||
{{ author.name }}
|
||||
</button>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% bootstrap_form_errors submitter_form %}
|
||||
{% bootstrap_field submitter_form.name %}
|
||||
|
|
|
@ -486,6 +486,51 @@ class XMLDraftTests(TestCase):
|
|||
("-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):
|
||||
|
||||
|
|
|
@ -179,6 +179,29 @@ class XMLDraft(Draft):
|
|||
# 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 @@ class XMLDraft(Draft):
|
|||
|
||||
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'),
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue