Merged changes from current trunk to Py3 branch.
- Legacy-Id: 16468
This commit is contained in:
commit
e03784132d
8
PLAN
8
PLAN
|
@ -15,6 +15,14 @@ Planned work in rough order
|
|||
* Transition to Python 3. This will make it easier to add add support for
|
||||
internationalsed email, and also other i18n enhancements.
|
||||
|
||||
* Change the draft submission form so that an email address is required for
|
||||
each author in order to complete self-service draft submission. Missing
|
||||
email address(es) will lead to failure, and require submission via the
|
||||
secretariat (where email addresses for all will also be required).
|
||||
|
||||
* Simplify submission if submitter is logged into the datatracker, skipping the
|
||||
email verification step.
|
||||
|
||||
* Polish the htmlization pages, making the style identical with tools.ietf.org.
|
||||
|
||||
* Revisit the review tool, work through the accumulated tickets.
|
||||
|
|
68
changelog
68
changelog
|
@ -1,3 +1,71 @@
|
|||
ietfdb (6.98.4) ietf; urgency=medium
|
||||
|
||||
This is a small bugfix release, to clear the slate before merging
|
||||
in the Python 2/3 conversion. From the commit log:
|
||||
|
||||
* Added a validation step for SearchablePersonField, to avoid later
|
||||
server 500 errors on bad input.
|
||||
|
||||
* Merged in [16404] from rjsparks@nostrum.com:
|
||||
Only look for ietf/datatracker-env images when extracting the most
|
||||
recent build to tag as latest.
|
||||
|
||||
* Merged in [16359] from rcross@amsl.com:
|
||||
Fix registration import, use user.person if it exists.
|
||||
|
||||
* Merged in [16096] from rcross@amsl.com:
|
||||
Update admin permissions. Grant secretariat change permissions on
|
||||
dbtemplate so they can update proceedings pages.
|
||||
|
||||
* Turned off html autoescape in IPR email templates. This fixes
|
||||
inappropriate html escapes that occurred in various IPR-related
|
||||
emails.
|
||||
|
||||
* Added missing code to skip coverage measurement for skippable tests.
|
||||
|
||||
-- Henrik Levkowetz <henrik@levkowetz.com> 16 Jul 2019 14:14:12 +0000
|
||||
|
||||
|
||||
ietfdb (6.98.3) ietf; urgency=medium
|
||||
|
||||
* Increased the length of the list Subscribed email field from 64 to 128,
|
||||
updated the import_mailman_listinfo management command, and added a
|
||||
migration for the model change.
|
||||
|
||||
-- Henrik Levkowetz <henrik@levkowetz.com> 04 Jul 2019 16:07:14 +0000
|
||||
|
||||
|
||||
ietfdb (6.98.2) ietf; urgency=medium
|
||||
|
||||
This is a minor release that fixes some bugs and tweaks some settings.
|
||||
From the commit log:
|
||||
|
||||
* Changed some tests to match production group type changes for some special
|
||||
groups.
|
||||
|
||||
* Made the bin/daily cron script quiteter.
|
||||
|
||||
* Various changes to make yang-related management commands quieter
|
||||
|
||||
* Added a fix for an issue in get_meeting_registration_data() which could
|
||||
happen if we tried to create a Person record for with a user of an
|
||||
existing Person.
|
||||
|
||||
* Changed the permitted length of patent_title from 127 to 255.
|
||||
|
||||
* Added additional guards against duplicate m2m entries.
|
||||
|
||||
* Added a utility to check copyright statements in specified files.
|
||||
|
||||
* Updated some functions and views in secr/srec/ to use GroupFeatures
|
||||
instead of hardcoded lists of group types.
|
||||
|
||||
* Made session requests also work for ad-hoc groups, which may not have a
|
||||
parent area.
|
||||
|
||||
-- Henrik Levkowetz <henrik@levkowetz.com> 03 Jul 2019 20:27:54 +0000
|
||||
|
||||
|
||||
ietfdb (6.98.1) ietf; urgency=medium
|
||||
|
||||
This is a bugfix release that cleans up some remaining issues from the
|
||||
|
|
|
@ -123,6 +123,6 @@ fi
|
|||
|
||||
docker rmi -f ietf/datatracker-environment:trunk || true
|
||||
docker build -t ietf/datatracker-environment:$TAG docker/
|
||||
docker tag $(docker images -q | head -n 1) ietf/datatracker-environment:latest
|
||||
docker tag $(docker images -q ietf/datatracker-environment | head -n 1) ietf/datatracker-environment:latest
|
||||
docker push ietf/datatracker-environment:latest
|
||||
docker push ietf/datatracker-environment:$TAG
|
||||
docker push ietf/datatracker-environment:$TAG
|
||||
|
|
|
@ -7,13 +7,13 @@ from __future__ import absolute_import, print_function, unicode_literals
|
|||
from . import checks # pyflakes:ignore
|
||||
|
||||
# Don't add patch number here:
|
||||
__version__ = "6.98.2.dev0"
|
||||
__version__ = "6.98.5.dev0"
|
||||
|
||||
# set this to ".p1", ".p2", etc. after patching
|
||||
__patch__ = ""
|
||||
|
||||
__date__ = "$Date$"
|
||||
|
||||
__rev__ = "$Rev$ (dev) Latest release: Rev. 16294 "
|
||||
__rev__ = "$Rev$ (dev) Latest release: Rev. 16464 "
|
||||
|
||||
__id__ = "$Id$"
|
||||
|
|
|
@ -55,6 +55,7 @@ def main():
|
|||
|
||||
# Set Auth Group Admin Permissions
|
||||
names = ['auth.add_user','auth.change_user','auth.delete_user',
|
||||
'dbtemplate.change_dbtemplate',
|
||||
'group.add_group','group.change_group','group.delete_group',
|
||||
'group.add_role','group.change_role','group.delete_role',
|
||||
'group.add_groupevent','group.change_groupevent','group.delete_groupevent',
|
||||
|
|
|
@ -88,7 +88,8 @@ class CommunityListTests(TestCase):
|
|||
|
||||
# with list
|
||||
clist = CommunityList.objects.create(user=User.objects.get(username="plain"))
|
||||
clist.added_docs.add(draft)
|
||||
if not draft in clist.added_docs.all():
|
||||
clist.added_docs.add(draft)
|
||||
SearchRule.objects.create(
|
||||
community_list=clist,
|
||||
rule_type="name_contains",
|
||||
|
@ -250,7 +251,8 @@ class CommunityListTests(TestCase):
|
|||
|
||||
# with list
|
||||
clist = CommunityList.objects.create(user=User.objects.get(username="plain"))
|
||||
clist.added_docs.add(draft)
|
||||
if not draft in clist.added_docs.all():
|
||||
clist.added_docs.add(draft)
|
||||
SearchRule.objects.create(
|
||||
community_list=clist,
|
||||
rule_type="name_contains",
|
||||
|
@ -285,7 +287,8 @@ class CommunityListTests(TestCase):
|
|||
|
||||
# with list
|
||||
clist = CommunityList.objects.create(user=User.objects.get(username="plain"))
|
||||
clist.added_docs.add(draft)
|
||||
if not draft in clist.added_docs.all():
|
||||
clist.added_docs.add(draft)
|
||||
SearchRule.objects.create(
|
||||
community_list=clist,
|
||||
rule_type="name_contains",
|
||||
|
@ -326,7 +329,8 @@ class CommunityListTests(TestCase):
|
|||
|
||||
# subscription with list
|
||||
clist = CommunityList.objects.create(user=User.objects.get(username="plain"))
|
||||
clist.added_docs.add(draft)
|
||||
if not draft in clist.added_docs.all():
|
||||
clist.added_docs.add(draft)
|
||||
SearchRule.objects.create(
|
||||
community_list=clist,
|
||||
rule_type="name_contains",
|
||||
|
@ -369,7 +373,8 @@ class CommunityListTests(TestCase):
|
|||
draft = WgDraftFactory()
|
||||
|
||||
clist = CommunityList.objects.create(user=User.objects.get(username="plain"))
|
||||
clist.added_docs.add(draft)
|
||||
if not draft in clist.added_docs.all():
|
||||
clist.added_docs.add(draft)
|
||||
|
||||
EmailSubscription.objects.create(community_list=clist, email=Email.objects.filter(person__user__username="plain").first(), notify_on="significant")
|
||||
|
||||
|
|
|
@ -59,7 +59,8 @@ def manage_list(request, username=None, acronym=None, group_type=None):
|
|||
clist.save()
|
||||
|
||||
for d in add_doc_form.cleaned_data['documents']:
|
||||
clist.added_docs.add(d)
|
||||
if not d in clist.added_docs.all():
|
||||
clist.added_docs.add(d)
|
||||
|
||||
return HttpResponseRedirect("")
|
||||
else:
|
||||
|
@ -136,7 +137,8 @@ def track_document(request, name, username=None, acronym=None):
|
|||
if clist.pk is None:
|
||||
clist.save()
|
||||
|
||||
clist.added_docs.add(doc)
|
||||
if not doc in clist.added_docs.all():
|
||||
clist.added_docs.add(doc)
|
||||
|
||||
if request.is_ajax():
|
||||
return HttpResponse(json.dumps({ 'success': True }), content_type='application/json')
|
||||
|
|
|
@ -101,8 +101,6 @@ class ReviewTests(TestCase):
|
|||
|
||||
self.assertEqual(len(outbox),2)
|
||||
self.assertTrue('reviewteam Early' in outbox[0]['Subject'])
|
||||
if not 'reviewsecretary@' in outbox[0]['To']:
|
||||
print(outbox[0].as_string())
|
||||
self.assertTrue('reviewsecretary@' in outbox[0]['To'])
|
||||
self.assertTrue('reviewteam3 Early' in outbox[1]['Subject'])
|
||||
if not 'reviewsecretary3@' in outbox[1]['To']:
|
||||
|
|
|
@ -11,6 +11,8 @@ from django.utils.html import escape
|
|||
from django import forms
|
||||
from django.urls import reverse as urlreverse
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
from ietf.ipr.models import IprDisclosureBase
|
||||
|
||||
def select2_id_ipr_title_json(value):
|
||||
|
|
|
@ -160,7 +160,7 @@ class GenericDisclosureForm(forms.Form):
|
|||
patent_number = forms.CharField(max_length=127, required=False, validators=[ validate_patent_number ],
|
||||
help_text = "Patent publication or application number (2-letter country code followed by serial number)")
|
||||
patent_inventor = forms.CharField(max_length=63, required=False, validators=[ validate_name ], help_text="Inventor name")
|
||||
patent_title = forms.CharField(max_length=127, required=False, validators=[ validate_title ], help_text="Title of invention")
|
||||
patent_title = forms.CharField(max_length=255, required=False, validators=[ validate_title ], help_text="Title of invention")
|
||||
patent_date = forms.DateField(required=False, help_text="Date granted or applied for")
|
||||
patent_notes = forms.CharField(max_length=1024, required=False, widget=forms.Textarea)
|
||||
|
||||
|
@ -229,7 +229,7 @@ class IprDisclosureFormBase(forms.ModelForm):
|
|||
patent_number = forms.CharField(max_length=127, required=True, validators=[ validate_patent_number ],
|
||||
help_text = "Patent publication or application number (2-letter country code followed by serial number)")
|
||||
patent_inventor = forms.CharField(max_length=63, required=True, validators=[ validate_name ], help_text="Inventor name")
|
||||
patent_title = forms.CharField(max_length=127, required=True, validators=[ validate_title ], help_text="Title of invention")
|
||||
patent_title = forms.CharField(max_length=255, required=True, validators=[ validate_title ], help_text="Title of invention")
|
||||
patent_date = forms.DateField(required=True, help_text="Date granted or applied for")
|
||||
patent_notes = forms.CharField(max_length=1024, required=False, widget=forms.Textarea)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright The IETF Trust 2016, All Rights Reserved
|
||||
# Copyright The IETF Trust 2016-2019, All Rights Reserved
|
||||
|
||||
import sys
|
||||
from textwrap import dedent
|
||||
|
@ -35,6 +35,7 @@ def import_mailman_listinfo(verbosity=0):
|
|||
|
||||
names = list(Utils.list_names())
|
||||
names.sort()
|
||||
addr_max_length = Subscribed._meta.get_field('email').max_length
|
||||
for name in names:
|
||||
mlist = MailList.MailList(name, lock=False)
|
||||
note("List: %s" % mlist.internal_name())
|
||||
|
@ -62,7 +63,7 @@ def import_mailman_listinfo(verbosity=0):
|
|||
note(" Removing address with no subscriptions: %s" % (addr))
|
||||
old.delete()
|
||||
for addr in members:
|
||||
if len(addr) > 64:
|
||||
if len(addr) > addr_max_length:
|
||||
sys.stderr.write(" ** Email address subscribed to '%s' too long for table: <%s>\n" % (name, addr))
|
||||
continue
|
||||
if not addr in known:
|
||||
|
|
22
ietf/mailinglists/migrations/0002_auto_20190703_1344.py
Normal file
22
ietf/mailinglists/migrations/0002_auto_20190703_1344.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright The IETF Trust 2019, All Rights Reserved
|
||||
# Generated by Django 1.11.22 on 2019-07-03 13:44
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mailinglists', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='subscribed',
|
||||
name='email',
|
||||
field=models.CharField(max_length=128, validators=[django.core.validators.EmailValidator()]),
|
||||
),
|
||||
]
|
|
@ -26,7 +26,7 @@ class List(models.Model):
|
|||
@python_2_unicode_compatible
|
||||
class Subscribed(models.Model):
|
||||
time = models.DateTimeField(auto_now_add=True)
|
||||
email = models.CharField(max_length=64, validators=[validate_email])
|
||||
email = models.CharField(max_length=128, validators=[validate_email])
|
||||
lists = models.ManyToManyField(List)
|
||||
def __str__(self):
|
||||
return "<Subscribed: %s at %s>" % (self.email, self.time)
|
||||
|
|
|
@ -34,8 +34,9 @@ from ietf.meeting.models import Session, TimeSlot, Meeting, SchedTimeSessAssignm
|
|||
from ietf.meeting.test_data import make_meeting_test_data, make_interim_meeting
|
||||
from ietf.meeting.utils import finalize
|
||||
from ietf.name.models import SessionStatusName, ImportantDateName
|
||||
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
|
||||
from ietf.utils.decorators import skip_coverage
|
||||
from ietf.utils.mail import outbox, empty_outbox
|
||||
from ietf.utils.test_utils import TestCase, login_testing_unauthorized, unicontent
|
||||
from ietf.utils.text import xslugify
|
||||
|
||||
from ietf.person.factories import PersonFactory
|
||||
|
@ -490,6 +491,7 @@ class MeetingTests(TestCase):
|
|||
os.unlink(filename)
|
||||
|
||||
@skipIf(skip_pdf_tests, skip_message)
|
||||
@skip_coverage
|
||||
def test_session_draft_pdf(self):
|
||||
session = SessionFactory(group__type_id='wg',meeting__type_id='ietf')
|
||||
doc = DocumentFactory(type_id='draft')
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,9 +10,10 @@ import six
|
|||
from collections import Counter
|
||||
from six.moves.urllib.parse import urlencode
|
||||
|
||||
from django.utils.html import escape
|
||||
from django import forms
|
||||
from django.core.validators import validate_email
|
||||
from django.urls import reverse as urlreverse
|
||||
from django.utils.html import escape
|
||||
|
||||
import debug # pyflakes:ignore
|
||||
|
||||
|
@ -76,6 +77,16 @@ class SearchablePersonsField(forms.CharField):
|
|||
def parse_select2_value(self, value):
|
||||
return [x.strip() for x in value.split(",") if x.strip()]
|
||||
|
||||
def check_pks(self, pks):
|
||||
if self.model == Person:
|
||||
for pk in pks:
|
||||
if not pk.isdigit():
|
||||
raise forms.ValidationError("Unexpected value: %s" % pk)
|
||||
elif self.model == Email:
|
||||
for pk in pks:
|
||||
validate_email(pk)
|
||||
return pks
|
||||
|
||||
def prepare_value(self, value):
|
||||
if not value:
|
||||
value = ""
|
||||
|
@ -105,7 +116,7 @@ class SearchablePersonsField(forms.CharField):
|
|||
|
||||
def clean(self, value):
|
||||
value = super(SearchablePersonsField, self).clean(value)
|
||||
pks = self.parse_select2_value(value)
|
||||
pks = self.check_pks(self.parse_select2_value(value))
|
||||
|
||||
objs = self.model.objects.filter(pk__in=pks)
|
||||
if self.model == Email:
|
||||
|
|
|
@ -50,7 +50,7 @@ class SessionRequestTestCase(TestCase):
|
|||
self.assertEqual(r.status_code, 200)
|
||||
sched = r.context['scheduled_groups']
|
||||
unsched = r.context['unscheduled_groups']
|
||||
self.assertEqual(len(unsched),3)
|
||||
self.assertEqual(len(unsched),8)
|
||||
self.assertEqual(len(sched),2)
|
||||
|
||||
def test_approve(self):
|
||||
|
|
|
@ -91,7 +91,7 @@ def get_requester_text(person,group):
|
|||
roles = group.role_set.filter(name__in=('chair','secr'),person=person)
|
||||
if roles:
|
||||
return '%s, a %s of the %s working group' % (person.ascii, roles[0].name, group.acronym)
|
||||
if group.parent.role_set.filter(name='ad',person=person):
|
||||
if group.parent and group.parent.role_set.filter(name='ad',person=person):
|
||||
return '%s, a %s Area Director' % (person.ascii, group.parent.acronym.upper())
|
||||
if person.role_set.filter(name='secr',group__acronym='secretariat'):
|
||||
return '%s, on behalf of the %s working group' % (person.ascii, group.acronym)
|
||||
|
@ -494,7 +494,8 @@ def main(request):
|
|||
)
|
||||
|
||||
meeting = get_meeting()
|
||||
scheduled_groups,unscheduled_groups = groups_by_session(request.user, meeting, types=['wg','rg','ag'])
|
||||
|
||||
scheduled_groups, unscheduled_groups = groups_by_session(request.user, meeting)
|
||||
|
||||
# warn if there are no associated groups
|
||||
if not scheduled_groups and not unscheduled_groups:
|
||||
|
|
|
@ -13,7 +13,7 @@ from django.conf import settings
|
|||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
# Datatracker imports
|
||||
from ietf.group.models import Group
|
||||
from ietf.group.models import Group, GroupFeatures
|
||||
from ietf.meeting.models import Session
|
||||
from ietf.ietfauth.utils import has_role
|
||||
|
||||
|
@ -56,9 +56,8 @@ def get_my_groups(user,conclude=False):
|
|||
states = ['bof','proposed','active']
|
||||
if conclude:
|
||||
states.extend(['conclude','bof-conc'])
|
||||
types = ['wg','rg','ag','team','iab']
|
||||
|
||||
all_groups = Group.objects.filter(type__in=types,state__in=states).order_by('acronym')
|
||||
|
||||
all_groups = Group.objects.filter(type__features__has_meetings=True, state__in=states).order_by('acronym')
|
||||
if user == None or has_role(user,'Secretariat'):
|
||||
return all_groups
|
||||
|
||||
|
@ -101,8 +100,10 @@ def groups_by_session(user, meeting, types=None):
|
|||
if group.state_id not in ('conclude','bof-conc'):
|
||||
groups_no_session.append(group)
|
||||
|
||||
if types:
|
||||
groups_session = [x for x in groups_session if x.type_id in types]
|
||||
groups_no_session = [x for x in groups_no_session if x.type_id in types]
|
||||
if not types:
|
||||
types = GroupFeatures.objects.filter(has_meetings=True).values_list('type', flat=True)
|
||||
|
||||
groups_session = [x for x in groups_session if x.type_id in types]
|
||||
groups_no_session = [x for x in groups_no_session if x.type_id in types]
|
||||
|
||||
return groups_session, groups_no_session
|
||||
|
|
|
@ -63,7 +63,6 @@ ADMINS = (
|
|||
# ('Ole Laursen', 'olau@iola.dk'),
|
||||
('Ryan Cross', 'rcross@amsl.com'),
|
||||
('Glen Barney', 'glen@amsl.com'),
|
||||
('Matt Larson', 'mlarson@amsl.com'),
|
||||
)
|
||||
|
||||
BUG_REPORT_EMAIL = "datatracker-project@ietf.org"
|
||||
|
|
|
@ -294,16 +294,19 @@ def get_meeting_registration_data(meeting):
|
|||
email=address,
|
||||
)
|
||||
|
||||
aliases = Alias.objects.filter(name=regname)
|
||||
if aliases.exists():
|
||||
person = aliases.first().person
|
||||
else:
|
||||
# Create the new Person object.
|
||||
person = Person.objects.create(
|
||||
name=regname,
|
||||
ascii=ascii_name,
|
||||
user=user,
|
||||
)
|
||||
try:
|
||||
person = user.person
|
||||
except Person.DoesNotExist:
|
||||
aliases = Alias.objects.filter(name=regname)
|
||||
if aliases.exists():
|
||||
person = aliases.first().person
|
||||
else:
|
||||
# Create the new Person object.
|
||||
person = Person.objects.create(
|
||||
name=regname,
|
||||
ascii=ascii_name,
|
||||
user=user,
|
||||
)
|
||||
|
||||
# Create an associated Email address for this Person
|
||||
try:
|
||||
|
|
|
@ -84,7 +84,9 @@ def has_been_replaced_by(name):
|
|||
return None
|
||||
|
||||
def validate_submission_name(name):
|
||||
if not re.search(r'^draft-[a-z][-a-z0-9]{0,43}$', name):
|
||||
if not re.search(r'^draft-[a-z][-a-z0-9]{0,43}(-\d\d)?$', name):
|
||||
if re.search(r'-\d\d$', name):
|
||||
name = name[:-3]
|
||||
if len(name) > 50:
|
||||
return "Expected the draft name to be at most 50 ascii characters long; found %d." % len(name)
|
||||
else:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load ietf_filters %}
|
||||
{% autoescape off %}{% load ietf_filters %}
|
||||
The Patent Holder states that its position with respect to licensing any patent claims
|
||||
contained in the patent(s) or patent application(s) disclosed above that would necessarily
|
||||
be infringed by implementation of the technology required by the relevant IETF
|
||||
|
@ -29,3 +29,4 @@ specification, is as follows(select one licensing declaration option only):
|
|||
{% endif %}Licensing information, comments, notes or URL for further information:
|
||||
|
||||
{{ info|safe|wordwrap:76|indent }}
|
||||
{% endautoescape %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load ietf_filters %}To: {{ to_email }}
|
||||
{% autoescape off %}{% load ietf_filters %}To: {{ to_email }}
|
||||
From: IETF Secretariat <ietf-ipr@ietf.org>
|
||||
Subject: IPR Disclosure {{ ipr.title }}
|
||||
Cc: {{ cc_email }}
|
||||
|
@ -12,3 +12,4 @@ An IPR disclosure that pertains to your {{ doc_info }} was submitted to the IETF
|
|||
Thank you
|
||||
|
||||
IETF Secretariat
|
||||
{% endautoescape %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
To: {{ to_email }}
|
||||
{% autoescape off %}To: {{ to_email }}
|
||||
From: IETF Secretariat <ietf-ipr@ietf.org>
|
||||
Subject: Posting of IPR Disclosure
|
||||
Cc:
|
||||
|
@ -12,4 +12,5 @@ and has been posted on the "IETF Page of Intellectual Property Rights Disclosure
|
|||
|
||||
Thank you
|
||||
|
||||
IETF Secretariat
|
||||
IETF Secretariat
|
||||
{% endautoescape %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
To: {{ to_email }}
|
||||
{% autoescape off %}To: {{ to_email }}
|
||||
From: IETF Secretariat <ietf-ipr@ietf.org>
|
||||
Subject: Posting of IPR {% if ipr.updates %}Updated {% endif %}Disclosure
|
||||
Cc: {{ cc_email }}
|
||||
|
@ -17,4 +17,5 @@ IPR disclosure ID #{{ rel.target.pk }}, "{{ rel.target.title }}", which was post
|
|||
|
||||
Thank you
|
||||
|
||||
IETF Secretariat
|
||||
IETF Secretariat
|
||||
{% endautoescape %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
To: {{ to_email }}
|
||||
{% autoescape off %}To: {{ to_email }}
|
||||
From: IETF Secretariat <ietf-ipr@ietf.org>
|
||||
Subject: IPR update notification
|
||||
Reply-To: {{ reply_to }}
|
||||
|
@ -24,4 +24,5 @@ the update until we can be assured it is authorized.
|
|||
|
||||
Thank you
|
||||
|
||||
IETF Secretariat
|
||||
IETF Secretariat
|
||||
{% endautoescape %}
|
||||
|
|
|
@ -281,7 +281,8 @@ def condition_message(to, frm, subject, msg, cc, extra):
|
|||
if name:
|
||||
to_hdr.append('"%s"' % name)
|
||||
to_hdr.append("<%s>," % addr)
|
||||
to_str = to_hdr.encode('utf-8')
|
||||
# Please note: The following .encode() does _not_ take a charset argument
|
||||
to_str = to_hdr.encode()
|
||||
if to_str and to_str[-1] == ',':
|
||||
to_str=to_str[:-1]
|
||||
# It's important to use this string, and not assign the Header object.
|
||||
|
|
|
@ -82,7 +82,7 @@ class Command(BaseCommand):
|
|||
modfile.rename(str(moddir/name))
|
||||
model_list = [ n.replace('"','') for n in model_list ]
|
||||
except Exception as e:
|
||||
print("** Error when extracting from %s: %s" % (file, str(e)))
|
||||
self.stderr.write("** Error when extracting from %s: %s" % (file, str(e)))
|
||||
sys.stdout = saved_stdout
|
||||
sys.stderr = saved_stderr
|
||||
#
|
||||
|
@ -107,7 +107,8 @@ class Command(BaseCommand):
|
|||
if item.stat().st_mtime > latest:
|
||||
latest = item.stat().st_mtime
|
||||
|
||||
print("Extracting to %s ..." % moddir)
|
||||
if verbosity > 0:
|
||||
self.stdout.write("Extracting to %s ..." % moddir)
|
||||
for item in rfcdir.iterdir():
|
||||
if item.is_file() and item.name.startswith('rfc') and item.name.endswith('.txt') and item.name[3:-4].isdigit():
|
||||
if item.stat().st_mtime > latest:
|
||||
|
@ -115,16 +116,17 @@ class Command(BaseCommand):
|
|||
for name in model_list:
|
||||
if name.startswith('ietf') or name.startswith('iana'):
|
||||
if verbosity > 1:
|
||||
print(" Extracted from %s: %s" % (item, name))
|
||||
else:
|
||||
sys.stdout.write('.')
|
||||
sys.stdout.flush()
|
||||
self.stdout.write(" Extracted from %s: %s" % (item, name))
|
||||
elif verbosity > 0:
|
||||
self.stdout.write('.', ending='')
|
||||
self.stdout.flush()
|
||||
else:
|
||||
modfile = moddir / name
|
||||
modfile.unlink()
|
||||
if verbosity > 1:
|
||||
print(" Skipped module from %s: %s" % (item, name))
|
||||
print("")
|
||||
self.stdout.write(" Skipped module from %s: %s" % (item, name))
|
||||
if verbosity > 0:
|
||||
self.stdout.write("")
|
||||
|
||||
# Extract valid modules from drafts
|
||||
|
||||
|
@ -137,11 +139,13 @@ class Command(BaseCommand):
|
|||
moddir = Path(settings.SUBMIT_YANG_DRAFT_MODEL_DIR)
|
||||
if not moddir.exists():
|
||||
moddir.mkdir(parents=True)
|
||||
print("Emptying %s ..." % moddir)
|
||||
if verbosity > 0:
|
||||
self.stdout.write("Emptying %s ..." % moddir)
|
||||
for item in moddir.iterdir():
|
||||
item.unlink()
|
||||
|
||||
print("Extracting to %s ..." % moddir)
|
||||
if verbosity > 0:
|
||||
self.stdout.write("Extracting to %s ..." % moddir)
|
||||
for item in draftdir.iterdir():
|
||||
try:
|
||||
if item.is_file() and item.name.startswith('draft') and item.name.endswith('.txt') and active(item):
|
||||
|
@ -149,18 +153,19 @@ class Command(BaseCommand):
|
|||
for name in model_list:
|
||||
if not name.startswith('example'):
|
||||
if verbosity > 1:
|
||||
print(" Extracted module from %s: %s" % (item, name))
|
||||
else:
|
||||
sys.stdout.write('.')
|
||||
sys.stdout.flush()
|
||||
self.stdout.write(" Extracted module from %s: %s" % (item, name))
|
||||
elif verbosity > 0:
|
||||
self.stdout.write('.', ending='')
|
||||
self.stdout.flush()
|
||||
else:
|
||||
modfile = moddir / name
|
||||
modfile.unlink()
|
||||
if verbosity > 1:
|
||||
print(" Skipped module from %s: %s" % (item, name))
|
||||
self.stdout.write(" Skipped module from %s: %s" % (item, name))
|
||||
except UnicodeDecodeError as e:
|
||||
sys.stderr.write('\nError: %s\n' % (e, ))
|
||||
sys.stderr.write(item.name)
|
||||
sys.stderr.write('\n')
|
||||
print("")
|
||||
self.stderr.write('\nError: %s' % (e, ))
|
||||
self.stderr.write(item.name)
|
||||
self.stderr.write('')
|
||||
if verbosity > 0:
|
||||
self.stdout.write('')
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
|
||||
import sys
|
||||
import json
|
||||
|
||||
from textwrap import dedent
|
||||
|
@ -40,8 +39,8 @@ class Command(BaseCommand):
|
|||
def check_yang(self, checker, draft, force=False):
|
||||
if self.verbosity > 1:
|
||||
self.stdout.write("Checking %s-%s" % (draft.name, draft.rev))
|
||||
else:
|
||||
sys.stderr.write('.')
|
||||
elif self.verbosity > 0:
|
||||
self.stderr.write('.', ending='')
|
||||
submission = Submission.objects.filter(name=draft.name, rev=draft.rev).order_by('-id').first()
|
||||
if submission or force:
|
||||
check = submission.checks.filter(checker=checker.name).order_by('-id').first()
|
||||
|
@ -62,7 +61,7 @@ class Command(BaseCommand):
|
|||
message=message, errors=errors, warnings=warnings, items=items,
|
||||
symbol=checker.symbol)
|
||||
else:
|
||||
self.stderr.write("Error: did not find any submission object for %s-%s\n" % (draft.name, draft.rev))
|
||||
self.stderr.write("Error: did not find any submission object for %s-%s" % (draft.name, draft.rev))
|
||||
|
||||
def handle(self, *filenames, **options):
|
||||
"""
|
||||
|
|
|
@ -79,16 +79,16 @@ def make_immutable_base_data():
|
|||
iab = create_group(name="Internet Architecture Board", acronym="iab", type_id="ietf", parent=ietf)
|
||||
create_person(iab, "chair")
|
||||
|
||||
ise = create_group(name="Independent Submission Editor", acronym="ise", type_id="ietf")
|
||||
ise = create_group(name="Independent Submission Editor", acronym="ise", type_id="rfcedtyp")
|
||||
create_person(ise, "chair")
|
||||
|
||||
rsoc = create_group(name="RFC Series Oversight Committee", acronym="rsoc", type_id="ietf")
|
||||
rsoc = create_group(name="RFC Series Oversight Committee", acronym="rsoc", type_id="rfcedtyp")
|
||||
create_person(rsoc, "chair")
|
||||
|
||||
iepg = create_group(name="IEPG", acronym="iepg", type_id="ietf")
|
||||
iepg = create_group(name="IEPG", acronym="iepg", type_id="adhoc")
|
||||
create_person(iepg, "chair")
|
||||
|
||||
iana = create_group(name="IANA", acronym="iana", type_id="ietf")
|
||||
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")
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue